不再相信网上的鬼才配置了java
这里指的是Spring Cache的配置redis
以前找来的配置以下缓存
@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都会返回-1bash
127.0.0.1:6379> ttl user::userID21 (integer) -1 127.0.0.1:6379> ttl problems::getConsequentProblems::1:20 (integer) -1
网上找了一遍问题,好像都没这问题。。。本身找吧测试
测试ui
直接在Bean装载时观察是否有效this
@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; }
输出部分code
你的TTL:PT0S
观察Duration的toString方法部分get
if (this == ZERO) { return "PT0S"; }
这就十分酸爽了。。源码
找坑点:
顺着网线(指源码)找了这么一个构造
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
观察可疑部分
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