SpringBoot 使用自定义redis 序列化解析
最近在学习redis 时,看了网上的文章,发现他们的序列化我这边无法使用,原因是用来序列化的类里面引用的jar 我这边项目竟然没有,所以打算自定义一个序列化存储方式,特此记录。
当前日期:2018-5-31
项目环境为:
- IDEA 2018.1.4
- Springboot 2.0.2
- spring-boot-starter-web
- spring-boot-starter-cache
- spring-boot-starter-data-redis
##创建RedisConfiguration
类进行redia 配置。
其实对于
spring-boot-starter-data-redis
这个包中的默认配置了redia 服务器的默认链接、端口号等其他的连接信息,详细的属性,可以查看org.springframework.boot.autoconfigure.data.redis.RedisProperties
中的详细配置信息
创建RedisConfiguration
类实现CachingConfigurer
接口,注入redia 连接工厂,重写cacheManager
方法,实现spring cache 管理redia 缓存。
@Autowired
RedisConnectionFactory redisConnectionFactory;
@Override
public CacheManager cacheManager(){
return RedisCacheManager.create(redisConnectionFactory);
}
缓存对象集合中,缓存是以key-value形式保存的。当不指定缓存的key时,SpringBoot会使用keyGenerator()
方法生成key,所以重写keyGenerator()
方法。
@Override
public KeyGenerator keyGenerator() {
return new KeyGenerator() {
@Override
public Object generate(Object target, Method method, Object... params) {
StringBuilder sb = new StringBuilder();
sb.append(target.getClass().getName());
sb.append(method.getName());
for (Object obj : params) {
sb.append(obj.toString());
}
return sb.toString();
}
};
}
可自行更改,自定义序列化key 的方法。
添加RedisTemplate
类型的bean 供自己手动调用redia 功能。
@Bean
public RedisTemplate<String, String> redisTemplate() {
StringRedisTemplate stringRedisTemplate = new StringRedisTemplate();
stringRedisTemplate.setValueSerializer(new UserRedisSerializer());
stringRedisTemplate.setConnectionFactory(this.redisConnectionFactory);
return stringRedisTemplate;
}
使用
StringRedisTemplate
类进行属性的序列化,序列化方式使用UserRedisSerializer
类。
创建UserRedisSerializer
类,实现RedisSerializer<Object>
接口,重写序列化与反序列化方法。
public class UserRedisSerializer implements RedisSerializer<Object> {
@Override
public byte[] serialize(Object o) throws SerializationException {
ByteArrayOutputStream byteOut = new ByteArrayOutputStream();
ObjectOutputStream objOut;
try {
objOut = new ObjectOutputStream(byteOut);
objOut.writeObject(o);
} catch (IOException e) {
e.printStackTrace();
}
return byteOut.toByteArray();
}
@Override
public Object deserialize(byte[] bytes) throws SerializationException {
if(bytes == null) return null;
ByteArrayInputStream byteIn = new ByteArrayInputStream(bytes);
ObjectInputStream objIn;
Object obj;
try {
objIn = new ObjectInputStream(byteIn);
obj =objIn.readObject();
} catch (IOException | ClassNotFoundException e) {
e.printStackTrace();
return null;
}
return obj;
}
}
功能是将需要处理的类,通过object 流序列化为字符串,存入redis 中。
deserialize()
反序列化方法中,第一行检测是否为空的原因是在存储的时候,存储结束会调用一次反序列化,原因尚未知,如有了解的可以回复评论我,多谢。
此时即可创建JUnit 测试类进行测试。
@Test
public void test1(){
@Autowired
RedisTemplate redisTemplate;
redisTemplate.opsForValue().set("TestData", new User("zhangsan", "123456"));
System.out.println(redisTemplate.opsForValue().get("TestData"));
}
此时会在redis 中
getTestData
获取到key 的信息并在控制台发现User
类的输出。
User 类自行创建就好。
这样自定义序列化方式就OK 了。