Redis序列化器
引言
SpringDataRedis的使用步骤:
在使用SpringDataRedis时,必然需要注入RedisTemplate,并进行对Redis的相关操作。
SpringDataRedis的序列化方式
RedisTemplate可以接收任意Object作为值写入Redis,只不过写入前会把Object序列化为字节形式,默认是采用JDK序列化。绝大多数情况下,不推荐使用 JdkSerializationRedisSerializer 进行序列化。主要是不方便人工排查数据,且操作的对象还需要实现Serializable 接口。
问题:

序列化方式一
使用配置类自定义序列化方式:
1 2 3 4 5 6 7 8 9 10 11 12 13 14 15 16 17 18 19 20 21 22 23 24 25 26 27
|
@Configuration public class RedisConfig extends CachingConfigurerSupport {
@Bean public RedisTemplate<Object, Object> redisTemplate(RedisConnectionFactory connectionFactory) {
RedisTemplate<Object, Object> redisTemplate = new RedisTemplate<>();
redisTemplate.setKeySerializer(new StringRedisSerializer()); redisTemplate.setHashKeySerializer(new StringRedisSerializer());
redisTemplate.setValueSerializer(new GenericJackson2JsonRedisSerializer()); redisTemplate.setHashValueSerializer(new GenericJackson2JsonRedisSerializer()); 手动序列化
redisTemplate.setConnectionFactory(connectionFactory);
return redisTemplate; }
}
|
尽管JSON的序列化方式可以满足我们的需求,但依然存在一些问题:为了在反序列化时知道对象的类型,JSON序列化器会将类的Class类型写入json结果中,存入Redis,会带来额外的内存开销。
内存开销问题:

序列化方式二
为了节省内存空间,我们并不会使用JSON序列化器来处理value,而是统一使用String序列化器,要求只能存储String类型的key和value。当需要存储Java对象时,手动完成对象的序列化和反序列化。
注入StringRedisTemplate对象,该对象key和value默认使用的是String序列化器。
1 2 3 4 5 6 7 8 9 10 11 12 13 14 15 16 17 18 19
| @Autowired private StringRedisTemplate stringRedisTemplate;
private static final ObjectMapper mapper = new ObjectMapper();
@Test void testStringTemplate() throws JsonProcessingException { User user = new User("虎哥", 18); String json = mapper.writeValueAsString(user); stringRedisTemplate.opsForValue().set("user:200", json); String val = stringRedisTemplate.opsForValue().get("user:200"); User user1 = mapper.readValue(val, User.class); System.out.println("user1 = " + user1); }
|
Tips:该方式解决了Redis存储额外开销的问题,但需要使用json工具对需要缓存的对象进行序列化后再存储,取值的时候需要反序列化成对应的对象。