SpringBoot2.x使⽤缓存注解时,⾃定义RedisTemplate序列化对象为js。。。
⾸先我们要知道,当使⽤缓存注解时,RedisCacheManager帮我们创建RedisCache来作为缓存组件,RedisCache通过操作redis缓存数据。⽽在springboot 1.5.x,RedisCache⼜是通过RedisTemplate来操作redis缓存数据。⽽在srpingboot 2.x,RedisCache没有使⽤到RedisTemplate。
下⾯来看srpingboot 2.x中RedisCache是如何序列化对象的,直接看RedisCache的put⽅法。
public class RedisCache extends AbstractValueAdaptingCache {
private final RedisCacheConfiguration cacheConfig;
@Override
public void put(Object key,@Nullable Object value){
Object cacheValue =preProcessCacheValue(value);
if(!isAllowNullValues()&& cacheValue == null){
throw new IllegalArgumentException(String.format(
"Cache '%s' does not allow 'null' values. Avoid storing null via '@Cacheable(unless=\"#result == null\")' or configure RedisCache to allow 'null' via RedisC acheConfiguration.",
name));
}
cacheWriter.put(name,createAndConvertCacheKey(key),
serializeCacheValue(cacheValue), Ttl());
}
/**
* 序列化value
*/
protected byte[]serializeCacheValue(Object value){
if(isAllowNullValues()&& value instanceof NullValue){
return BINARY_NULL_VALUE;
}
ValueSerializationPair().write(value));
}
}
在put⽅法中通过serializeCacheValue⽅法序列化value,在serializeCacheValue⽅法中通过从RedisCacheConfiguration获取valueSerializationPair类序列化对象。查看RedisCacheConfiguration的默认配置如下:
public class RedisCacheConfiguration {
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(),
cacheableSerializationPair.fromSerializer(RedisSerializer.string()),
SerializationPair.fromSerializer(RedisSerializer.java(classLoader)),
conversionService);
}
/**
* @param ttl 缓存持续时间
* @param cacheNullValues 是否允许缓存Null值
* @param usePrefix 是否使⽤前缀
* @param keyPrefix key的前缀
* @param keySerializationPair key的序列化⽅式
* @param valueSerializationPair value的序列化⽅式
* @param conversionService
*/
private RedisCacheConfiguration(Duration ttl,
Boolean cacheNullValues,
Boolean usePrefix,
CacheKeyPrefix keyPrefix,
SerializationPair<String> keySerializationPair,
SerializationPair<?> valueSerializationPair,
ConversionService conversionService){
this.cacheNullValues = cacheNullValues;
this.usePrefix = usePrefix;
this.keyPrefix = keyPrefix;
this.keySerializationPair = keySerializationPair;
this.valueSerializationPair =(SerializationPair<Object>) valueSerializationPair;
}
}
第15、16⾏就是序列化的默认配置,key采⽤StringRedisSerializer序列化,value采⽤jdk序列化,所以⾃定义RedisTemplate是没有效果的,需要配置RedisCacheConfiguration才⾏。
解决办法
⾃定义RedisCacheManager,配置RedisCacheConfiguration的序列化⽅式为json
@Configuration
public class MyRedisConfig {
@Bean
public CacheManager cacheManager(RedisConnectionFactory factory){
RedisSerializer<String> redisSerializer =new StringRedisSerializer();
Jackson2JsonRedisSerializer jackson2JsonRedisSerializer =new Jackson2JsonRedisSerializer(Object.class);
ObjectMapper objectMapper =new ObjectMapper();
objectMapper.setVisibility(PropertyAccessor.ALL, JsonAutoDetect.Visibility.ANY);
jackson2JsonRedisSerializer.setObjectMapper(objectMapper);
// 配置序列化
RedisCacheConfiguration config = RedisCacheConfiguration.defaultCacheConfig()
.serializeKeysWith(RedisSerializationContext.SerializationPair.fromSerializer(redisSerializer))
.serializeValuesWith(RedisSerializationContext.SerializationPair.fromSerializer(jackson2JsonRedisSerializer));
RedisCacheManager cacheManager = RedisCacheManager.builder(factory)
.cacheDefaults(config)
.build();
return cacheManager;
}
}
RedisCacheConfiguration可根据⾃⼰的需求进⾏配置。

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