我正在基于 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()
。
所以,如果我们执行上面的测试,你会期望
建议 FOO! 忠告 FOO!
然而,我得到的是:
建议 FOO!
第二次调用永远不会得到建议!更糟糕的是,目标方法甚至没有被执行。
您是否知道为何会发生这种情况?
注1:更糟糕的是:有时,当我使用调试器执行并逐步执行时,它确实正常工作。不开玩笑......
注意2:如果配置中存在拼写错误,它们只是拼写错误,因为我调整了原始代码以使其更简单。考虑到该方面适用于第一次调用。
注3:我确实想坚持使用Spring。我不能在Java代码中硬编码切入点,因为我希望库用户提供他们自己的,并且我能想到的唯一方法是让他们定义aop:config
块。
答案 0 :(得分:2)
看着2公里长的堆栈跟踪,我看到了CachingInterceptor
......这就是解决这个问题的方法:基于Spring方法拦截器的自定义缓存机制就是这样做的。它的超时时间为120秒,这就是我使用调试器时执行似乎很好的原因。
我不会关闭我的(愚蠢的)问题,以防它帮助别人。一些透视和开箱即用的想法会有所帮助!