Spring官方现在还存在的6大序列化器:
1.OxmSerializer
以xml格式存储(但还是String类型~),解析起来也比较复杂,效率也比较低。因此几乎没有人再使用此方式了。
2.JdkSerializationRedisSerializer
从源码里可以看出,这是RestTemplate类默认的序列化方式。若你没有自定义,那就是它了。
使用JDK自带的序列化方式,有明显的缺点:
首先它要求存储的对象都必须实现java.io.Serializable接口,比较笨重
其次,他存储的为二进制数据,这对开发者是不友好的
再次,因为他存储的为二进制。但是有时候,我们的Redis会在一个项目的多个project中共用,这样如果同一个可以缓存的对象在不同的project中要使用两个不同的key来分别缓存,既麻烦,又浪费。
使用JDK提供的序列化功能。 优点是反序列化时不需要提供(传入)类型信息(class),但缺点是需要实现Serializable接口,还有序列化后的结果非常庞大,是JSON格式的5倍左右,这样就会消耗redis服务器的大量内存。
@Autowired
private RedisTemplate redisTemplate;
@Test
void contextLoads() {
redisTemplate.opsForValue().set("user", new UserInfo("admin"));
Object user = redisTemplate.opsForValue().get("user");
}
直接序列化会报错误:
Caused by: java.lang.IllegalArgumentException: DefaultSerializer requires a Serializable payload but received an object of type [com.example.blog.view.UserInfo]
必须让存储的对象实现 Serializable 接口
@Setter
@Getter
public class UserInfo implements Serializable {
private String name;
public UserInfo(String name) {
this.name = name;
}
}
虽然序列化成功了,但是存储的是二进制文件
3.StringRedisSerializer
也是StringRedisTemplate默认的序列化方式,key和value都会采用此方式进行序列化,是被推荐使用的,对开发者友好,轻量级,效率也比较高。
4.GenericToStringSerializer
他需要调用者给传一个对象到字符串互转的Converter(相当于转换为字符串的操作交给转换器去做),个人觉得使用起来其比较麻烦,还不如直接用字符串呢。所以不太推荐使用
5.Jackson2JsonRedisSerializer
从名字可以看出来,这是把一个对象以Json的形式存储,效率高且对调用者友好
优点是速度快,序列化后的字符串短小精悍,不需要实现Serializable接口。
但缺点也非常致命:那就是此类的构造函数中有一个类型参数,必须提供要序列化对象的类型信息(.class对象)。 通过查看源代码,发现其在反序列化过程中用到了类型信息(必须根据此类型信息完成反序列化)。
6.GenericJackson2JsonRedisSerializer
基本和上面的Jackson2JsonRedisSerializer功能差不多,使用方式也差不多。
指定RedisTemplate的序列化方式
指定序列化方式
@Configuration
public class RedisConfig {
/**
* redisTemplate 默认的序列化方式为 JdkSerializationRedisSerializer
* StringRedisTemplate 的默认序列化方式为 StringRedisSerializer
* 使用 fastJsonRedisSerializer 替换默认序列化方式
*/
@Bean
public RedisTemplate<String, Object> redisTemplate(RedisConnectionFactory redisConnectionFactory) {
RedisTemplate<String, Object> redisTemplate = new RedisTemplate<>();
redisTemplate.setConnectionFactory(redisConnectionFactory);
FastJsonRedisSerializer<Object> fastJsonRedisSerializer = new FastJsonRedisSerializer<>(Object.class);
// 设置值value的序列化方式
redisTemplate.setValueSerializer(fastJsonRedisSerializer);
redisTemplate.setHashValueSerializer(fastJsonRedisSerializer);
// 设置键key的序列化方式
redisTemplate.setKeySerializer(new StringRedisSerializer());
redisTemplate.setHashKeySerializer(new StringRedisSerializer());
redisTemplate.afterPropertiesSet();
return redisTemplate;
}
}
set/get方法:
@Component
public class RedisUtil {
@Autowired
private RedisTemplate<String, Object> redisTemplate;
public void set(String key, Object value, Long time){
redisTemplate.opsForValue().set(key, value, time, TimeUnit.SECONDS);
}
public Object get(String key){
return redisTemplate.opsForValue().get(key);
}
}