如何从触发方面方法调用中排除 类

How to exclude classes from triggering Aspect method call

我在 @Aspect 服务方法中有一个名为 logChangesAndAnnounceNewContributions 的方法,只要在 webapp 的某处调用 Spring-data 的 JpaRepository 的保存方法,它就会触发。我不希望在方面 class 本身中使用保存方法时调用 logChanges 方法,因此我在切入点定义 !within(Services.SystemListenerService) 中使用了它。但它没有任何效果!尽管在定义中使用了此条件,但仍会调用保存方法。完整的定义如下所示:

@AfterReturning("execution(* org.springframework.data.jpa.repository.JpaRepository.save(..))" +
           "&& !within(Services.SystemListenerService) && args(entity)")
    private void logChangesAndAnnounceNewContributions(Object entity){

我在这里错过了什么?

编辑:我尝试将 !within content 更改为 !within(@org.aspectj.lang.annotation.Aspect *) 但这也不起作用..

假设 Services.SystemListenerService 是你的方面的完全限定名称(class 名称 SystemListenerService,包名称 Services 首字母大写,within() 不起作用,因为在 execution(* org.springframework.data.jpa.repository.JpaRepository.save(..)) 时我们不是 within(Services.SystemListenerService),而是 within(org.springframework.data.jpa.repository.JpaRepository)。所以你的切入点存在逻辑错误。

在AspectJ中有一些方法可以解决这个问题,比如

  • call(A) && !adviceexecution(),
  • execution(A) && !cflow(execution(B)),

但两种切入点类型都是 unsupported in Spring AOP。所以你

  • 要么需要在Springactivate full AspectJ via LTW
  • 或滥用某些 Spring 方法以通过 ((Advised) myProxy).getTargetSource().getTarget() 并从您的方面直接对该对象调用该方法
  • 或者从新创建的异常或当前线程获取堆栈跟踪并手动检查它 - 非常难看。

抱歉,但是 Spring AOP 只是 "AOP lite",我认为你应该选择 AspectJ。第二个选项也有点老套,但可能会奏效。