redis配置序列化

时间:2025-03-10 21:31:08

序列化最终的目的是为了对象可以跨平台存储,和进行网络传输。而我们进行跨平台存储和网络传输的方式就是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);

    }