AOP不会在Spring Batch中拦截

时间:2017-07-25 17:30:37

标签: spring spring-boot spring-batch spring-aop

我在Spring Batch Item Writer中创建了一个方法,我希望在其上运行@After,但由于某种原因,AOP建议在方法返回后没有运行。

代码如下:

package com.mypackage.item;
// some imports

@Slf4j
@Component
@StepScope
public class MyItemWriter implements ItemWriter<MyClass> {

    @Override
    public void write(List<? extends MyClass> items) throws Exception {
      for (MyClass myClass : items) {
        Status status = doWork(myClass);
        log.info(status);
      }
    }

    public Status doWork(MyClass myClass) {
        return doLotsOfWork(myClass);
    }
}

AOP建议:

@Aspect
@Component
@Slf4j
public class OperationsAop {

    @AfterReturning(
          pointcut="execution(* com.mypackage.item.MyItemWriter.doWork(..)) && args(myClass))",
  returning="retValue")
    public void invokeAfterDoWork(JoinPoint joinPoint, Object retValue, MyClass myClass) {
    .... some stuff here
    }
}

正确调用doWork并返回状态,但建议不会被调用。我认为切入点表达式是正确的,因为我在IntelliJ旁边看到了一个图标(建议和建议),您可以在其中单击并导航到另一个。但是,我不确定为什么它没有被调用。

一些设置信息:

springBootVersion = "1.5.4.RELEASE"

compile (group: "org.springframework.boot", name: "spring-boot-starter-jetty", version: "${springBootVersion}")
compile group: "org.springframework.boot", name: "spring-boot-starter-aop", version: "${springBootVersion}"

AOP类肯定是加载的,因为我可以在调试日志中看到它:

Found AspectJ method public void com.mypackage.aop.OperationsAop.invokeAfterDoWork(org.aspectj.lang.JoinPoint,java.lang.Object,com.mypackage.domain.MyClass)

根据M.Deinum的评论,我做了一些搜索并从Spring Documentation

提出这个建议
  

这里要理解的关键是Main类的main(..)中的客户端代码具有对代理的引用。这意味着对该对象引用的方法调用将是代理上的调用,因此代理将能够委托给与该特定方法调用相关的所有拦截器(通知)。但是,一旦调用最终到达目标对象,在这种情况下,SimplePojo引用,它可能对其自身进行的任何方法调用,例如this.bar()或this.foo(),将被调用这个引用,而不是代理。这具有重要意义。这意味着自我调用不会导致与方法调用相关的建议有机会执行。

     

好的,那么该怎么办呢?最好的方法(这里松散地使用最好的术语)是重构代码,以便不会发生自我调用。当然,这确实需要你做一些工作,但这是最好的,最少侵入性的方法。

0 个答案:

没有答案