我正在我的基于 Spring 的 Java 项目中添加一些 AspectJ 建议。当我运行一次被拦截的方法时,一切正常(即,建议被执行)。但是,下一次调用同一方法将不再通过代理。
这是我的测试代码:
@Test
public void testFooOperationIsAdviced() throws Exception {
TestController testController = appContext.getBean("testController");
testController.foo();
testController.foo();
}
这是 foo()
方法:
@Protect()
public void foo() {
System.err.println("foo!")
}
这是我的 Spring 配置中的相关部分:
<aop:aspectj-autoproxy />
<bean name="myAdvice" class="mypackage.MyAdvice"/>
<bean id="testController" class="mypackage.MyTestControllerImpl" />
<aop:config>
<aop:aspect id="protectAspect" ref="myAdvice">
<aop:pointcut id="annotatedController" expression="execution(public * mypackage.*+.*(..)) and @annotation(protect)" />
<aop:around pointcut-ref="annotatedController" method="applyProtectionRules" arg-names="protect"/>
</aop:aspect>
</aop:config>
该方面当前仅执行 System.err.println("advice")
和 pp.proceed()
。
所以,如果我们执行上面的测试,您会期望
advice foo! advice foo!
但是,我得到的是:
advice foo!
第二次调用永远不会得到建议!而且,更糟糕的是,目标方法甚至没有执行。
您知道为什么会发生这种情况吗?
注1:更糟糕的是:有时,当我使用调试器并一步步执行时,它确实可以正常工作。别开玩笑了...
注2:如果配置中有拼写错误,它们只是拼写错误,因为我调整了原始代码以使其更简单。请考虑到该方面确实适用于第一次调用。
注3:我确实想坚持使用Spring。我无法在 Java 代码中硬编码切入点,因为我希望库用户提供自己的切入点,而我能想到的唯一方法就是让他们定义 aop:config
block 。
最佳答案
查看 2 公里长的堆栈跟踪,我看到了一个 CachingInterceptor
...这就是谜团的解决方案:我们基于 Spring 方法拦截器的自定义缓存机制正在执行以下操作:诡计。它有 120 秒的超时,这就是为什么当我使用调试器时执行看起来很好。
我不会关闭我的(诚然愚蠢的)问题,以防它对其他人有帮助。一些观点和跳出框框的思考会有帮助!
关于java - 第二次调用 Aspectj 建议的方法被忽略,我们在Stack Overflow上找到一个类似的问题: https://stackoverflow.com/questions/7318203/