我有一个 SpringBoot 应用程序。 我定义了一个注释“Track”,并且在不同的包中注释了一些我希望 aop 考虑的方法。 注释定义如下:
@Retention(RetentionPolicy.RUNTIME)
@Target(ElementType.METHOD)
public @interface Track {
}
我没有错过我的包的@Configuration类中的@EnableAspectJAutoProxy。
我在方面定义了一个切入点和一个建议,如下所示:
@Aspect
@Component
public class MyAspect {
@Pointcut("execution(@Track * *.*(..))")
void annotatedMethod() {
// No Implementation required
}
@Around("annotatedMethod() && @annotation(methodLevelTrack)")
public void adviseAnnotatedMethods(ProceedingJoinPoint proceedingJoinPoint,
Track methodLevelTrack) throws Throwable {
// do some task
proceedingJoinPoint.proceed();
// do some task after the method is executed.
}
}
我的意图是:对于任何包中的任何方法(用 @Track 注释)、任何访问修饰符、任何数量的输入参数以及任何返回类型,都遵循方面的 @Around 建议。强>
现在,有趣的情况如下: 我有一个名为“Engine”的类,它调用其他类和下游系统来执行长时间运行的操作。让我们按如下方式定义该类:
public class Engine {
// bunch of other autowired objects
public void processTask() {
<autowired_object_A>.someMethod() // this method has been annotated with @Track
<autowired_object_B>.someMethod() // this method has also been annotated with @ Track
.... // bunch of other methods in other autowired objects that have been annotated with @ Track
someMethodOfEngineClass(); // Now this has been defined in the Engine class as below, but pointcut doesn't recognize this method!
}
@Track
private void someMethodOfEngineClass() {
// do something
}
}
所有“其他” Autowiring 对象的方法都按预期被切入点识别,但此 Engine 类中已用 @Track 注释的方法无法识别。其中有何奥秘?
我尝试过将“someMethodOfEngineClass”方法公开,返回一些内容而不是 void 以及所有这些组合,但它不起作用。
我错过了什么? 是切入点定义表达式吗? 我已经在其中一个子包中定义了切面,切面是否应该在包结构的顶层定义?
你们能推荐一些可行的东西吗?我有点陷入困境。
最佳答案
当你定义aop时,spring会在类周围创建代理, 所以当调用该方法时,实际上调用被委托(delegate)给代理,就像
your.package.Engine$$FastClassBySpringCGLIB$$c82923b4.someMethodOfEngineClass()
但这仅在从类外部调用方法时才有效
如果您从同一个类调用类方法,则可以通过 this.someMethodOfEngineClass()
此处 -> http://www.nurkiewicz.com/2011/10/spring-pitfalls-proxying.html 您可以找到有关代理的更多信息
因此代理被绕过,aop 无法工作。
关于java - Spring AOP - 切入点没有被调用,我们在Stack Overflow上找到一个类似的问题: https://stackoverflow.com/questions/48243579/