spring原生@cacheable无timetolive属性,ttl需通过rediscacheconfiguration.entryttl()全局配置;按cachename差异化ttl须配置多个rediscachemanager;强时效场景推荐直接使用redistemplate.set()。

@Cacheable 的 timeToLive 属性根本不存在
你写的 @Cacheable(timeToLive = 60) 会直接编译报错——Spring 原生注解压根没这个字段。别被某些博客误导,也别在 IDE 里瞎试。所有声称“加个属性就能动态设 TTL”的写法,要么是自定义注解、要么是包装层,不是 Spring Cache 标准行为。
全局 TTL 配置只走 RedisCacheConfiguration.entryTtl()
真正起作用的是 RedisCacheConfiguration 实例里的 entryTtl() 方法。它决定所有走这个 RedisCacheManager 的缓存项统一过期时间。
- 配置方式:在
@Bean创建RedisCacheManager时调用.entryTtl(Duration.ofMinutes(5)) - 注意:必须显式调用
cacheDefaults(config),否则 fallback 到空配置,TTL 变成永不过期 - 如果用了
RedisCacheManager.builder(redisConnectionFactory())却漏掉cacheDefaults(),你的entryTtl()就白设了
按 cacheName 区分 TTL:配多个 RedisCacheManager
想让 "user" 缓存过期 2 小时、"config" 过期 10 分钟?只能靠多个 CacheManager 实例。
- 每个
@Bean返回独立的RedisCacheManager,绑定不同RedisCacheConfiguration -
@Cacheable(cacheManager = "userCacheManager")中的字符串必须和@Bean方法名(或@Primary指定的 name)完全一致,大小写敏感 - 每个
RedisCacheManager默认创建自己的 Lettuce 连接池,高并发下注意max-active配置,避免连接耗尽
RedisTemplate.set(key, value, timeout, unit) 是最简可控路径
不走 Spring Cache 抽象层,直接用 RedisTemplate 写入+设过期,粒度最细、语义最明确。
- 推荐写法:
redisTemplate.opsForValue().set(key, value, duration, TimeUnit.SECONDS) - 别用
StringRedisTemplate.opsForValue().set(key, value, duration, TimeUnit.SECONDS)后续再expire()——它底层是SETEX,key 存在时会覆盖值但不重置 TTL,行为不可控 - 如果 value 是对象,确认
redisTemplate的valueSerializer是GenericJackson2JsonRedisSerializer或兼容类型,否则读出来是null或乱码 -
expire()返回false?说明 key 根本没写进去,得先检查set()是否成功
CacheManager + @Cacheable,带强时效语义的数据(如 token、验证码)一律走 RedisTemplate 手动控制。别指望一个抽象层包打天下。











