Spring 春季批次中未拦截AOP

Spring 春季批次中未拦截AOP,spring,spring-boot,spring-batch,spring-aop,Spring,Spring Boot,Spring Batch,Spring Aop,我在Spring批处理项目编写器中有一个方法,我想在其上运行@After,但由于某些原因,AOP建议在该方法返回后不会运行 守则如下: package com.mypackage.item; // some imports @Slf4j @Component @StepScope public class MyItemWriter implements ItemWriter<MyClass> { @Override public void write(List&l

我在Spring批处理项目编写器中有一个方法,我想在其上运行@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);
    }
}
doWork被正确调用并返回状态,但通知未被调用。我认为切入点表达式是正确的,因为我在IntelliJ中看到两个方法(advised和Advise)旁边都有一个图标,您可以单击并导航到另一个方法。但是我不知道为什么它没有被呼叫

一些设置信息:

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的评论,我做了一些搜索,并从

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

好吧,那我们该怎么办?最好的方法(这里宽松地使用术语best)是重构代码,这样就不会发生自调用。当然,这确实需要你做一些工作,但这是最好的、侵入性最小的方法


Spring AOP使用代理,因此只有对对象的方法调用才会应用方面,内部方法调用不会通过代理。Thank@M.Deinum有什么方法可以实现我想要的吗?也许通过重组代码?你也可以添加你的评论作为回答。你想使用方面吗?这个方面只适用于这里,所以我很难说是一个贯穿各领域的问题。为什么不直接在代码本身中实现它,而不是使用方面。方面不仅在这里,问题中的代码被大量篡改。将
doWork
移动到外部类,然后您可以拦截该方法调用,因为它将是一个外部方法调用。
Found AspectJ method public void com.mypackage.aop.OperationsAop.invokeAfterDoWork(org.aspectj.lang.JoinPoint,java.lang.Object,com.mypackage.domain.MyClass)