1、参考
基于redis2.1.6实现spring cache生成的key多出一个冒号
2、解决
需要对key进行处理,【重点】是computePrefixWith方法
config = config.computePrefixWith(cacheName -> {
return cacheName + StrUtil.COLON;
});
以下是完整代码
实现 CacheKeyPrefix 接口的 String compute(String cacheName);方法,重写定义cache名称
private RedisCacheConfiguration getRedisCacheConfiguration(Duration duration) {
RedisCacheConfiguration config = RedisCacheConfiguration
.defaultCacheConfig()
.entryTtl(duration)
// .disableCachingNullValues()
.serializeKeysWith(RedisSerializationContext.SerializationPair.fromSerializer(new StringRedisSerializer()))
.serializeValuesWith(RedisSerializationContext.SerializationPair.fromSerializer(new GenericJackson2JsonRedisSerializer()));
config = config.computePrefixWith(cacheName -> {
// keyPrefix是cacheProperties设置的的redis前缀
String keyPrefix = cacheProperties.getRedis().getKeyPrefix();
if (StringUtils.hasText(keyPrefix)) {
keyPrefix = keyPrefix.lastIndexOf(StrUtil.COLON) == -1 ? keyPrefix + StrUtil.COLON : keyPrefix;
return keyPrefix + cacheName + StrUtil.COLON;
}
return cacheName + StrUtil.COLON;
});
return config;
}
3、排查
在@Cacheable生成缓存key时,总是产生sys:cache:user::admin,多出两个冒号的情况
@Override
@Cacheable(cacheNames = CacheConstant.SYS_USERS_CACHE, key = "#username")
public LoginUser getUserByName(String username) {
if (org.jeecg.framework.common.util.CN.isEmpty(username)) {
return null;
}
LoginUser loginUser = new LoginUser();
SysUser sysUser = userMapper.getUserByName(username);
if (sysUser == null) {
return null;
}
BeanUtils.copyProperties(sysUser, loginUser);
return loginUser;
}
经过查看源码,发现defaultCacheConfig()生成的RedisCacheConfiguration对象
public static RedisCacheConfiguration defaultCacheConfig() {
return defaultCacheConfig((ClassLoader)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的生成策略是simple()方法,其中String SEPARATOR = "::"; 明确是两个冒号,终于找到原因了
@FunctionalInterface
public interface CacheKeyPrefix {
String SEPARATOR = "::";
String compute(String cacheName);
static CacheKeyPrefix simple() {
return (name) -> {
return name + "::";
};
}
static CacheKeyPrefix prefixed(String prefix) {
Assert.notNull(prefix, "Prefix must not be null!");
return (name) -> {
return prefix + name + "::";
};
}
}
标签:Cacheable,return,String,RedisCacheConfiguration,redisKey,cacheName,keyPrefix,jav
From: https://www.cnblogs.com/kikyoqiang/p/18333022