问题
I have implemented the standard redis caching template in a Spring boot application as per the following article:
What I have is two different services that get a list of objects:
@RequestMapping("/admin/test/list")
public String testCache() {
List<Cocktail> cocktails = cocktailsService.list();
List<Ingredient> ingredients = ingredientsService.list();
return "index";
}
Note: that the method name and signature is the same (i.e. list()
) but they both have different cache names as such:
// CocktailService
@Cacheable(value = “COCKTAILS”)
public List<Cocktail> list() {
return repository.findAll();
}
// IngredientsService
@Cacheable(value = “INGREDIENTS”)
public List<Ingredient> list() {
return repository.findAll();
}
The Problem
Even thou the cache name is different the method is always returning the list from the cache as there is no distinction at method level when generating the keys.
Possible Solutions
I know three solutions could be:
- Change the method name
- Write a custom KeyGenerator
Set Cache SpEL to make use of #root.target such as:
@Cacheable(value=”COCKTAILS”, key="{#root.targetClass}") @Cacheable(value=”INGREDIENTS”, key="{#root.targetClass}")
Question
But surly there must be a better way or not?
回答1:
There is an issue in the article you've followed. When creating your CacheManager bean, you need to invoke cacheManager.setUsePrefix(true);
, only then the cache names COCKTAILS and INGREDIENTS will be used as Redis cache key discriminator.
Here is how you should declare your cache manager bean:
@Bean
public CacheManager cacheManager(RedisTemplate redisTemplate) {
RedisCacheManager cacheManager = new RedisCacheManager(redisTemplate);
// Number of seconds before expiration. Defaults to unlimited (0)
cacheManager.setDefaultExpiration(300);
cacheManager.setUsePrefix(true);
return cacheManager;
}
来源:https://stackoverflow.com/questions/47993681/spring-cacheable-annotation-for-same-method-in-different-service