赞
踩
RedisTemplate 看这个类的名字后缀是 Template ,如果了解过 Spring 如何连接关系型数据库的,大概不会难猜出这个类是做什么的 ,它跟 JdbcTemplate 一样封装了对Redis的一些常用的操作,当然 StringRedisTemplate 跟 RedisTemplate 功能类似那么肯定就会有人问,为什么会需要两个Template呢,一个不就够了吗?其实他们两者之间的区别主要在于他们使用的序列化类是不同的。
RedisTemplate 默认使用的序列类在在操作数据的时候,比如说存入数据会将数据先序列化成字节数组然后在存入 Redis 数据库,这个时候打开 Redis 查看的时候,你会看到你的数据不是以可读的形式展现的,而是以字节数组显示,类似下面:
StringRedisTemplate 默认存入的数据就是原文,因为 StringRedisTemplate 默认使用的是 String 序列化策略,使用 StringRedisTemplate 默认存入数据长这个样:
造成两者差异的原因是因为在初始化时,两者使用的序列化策略不同导致的,翻开源码可以看到,如下:
- public class RedisTemplate<K, V> extends RedisAccessor implements RedisOperations<K, V>, BeanClassLoaderAware {
- private boolean enableTransactionSupport = false;
- private boolean exposeConnection = false;
- private boolean initialized = false;
- private boolean enableDefaultSerializer = true;
- @Nullable
- private RedisSerializer<?> defaultSerializer;
- @Nullable
- private RedisSerializer keySerializer = null;
- @Nullable
- private RedisSerializer valueSerializer = null;
- @Nullable
- private RedisSerializer hashKeySerializer = null;
- @Nullable
- private RedisSerializer hashValueSerializer = null;
- // 其它字段略...
-
- public RedisTemplate() {
- }
-
-
- // 该方法是重写RedisAccessor的方法 RedisAccessor实现了spring的InitializingBean 也就是在启动时会执行该方法 可以看到该方法默认的序列化为JdkSerializationRedisSerializer
- public void afterPropertiesSet() {
- super.afterPropertiesSet();
- boolean defaultUsed = false;
- if (this.defaultSerializer == null) {
- this.defaultSerializer = new JdkSerializationRedisSerializer(this.classLoader != null ? this.classLoader : this.getClass().getClassLoader());
- }
-
- if (this.enableDefaultSerializer) {
- if (this.keySerializer == null) {
- this.keySerializer = this.defaultSerializer;
- defaultUsed = true;
- }
-
- if (this.valueSerializer == null) {
- this.valueSerializer = this.defaultSerializer;
- defaultUsed = true;
- }
-
- if (this.hashKeySerializer == null) {
- this.hashKeySerializer = this.defaultSerializer;
- defaultUsed = true;
- }
-
- if (this.hashValueSerializer == null) {
- this.hashValueSerializer = this.defaultSerializer;
- defaultUsed = true;
- }
- }
-
- if (this.enableDefaultSerializer && defaultUsed) {
- Assert.notNull(this.defaultSerializer, "default serializer null and not all serializers initialized");
- }
-
- if (this.scriptExecutor == null) {
- this.scriptExecutor = new DefaultScriptExecutor(this);
- }
-
- this.initialized = true;
- }
- // 其余方法略...
- }
可以看到 RedisTemplate 在初始化时是无参构造,通过 Spring 的 Bean 加载机制在项目启动时执行afterPropertiesSet来完成序列化设置,如果需要自定义序列化配置,可以自己写一个 RedisTemplate 的Bean,来完成配置。
- @Configuration
- public class RedisConfig {
-
- @Bean
- public RedisTemplate<String,Object> redisTemplate(@Autowired RedisConnectionFactory redisConnectionFactory) {
- // 创建RedisTemplate
- RedisTemplate<String,Object> redisTemplate = new RedisTemplate<String,Object>();
- // 字符串和JDK序列化器
- RedisSerializer<String> strSerializer = RedisSerializer.string();
- RedisSerializer<Object> jdkSerializer = RedisSerializer.java();
- // 设置键值序列化器
- redisTemplate.setKeySerializer(strSerializer);
- redisTemplate.setValueSerializer(jdkSerializer);
- // 设置哈希字段和值序列化器
- redisTemplate.setHashKeySerializer(strSerializer);
- redisTemplate.setHashValueSerializer(jdkSerializer);
- // 给redisTemplate设置连接工厂
- redisTemplate.setConnectionFactory(redisConnectionFactory);
- return redisTemplate;
- }
- }
StringRedisTemplate 就比较简单了,直接继承了 RedisTemplate,在初始化时默认使用了 String 序列化,源码如下:
- public class StringRedisTemplate extends RedisTemplate<String, String> {
- public StringRedisTemplate() {
- this.setKeySerializer(RedisSerializer.string());
- this.setValueSerializer(RedisSerializer.string());
- this.setHashKeySerializer(RedisSerializer.string());
- this.setHashValueSerializer(RedisSerializer.string());
- }
- // 其他方法略...
- }
那么就可以得出一个结论,如果你想使用默认的配置来操作 Redis,则如果操作的数据是字节数组,就是用RedisTemplate,如果操作的数据是明文,使用 StringRedisTemplate。
当然在项目中真实使用时,一般是自定义 RedisTemplate 的 Bean 实例,来设置具体的序列化策略,说白了就是 RedisTemplate 通过自定义 Bean 可以实现和 StringRedisTemplate 一样的序列化,使用起来更加灵活。
Copyright © 2003-2013 www.wpsshop.cn 版权所有,并保留所有权利。