Spring Boot 2.7升级至3.x后SessionCreatedEvent等事件未触发求助
问题解决:Spring Boot 3.x 下 Redis 会话事件不触发的修复方案
核心问题分析
Spring Boot 3.x 对应的 Spring Session 3.x 架构做了调整:原有的 Servlet 容器会话事件机制不再适配 Redis 分布式会话,同时会话过期检测依赖 Redis 键空间通知,若配置缺失或监听事件类型错误,就会出现SessionCreatedEvent/SessionDestroyedEvent不触发的情况。
具体修复步骤
1. 切换到 Spring Session 原生事件监听
确保监听器监听的是 Spring Session 提供的分布式会话事件类,而非 Servlet 容器本地会话事件:
import org.springframework.session.events.SessionCreatedEvent; import org.springframework.session.events.SessionDestroyedEvent; import org.springframework.context.event.EventListener; import org.springframework.core.Ordered; import org.springframework.core.annotation.Order; import org.springframework.security.web.session.SessionFixationProtectionEvent; import org.slf4j.Logger; import org.slf4j.LoggerFactory; import org.springframework.stereotype.Component; @Component public class SessionEventListener { private static final Logger log = LoggerFactory.getLogger(SessionEventListener.class); @EventListener public void onSessionCreated(SessionCreatedEvent event) { log.info("session created: {}", event.getSessionId()); } @EventListener public void onSessionDestroyed(SessionDestroyedEvent event) { log.info("session destroyed: {}", event.getSessionId()); } @Order(Ordered.HIGHEST_PRECEDENCE) @EventListener(SessionFixationProtectionEvent.class) public void onSessionFixationProtectionEvent(SessionFixationProtectionEvent event) { log.info("session migrated: oldId={}, newId={}", event.getOldSessionId(), event.getNewSessionId()); } }
2. 移除无用的HttpSessionEventPublisherBean
HttpSessionEventPublisher仅对 Servlet 容器本地会话生效,Redis 分布式会话不会触发 Servlet 容器的会话事件,直接删除该配置:
// 移除以下代码 // @Bean // public ServletListenerRegistrationBean<HttpSessionEventPublisher> httpSessionEventPublisher() { // return new ServletListenerRegistrationBean<>(new HttpSessionEventPublisher()); // }
3. 配置 Redis 键空间通知(针对SessionDestroyedEvent)
Spring Session Redis 依赖 Redis 键空间通知检测会话过期,需开启该功能:
- 修改 Redis 配置文件
redis.conf:notify-keyspace-events Ex - 若使用 Spring Boot 管理 Redis(如内嵌/容器化 Redis),可在
application.properties中指定配置文件:
然后在spring.redis.lettuce.config=classpath:redis-config.confsrc/main/resources/redis-config.conf中写入notify-keyspace-events Ex。
4. 确认会话保存配置有效性
你的@EnableRedisHttpSession配置已设置saveMode=SaveMode.ALWAYS,该配置会确保会话创建后立即同步到 Redis,从而触发SessionCreatedEvent,无需修改。
版本兼容性说明
Spring Boot 3.0.x 对应 Spring Session 3.0.x,3.1.x 对应 Spring Session 3.1.x,无需手动指定版本,Spring Boot 的依赖管理会自动处理版本匹配。
内容的提问来源于stack exchange,提问作者M. Da
相关产品推荐
相关产品推荐

