本文主要是介绍SpringBoot2.0版本自定义Redis序列化,希望对大家解决编程问题提供一定的参考价值,需要的开发者们随着小编来一起学习吧!
题记
跟着B站的视频学着学着突然遇到版本问题,在SpringBoot1.0版本中,自定义Redis序列化操作特别简单,new一个自定义的RedisTemplate就好了,但是在SpringBoot2.0版本中,自定义Redis的序列化就变得稍微复杂一点。
出现的问题:
默认使用的序列器是JdkSerializationRedisSerializer,此序列化器导致下图结果,所以我们需要自定义序列化。
自定义序列化过程:
1. 先看默认序列化的实现
实现过程在org.springframework.boot.autoconfigure.cache.RedisCacheConfiguration(自动配置组件)中
@BeanRedisCacheManager cacheManager(CacheProperties cacheProperties, CacheManagerCustomizers cacheManagerCustomizers,ObjectProvider<org.springframework.data.redis.cache.RedisCacheConfiguration> redisCacheConfiguration,ObjectProvider<RedisCacheManagerBuilderCustomizer> redisCacheManagerBuilderCustomizers,RedisConnectionFactory redisConnectionFactory, ResourceLoader resourceLoader) {RedisCacheManagerBuilder builder = RedisCacheManager.builder(redisConnectionFactory).cacheDefaults(determineConfiguration(cacheProperties, redisCacheConfiguration, resourceLoader.getClassLoader()));List<String> cacheNames = cacheProperties.getCacheNames();if (!cacheNames.isEmpty()) {builder.initialCacheNames(new LinkedHashSet<>(cacheNames));}redisCacheManagerBuilderCustomizers.orderedStream().forEach((customizer) -> customizer.customize(builder));return cacheManagerCustomizers.customize(builder.build());}
其实这个方法的重点就在下面这句代码中:
RedisCacheManagerBuilder builder = RedisCacheManager.builder(redisConnectionFactory).cacheDefaults(determineConfiguration(cacheProperties, redisCacheConfiguration, resourceLoader.getClassLoader()));
分析:
在这句代码中,代码结构就是使用建造者模式,创建出一个builder对象,之后需要用这个builder对象建造我们需要用于实现序列化的RedisCacheManager对象。生成创建者时涉及到的主要对象有CacheProperties ,RedisCacheConfiguration。而这两个对象中,cacheProperties是加载配置文件中的缓存配置的,与自定义实现序列化没啥关系,关键是RedisCacheConfiguration这个对象。
看看这个类注释怎么写的
/*** Immutable {@link RedisCacheConfiguration} helps customizing {@link RedisCache} behaviour such as caching* {@literal null} values, cache key prefixes and binary serialization. <br />* Start with {@link RedisCacheConfiguration#defaultCacheConfig()} and customize {@link RedisCache} behaviour from there* on.** @author Christoph Strobl* @author Mark Paluch* @since 2.0*/
简单翻译一下,RedisCacheConfiguration帮助自定义行为,如缓存值,缓存键前缀和二进制序列化。现在的任务就是搞清楚RedisCacheConfiguration实现序列化的过程,在RedisCacheConfiguration类中有两个成员变量:
private final SerializationPair<String> keySerializationPair;private final SerializationPair<Object> valueSerializationPair;
这一看知道是用来实现序列化的,其中keySerializationPair的类型是String,valueSerializationPair的类型是Object,这就解释了为什么存入redis时,key是正常显示,而value是看不懂的转译后的序列字节码。所以我们需要自定义值的序列化。在类RedisCacheConfiguration中有一个serializeValuesWith方法,这个方法就实现了值序列化的过程。
public RedisCacheConfiguration serializeValuesWith(SerializationPair<?> valueSerializationPair) {Assert.notNull(valueSerializationPair, "ValueSerializationPair must not be null!");//返回一个RedisCacheConfiguration对象,其中的valueSerializationPair是由参数传入的SerializationPair对象return new RedisCacheConfiguration(ttl, cacheNullValues, usePrefix, keyPrefix, keySerializationPair,valueSerializationPair, conversionService);}
在SerializationPair对象中有一个静态代码块,使用了适配器模式,提供了我们自定义序列化器的接口,我们只要把自定义的序列化器传进去就可以实现自定义序列化了。
/*** Creates a {@link SerializationPair} adapter given {@link RedisSerializer}.** @param serializer must not be {@literal null}.* @return a {@link SerializationPair} adapter for {@link RedisSerializer}.*/static <T> SerializationPair<T> fromSerializer(RedisSerializer<T> serializer) {Assert.notNull(serializer, "RedisSerializer must not be null!");return new RedisSerializerToSerializationPairAdapter<>(serializer);}
2.自定义序列化
1.实现自定义RedisCacheConfiguration:
@Bean
public RedisCacheConfiguration myRedisCacheConfiguration() {//使用json序列化器RedisSerializer<Object> jackson2JsonRedisSerializer = new GenericJackson2JsonRedisSerializer();//将选用的自定义序列化器传入SerializationPair.fromSerializer这个静态代码块中,从而得到一个SerializationPairRedisSerializationContext.SerializationPair<Object> serializationPair = RedisSerializationContext.SerializationPair.fromSerializer(jackson2JsonRedisSerializer);//将SerializationPair用于存入Redis中值的序列化return RedisCacheConfiguration.defaultCacheConfig().serializeValuesWith(serializationPair);
}
2. 实现自定义RedisCacheManager:
@Beanpublic RedisCacheManager myCacheManager(RedisConnectionFactory redisConnectionFactory) {//把前面自定义好的myRedisCacheConfiguration作为参数传入,最后使用创建者模式返回RedisCacheManager对象,实现自定义序列化RedisCacheManager.RedisCacheManagerBuilder builder = RedisCacheManager.RedisCacheManagerBuilder.fromConnectionFactory(redisConnectionFactory).cacheDefaults(myRedisCacheConfiguration());RedisCacheManager cm = builder.build();return cm;}
这篇关于SpringBoot2.0版本自定义Redis序列化的文章就介绍到这儿,希望我们推荐的文章对编程师们有所帮助!