spring-boot中@CacheXXX系列注解的使得缓存应用十分便利,但是其默认序列化格式为二进制,在配合redis使用时不能直观的观察缓存的数据,所以通常会手动将序列化方式改为json。
这样的序列化配置在网上很多,无非就是CachaManager的配置。
如:
@Bean
public RedisCacheManager cacheManager(RedisConnectionFactory connectionFactory) {
RedisCacheWriter redisCacheWriter = RedisCacheWriter.nonLockingRedisCacheWriter(connectionFactory);
Jackson2JsonRedisSerializer jackson2JsonRedisSerializer = new Jackson2JsonRedisSerializer(Object.class);
ObjectMapper om = new ObjectMapper();
om.setVisibility(PropertyAccessor.ALL, JsonAutoDetect.Visibility.ANY);
om.enableDefaultTyping(ObjectMapper.DefaultTyping.NON_FINAL);
jackson2JsonRedisSerializer.setObjectMapper(om);
RedisSerializationContext.SerializationPair
然后神奇的配置出现了:
RedisCacheConfiguration redisCacheConfiguration = RedisCacheConfiguration.defaultCacheConfig();
redisCacheConfiguration .entryTtl(Duration.ofSeconds(300))
.serializeValuesWith(pair);
这样先获取redisCacheConfiguration在设置,就会发现redis中的类型为二进制,ttl也没有生效:
然而只需要将配置的方式改为链式配置:
RedisCacheConfiguration redisCacheConfiguration = RedisCacheConfiguration.defaultCacheConfig()
.entryTtl(Duration.ofSeconds(300))
.serializeValuesWith(pair);
实际上是犯了经验主义的错误,习惯性的设置(配置)属性,而RedisCacheConfiguration的配置并不是在源对象上作设置的, 看源码:
public RedisCacheConfiguration serializeValuesWith(SerializationPair> valueSerializationPair) {
Assert.notNull(valueSerializationPair, "ValueSerializationPair must not be null!");
return new RedisCacheConfiguration(ttl, cacheNullValues, usePrefix, keyPrefix, keySerializationPair,
valueSerializationPair, conversionService);
}
没错,设置序列化后返回的是新的RedisCacheConfiguration。
所以……
知道原因后就没有什么好说的了,在此也只是记录,望自己以后引以为戒。
以下列出demo源码:
pom
<dependency>
<groupId>org.springframework.bootgroupId>
<artifactId>spring-boot-starter-data-redisartifactId>
dependency>
<dependency>
<groupId>com.fasterxml.jackson.coregroupId>
<artifactId>jackson-databindartifactId>
<version>RELEASEversion>
<scope>compilescope>
dependency>
<dependency>
<groupId>org.springframework.bootgroupId>
<artifactId>spring-boot-starter-testartifactId>
<scope>testscope>
dependency>
config
@EnableCaching
@Configuration
public class RedisCacheConfig extends CachingConfigurerSupport {
@Bean
public RedisCacheConfiguration redisCacheConfiguration() {
Jackson2JsonRedisSerializer jackson2JsonRedisSerializer = new Jackson2JsonRedisSerializer(Object.class);
ObjectMapper om = new ObjectMapper();
om.setVisibility(PropertyAccessor.ALL, JsonAutoDetect.Visibility.ANY);
om.enableDefaultTyping(ObjectMapper.DefaultTyping.NON_FINAL);
jackson2JsonRedisSerializer.setObjectMapper(om);
RedisSerializationContext.SerializationPair
service
@Service
public class RedisAnnotationCacheService {
@CachePut(value = "CacheModel", key = "#version + '-' + #key + '-' + #value")
public CacheModel save(String version, String key, String value) {
return new CacheModel(version, key, value);
}
}
test
public class RedisAnnotationCacheServiceTest extends RedisDemoApplicationTests {
@Autowired
RedisAnnotationCacheService service;
@Test
public void save() {
service.save("v1.1.1", "AndroidInfo", "百度app");
}
}