Spring-AOP切入点不起作用?

时间:2017-03-22 11:35:26

标签: java spring-aop

以下是我的代码段:

ServiceImpl.java

@Service
public class ServiceImpl implements Service {
  private Response worker(Audit send) throws ArgumentException {
    System.out.println("STEP_1");
    worker(send.getRequest(), send.getId());
  }

  private Response worker(Request request, String id) throws ArgumentException {
    System.out.println("STEP_2");
    try {
      //throwing some exception
    } catch (Exception e) {
      System.out.println("STEP_3");
    }
  }
}

现在,我想要的是从方法NullPointerException抛出worker(Request request, String id),如上所示,我想执行一些特定的任务。为此,我写了一个Aspect类,其中包括:

MyAspect.java

@Aspect
@Component
public class MyAspect{
  @Pointcut("com.xyz.myapp.ServiceImpl.worker() && args(request,..)")
  private void someOperation(Request request) {}

  @Before("someOperation(request)")
  public void process(Request request) {
    System.out.println("SUCCESS");
  }

  @AfterThrowing("com.xyz.myapp.ServiceImpl.worker() && args(request,..)")
  public void doRecoveryActions() {
    System.out.println("EXCEPTION_SUCCESS");
  }
}

当前输出:

STEP_1 
STEP_2
STEP_3

期望输出:

STEP_1 
STEP_2
STEP_3
SUCCESS
EXCEPTION_SUCCESS

正如您所看到的,MyAspect.java未被触发,因此不打印值。 这可能是什么原因?

注意:

  1. 我也尝试将工人作为公共课程,但它没有用。

  2. 还尝试更改方法的名称,以消除任何无法解决的超载问题。

  3. 截至目前,尝试各种其他切入点表达式都是徒劳的。

  4. 在我的应用程序中,还有其他方面类可以正常工作。

2 个答案:

答案 0 :(得分:3)

你做了一个典型的Spring AOP初学者的错误:你认为它适用于私有方法,但正如文档明确指出的那样,它没有。 Spring AOP基于动态代理,当使用CGKIB代理实现接口时,它们仅适用于公共方法,还适用于受保护和包范围方法。

如果你想从一个方面拦截它,你应该公开worker()方法。

P.S。:完全成熟的AspectJ也适用于私有方法,但是切换到另一个AOP框架在这里会有点过分。

更新:您的代码中还有其他问题:

  • 第一个worker方法,即使您将其公开,也不会返回任何内容。最后一个语句应为return worker(send.getRequest(), send.getId());,而不仅仅是worker(send.getRequest(), send.getId());
  • 你的切入点com.xyz.myapp.ServiceImpl.worker()永远不会匹配,因为它有一个空参数列表,但你的方法有参数。 args()对您没有帮助。
  • 切入点的语法也是错误的,因为它没有为方法指定返回类型,甚至不指定*。此外,方法名称本身是不够的,它应该包含在实际的切入点类型中,例如execution()。即你想写一些类似的东西:
@Pointcut("execution(* com.xyz.myapp.ServiceImpl.worker(..)) && args(request, ..)")
private void someOperation(Request request) {}

答案 1 :(得分:0)

要拦截抛出异常的方法,您可以使用此代码(仅当方法是公共的时才有效):

calendarView.calendarWeekdayView.removeFromSuperview()

来源:Spring AOP