当前位置: 首页 > 知识库问答 >
问题:

Spring AOP切入点不工作?

微生毅
2023-03-14

下面是我的代码片段:

服务我mpl.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(请求,字符串id)抛出null点异常时,我想要执行一些特定的任务,如上图所示。为此,我编写了一个方面类,如下所示:

我的方面。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没有被触发,因此没有打印值。这是什么原因?

注:

>

还尝试更改方法的名称,以消除任何也不起作用的重载问题。

到目前为止,尝试了各种其他切入点的表达方式都没有成功。

在我的应用程序中,还有其他方面的类工作得非常好。

共有2个答案

墨财
2023-03-14

要拦截引发异常的方法,可以使用以下代码(仅当方法是公共的时才有效):

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

资料来源:Spring AOP

井镜
2023-03-14

您犯了一个典型的Spring AOP初学者错误:您假设它适用于私有方法,但正如文档中明确指出的那样,它不适用。Spring AOP基于动态代理,当通过JDK代理实现接口时,这些代理仅适用于公共方法,此外,当使用CGLIB代理时,这些代理还适用于受保护和包范围的方法。

如果您想从方面拦截它,您应该将ker()方法公开。

P、 美国:成熟的AspectJ也适用于私有方法,但在这里切换到另一个AOP框架就太过分了。

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

  • 第一个工人方法,即使你把它公开,也不返回任何东西,最后一条语句应该是返回工人(send.getRequest(),send.getId());,而不仅仅是工人(send.getRequest(),send.getId());.
  • 您的切入点com.xyz.myapp.ServiceImpl.worker()永远不会匹配,因为它有一个空参数列表,但您的方法有参数。args()在这里对您没有帮助。
  • 您的切入点的语法也是错误的,因为它没有为方法指定返回类型,甚至没有*。此外,方法名称本身还不够,它应该包含在实际的切入点类型中,例如执行()。即,您想编写如下内容:
@Pointcut("execution(* com.xyz.myapp.ServiceImpl.worker(..)) && args(request, ..)")
private void someOperation(Request request) {}
 类似资料:
  • 在Spring中将一个方面配置为: 是: } 如果我使用注释实现方法,正在按预期工作。但是如果注释在接口上,它就不起作用。这是正常行为还是我做错了什么?

  • RESTEasy代码的一部分。 这是因为“Spring AOP不能通知实现模板接口的pointcut类”吗?有什么想法吗?Spring AOP如何为实现参数化接口的类创建代理对象?...它使用CGLIB还是JDK代理?

  • 我就是不明白为什么我的切入点不起作用。编译器并没有给出任何警告,所以我无法解释它为什么不工作。我正在maven javafx应用程序中使用aspectjrt 1.7.2和aspectjtools 1.7.0。 我的样子是这样的 我的电影方面位于包主要。模型 下面是对我的代码中实际发生的事情的一点解释 当我的gui加载时,我初始化MainFrame类。在此之前,另一个方面加载所有电影对象。然后,当主

  • 我对Spring和AOP是新手。我正在尝试这个简单的事情,我已经创建了一个自定义注释,当放在任何方法之前时,它应该执行一些代码。这是我创建的注释 问题是我的spring aop从来没有被触发过。我在中包含了一个bean 有人能指出我缺少什么吗?

  • 嗨,我有一个使用Spring 5、Spring Data、Spring AOP和Java 11的应用程序(我也在使用JAVA 9模块系统)。我的spring-context/spring-aspects版本是5.1.2.RELEASE Spring数据版本是2.1.2.RELEASE这两个版本都是最新的。我以下列方式创建了存储库: 我已启用Spring Data Repositories使用 在我

  • 问题内容: 我正在使用Spring框架(2.5)及其AOP功能。我有一个切入点表达,例如 凡ItemReader接口是一个Spring接口,它的签名是: 该接口有一个名为“ read”的方法,我要对其应用此建议:方法签名为: 但是,当我使用上述切入点表达式运行应用程序时,出现以下异常: java.lang.IllegalArgumentException:警告与此类型名称不匹配:org.sprin