13_Spring Boot 3.5.8 + Redisson 3.45.1 导致 Sa-Token 登录 StackOverflowError
一、问题背景
项目环境:
Spring Boot 3.5.8 Sa-Token 1.45.0 Redisson 3.45.1 Spring Data Redis 3.5.6项目登录时:
StpUtil.login(userId);出现:
java.lang.StackOverflowError at org.springframework.data.redis.connection.DefaultedRedisConnection.pExpire二、依赖关系分析
项目基于:
<parent><groupId>org.springframework.boot</groupId><artifactId>spring-boot-starter-parent</artifactId><version>3.5.8</version></parent>Spring Boot 会统一管理 Spring 生态依赖版本。
项目引入:
<!-- Spring Data Redis --><dependency><groupId>org.springframework.boot</groupId><artifactId>spring-boot-starter-data-redis</artifactId></dependency>由于没有指定版本:
<version>版本由 Spring Boot 依赖管理控制。
因此:
spring-boot-starter-data-redis | | spring-data-redis:3.5.6实际项目使用:
Spring Data Redis 3.5.6三、Redisson 依赖分析
项目同时引入:
<dependency><groupId>org.redisson</groupId><artifactId>redisson-spring-boot-starter</artifactId><version>3.45.1</version></dependency>Redisson 会引入自己的 Spring Data Redis 适配模块:
依赖树:
redisson-spring-boot-starter:3.45.1 | | redisson-spring-data-34:3.45.1 | | spring-data-redis其中:
redisson-spring-data-34表示:
Redisson 针对 Spring Data Redis 3.4.x 的适配模块。
四、版本冲突
最终项目运行环境:
Spring Boot 3.5.8 | | spring-boot-starter-data-redis | | spring-data-redis:3.5.6 Redisson 3.45.1 | | redisson-spring-data-34 | | 针对 Spring Data Redis 3.4.x形成:
Redisson Spring Data 适配版本 3.4 VS 实际 Spring Data Redis 3.5.6存在版本不匹配。
五、异常触发流程
登录:
StpUtil.login(userId);进入 Sa-Token:
StpUtil.login() | | createLoginSession() | | session.updateMinTimeout() | | SaTokenDaoForRedisTemplate.updateSessionTimeout() | | StringRedisTemplate.expire()最终调用:
RedisTemplate.expire()执行:
connection.pExpire()此时底层 RedisConnection:
StringRedisTemplate | | DefaultStringRedisConnection | | RedissonConnection由于 Redisson 适配版本与 Spring Data Redis 版本不一致,导致 RedisConnection 方法调用异常。
最终:
pExpire() ↓ expire() ↓ pExpire() ↓ expire() ↓ ...形成递归。
最终:
StackOverflowError六、解决方案
升级 Redisson:
原:
<redisson.version>3.45.1</redisson.version>升级:
<redisson.version>3.52.0</redisson.version>升级后:
Redisson 3.52.0 | | redisson-spring-data-35 | | Spring Data Redis 3.5.x与 Spring Boot 3.5.8 匹配。
问题解决。
七、总结
本次问题的根因:
Spring Boot 3.5.8 默认管理 Spring Data Redis 3.5.6,而 Redisson 3.45.1 引入了针对 Spring Data Redis 3.4 的适配模块(redisson-spring-data-34),两者版本不匹配,导致 RedisConnection 方法调用异常,在 Sa-Token 更新 Session 过期时间时触发 StackOverflowError。
排查类似问题时:
查看 Spring Boot 版本管理的依赖:
spring-boot-starter-data-redis ↓ spring-data-redis查看第三方 Redis 客户端适配模块:
redisson-spring-data-xx确认二者版本匹配。