繁体   English   中英

Spring-AOP切入点不起作用?

[英]Spring-AOP pointcut not working?

以下是我的代码段:

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");
    }
  }
}

现在,我想要的是每当从方法worker(Request request, String id)抛出NullPointerExceptionworker(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. 在我的应用程序中,还有其他方面的类也可以正常工作。

您犯了一个典型的Spring AOP初学者错误:您假定它适用于私有方法,但正如文档明确指出的那样,它不是。 Spring AOP基于动态代理,当通过JDK代理实现接口时,它们仅适用于公共方法,而使用CGLIB代理时,仅适用于受保护的和程序包作用域的方法。

如果要从一个方面截获该方法,则应公开worker()方法。

PS:成熟的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) {}

要拦截引发异常的方法,您可以使用以下代码(仅在方法是公共的情况下有效):

 @AfterThrowing(pointcut="com.xyz.myapp.SystemArchitecture.dataAccessOperation()",throwing="ex")
         public void doRecoveryActions(NullPointerException ex) {
          // ...
         }

资料来源: Spring AOP

暂无
暂无

声明:本站的技术帖子网页,遵循CC BY-SA 4.0协议,如果您需要转载,请注明本站网址或者原文地址。任何问题请咨询:yoyou2525@163.com.

 
粤ICP备18138465号  © 2020-2024 STACKOOM.COM