大家好,今天是对SpringBoot中redis缓存存储对象序列化问题的一个探讨。
Redis序列化
熟悉redis的小伙伴都知道,通过String存入到数据库中,数据是不会出现序列化问题的。如图:
但是我们在项目中并不会每次都存字符串进入,而是会存储对象,举个栗子:
我们在通过id查询时,返回了一个emp对象。我们给他标注了@Cacheable注解,那么每次通过id查询完以后就会将返回值对象给存入到缓存中,也就是我们的redis中。
我们这里查询了一个id为8的对象,那么打开redis,可以发现自动生成了一个emp::8的键
但是我们去查看这个emp::8的value值时,则会发现和我们想象的不太一样,返回的都是乱码而不是我们熟悉的对象。
通过测试取出来的是这样的东西:
这是因为redis的序列化问题,如果自己不设定,则会采用默认的jdk序列化格式。所以我们需要修改这个默认的序列化的格式。在SpringBoot中修改默认配置咋改?当然是直接自己写一个然后扔到容器中代替默认设置就好了。
@Configuration
public class MyRedisConfig {
@Bean
public RedisTemplate<Object, TblEmp> empRedisTemplate(RedisConnectionFactory redisConnectionFactory)throws UnknownHostException{
//设置redis模板
RedisTemplate<Object, TblEmp> template = new RedisTemplate<>();
//为redis模板传入连接工厂
template.setConnectionFactory(redisConnectionFactory);
//设置json的序列化
Jackson2JsonRedisSerializer<TblEmp> ser = new Jackson2JsonRedisSerializer<>(TblEmp.class);
//为redis模板设置默认的序列化方式
template.setDefaultSerializer(ser);
//将设置好的模板设置到容器中
return template;
}
@Bean //传入上面定义好序列化方式的redis模板
public RedisCacheManager redisCacheManager(RedisTemplate<Object, TblEmp> empRedisTemplate){
//2.0以上开始就需要传入一个redisCacheWriter参数,并传入上面写的模板对象的连接工厂 内部也是为其设置连接工厂和sleeptime
RedisCacheWriter redisCacheWriter = RedisCacheWriter.nonLockingRedisCacheWriter(empRedisTemplate.getConnectionFactory());
//在redis缓存配置文件中传入刚定义好的缓存配置empRedisTemplate.getValueSerializer()
RedisCacheConfiguration redisCacheConfiguration = RedisCacheConfiguration.defaultCacheConfig()
.serializeValuesWith(RedisSerializationContext.SerializationPair
.fromSerializer(empRedisTemplate.getValueSerializer()));
//将定义好的配置文件放入Redis缓存管理器,放入容器中。
return new RedisCacheManager(redisCacheWriter, redisCacheConfiguration);
}
}
配置好以后就默认生效了,这样我们传入的value如果是对象的格式,那么就会变成json字符串,如下图所示:
通过测试取出来也是没问题的。