redistemplate 不支持过期回调,需通过 redis 键空间通知(配置 notify-keyspace-events ex)配合 redismessagelistenercontainer 监听 __keyevent@*:expired 通道实现,且事件触发存在延迟。

RedisTemplate 本身不提供过期回调能力 —— 它只是操作 Redis 的客户端工具,不会自动监听或触发任何事件。你要的“key过期时执行逻辑”,必须靠 Redis 自身的键空间通知(Keyspace Notifications) + Spring 的消息监听机制来实现,不是 RedisTemplate 的功能范畴。
notify-keyspace-events 配置必须生效,否则根本收不到事件
Redis 默认关闭键空间通知,即使你写了监听器,也永远收不到消息。关键点:
-
notify-keyspace-events的值不能为空字符串,且至少含E或K - 过期事件对应的是
x(小写 x),所以最简配置是Ex - 如果你只想要过期事件,别用
AKE—— 它会广播所有事件,徒增网络和 CPU 开销 - 修改后必须重启 Redis,或运行命令:
CONFIG SET notify-keyspace-events Ex - 检查是否生效:连上 redis-cli,执行
CONFIG GET notify-keyspace-events,返回值应为Ex
监听器必须订阅 <strong>keyevent@*</strong>:expired,不能依赖 RedisTemplate
RedisTemplate 没有内置订阅能力;监听要靠 RedisMessageListenerContainer + MessageListener 实现:
Redis 缓存和数据结构管理技能。通过自然语言操作 Redis,支持 String、Hash、List、Set、ZSet、Stream 等数据结构操作。当用户提到 Redis、缓存、消息队列、会话存储时使用此技能。
- 订阅通道必须是
PatternTopic("<strong>keyevent@*</strong>:expired")(注意双下划线、星号通配 db) - 不要用
ChannelTopic("<strong>keyevent@0</strong>:expired")—— 这只监听 0 号库,且不支持通配 - 如果你的 key 存在非 0 库(比如用了
database: 1),而监听器只订了@0,就会漏事件 -
RedisMessageListenerContainer必须注册为@Bean,且传入正确的RedisConnectionFactory
示例片段:
@Bean
public RedisMessageListenerContainer container(RedisConnectionFactory factory) {
RedisMessageListenerContainer container = new RedisMessageListenerContainer();
container.setConnectionFactory(factory);
container.addMessageListener(new KeyExpiredListener(), new PatternTopic("__keyevent@*__:expired"));
return container;
}
KeyExpirationEventMessageListener 是简化封装,但容易忽略它的限制
Spring Data Redis 提供了 KeyExpirationEventMessageListener(继承自 MessageListener),它帮你自动解包 message.body 为 String key,省去字节转换:
- 它只处理
<strong>keyevent@*</strong>:expired类型消息,其他事件(如 del、set)会被忽略 - 它内部默认使用
StringRedisTemplate的序列化器,如果你自定义了RedisTemplate的 key/value 序列化器,但没同步给监听容器,可能解码失败(表现为new String(message.getBody())出乱码或空) - 它的构造器必须传入
RedisMessageListenerContainer,否则super(listenerContainer)会 NPE
真正容易被忽略的点是:Redis 键过期是惰性+定期双重清理,事件可能延迟数秒甚至更久。
尤其在低流量实例中,Redis 不会主动扫描过期 key,而是等下次访问时才判断并触发事件 —— 所以它不适合对时效性要求毫秒级的场景。如果业务强依赖“准时回调”,得配合后台定时扫描 + SCAN + TTL 做兜底。










