Redisson 自定义序列化 Codec 实战指南:原理、实现与踩坑记录
📚 背景介绍:为什么要自定义 Codec?
Redisson 默认支持多种序列化方式(如 JsonJacksonCodec, FstCodec, KryoCodec 等),但在实际项目中可能遇到如下问题:
- 默认的序列化器无法满足精度、兼容性或安全性要求
- 要与其他服务(如 Python/Golang)兼容通信格式
- 想要替换掉过大的 Jackson,换成轻量的 JSON 序列化方式
- 需要对某些字段做脱敏或加密处理
🧩 Codec 接口原理简析
java
public interface Codec extends Serializable {
Decoder<Object> getValueDecoder();
Encoder getValueEncoder();
Decoder<Object> getMapValueDecoder();
Encoder getMapValueEncoder();
Decoder<Object> getMapKeyDecoder();
Encoder getMapKeyEncoder();
}
✍️ 实战演练:自定义 FastJson Codec
java
public class FastJsonCodec implements Codec {
private final Charset charset = StandardCharsets.UTF_8;
@Override public Decoder<Object> getValueDecoder() { return this::decode; }
@Override public Encoder getValueEncoder() { return this::encode; }
@Override public Decoder<Object> getMapValueDecoder() { return getValueDecoder(); }
@Override public Encoder getMapValueEncoder() { return getValueEncoder(); }
@Override public Decoder<Object> getMapKeyDecoder() { return getValueDecoder(); }
@Override public Encoder getMapKeyEncoder() { return getValueEncoder(); }
private byte[] encode(Object in) throws IOException {
if (in == null) return new byte[0];
String json = JSON.toJSONString(in);
return json.getBytes(charset);
}
private Object decode(ByteBuffer buf, ClassLoader classLoader) throws IOException {
if (!buf.hasRemaining()) return null;
byte[] bytes = new byte[buf.remaining()];
buf.get(bytes);
return JSON.parse(new String(bytes, charset));
}
}
🔧 配置与使用
java
Config config = new Config();
config.useSingleServer().setAddress("redis://127.0.0.1:6379");
config.setCodec(new FastJsonCodec());
RedissonClient redisson = Redisson.create(config);
🧪 测试验证
java
@Test
public void testFastJsonCodec() {
RMap<String, MyDTO> map = redisson.getMap("myMap");
map.put("key", new MyDTO("test", 123));
MyDTO value = map.get("key");
assertEquals("test", value.getName());
assertEquals(123, value.getValue());
}
⚠️ 踩坑与注意事项
- 类型信息丢失:使用 WriteClassName 写入类型,启用 autoType 支持(有安全风险)
- 编码一致性:统一使用 UTF-8 避免乱码
- 服务兼容性:跨语言建议使用 JSON 或 Protobuf