Redis《RedisSerializer》
文章目录
- RedisSerializer
- 为什么要使用
- 如何使用RedisSerializer
- 总结
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 {@Beanpublic 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 {@Resourceprivate RedisTemplate redisTemplate;@Testvoid testString() {redisTemplate.opsForValue().set("name", "虎哥");// 从redis中获取nameObject name = redisTemplate.opsForValue().get("name");System.out.println("name: " + name);}
}
总结
本篇博客介绍了有关RedisTemplate中的RedisSerializer,关于为什么要用,已经如何使用,如果有什么不正确或比较片面的地方,还望指正,谢谢大家!!!