再也不相信网上的鬼才配置了
这里指的是Spring Cache的配置
之前找来的配置如下
@Bean(name="redisCache")
public CacheManager cacheManager(RedisConnectionFactory connectionFactory) {
RedisCacheWriter redisCacheWriter = RedisCacheWriter.nonLockingRedisCacheWriter(connectionFactory);
RedisCacheConfiguration defaultCacheConfig = RedisCacheConfiguration.defaultCacheConfig();
//设置默认超过期时间是1天 // 我差点就信了
defaultCacheConfig.entryTtl(Duration.ofDays(1));
//初始化RedisCacheManager
RedisCacheManager cacheManager = new RedisCacheManager(redisCacheWriter, defaultCacheConfig);
return cacheManager;
}
但是无论如何ttl查询,对应缓存的key都会返回-1
127.0.0.1:6379> ttl user::userID21
(integer) -1
127.0.0.1:6379> ttl problems::getConsequentProblems::1:20
(integer) -1
网上找了一遍问题,好像都没这问题。。。自己找吧
找坑点:
顺着网线(指源码)找了这么一个构造
static RedisCacheWriter nonLockingRedisCacheWriter(RedisConnectionFactory connectionFactory) {
Assert.notNull(connectionFactory, "ConnectionFactory must not be null!");
return new DefaultRedisCacheWriter(connectionFactory);
}
// ...忽略
DefaultRedisCacheWriter(RedisConnectionFactory connectionFactory) {
this(connectionFactory, Duration.ZERO);
}
不过发现Duration.ZERO指的是SleepTime,排除
DefaultRedisCacheWriter(RedisConnectionFactory connectionFactory, Duration sleepTime)
而RedisCacheManager的配置是依赖于RedisCacheConfiguration的
其中ttl部分只会在这里出现
public class RedisCacheConfiguration {
private final Duration ttl;
private final boolean cacheNullValues;
private final CacheKeyPrefix keyPrefix;
//.....
@SuppressWarnings("unchecked")
private RedisCacheConfiguration(Duration ttl, Boolean cacheNullValues, Boolean usePrefix, CacheKeyPrefix keyPrefix,
SerializationPair<String> keySerializationPair, SerializationPair<?> valueSerializationPair,
ConversionService conversionService) {
this.ttl = ttl;
//....
至少证明构造方面没坑,TTL确实依赖于Configuration
测试
直接在Bean装载时观察是否有效
@Bean(name="redisCache")
public CacheManager cacheManager(RedisConnectionFactory connectionFactory) {
RedisCacheWriter redisCacheWriter = RedisCacheWriter.nonLockingRedisCacheWriter(connectionFactory);
RedisCacheConfiguration defaultCacheConfig = RedisCacheConfiguration.defaultCacheConfig();
defaultCacheConfig.entryTtl(Duration.ofDays(1));
//////
System.out.println("你的TTL:"+defaultCacheConfig.getTtl());
RedisCacheManager cacheManager = new RedisCacheManager(redisCacheWriter, defaultCacheConfig);
return cacheManager;
}
输出部分
你的TTL:PT0S
观察Duration的toString方法部分
if (this == ZERO) {
return "PT0S";
}
这就十分酸爽了。。
观察可疑部分
public RedisCacheConfiguration entryTtl(Duration ttl) {
Assert.notNull(ttl, "TTL duration must not be null!");
return new RedisCacheConfiguration(ttl, cacheNullValues, usePrefix, keyPrefix, keySerializationPair,
valueSerializationPair, conversionService);
}
发现是Builder形式
那么重新=一下就应该没问题了
defaultCacheConfig = defaultCacheConfig.entryTtl(Duration.ofDays(1));
127.0.0.1:6379> flushall
OK
127.0.0.1:6379> keys *
(empty list or set)
127.0.0.1:6379> keys *
1) "user::getUserByUserID::21"
2) "problems::getConsequentProblems::1:20"
127.0.0.1:6379> ttl problems::getConsequentProblems::1:20
(integer) 86387