第二次调用Aspectj-adviced方法被忽略

时间:2011-09-06 10:09:27

标签: java spring aop aspectj spring-aop

我正在基于 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块。

1 个答案:

答案 0 :(得分:2)

看着2公里长的堆栈跟踪,我看到了CachingInterceptor ......这就是解决这个问题的方法:基于Spring方法拦截器的自定义缓存机制就是这样做的。它的超时时间为120秒,这就是我使用调试器时执行似乎很好的原因。

我不会关闭我的(愚蠢的)问题,以防它帮助别人。一些透视和开箱即用的想法会有所帮助!