Spring Boot默认Redis缓存永不过期(Duration.ZERO),entryTtl不生效主因是:配置未注入CacheManager(漏掉.cacheDefaults())、cacheName不匹配、多CacheManager冲突、或误用已弃用的application.yml中spring.cache.redis.expiration。

Spring Boot 默认的 Redis 缓存不设过期时间 —— Duration.ZERO 是真实值,不是“没配”,而是明确配置为永不过期。
RedisCacheConfiguration.entryTtl() 不生效的常见原因
你写了 entryTtl(Duration.ofMinutes(10)) 却发现缓存还是不消失,大概率是以下情况之一:
- 配置 Bean 没被 Spring 扫描到(比如类没加
@Configuration,或包路径不在组件扫描范围内) - 多个
CacheManagerBean 冲突,Spring 用了另一个未配置 TTL 的实例(检查是否有其他@Bean CacheManager定义) - 使用了
@Cacheable但 cacheName 不在你配置的RedisCacheConfiguration生效范围内(例如你只对"user"配置了 TTL,却在注解里写了@Cacheable("order")) - 手动 new 出的
RedisCacheManager或调用builder().withCache(...)覆盖了全局默认配置,而新 cache 实例没显式传入 TTL 配置
必须用 builder().cacheDefaults(),不能只改 defaultCacheConfig()
RedisCacheConfiguration.defaultCacheConfig() 返回的是一个不可变实例,链式调用如 .entryTtl(...).disableCachingNullValues() 确实会返回新对象,但如果你没把它真正塞进 CacheManager,就等于白配。
正确写法必须绑定到 RedisCacheManager.builder() 的默认配置上:
@Bean
public CacheManager cacheManager(RedisConnectionFactory factory) {
RedisCacheConfiguration config = RedisCacheConfiguration.defaultCacheConfig()
.entryTtl(Duration.ofMinutes(10))
.disableCachingNullValues();
<pre class="brush:php;toolbar:false;">return RedisCacheManager.builder(factory)
.cacheDefaults(config) // ✅ 关键:必须显式传入
.build();}
漏掉 .cacheDefaults(config),就等同于用空配置初始化,entryTtl 完全不会起作用。
application.yml 中的 spring.cache.redis.expiration 是摆设
这个配置项仅对 Spring Boot 1.x 的 RedisCacheManager 有效;2.x+ 版本(Spring Data Redis 2.2+)已弃用该配置,**完全忽略** spring.cache.redis.expiration。
Redis 缓存和数据结构管理技能。通过自然语言操作 Redis,支持 String、Hash、List、Set、ZSet、Stream 等数据结构操作。当用户提到 Redis、缓存、消息队列、会话存储时使用此技能。
如果你在 application.yml 里写了:
spring:
cache:
redis:
expiration: 600000
它不会触发任何 TTL 设置,也不会报错 —— 就是静默失效。必须通过 Java Config 显式构造 RedisCacheConfiguration 并注入 CacheManager。
为什么缓存 key 还是没过期?查 Redis 本身更可靠
别只信日志或业务表现。直接连 Redis,用命令验证:
-
GET user:123看值是否存在 -
TTL user:123看剩余秒数(返回-1表示永不过期,-2表示 key 不存在)
如果 TTL 返回 -1,说明你的 entryTtl() 配置根本没生效;如果返回正数但业务读取仍命中,可能是缓存穿透兜底逻辑(如空值缓存)或 AOP 代理未生效(比如方法被 private / final 修饰、没走 Spring 代理)。
最易被忽略的一点:Redis 的过期是惰性+定期删除,TTL 到零不等于立刻消失,只是“已过期”。应用层不应依赖精确清除时刻,而应接受“过期后首次访问时才触发删除”这一事实。










