本章节将介绍怎样自定义 Spring Data Redis 序列化器。
如果我们要实现自定义序列化器必须实现 RedisSerializer 接口,该接口中定义了两个方法:
public byte[] serialize(T obj) throws SerializationException
将 obj 对象序列化为字节数组
public T deserialize(byte[] bytes) throws SerializationException
将 bytes 字节数组反序列化为 T 类型的对象
自定义一个 Spring Data Redis 序列化器,该序列化器将 Properties 对象序列化为一个字符串,字符串格式如下:
key1=value1,key2=value2,....,keyn=valuen
自定义序列化器实现 RedisSerializer 接口,并且指定泛型类型为 Properties。代码如下:
package com.hxstrive.redis.custom;
import org.springframework.data.redis.serializer.RedisSerializer;
import org.springframework.data.redis.serializer.SerializationException;
import org.springframework.util.StringUtils;
import java.nio.charset.StandardCharsets;
import java.util.Properties;
/**
* 自定义属性序列化器
* @author hxstrive.com 2022/10/1
*/
public class PropertiesSerializer implements RedisSerializer<Properties> {
// 序列化方法,将 Properties 转换为 key1=value1,key2=value2,... 格式
@Override
public byte[] serialize(Properties properties) throws SerializationException {
StringBuilder builder = new StringBuilder();
for(Object keyObj : properties.keySet()) {
if(builder.length() > 0) {
builder.append(",");
}
String key = (String) keyObj;
String value = properties.getProperty(key);
builder.append(key).append("=").append(value);
}
return builder.toString().getBytes(StandardCharsets.UTF_8);
}
// 反序列化,将字符串 key1=value1,key2=value2,... 转换成 Properties 对象
@Override
public Properties deserialize(byte[] bytes) throws SerializationException {
if(null == bytes) {
return null;
}
String byteStr = new String(bytes, StandardCharsets.UTF_8);
Properties properties = new Properties();
for(String item : byteStr.split(",")) {
if(StringUtils.isEmpty(item)) {
continue;
}
String[] items = item.split("=");
properties.setProperty(items[0], items[1]);
}
return properties;
}
}使用 @Configuration 配置一个 RedisTeamplate,该 RedisTeamplate 配置 key 使用 StringRedisSerializer 序列化器,value 使用自定义的 PropertiesSerializer 序列化器。代码如下:
@Bean
public RedisTemplate<String, Properties> propertiesSerialRedisTemplate(RedisConnectionFactory factory) {
RedisTemplate<String,Properties> redisTemplate = new RedisTemplate<>();
redisTemplate.setConnectionFactory(factory);
redisTemplate.setKeySerializer(new StringRedisSerializer());
// 将 value 使用自定义的序列化器进行序列化/反序列化
redisTemplate.setValueSerializer(new PropertiesSerializer());
redisTemplate.afterPropertiesSet();
return redisTemplate;
}创建一个 Spring Boot 的测试用例,验证自定义的序列化器能够正常工作。代码如下:
package com.hxstrive.redis.serializer.custom;
import org.junit.Test;
import org.junit.runner.RunWith;
import org.springframework.beans.factory.annotation.Autowired;
import org.springframework.beans.factory.annotation.Qualifier;
import org.springframework.boot.test.context.SpringBootTest;
import org.springframework.data.redis.core.RedisTemplate;
import org.springframework.data.redis.core.ValueOperations;
import org.springframework.test.context.junit4.SpringRunner;
import java.util.Properties;
/**
* 测试验证 PropertiesSerializer 序列化器
* @author hxstrive.com 2022/10/1
*/
@RunWith(SpringRunner.class)
@SpringBootTest
public class PropertiesSerializerTest {
@Autowired
@Qualifier("propertiesSerialRedisTemplate")
private RedisTemplate<String,Properties> redisTemplate;
@Test
public void demo() {
ValueOperations<String,Properties> ops = redisTemplate.opsForValue();
// 构建一个 Properties
Properties properties = new Properties();
properties.setProperty("id", "100");
properties.setProperty("name", "张三");
properties.setProperty("age", "30");
// 保存值
ops.set("key", properties);
// 获取值
Properties value = ops.get("key");
if(null != value) {
System.out.println("id=" + value.getProperty("id"));
System.out.println("name=" + value.getProperty("name"));
System.out.println("age=" + value.getProperty("age"));
}
}
}运行示例,输出结果如下:
id=100 name=张三 age=30
Redis 中保存的数据如下:
age=30,name=张三,id=100