@Cacheable在Controller中工作,但在服务内部工作

时间:2018-07-17 04:39:47

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

我在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);
    }
}

但是当我像这样在Service中进行操作时,@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呼叫。

1 个答案:

答案 0 :(得分:4)

您的缓存应该可以正常工作。确保您具有@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'