У меня эта странная проблема в Spring Boot, где @Cacheable работает в контроллере, но не внутри службы. Я вижу вызов GET в Redis, но не вызов 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;
}
}
}
Я вижу вызов GET в Redis, но не вызов PUT.




Ваше кеширование и так должно работать нормально. Убедитесь, что у вас есть аннотация @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 '=='
Или, как упоминалось в комментариях, вместо изменения условия, вы можете использовать condition вместо unless:
@Cacheable(
value = "com.example.webservice.api.AwesomeApi",
key = "#query",
condition = "#result != null") // Change 'unless' into 'condition'
Вы также можете переименовать unless в condition и сохранить то, что у вас есть, чтобы сделать намерение немного более ясным.
@StephaneNicoll Ты прав, не думал об этом. Я обновил свой ответ.
Что ж, обидно, что проблема оказалась такой маленькой ошибкой. К несчастью, это произошло потому, что кеш уже был введен, когда я добавил это условие. Итак, мне не удалось обнаружить эту проблему. В любом случае большое спасибо за вашу помощь.
Он никогда не будет кэшироваться, так как у вас есть
unless = "#result != null", что означает, что не кешируйте, если результат неnull. Таким образом, фактический результат вызова метода никогда не будет кэшироваться. В основномunless- это противоположностьconditionв аннотации@Cachable.