@cacheable 注解没有 timetolive 属性,硬加会编译报错;spring 原生不支持单个缓存项动态设 ttl,“@cacheable(timetolive=60)”写法均错误或基于自定义封装;全局 ttl 需通过 rediscacheconfiguration.entryttl() 配置,按 cachename 差异化需配置多个 rediscachemanager,强时效场景应直接使用 redistemplate.set()。

@Cacheable 注解根本没有 timeToLive 属性,硬加会编译报错。 Spring 原生缓存抽象不支持单个缓存项动态设 TTL,所有“@Cacheable(timeToLive = 60)”写法都是错的或基于自定义封装——你得先认清这点,再选路径。
全局统一 TTL:用 RedisCacheConfiguration.entryTtl()
这是最简方式,适用于所有缓存项过期时间一致的场景(比如全站缓存默认 5 分钟)。
-
RedisCacheConfiguration.entryTtl(Duration.ofMinutes(5))是唯一生效入口,必须显式调用 - 漏掉
cacheDefaults(config)就等于没配置,TTL 回退为永不过期(Duration.ZERO表示永不过期,不是 null) - 别直接 new
RedisCacheManager,要用 builder:RedisCacheManager.builder(connectionFactory).cacheDefaults(config) - 序列化建议配
GenericJackson2JsonRedisSerializer,否则 value 反序列化失败返回 null
按 cacheName 区分 TTL:配多个 RedisCacheManager
想让 "user" 缓存 2 小时、"token" 缓存 10 分钟?只能靠多个独立 RedisCacheManager 实例。
Redis 8.2.3 是一款安全优先的高性能键值存储系统。该版本紧急修复了可能引发远程代码执行(RCE)的高危漏洞(CVE-2025-62507),并解决了 HyperLogLog 及 Cuckoo Filter 等数据结构在特定场景下的崩溃问题。建议所有用户立即升级,以保障生产环境的系统稳定与数据安全。
- 每个
@Bean返回一个RedisCacheManager,绑定不同RedisCacheConfiguration -
@Cacheable(cacheManager = "userCacheManager")中的字符串必须和@Bean方法名完全一致(大小写敏感) - Lettuce 连接池默认每个
RedisCacheManager创建独立连接池,max-active总数不能超 Redis 实例上限 - 别试图复用同一个
RedisConnectionFactory却只改 config——builder 内部会 clone,但连接池仍隔离
强时效场景:绕过 @Cacheable,直用 RedisTemplate.set()
验证码、临时 token、秒杀库存等需要精确控制生命周期的,RedisTemplate 是唯一可靠路径。
- 用
redisTemplate.opsForValue().set(key, value, duration, TimeUnit.SECONDS)——底层是SETEX,覆盖即重置 TTL - 别用
StringRedisTemplate+expire()组合:key 存在时expire()不重置 TTL,行为不可控 - value 是对象时,确认
redisTemplate的valueSerializer已设为GenericJackson2JsonRedisSerializer -
expire()返回false?说明 key 根本没写进去,先检查set()是否成功
真正难的不是怎么写,而是判断该走哪条路:@Cacheable 适合读多写少、语义稳定的业务数据;RedisTemplate 适合带明确时效契约的原子操作。混用才是常态,但别让缓存策略变成运行时黑盒——每个 key 的 TTL 必须可追溯、可验证。










