不再相信網上的鬼才配置了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