RedisSerializer
为什么要使用
RedisTemplate
有默认的序列化器,但默认使用的
JdkSerializationRedisSerializer
存在一些问题:
- 序列化后的数据包含类信息等额外内容,导致存储的数据体积较大
- 生成的是二进制数据,在 Redis 客户端中查看时可读性差
RedisTemplate
是操作 Redis 的主体,而 RedisSerializer
是 RedisTemplate
中负责数据格式转换的关键组件。正确配置序列化器可以让 Redis 存储的数据更高效、更易读、更具兼容性
首先看一下RedisTemplate
的部分源码
这四个引用默认为空,当afterPropertiesSet方法进行判断时,为空的话,默认创建一个jdk的序列化器,这就是后面我们会调用的类
现在我们使用这个对象的set方法,通过debug方式看看它怎么运行
当我们点击set方法
会将传入的key和value传入rawKey和rawValue,当我们点入rawKey
这里的逻辑有点绕,可能大家会想,我明明没有设置序列化器,为什么还是走else
其实不是
这里我们可以看到,如果我们不定义序列化器,他会把上面的afterPropertiesSet
方法初始化的JdkSerializationRedisSerializer
给keySerializer
,后续我们所调用的序列化器就有了默认的序列化器
小插曲:
大家知道为什么会调用afterPropertiesSet
方法吗?
还是源码
当一个 Bean 实现了 InitializingBean
接口后,Spring 容器在完成该 Bean 的所有属性注入(即调用完所有 setter 方法)后,会自动调用接口中的 afterPropertiesSet()
方法。
书接上回,经过一系列的赋值和调用,这里会判断是否已经自己定义序列化器,如果没有,且我们自己将key给序列化了——不是自动的
比如我自己将"user:100"序列化了,这样redis就能直接存储原始的二进制,不需要再进行序列化转换
虽然我们没有设定序列化器但我们有默认的,且没有手动将字符串序列化,所以我们走else
点击serialize()
如果是debug的形式我们会进入这个类——熟悉吗,上面初始化的类
点击convert()
点击serializeToByteArray()
这里我们可以看到通过ObjectOutputStream
类将java对象转成字节
最后会在redis中以这样的方式存储
如何使用RedisSerializer
引入依赖
<dependency>
<groupId>com.fasterxml.jackson.core</groupId>
<artifactId>jackson-databind</artifactId>
</dependency>
@Configuration
public class RedisConfig {
@Bean
public RedisTemplate<String, Object> redisTemplate(RedisConnectionFactory connectionFactory) {
// 创建RedisTemplate对象
RedisTemplate<String, Object> template = new RedisTemplate<>();
// 设置连接工厂
template.setConnectionFactory(connectionFactory);
// 设置序列化工具
GenericJackson2JsonRedisSerializer serializer = new GenericJackson2JsonRedisSerializer();
// 设置key的序列化
template.setKeySerializer(RedisSerializer.string());
template.setHashKeySerializer(RedisSerializer.string());
// 设置value的序列化
template.setValueSerializer(serializer);
template.setHashValueSerializer(serializer);
// 返回
return template;
}
}
这里实际上就是将我们之前提到的几个引用为null的引用进行赋值,从而改变序列化器,改变reids中存储的内容
@SpringBootTest
class SpringdataredisDemoApplicationTests {
@Resource
private RedisTemplate redisTemplate;
@Test
void testString() {
redisTemplate.opsForValue().set("name", "虎哥");
// 从redis中获取name
Object name = redisTemplate.opsForValue().get("name");
System.out.println("name: " + name);
}
}
总结
本篇博客介绍了有关RedisTemplate中的RedisSerializer,关于为什么要用,已经如何使用,如果有什么不正确或比较片面的地方,还望指正,谢谢大家!!!