【问题标题】:@Cacheable is working in Controller but not inside service@Cacheable 在 Controller 中工作,但不在服务内部
【发布时间】:2018-12-24 16:19:15
【问题描述】:

我在 Spring Boot 中遇到了这个奇怪的问题,@Cacheable 在控制器中工作,但不在服务内部。我可以在 Redis 中看到 GET 调用,但看不到 PUT 调用。

这是有效的,因为它在控制器内部

@RestController
@RequestMapping(value="/places")
public class PlacesController {

    private AwesomeService awesomeService;

    @Autowired
    public PlacesController(AwesomeService awesomeService) {
        this.awesomeService = awesomeService;
    }

    @GetMapping(value = "/search")
    @Cacheable(value = "com.example.webservice.controller.PlacesController", key = "#query", unless = "#result != null")
    public Result search(@RequestParam(value = "query") String query) {
        return this.awesomeService.queryAutoComplete(query);
    }
}

但是当我在这样的服务中这样做时,@Cacheable 不起作用

@Service
public class AwesomeApi {

    private final RestTemplate restTemplate = new RestTemplate();

    @Cacheable(value = "com.example.webservice.api.AwesomeApi", key = "#query", unless = "#result != null")
    public ApiResult queryAutoComplete(String query) {
        try {
            return restTemplate.getForObject(query, ApiResult.class);
        } catch (Throwable e) {
            return null;
        }
    }
}

我可以在 Redis 中看到 GET 调用,但看不到 PUT 调用。

【问题讨论】:

  • 它永远不会像你有unless = "#result != null"那样缓存,这意味着如果结果不是null,就不要缓存。所以方法调用的实际结果永远不会被缓存。基本上unlesscondition 上的@Cachable 注释相反。

标签: spring-boot redis spring-restcontroller spring-cache


【解决方案1】:

您的缓存应该可以正常工作。确保您有 @EnableCaching 注释并且您的 unless 标准是正确的。

现在,您正在使用unless="#result != null",这意味着它将缓存结果,除非它不是null。这意味着它几乎永远不会缓存,除非restTemplate.getForObject() 返回null,或者发生异常时,因为那时你也返回null

我假设您要缓存每个值,null 除外,但在这种情况下,您必须反转您的条件,例如:

@Cacheable(
    value = "com.example.webservice.api.AwesomeApi",
    key = "#query",
    unless = "#result == null") // Change '!=' into '=='

或者,as mentioned in the comments,而不是颠倒条件,您可以使用condition 代替unless

@Cacheable(
    value = "com.example.webservice.api.AwesomeApi",
    key = "#query",
    condition = "#result != null") // Change 'unless' into 'condition'

【讨论】:

  • 您也可以将unless 重命名为condition 并保留您所拥有的内容以使意图更加清晰
  • @StephaneNic​​oll 你说得对,没想到。我已经更新了我的答案。
  • 好吧,问题是这么小的一个错误,真是令人尴尬。更糟糕的是,发生这种情况是因为当我添加除非条件时已经输入了缓存。所以,我无法发现这个问题。无论如何,非常感谢您的帮助。
猜你喜欢
  • 1970-01-01
  • 2023-03-08
  • 1970-01-01
  • 1970-01-01
  • 1970-01-01
  • 1970-01-01
  • 1970-01-01
  • 2021-10-14
  • 1970-01-01
相关资源
最近更新 更多