13_Spring Boot 3.5.8 + Redisson 3.45.1 导致 Sa-Token 登录 StackOverflowError
一、问题背景
项目环境:
text
Spring Boot 3.5.8
Sa-Token 1.45.0
Redisson 3.45.1
Spring Data Redis 3.5.6
项目登录时:
java
StpUtil.login(userId);
出现:
text
java.lang.StackOverflowError
at org.springframework.data.redis.connection.DefaultedRedisConnection.pExpire
二、依赖关系分析
项目基于:
xml
<parent>
<groupId>org.springframework.boot</groupId>
<artifactId>spring-boot-starter-parent</artifactId>
<version>3.5.8</version>
</parent>
Spring Boot 会统一管理 Spring 生态依赖版本。
项目引入:
xml
<!-- Spring Data Redis -->
<dependency>
<groupId>org.springframework.boot</groupId>
<artifactId>spring-boot-starter-data-redis</artifactId>
</dependency>
由于没有指定版本:
xml
<version>
版本由 Spring Boot 依赖管理控制。
因此:
spring-boot-starter-data-redis
|
|
spring-data-redis:3.5.6
实际项目使用:
text
Spring Data Redis 3.5.6
三、Redisson 依赖分析
项目同时引入:
xml
<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
存在版本不匹配。
五、异常触发流程
登录:
java
StpUtil.login(userId);
进入 Sa-Token:
StpUtil.login()
|
|
createLoginSession()
|
|
session.updateMinTimeout()
|
|
SaTokenDaoForRedisTemplate.updateSessionTimeout()
|
|
StringRedisTemplate.expire()
最终调用:
java
RedisTemplate.expire()
执行:
java
connection.pExpire()
此时底层 RedisConnection:
StringRedisTemplate
|
|
DefaultStringRedisConnection
|
|
RedissonConnection
由于 Redisson 适配版本与 Spring Data Redis 版本不一致,导致 RedisConnection 方法调用异常。
最终:
pExpire()
↓
expire()
↓
pExpire()
↓
expire()
↓
...
形成递归。
最终:
StackOverflowError
六、解决方案
升级 Redisson:
原:
xml
<redisson.version>3.45.1</redisson.version>
升级:
xml
<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 -
确认二者版本匹配。