项目场景:
spring项目对redis缓存管理器进行全局配置。
问题描述
- 在
RedisCacheConfiguration
配置了缓存过期时间为1天,但是并未生效;
@Bean
public RedisCacheConfiguration redisCacheConfiguration() {
RedisCacheConfiguration config = RedisCacheConfiguration.defaultCacheConfig();
config.entryTtl(Duration.ofDays(1)); // 设置缓存过期时间
config.usePrefix(); // 使用前缀
return config;
}
- 配置序列化 value 的工具为 fastjson,但是在使用
@Cacheable
注解写入缓存时未生效
@Bean
public RedisTemplate<Object, Object> cacheRedisTemplate(RedisConnectionFactory connectitionFactory) {
RedisTemplate<Object, Object> redisTemplate = new RedisTemplate<>();
redisTemplate.setConnectionFactory(connectitionFactory);
redisTemplate.setKeySerializer(new StringRedisSerializer());
redisTemplate.setHashKeySerializer(new StringRedisSerializer());
redisTemplate.setValueSerializer(new GenericFastJsonRedisSerializer());
redisTemplate.setDefaultSerializer(new GenericFastJsonRedisSerializer());
return redisTemplate;
}
原因分析:
- 查看
entryTtl
方法源码发现,entryTtl
方法return
时会new
一个新的RedisCacheConfiguration
对象,并未覆盖原对象。
public RedisCacheConfiguration entryTtl(Duration ttl) {
Assert.notNull(ttl, "TTL duration must not be null!");
return new RedisCacheConfiguration(ttl, this.cacheNullValues, this.usePrefix, this.keyPrefix, this.keySerializationPair, this.valueSerializationPair, this.conversionService);
}
CacheManager
和RedisTemplate
使用方法不同:
CacheManager
:
与Spring的 @Cacheable、@CacheEvict 等注解一起使用,提供声明式缓存管理。
RedisTemplate
:
用于编写低级别、更具体的Redis操作,比如直接设置、获取、删除键值对,执行复杂的Redis命令等。
解决方案:
- 修改entryTtl方法调用位置;
- 如果使用@Cacheable、@CacheEvict 等注解实现redis缓存写入和删除,需要在实现CacheManager配置,而不是RedisTemplate。
代码如下:
@Bean
public RedisCacheConfiguration redisCacheConfiguration() {
RedisCacheConfiguration redisCacheConfiguration = RedisCacheConfiguration
.defaultCacheConfig()
.entryTtl(Duration.ofSeconds(expireTime)) // 设置缓存有效期
.serializeKeysWith(RedisSerializationContext.SerializationPair.fromSerializer(new StringRedisSerializer()))
.serializeValuesWith(RedisSerializationContext.SerializationPair.fromSerializer(new GenericFastJsonRedisSerializer()));
redisCacheConfiguration.usePrefix();// 使用key的前缀
return redisCacheConfiguration;
}