0

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

@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 *)但这也不起作用..

4

1 回答 1

2

假设这Services.SystemListenerService是您方面的完全限定名称(类名、带有奇怪的大写第一个字母的SystemListenerService包名),这是行不通的,因为当时我们不是无论如何,而是. 因此,您的切入点存在逻辑错误。Serviceswithin()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)),

但是Spring AOP 不支持这两种切入点类型。那么你

  • 要么需要在 Spring 中通过 LTW 激活完整的 AspectJ
  • 或滥用一些 Spring 方法,以便通过代理获取真实对象,((Advised) myProxy).getTargetSource().getTarget()并从您的角度直接在该对象上调用该方法
  • 或从新创建的异常或当前线程获取堆栈跟踪并手动检查它 - 非常难看。

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

于 2018-08-07T07:28:23.503 回答