Spring Boot登录认证抛出java.lang.StackOverflowError求助
排查登录时
java.lang.StackOverflowError的思路 核心原因定位
StackOverflowError本质是无限递归调用,结合你触发错误的authenticationManager.authenticate(authToken)方法,大概率是Spring Security认证流程中加载用户信息时,出现了循环引用或递归调用的情况。
具体排查方向及解决方法
1. 检查AppUser实体与关联对象的双向引用
如果AppUser和Role(或其他关联实体)是双向关联,比如:
// AppUser类 @OneToMany(mappedBy = "user") private List<Role> roles; // Role类 @ManyToOne private AppUser user;
这种情况下,当Spring Security加载用户信息时,序列化或toString方法会触发双向对象的循环调用,直接导致栈溢出。
解决方法:
- 去掉关联关系中任意一方的
toString、hashCode、equals方法里的关联对象引用; - 用Jackson的
@JsonIgnore注解标记关联关系的其中一端,避免序列化时递归加载; - 若业务不需要双向关联,直接改成单向关联。
2. 检查UserDetailsService的实现逻辑
如果自定义的UserDetailsServiceImpl在加载用户时,递归加载了多层级的关联对象(比如加载用户时同时加载角色,角色又反向加载用户),会形成循环调用链。
解决方法:
- 查询用户时使用
JOIN FETCH只加载必要的关联数据,避免懒加载触发的递归; - 确保查询结果的对象结构中没有循环引用。
3. 检查自定义认证组件
如果自定义了AuthenticationProvider、UserDetails等组件,排查其中是否存在递归调用逻辑,比如在某个方法中重复调用authenticationManager.authenticate,或是UserDetails实现类的属性中存在循环引用。
解决方法:
- 梳理自定义组件的调用链路,移除不必要的递归调用;
- 确保
UserDetails实现类的属性无循环引用。
4. 排查Lombok的潜在问题
即便你试过使用Lombok,也要注意:
- Lombok的
@Data注解会自动生成包含所有属性的toString、hashCode、equals,若存在双向关联,必然触发循环调用; - 替换
@Data为@Getter+@Setter,手动编写toString、hashCode、equals,排除关联对象的引用。
快速验证步骤
- 临时注释掉
AppUser中关联对象的toString输出,再尝试登录,观察是否还会报错; - 查看堆栈跟踪里的重复调用栈,找到循环调用的两个方法,直接定位问题源头。
内容的提问来源于stack exchange,提问作者Demir
相关产品推荐
相关产品推荐

