问题
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,
Due to the proxy-based nature of Spring’s AOP framework, calls within the target object are by definition not intercepted.
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 tomyMethod
will not be intercepted. Please refer to the second point mentioned above. - Even if your
myMethod
was public, the call tomyMethod
would not have been intercepted if the call was made viaschedule
method. Please refer to the first point mentioned above. - Now if your
myMethod
was public, the call tomyMethod
would be intercepted if the call was made directly tomyMethod
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 yourpom.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