3

亲爱的 Spring Cache 项目社区,

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

在查看了 启用缓存注释调度程序 servlet下面的当前 Spring 文档后,我认为这可能是由于以下事实:

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

目前,在“web.xml”部署描述符中注册的 Apache CXF“CXFServlet”默认使用“cxf-servlet.xml”Spring 应用程序上下文文件启动 Spring WebApplicationContext。在那里,<cache:annotation-driven/>位于。

或者可能是因为我从同一个 Spring bean 中调用 @Cacheable 注释方法,以便绕过生成的 Spring 代理?详细信息也可以在 Spring 文档的“代理机制”章节 (9.6) 中找到。

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

4

1 回答 1

4

亲爱的春天社区,

我在Spring 文档中找到了支持我的假设的重要评论:

In proxy mode (which is the default), only external method calls coming in through the proxy are intercepted. This means that self-invocation, in effect, a method within the target object calling another method of the target object, will not lead to an actual caching at runtime even if the invoked method is marked with @Cacheable - considering using the aspectj mode in this case. Also, the proxy must be fully initialized to provide the expected behaviour so you should not rely on this feature in your initialization code, i.e. @PostConstruct.

In consequence this means refactoring the code when relying on Spring AOP and its proxy mode technique or switching the mode from "proxy" to "aspectj" <cache:annotation-driven mode="aspectj"/>. This allows using self-invoking methods within the same class as AOP does static respectively dynamic weaving and so manipulates the byte code directly.

于 2015-03-14T08:50:15.003 回答