序列化最终的目的是为了对象可以跨平台存储,和进行网络传输。而我们进行跨平台存储和网络传输的方式就是IO,而我们的IO支持的数据格式就是字节数组。 (推荐学习:Redis视频教程)
通过上面我想你已经知道了凡是需要进行“跨平台存储”和”网络传输”的数据,都需要进行序列化。
本质上存储和网络传输 都需要经过 把一个对象状态保存成一种跨平台识别的字节格式,然后其他的平台才可以通过字节信息解析还原对象信息。
redis序列化方式对比:
redis的默认方式是JdkSerializationRedisSerializer
JdkSerializationRedisSerializer: 使用JDK提供的序列化功能。
优点是反序列化时不需要提供类型信息(class),但缺点是需要实现Serializable接口,还有序列化后的结果非常庞大,是JSON格式的5倍左右,这样就会消耗redis服务器的大量内存。
Jackson2JsonRedisSerializer: 使用Jackson库将对象序列化为JSON字符串。
优点是速度快,序列化后的字符串短小精悍,不需要实现Serializable接口。
但缺点也非常致命,那就是此类的构造函数中有一个类型参数,必须提供要序列化对象的类型信息(.class对象)。 通过查看源代码,发现其只在反序列化过程中用到了类型信息。
问题:使用默认的JDK序列化方式,在RDM工具中查看k-v值时会出现“乱码”,不方便查看。
解决:自定义系列化方式,使用Jackson2JsonRedisSerializer
@Configuration
public class RedisConfig extends CachingConfigurerSupport {
private static final String STANDARD_PATTERN = "yyyy/MM/dd HH:mm:ss";
private static final String DATE_PATTERN = "yyyy/MM/dd";
private static final String TIME_PATTERN = "HH:mm:ss";
@Bean
public RedisTemplate<String, Object> redisTemplate(RedisConnectionFactory connectionFactory) {
RedisTemplate<String, Object> template = new RedisTemplate<>();
// 使用Jackson2JsonRedisSerialize 替换默认序列化
Jackson2JsonRedisSerializer<Object> jackson2JsonRedisSerializer =
new Jackson2JsonRedisSerializer<>();
ObjectMapper objectMapper = new ObjectMapper();
((),
.NON_FINAL,
);
(SerializationFeature.FAIL_ON_EMPTY_BEANS);
(DeserializationFeature.FAIL_ON_UNKNOWN_PROPERTIES, false);
(objectMapper);
(objectMapper);
(connectionFactory);
// key采用String的序列化方式
(new StringRedisSerializer());
// value序列化方式采用jackson
(jackson2JsonRedisSerializer);
// hash的key也采用String的序列化方式
(new StringRedisSerializer());
// hash的value序列化方式采用jackson
(jackson2JsonRedisSerializer);
();
return template;
}
/**
* 处理时间类型
*
* @param objectMapper
*/
private void registerLocalDateTime(ObjectMapper objectMapper) {
// 设置时间类的序列化以及反序列化的格式
(new SimpleDateFormat(STANDARD_PATTERN));
JavaTimeModule timeModule = new JavaTimeModule();
// LocalDateTime
DateTimeFormatter dateTimeFormatter = (STANDARD_PATTERN);
(, new LocalDateTimeSerializer(dateTimeFormatter));
(, new LocalDateTimeDeserializer(dateTimeFormatter));
// LocalDate
DateTimeFormatter dateFormatter = (DATE_PATTERN);
(, new LocalDateSerializer(dateFormatter));
(, new LocalDateDeserializer(dateFormatter));
// LocalTime
DateTimeFormatter timeFormatter = (TIME_PATTERN);
(, new LocalTimeSerializer(timeFormatter));
(, new LocalTimeDeserializer(timeFormatter));
(timeModule);
}