spring使⽤RedisCacheManager管理key的⼀些问题spring可以很好地管理各种内存的快速缓存。
这些常见的内存缓存库实现⽅式有redis,Ehcache。
本⽂阐述的是redis,毕竟这个东西相当容易使⽤。
spring通过 org.springframework.cache.Cache 和org.springframework.cache.CacheManager两个接⼝来管理缓存
redis的cache实现类是 RedisCacheManager,它们的关系是这样的:
object
<-AbstractCacheManager=>(, )
<-AbstractTransactionSupportingCacheManager
<-RedisCacheManager
可以看出RedisCacheManager实现了接⼝CacheManager接⼝。
⼀、如何⾃定义redis中key
如果使⽤默认的⽅式来注册RedisCacheManager,如下:
RedisCacheConfiguration redisCacheConfiguration = RedisCacheConfiguration.defaultCacheConfig()
.entryTtl(Duration.ofHours(this.cacheTimeOutHour))
假定注解是这样的:
@Cacheable(value="getUserPoJoById",key="#userId")
那么⽣成redis的key是形如这样的:
getUserPoJoById::103
其中双冒号(::)是分隔符。
这是因为RedisCacheConfiguration.defaultCacheConfig()的源码如下:
public static RedisCacheConfiguration defaultCacheConfig() {
return defaultCacheConfig(null);
}
public static RedisCacheConfiguration defaultCacheConfig(@Nullable ClassLoader classLoader) {
DefaultFormattingConversionService conversionService = new DefaultFormattingConversionService();
registerDefaultConverters(conversionService);
return new RedisCacheConfiguration(Duration.ZERO, true, true, CacheKeyPrefix.simple(),
SerializationPair.fromSerializer(RedisSerializer.string()),
SerializationPair.fromSerializer(RedisSerializer.java(classLoader)), conversionService);
}
从上⾯代码可以看到使⽤的key前缀是CacheKeyPrefix.simple(),CacheKeyPrefix.simple()的实现如下:
@FunctionalInterface
public interface CacheKeyPrefix {
/
**
* Compute the prefix for the actual {@literal key} stored in Redis.
*
* @param cacheName will never be {@literal null}.
* @return never {@literal null}.
*/
String compute(String cacheName);
/**
* Creates a default {@link CacheKeyPrefix} scheme that prefixes cache keys with {@code cacheName} followed by double
* colons. A cache named {@code myCache} will prefix all cache keys with {@code myCache::}.
*
* @return the default {@link CacheKeyPrefix} scheme.
*/
static CacheKeyPrefix simple() {
return name -> name + "::";
}
}
simple实现的CacheKeyPrefix的compute⽅法等同于:
String compute(String cacheName){
return cacheName+"::";
}
所以默认的是使⽤双冒号进⾏分隔。cacheable
但很多情况下,我们并不希望redis的key就是这样的形式,我们可能想:
1. 在整个key前加前缀
2. 使⽤不同的分隔符号
怎么做了?调⽤CacheKeyPrefix 的定制实现即可。
先来看看CacheKeyPrefix 的唯⼀接⼝⽅法(⾮静态):
String compute(String cacheName);
也就是说我们可以通过compute来指定需要的实现。
思路有了,那么以下就是实现⽅式:
RedisCacheConfiguration redisCacheConfiguration = RedisCacheConfiguration.defaultCacheConfig()
.entryTtl(Duration.ofHours(this.cacheTimeOutHour))putePrefixWith(cacheName -> cacheName + this.keyPrefix);
RedisCacheManager cm=RedisCacheManager.builder(redisConnectionFactory).cacheDefaults(redisCacheConfiguration).build();        cm.setTransactionAware(true);
上⽂中的关键代码部分:computePrefixWith(cacheName -> cacheName + this.keyPrefix);
我们来看下RedisCacheConfiguration的computePrefixWith的实现代码:
public RedisCacheConfiguration computePrefixWith(CacheKeyPrefix cacheKeyPrefix) {
return new RedisCacheConfiguration(ttl, cacheNullValues, true, cacheKeyPrefix, keySerializationPair,
valueSerializationPair, conversionService);
}
所以代码:cacheName -> cacheName + this.keyPrefix 就是为了构建CacheKeyPrefix的compute⽅法
String compute(String cacheName){
return cacheName+this.keyPrefix;
}
如果想加前缀,可以这样:
computePrefixWith(cacheName -> CachePrefix+"->"+cacheName + this.keyPrefix)
这等同于compute⽅法变为: CachePrefix+"->"+cacheName + this.keyPrefix
spring 5.1.x后⼤量使⽤lambda,如果不熟悉,就⽆法阅读这个代码。
⼆、定义key所需要注意的其它⽅⾯
1.当多个应⽤共⽤⼀个redis实例的时候,需要注意使⽤前缀
2.如果有很多值,建议key短⼀些,并形成⼀个key的命名⽂档

版权声明:本站内容均来自互联网,仅供演示用,请勿用于商业和其他非法用途。如果侵犯了您的权益请与我们联系QQ:729038198,我们将在24小时内删除。