Spring缓存有时才起作用

Spring缓存有时才起作用,spring,caching,key,spring-cache,Spring,Caching,Key,Spring Cache,我有一个Spring控制器,希望缓存响应。当我将@Cacheable注释从getBooks移动到doGetBooks方法时,缓存将停止。一旦我将它移回getBooks方法,缓存就会再次工作。这是为什么?我该如何修复它 这将缓存公共方法响应 @GetMapping @Cacheable(value = "cache", key = "{ #root.methodName }") public Books getBooks(@RequestHeader(value = "user-agent", r

我有一个Spring控制器,希望缓存响应。当我将
@Cacheable
注释从
getBooks
移动到
doGetBooks
方法时,缓存将停止。一旦我将它移回
getBooks
方法,缓存就会再次工作。这是为什么?我该如何修复它

这将缓存公共方法响应

@GetMapping
@Cacheable(value = "cache", key = "{ #root.methodName }")
public Books getBooks(@RequestHeader(value = "user-agent", required = false) String userAgent) throws Exception {
     if(valid) {
          return this.doGetBooks();
     }
     throw new Exception();
}


public Books doGetBooks() throws Exception{
    ...
@GetMapping
public Books getBooks(@RequestHeader(value = "user-agent", required = false) String userAgent) throws Exception {
     if(valid) {
          return this.getBooks();
     }
     throw new Exception();
}


@Cacheable(value = "cache", key = "{ #root.methodName }")
public Books doGetBooks() throws Exception{
    ...
这将永远不会缓存私有方法响应

@GetMapping
@Cacheable(value = "cache", key = "{ #root.methodName }")
public Books getBooks(@RequestHeader(value = "user-agent", required = false) String userAgent) throws Exception {
     if(valid) {
          return this.doGetBooks();
     }
     throw new Exception();
}


public Books doGetBooks() throws Exception{
    ...
@GetMapping
public Books getBooks(@RequestHeader(value = "user-agent", required = false) String userAgent) throws Exception {
     if(valid) {
          return this.getBooks();
     }
     throw new Exception();
}


@Cacheable(value = "cache", key = "{ #root.methodName }")
public Books doGetBooks() throws Exception{
    ...

问题:您正在同一个类中调用doGetBooks(),而Spring缓存需要一个AOP代理来访问被调用的方法

这是一个很好的讨论,描述了为什么Spring AOP不能拦截其他类方法调用的方法:

至少有三种解决方法:

  • 重构代码:将doGetBooks()移动到另一个@Component中,并使用该(注入的)bean(refacturedbean.doGetBooks()调用该方法
  • 创建调用调用的服务的自引用(通过@Autowired private MyService MyService和invoke MyService.doGetBooks())
  • 使用ApplicationContext强制转换服务bean,并调用该bean上的方法

  • 一旦调用Spring Cache可以拦截的方法(通过AOP),那么@Cacheable()注释应该会触发。

    我认为第二个代码块中有一个输入错误(它从不调用doGetBooks()。但是缓存问题的根源必须是Spring Cache捕获getBooks()的代理,但无法捕获doGetBooks()方法。我将尝试找到一个关于如何解决此问题的链接,但可能有人会更快。您应该阅读此部分。。。