本章节将介绍怎样自定义 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