SpringBoot2使⽤@Cacheable注解时,Redis中保存的Value
为jav。。。
说明:SpringBoot版本为2.1.6.RELEASE
spring ioc注解
看了许多同学的博客都是通过⾃定义RedisCacheManager组件的⽅式来解决,我这⾥换⼀种⽅式,采⽤⾃定义
org.dis.cache.RedisCacheConfiguration组件的⽅式来解决,并附上源码分析过程:
⾸先要明确SpringBoot Data在整合Redis作为Cache的实现⽅式后,组件之间的依赖关系变为:
CacheAutoConfiguration-->RedisCacheConfiguration(autoconfigure.cache)-->RedisCacheManager-->RedisCache--
>RedisCacheConfiguration(redis.cache)
为什么使⽤@Cacheable注解后,保存的Value在Redis中是乱码,⾸先想到的是从RedisCache类中的put()⽅法⼊⼿。
put⽅法的逻辑如下图:
进⼊createAndConvertCacheKey(key)、serializeCacheValue(cacheValue)⽅法中,这⾥不贴代码了,可以知道对key和value的序列化规则都是从当前类的成员变量cacheConfig中获取配置的,⽽此成员变量cacheConfig对应的类型是
org.dis.cache.RedisCacheConfiguration类:
进⼊org.dis.cache.RedisCacheConfiguration类中:
发现该类类头没有注解,推测它并不是容器中的⼀个组件,且对两个成员变量keySerializationPair、valueSerializationPair并没有赋予初始值,且唯⼀的构造器还是private私有的。
但此类中有两个static静态⽅法对keySerializationPair和valueSerializationPair成员变量进⾏了赋值,且返回⼀个实例对象:
分析到这⾥,我们就要知道是谁调⽤了此静态⽅法:
Ctrl+单击此defaultCacheConfig静态⽅法,发现是org.springframework.boot.autoconfigure.cache.RedisCacheConfiguration配
置类在向IOC容器中注⼊组件RedisCacheManager时,调⽤了此静态⽅法,见下图:
上图说明:在调⽤RedisCacheManager.builder⽅法创建RedisCacheManagerBuilder对象后,调⽤determineConfiguration⽅法进⾏装配RedisCacheConfiguration时调⽤的此defaultCacheConfig静态⽅法。
⽽在determineConfiguration⽅法中,调⽤此静态⽅法之前的前提条件是:disCacheConfigurati
on不为空。否则就按照后⾯的逻辑对value实⾏Java序列化规则:JdkSerializationRedisSerializer。
现在就分析当前类的成员变量disCacheConfiguration的赋值逻辑,如下图:
发现在当前类的有参构造器中,它会从IOC容器中获取org.dis.cache.RedisCacheConfiguration组件并赋值给此成员变量。只不过IOC容器中并没有该可⽤组件,可以打断点看到:
解决办法:
通过以上的分析,那我们就可以⾃⼰⼿动向IOC容器中注册⼀个类型为
org.dis.cache.RedisCacheConfiguration的组件,并参照determineConfiguration⽅法:调⽤serializeValuesWith⽅法对value的序列化规则改为json类型:
/**
* 注册⾃定义RedisCacheConfiguration组件,解决@Cacheable @Cacheput注解在向Redis中保存的Value是java序列化乱码的问题
*/
@Bean
public RedisCacheConfiguration redisCacheConfiguration() {
RedisCacheConfiguration config = RedisCacheConfiguration.defaultCacheConfig();
config=config.serializeValuesWith(RedisSerializationContext.SerializationPair.fromSerializer(RedisSerializer.json()));
return config;
}
再次打断点观察RedisCacheManager组件的注册逻辑:就可以看到disCacheConfiguration不为null,且对Value的序列化规则已经改成我们⾃定义的了。
原创不易,转载请指明出处,谢谢!

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