spring boot 3 中必须使用 spring-session-data-redis + @enableredishttpsession 实现 session 共享,仅靠 spring-boot-starter-data-redis 无法接管 http 会话生命周期,否则 request.getsession() 仍走 tomcat 内存 session。

直接上结论:Spring Boot 3 中必须用 spring-session-data-redis + @EnableRedisHttpSession,不能只靠 spring-boot-starter-data-redis 自动配置 session 存储 —— 后者只管缓存,不管会话生命周期。
为什么加了 redis 依赖 session 还不共享?
常见现象是:本地启两个端口(如 8080/8081),登录后切端口就 404 或 session 属性丢失。根本原因是没启用 Spring Session 的 HTTP 会话代理机制。
Spring Boot 自动配置的 RedisConnectionFactory 和 RedisTemplate 只负责数据存取;而 session 共享需要 Spring Session 拦截 HttpServletRequest.getSession() 调用,把底层存储替换为 Redis。这一步必须显式开启。
-
spring-boot-starter-data-redis提供的是「Redis 数据访问能力」 -
spring-session-data-redis提供的是「HTTP Session 的 Redis 实现」 - 缺后者,
request.getSession()仍走 Tomcat 默认内存 session,跟 Redis 完全无关
必须声明的依赖和注解
仅在 pom.xml 中添加以下两项(Spring Boot 3.x 已弃用 spring-session 的旧 groupId):
Redis 缓存和数据结构管理技能。通过自然语言操作 Redis,支持 String、Hash、List、Set、ZSet、Stream 等数据结构操作。当用户提到 Redis、缓存、消息队列、会话存储时使用此技能。
<dependency><groupid>org.springframework.session</groupid><artifactid>spring-session-data-redis</artifactid></dependency><dependency><groupid>org.springframework.boot</groupid><artifactid>spring-boot-starter-data-redis</artifactid></dependency>
然后在任意 @Configuration 类上加:
@EnableRedisHttpSession( maxInactiveIntervalInSeconds = 1800, redisNamespace = "spring:session" )
-
maxInactiveIntervalInSeconds会覆盖server.servlet.session.timeout,且单位是秒(不是毫秒) -
redisNamespace建议显式指定,避免多个应用共用 Redis 时 key 冲突 - 不需要手动写
RedisHttpSessionConfiguration,@EnableRedisHttpSession已自动注册所有必要 Bean
application.yml 配置关键项
以下配置直接影响 session 是否能写入、读取、过期:
spring:
session:
store-type: redis
timeout: 1800 # ⚠️ 此处单位是秒,但仅作 fallback;实际以 @EnableRedisHttpSession 的参数为准
redis:
host: localhost
port: 6379
database: 3 # 建议用非 0 库,避免和业务缓存混用
password:
timeout: 2000ms
lettuce:
pool:
max-active: 8
max-idle: 4
min-idle: 0
-
spring.session.store-type: redis是触发 Spring Session 自动配置的开关,缺它不会加载 Redis session 支持 -
database必须和@EnableRedisHttpSession中LettuceConnectionFactory的配置一致(如果自定义了 factory) - 如果 Redis 有密码,
spring.redis.password必须填写,否则连接失败时日志里只有模糊的Unable to connect,不报明文认证错误
容易被忽略的兼容性细节
Spring Boot 3 默认使用 Jakarta EE 9+,所以 session 相关类全部在 jakarta.servlet.http.* 包下。如果你的代码里还 import javax.servlet.http.HttpSession,编译会通过但运行时报 NoClassDefFoundError。
- 检查所有
import javax.servlet.http.*→ 替换为jakarta.servlet.http.* -
HttpServletRequest.getSession()返回的仍是jakarta.servlet.http.HttpSession,无需改调用方式 - 若项目中混用 Shiro 或老版 Security,需确认其 filter chain 是否兼容 Jakarta EE,否则 session 可能被跳过
- Redis 中实际存储的 key 形如
spring:session:sessions:abc123...,value 是二进制序列化数据(默认用 JDK 序列化),调试时别指望直接GET出可读内容
真正麻烦的从来不是配对依赖或写对注解,而是当 session 看似“共享”了却在某些路径下失效——大概率是 filter 顺序错位、servlet context path 不一致,或者前端没传 Cookie(比如跨域请求没带 credentials: 'include')。










