13_Spring Boot 3.5.8 + Redisson 3.45.1 导致 Sa-Token 登录 StackOverflowError

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。

排查类似问题时:

  1. 查看 Spring Boot 版本管理的依赖:

    复制代码
    spring-boot-starter-data-redis
         ↓
    spring-data-redis
  2. 查看第三方 Redis 客户端适配模块:

    复制代码
    redisson-spring-data-xx
  3. 确认二者版本匹配。

相关推荐
学长毕业设计2 小时前
基于SpringBoot的公益基金管理系统(源码+文档+讲解视频)
java·spring boot·后端
东小西2 小时前
【SAA实战】第 3 篇 · 工具调用全攻略:把业务能力交给 Agent 自己调度
java·后端·spring
东小西2 小时前
【SAA实战】第 4 篇 · Agent 短期记忆:saver 让 Agent 跨轮记得住(threadId 隔离)
java·后端·spring
阿kun要赚马内3 小时前
MySQL 索引基础
后端·mysql
码事漫谈3 小时前
我啥都能做,却不知道做什么了
后端
geovindu3 小时前
CSharp: 万年历
开发语言·后端·c#·.net
独泪了无痕5 小时前
SpringBoot Event事件机制,轻松实现业务解耦
spring boot·后端·spring
悲且狂6 小时前
SpringBoot项目改造注意事项(旧项目框架复用)
java·spring boot·后端
敲代码的嘎仔6 小时前
28届后端开发-海康威视日常实习一面(已OC)
java·开发语言·后端·面试·海康威视·实习·大厂
IT_陈寒7 小时前
JavaScript数组排序踩的坑,差点让我加班到凌晨
前端·人工智能·后端