配置RedissonClient
@Bean
public RedissonClient redissonClient() {
    Config config = new Config();
    // 单节点模式
    SingleServerConfig singleServerConfig = config.useSingleServer();
    singleServerConfig.setAddress("redis://127.0.0.1:6379");
    singleServerConfig.setPassword("");
    // 使用json序列化方式
    Codec codec = new JsonJacksonCodec();
    config.setCodec(codec);
    RedissonClient redissonClient = Redisson.create(config);
    return redissonClient;
}除上方配置的单机模式,其它模式配置:
 
   数据序列化
Redisson的对象编码类是用于将对象进行序列化和反序列化,以实现对该对象在Redis里的读取和存储。Redisson提供了以下几种的对象编码应用,以供大家选择:
| 编码类名称 | 说明 | 
| org.redisson.codec.JsonJacksonCodec | Jackson JSON 编码 默认编码 | 
| org.redisson.codec.AvroJacksonCodec | Avro 一个二进制的JSON编码 | 
| org.redisson.codec.SmileJacksonCodec | Smile 另一个二进制的JSON编码 | 
| org.redisson.codec.CborJacksonCodec | CBOR 又一个二进制的JSON编码 | 
| org.redisson.codec.MsgPackJacksonCodec | MsgPack 再来一个二进制的JSON编码 | 
| org.redisson.codec.IonJacksonCodec | Amazon Ion 亚马逊的Ion编码,格式与JSON类似 | 
| org.redisson.codec.KryoCodec | Kryo 二进制对象序列化编码 | 
| org.redisson.codec.SerializationCodec | JDK序列化编码 | 
| org.redisson.codec.FstCodec | FST 10倍于JDK序列化性能而且100%兼容的编码 | 
| org.redisson.codec.LZ4Codec | LZ4 压缩型序列化对象编码 | 
| org.redisson.codec.SnappyCodec | Snappy 另一个压缩型序列化对象编码 | 
| org.redisson.client.codec.JsonJacksonMapCodec | 基于Jackson的映射类使用的编码。可用于避免序列化类的信息,以及用于解决使用byte[]遇到的问题。 | 
| org.redisson.client.codec.StringCodec | 纯字符串编码(无转换) | 
| org.redisson.client.codec.LongCodec | 纯整长型数字编码(无转换) | 
| org.redisson.client.codec.ByteArrayCodec | 字节数组编码 | 
| org.redisson.codec.CompositeCodec | 用来组合多种不同编码在一起 | 
自定义序列化
需求背景:
项目之前使用的RestTemplate api,RestTemplate的序列化使用的RedisSerializer接口,使用的实现类Jackson2JsonRedisSerializer。
现在改为使用RedissonClient,RedissonClient的序列化使用的Codec接口,默认实现类JsonJacksonCodec。
2种实现类序列化方式不同,而生产环境数据迁移有风险,所以需实现Codec接口,自定义RedissonClient序列化方式,替换Redisson的序列化对象JsonJacksonCodec,兼容旧数据。
目的:
兼容原有RedisTemplate Jackson2JsonRedisSerializer对象序列化数据。
分析:
RedisTemplate初始化代码:
    protected RedisTemplate<String, Object> buildRedisTemplate(RedisConnectionFactory redisConnectionFactory) {
        RedisTemplate<String, Object> template = new RedisTemplate<>();
        template.setConnectionFactory(redisConnectionFactory);
        Jackson2JsonRedisSerializer jackson2JsonRedisSerializer = new Jackson2JsonRedisSerializer(Object.class);
        ObjectMapper om = new ObjectMapper();
        om.setVisibility(PropertyAccessor.ALL, JsonAutoDetect.Visibility.ANY);
        // 指定序列化输入的类型,类必须是非final修饰的。序列化时将对象全类名一起保存下来
        om.activateDefaultTyping(LaissezFaireSubTypeValidator.instance, ObjectMapper.DefaultTyping.NON_FINAL);
        jackson2JsonRedisSerializer.setObjectMapper(om);
        StringRedisSerializer stringRedisSerializer = new StringRedisSerializer();
        // key采用String的序列化方式
        template.setKeySerializer(stringRedisSerializer);
        // hash的key也采用String的序列化方式
        template.setHashKeySerializer(stringRedisSerializer);
        // value序列化方式采用jackson
        template.setValueSerializer(jackson2JsonRedisSerializer);
        // hash的value序列化方式采用jackson
        template.setHashValueSerializer(jackson2JsonRedisSerializer);
        template.afterPropertiesSet();
        return template;
    }JsonJacksonCodec构造器初始化源码:
    public JsonJacksonCodec() {
        this(new ObjectMapper());
    }跟踪发现底层初始化时,默认给ObjectMapper设置了一些参数:
    init(this.mapObjectMapper);
    protected void init(ObjectMapper objectMapper) {
        objectMapper.setSerializationInclusion(Include.NON_NULL);
        objectMapper.setVisibility(objectMapper.getSerializationConfig()
                                                    .getDefaultVisibilityChecker()
                                                        .withFieldVisibility(JsonAutoDetect.Visibility.ANY)
                                                        .withGetterVisibility(JsonAutoDetect.Visibility.NONE)
                                                        .withSetterVisibility(JsonAutoDetect.Visibility.NONE)
                                                        .withCreatorVisibility(JsonAutoDetect.Visibility.NONE));
        objectMapper.disable(DeserializationFeature.FAIL_ON_UNKNOWN_PROPERTIES);
        objectMapper.enable(Feature.WRITE_BIGDECIMAL_AS_PLAIN);
        objectMapper.disable(SerializationFeature.FAIL_ON_EMPTY_BEANS);
        objectMapper.enable(MapperFeature.SORT_PROPERTIES_ALPHABETICALLY);
        objectMapper.addMixIn(Throwable.class, ThrowableMixIn.class);
    }就是这些ObjectMapper的初始化参数导致对象序列化数据不兼容,所以自定义Codec,和原来ObjectMapper的初始化保持一致即可!
实现:
自定义Codec实现类:RedissonCodec
/**
 * 替换Redisson的序列化对象JsonJacksonCodec,兼容原有RedisTemplate的对象序列化。
 *
 * @author yangzihe
 * @date 2022/12/13
 */
public class RedissonCodec extends BaseCodec {
    protected final ObjectMapper mapObjectMapper;
    /**
     * @see JsonJacksonCodec
     */
    private final Encoder encoder = new Encoder() {
        @Override
        public ByteBuf encode(Object in) throws IOException {
            ByteBuf out = ByteBufAllocator.DEFAULT.buffer();
            try {
                ByteBufOutputStream os = new ByteBufOutputStream(out);
                mapObjectMapper.writeValue((OutputStream) os, in);
                return os.buffer();
            } catch (IOException e) {
                out.release();
                throw e;
            } catch (Exception e) {
                out.release();
                throw new IOException(e);
            }
        }
    };
    private final Decoder<Object> decoder = new Decoder<Object>() {
        @Override
        public Object decode(ByteBuf buf, State state) throws IOException {
            return mapObjectMapper.readValue((InputStream) new ByteBufInputStream(buf), Object.class);
        }
    };
    public RedissonCodec(ObjectMapper mapObjectMapper) {
        this(mapObjectMapper, true);
    }
    public RedissonCodec(ObjectMapper mapObjectMapper, boolean copy) {
        if (copy) {
            this.mapObjectMapper = mapObjectMapper.copy();
        } else {
            this.mapObjectMapper = mapObjectMapper;
        }
    }
    @Override
    public Decoder<Object> getValueDecoder() {
        return decoder;
    }
    @Override
    public Encoder getValueEncoder() {
        return encoder;
    }
    @Override
    public ClassLoader getClassLoader() {
        if (mapObjectMapper.getTypeFactory().getClassLoader() != null) {
            return mapObjectMapper.getTypeFactory().getClassLoader();
        }
        return super.getClassLoader();
    }
}redis工具类
public final class RedisUtils {
    public static final Codec REDISSON_CODEC;
    static {
        ObjectMapper om = new ObjectMapper();
        om.setVisibility(PropertyAccessor.ALL, JsonAutoDetect.Visibility.ANY);
        // 指定序列化输入的类型,类必须是非final修饰的。序列化时将对象全类名一起保存下来
        om.activateDefaultTyping(LaissezFaireSubTypeValidator.instance, ObjectMapper.DefaultTyping.NON_FINAL);
        REDISSON_CODEC = new RedissonCodec(om);
    }
    private RedisUtils() {}
}代码使用
redissonClient.getConfig().setCodec(RedisUtils.REDISSON_CODEC);
redissonClient.getSet(redisKey, RedisUtils.REDISSON_CODEC).add(object);
redissonClient.getSet(redisKey, RedisUtils.REDISSON_CODEC).remove(object);


















