一.简介
简单的说,RedisTemplate
和StringRedisTemplate
的关系如下:
1.
StringRedisTemplate
是RedisTemplate
的子类。2.
StringRedisTemplate
的各个序列化策略都是StringRedisSerializer
,而RedisTemplate
用的是JdkSerializationRedisSerializer
。
二.RedisTemplate和StringRedisTemplate的代码结构
从RedisTemplate
类说起。
在RedisTemplate
类中,定义了这样四个变量:
@Nullable
private RedisSerializer keySerializer = null;
@Nullable
private RedisSerializer valueSerializer = null;
@Nullable
private RedisSerializer hashKeySerializer = null;
@Nullable
private RedisSerializer hashValueSerializer = null;
分别代表了普通key
,value
,和Hash
类型的key
,value的序列化策略,可以分别设置。
另外定义变量,用来指定默认的序列化策略:
@Nullable
private RedisSerializer> defaultSerializer;
在RedisTemplate
类中,定义了afterPropertiesSet()
方法,当Spring
创建RedisTemplate
类的对象时,会调用这个方法:
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
使用的默认序列化策略是JdkSerializationRedisSerializer
。包括RedisTemplate
下的key
,value
,hash-key
,hash-value的序列化,都用这种策略。
再来看看StringRedisTemplate
,他作为RedisTemplate的子类,只是修改了序列化策略:
public class StringRedisTemplate extends RedisTemplate<String, String> {
public StringRedisTemplate() {
RedisSerializer stringSerializer = new StringRedisSerializer();this.setKeySerializer(stringSerializer);this.setValueSerializer(stringSerializer);this.setHashKeySerializer(stringSerializer);this.setHashValueSerializer(stringSerializer);
}public StringRedisTemplate(RedisConnectionFactory connectionFactory) {
this();this.setConnectionFactory(connectionFactory);this.afterPropertiesSet();
}protected RedisConnection preProcessConnection(RedisConnection connection, boolean existingConnection) {
return new DefaultStringRedisConnection(connection);
}
}
以上就是StringRedisTemplate
整个类的内容,可以看到,在他的默认构造中,key
,value
,hash-key
,hash-value
都使用的是StringRedisSerializer类作为序列化策略。这也就是StringRedisTemplate
和他的父类RedisTemplate的主要区别。
三.序列化策略
更进一步,看一下这个序列化策略是什么。
上面提到的StringRedisSerializer
和JdkSerializationRedisSerializer
都是序列化策略类,他们都实现了一个RedisSerializer
接口:
public interface RedisSerializer<T> {
@Nullable
byte[] serialize(@Nullable T var1) throws SerializationException;
@Nullable
T deserialize(@Nullable byte[] var1) throws SerializationException;
}
接口表达的意思很简单,两个方法,serialize用于序列化,把对象变为byte
数组,deserialize
用于反序列化,把byte数组转为对象。
StringRedisSerializer
看看StringRedisSerializer
是怎么做的:
1.StringRedisSerializer的构造:
public StringRedisSerializer() {
this(StandardCharsets.UTF_8);
}
public StringRedisSerializer(Charset charset) {
Assert.notNull(charset, "Charset must not be null!");
this.charset = charset;
}
定义了编码格式,默认UTF_8
。
2.StringRedisSerializer的serialize和deserialize方法:
public String deserialize(@Nullable byte[] bytes) {
return bytes