Aspect does not capture method from Scheduled

こ雲淡風輕ζ 提交于 2019-12-13 20:15:41

问题


Why is set aspect of an annotation not working when it is set to a method from cron.

@Component
public class MyClass {
  @Scheduled(cron = "0/5 * * * * ?")
  public void schedule() {
    myMethod("test");
  }

  @MyAnno(cl = MyClass.class, description = "desc")
  private void myMethod(String text) {

  }
}

@Aspect
@Component
public MyAscpect {
  @Before("@annotation(myAnnoAnnotation)")
  public void myAnnoAspect(JoinPoint jp, MyAnno myAnnoAnnotation) {
}

回答1:


Spring AOP

Here are the points you should remember about Spring AOP,

  1. Due to the proxy-based nature of Spring’s AOP framework, calls within the target object are by definition not intercepted.

  2. For JDK proxies, only public interface method calls on the proxy can be intercepted. With CGLIB, public and protected method calls on the proxy will be intercepted, and even package-visible methods if necessary.

You can find more here.

  • Since your method myMethod is private, the call to myMethod will not be intercepted. Please refer to the second point mentioned above.
  • Even if your myMethod was public, the call to myMethod would not have been intercepted if the call was made via schedule method. Please refer to the first point mentioned above.
  • Now if your myMethod was public, the call to myMethod would be intercepted if the call was made directly to myMethod method from outside the object.

AspectJ Source Weaving

However, you can intercept private methods by taking advantage of AspectJ source weaving. In source weaving, the weaver becomes part of the compiler. The weaver acts as a compiler by processing the source code and generating woven Java bytecode. Instead of javac compiler, it uses ajc compiler.

Here are the changes you need to make:

  • Add Maven aspectj-maven-plugin plugin to your pom.xml
  • As shown below, changes to the pointcut of MyAspect to include private methods.

    @Component
    @Aspect
    public class MyAspect {
    
        @Before("@annotation(myAnnoAnnotation) && execution(private * *(..))")
        public void myAnnoAspect(JoinPoint jp, MyAnno myAnnoAnnotation) {
        ...
        }
    }
    

    You can find a complete working example here.




回答2:


Try to change Your source as following.

Of course, the application class with the main method should have @EnableScheduling attached.

@Component
public class MyClass {
    @MyAnno
    @Scheduled(cron = "0/5 * * * * ?")
    public void schedule() {
        myMethod("test");
    }
    private void myMethod(String text) {
        //TODO enter your code.
    }
}

@Target(ElementType.METHOD)
@Retention(RetentionPolicy.RUNTIME)
public @interface MyAnno{

}

@Aspect
@Component
public class MyAnnoAspect{
    @Before("@annotation(MyAnno)")
    public void myAnnoAspect(JoinPoint jp) {

    }
}


来源:https://stackoverflow.com/questions/47072554/aspect-does-not-capture-method-from-scheduled

易学教程内所有资源均来自网络或用户发布的内容,如有违反法律规定的内容欢迎反馈
该文章没有解决你所遇到的问题?点击提问,说说你的问题,让更多的人一起探讨吧!