最近产品提了一个需求,就是在新增某项记录的时候,需要删除其对应的redis缓存,问这个难实现吗?我当时没多想,这个很简单,心想这么简单的需求很快就能搞定;说干就干,开始通过maven引入redis相关jar包,然后配置文件写好对应的redis链接地址。然后项目里面直接使用redisTemplate来操作。使用的是redisTemplate.delete(key)。到此觉得开发工作已经结束。出于个人开发的习惯,还是决定自测一波。启动项目之后执行删除方法,心想这下这个key肯定被删除了。然后通过RedisDesktopManager去验证实际情况,发现这货竟然还活着。这时候没办法只能去看看redisTemplate.delete源码了。
public Boolean delete(K key) {
byte[] rawKey = this.rawKey(key);
Long result = (Long)this.execute((connection) -> {
return connection.del(new byte[][]{rawKey});
}, true);
return result != null && result.intValue() == 1;
}
然后去rawKey方法去看
private byte[] rawKey(Object key) {
Assert.notNull(key, "non null key required");
return this.keySerializer == null && key instanceof byte[] ? (byte[])((byte[])key) : this.keySerializer.serialize(key);
}
这时候我相信大家都明白了,这个key在存的时候已经使用序列化了对应的key。这时候就需要了解保存这个key的时候使用了哪种序列化方式。由于保存这块在另一个服务提供的,只能去那个服务看看
保存的时候怎么做的。原来这个服务写了一个redisTemplate配置方法
@Configuration
public class RedisTemplateAutoConfiguration {
@Bean(name = "redisTemplate")
public RedisTemplate<String,Object> redisTemplate(RedisConnectionFactory redisConnectionFactory) {
RedisTemplate<String, Object> template = new RedisTemplate<>();
template.setConnectionFactory(redisConnectionFactory);
//使用Jackson2JsonRedisSerializer来序列化和反序列化redis的value值
Jackson2JsonRedisSerializer<Object> jackson2JsonRedisSerializer = new Jackson2JsonRedisSerializer<>(Object.class);
ObjectMapper mapper = new ObjectMapper();
mapper.setVisibility(PropertyAccessor.ALL, JsonAutoDetect.Visibility.ANY);
mapper.enableDefaultTyping(ObjectMapper.DefaultTyping.NON_FINAL);
jackson2JsonRedisSerializer.setObjectMapper(mapper);
template.setValueSerializer(jackson2JsonRedisSerializer);
StringRedisSerializer stringRedisSerializer = new StringRedisSerializer();
//使用StringRedisSerializer来序列化和反序列化redis的key值
template.setKeySerializer(stringRedisSerializer);
template.setKeySerializer(stringRedisSerializer);
// hash的key也采用String的序列化方式
template.setHashKeySerializer(stringRedisSerializer);
// value序列化方式采用jackson
template.setValueSerializer(jackson2JsonRedisSerializer);
// hash的value序列化方式采用jackson
template.setHashValueSerializer(jackson2JsonRedisSerializer);
template.afterPropertiesSet();
return template;
}
@Bean
public StringRedisTemplate stringRedisTemplate(RedisConnectionFactory redisConnectionFactory) {
return new StringRedisTemplate(redisConnectionFactory);
}
}}
通过代码可以看到保存key的时候采用了Jackson2JsonRedisSerializer来序列化和反序列化redis的value值。
目前来看这种redis一共提供了序列化方式如下:
然后心想我在这个项目也这样配置下,应该可以了。这时候看到 redisConnectionFactory报错。显示不知道。最后定位发现项目里面引入了好几个spring-data-redis。这样redisConnnectFactory不知道该以那个为准。所以一个项目里避免引入同一个jar包的不同版本。至此遇到所有的问题都已经解决了。其实遇到的问题问下同事估计很快就解决了,但那样自己就得不到成长了,为了更好的成长自己,接下来立个flag。尝试去看经常使用框架的源码。