项目中使用redis做缓存序列化踩坑

示例代码

自定义的RedisTemplate,核心序列化器为GenericJackson2JsonRedisSerializer,其中使用了 jackson 来将对象转为 json 字符串。

import org.springframework.data.redis.connection.DefaultStringRedisConnection;
import org.springframework.data.redis.connection.RedisConnection;
import org.springframework.data.redis.connection.RedisConnectionFactory;
import org.springframework.data.redis.core.RedisTemplate;
import org.springframework.data.redis.serializer.GenericJackson2JsonRedisSerializer;
import org.springframework.data.redis.serializer.RedisSerializer;

public class ObjectRedisTemplate extends RedisTemplate<String, Object> {
    public ObjectRedisTemplate() {
        RedisSerializer<Object> objectRedisSerializer = new GenericJackson2JsonRedisSerializer();
        setKeySerializer(RedisSerializer.string());
        setValueSerializer(objectRedisSerializer);
        setHashKeySerializer(RedisSerializer.string());
        setHashValueSerializer(objectRedisSerializer);
    }
    public ObjectRedisTemplate(RedisConnectionFactory connectionFactory) {
        this();
        setConnectionFactory(connectionFactory);
        afterPropertiesSet();
    }
    protected RedisConnection preProcessConnection(RedisConnection connection, boolean existingConnection) {
        return new DefaultStringRedisConnection(connection);
    }
}

问题描述

项目中使用了自定义的 RedisTemplate,redis中值的序列化方式为 json,但是包含了类名,生成的 json 如下

{
  "@class": "com.imooc.User",
  "userName": "lisi",
  "address": {
    "@class": "com.imooc.Address",
    "province": "山东"
  }
}
  1. 如果 A 服务将 User 对象保存到 redis 中,但是 User 类增加了字段,这个时候 B 服务从 redis 读取会报错,默认是不忽略不认识的属性。
  2. 如果两个服务的 User 类所属的 package 不同,也会读取 redis 失败

扩展性很不好

解决方法

使用 Spring 中定义好的 StringRedisTemplate,它使用的序列化器为 StringRedisSerializer,我们在存到 redis 之前需要先自己将 Bean 对象转为 json 字符串(自已控制)。这样 redis 中存储的就是简单的 json 字符串,读取也不会有乱七八糟的问题。

posted @ 2025-04-08 21:57  strongmore  阅读(66)  评论(0)    收藏  举报