从同一个bean中自我调用方法时无法识别的Spring缓存注释

时间:2015-03-12 22:58:52

标签: spring-cache

亲爱的Spring Cache项目社区,

目前我正在使用合同第一种方法实现基于Apache CXF的Spring(版本4.1.5)Web服务端点。在这里,我观察在我的Web服务类中注释公共方法时,Spring缓存注释" @Cachable"每次我在同一个bean中以自调用方式调用此方法时,都会被忽略。在查看底层缓存提供程序(此处为:EhCache)的缓存存储库(通过JMX)时,可以证明这一点。在那里,没有填充缓存。

看一下下面的当前Spring文档 Enable caching annotationsThe dispatcher servlet我认为可能是因为:

  

<cache:annotation-driven/>仅在定义的相同应用程序上下文中查找bean上的@ Cacheable / @ CachePut / @ CacheEvict / @Caching。这意味着,如果您为DispatcherServlet放入WebApplicationContext,它只会检查控制器中的bean,而不是服务。有关更多信息,请参见第17.2节“DispatcherServlet”。

目前,Apache CXF&#34; CXFServlet&#34;在&#34; web.xml&#34;中注册部署描述符使用&#34; cxf-servlet.xml&#34;来启动Spring WebApplicationContext。默认情况下为Spring应用程序上下文在那里,找到<cache:annotation-driven/>

或者可能是因为我在同一个Spring bean中调用@Cacheable带注释的方法,以便绕过生成的Spring代理?细节可以在&#34;代理机制&#34;也是Spring文档的第(9.6)章。

但我不知道如何更改行为以便我的方法结果被缓存。你有什么想法?或者我上面发布的假设不正确?

1 个答案:

答案 0 :(得分:4)

亲爱的春天社区,

我在Spring documentation中找到了批准我的假设的重要评论:

  

在代理模式(默认设置)下,只拦截通过代理进入的外部方法调用。这意味着实际上,自调用目标对象中的一个方法调用目标对象的另一个方法,即使被调用的方法用@Cacheable标记,也不会在运行时导致实际的缓存 - 考虑使用aspectj模式这个案例。此外,代理必须完全初始化以提供预期的行为,因此您不应该在初始化代码中依赖此功能,即@PostConstruct。

因此,这意味着在依赖Spring AOP及其代理模式技术或从&#34; proxy&#34;切换模式时重构代码。到&#34; aspectj&#34; <cache:annotation-driven mode="aspectj"/>。这允许在同一个类中使用自调用方法,因为AOP分别进行静态动态编织,因此直接操作字节代码。