Spring缓存有时只能工作

时间:2018-01-23 18:03:30

标签: spring caching key spring-cache

我有一个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{
    ...

1 个答案:

答案 0 :(得分:2)

Problem: You are calling doGetBooks() within the same class, and Spring cache requires an AOP proxy to the called method.

This is a good discussion describing why Spring AOP can not intercept methods called by other class methods: AOP calling methods within methods

There are at least three workarounds:

  1. Refactor the code: Move doGetBooks() into another @Component, and invoke the method using that (injected) bean (refactoredBean.doGetBooks())
  2. Create a self-reference to the service invoking the call (By @Autowired private MyService myservice and invoke myservice.doGetBooks().
  3. Using the ApplicationContext to cast the service bean, and invoking the method on that bean.

Once you invoke a method that Spring Cache can intercept (via AOP), then the @Cacheable() annotation should trigger.