java - 第二次调用 Aspectj 建议的方法被忽略

标签 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()

所以,如果我们执行上面的测试,您会期望

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/

相关文章:

java - 在 spring boot embedded undertow 上将 http 重定向到 https

spring - JAVA spring (JPA)中的PostgreSQL + Elasticsearch同步

c# - 如何在来自单独应用程序的 c# 方法调用中注入(inject)代码

c# - 后锐利。如何引入可序列化属性

ios - 有关 iOS 应用程序包装的信息?

java - Maven依赖版本依赖于JVM版本

java - Arquillian 测试未执行

java - JDOM XPATH 什么时候比使用 getChildren 搜索元素更快?

java - 使用 try/catch 的正确方法

java - Spring 上下文中未加载 Spring Boot 全局 Controller 建议