Spring Boot中AuthenticationManager循环依赖引发StackOverflowError的排查与解决
解决Spring Boot中AuthenticationManager相关的循环依赖与StackOverflowError问题
核心问题定位
你的循环依赖源于SecurityConfig中不必要地注入了AuthenticationService,而AuthenticationService又依赖AuthenticationManager,AuthenticationManager的初始化需要SecurityConfig中的认证配置(比如UserDetailsService),最终形成闭环:SecurityConfig → AuthenticationService → AuthenticationManager → SecurityConfig,即使添加@Lazy也无法完全打破这个循环。
具体解决步骤
步骤1:移除SecurityConfig中多余的AuthenticationService依赖
查看你的SecurityConfig代码,构造函数注入了AuthenticationService,但整个类中并没有使用这个实例,直接删除该依赖即可:
@Configuration @EnableWebSecurity public class SecurityConfig { private final JwtRequestFilter jwtRequestFilter; // 移除AuthenticationService参数 @Autowired public SecurityConfig(JwtRequestFilter jwtRequestFilter) { this.jwtRequestFilter = jwtRequestFilter; } // 其他方法保持不变... }
步骤2:优化AuthenticationService的注入方式(可选,但更规范)
将字段注入改为构造注入,配合@Lazy延迟加载AuthenticationManager和PasswordEncoder,避免提前触发依赖初始化:
@Service public class AuthenticationService implements UserDetailsService { private final UserRepository userRepository; private final PasswordEncoder passwordEncoder; private final JwtUtil jwtUtil; private final AuthenticationManager authenticationManager; // 构造注入,对需要延迟的依赖添加@Lazy public AuthenticationService(UserRepository userRepository, @Lazy PasswordEncoder passwordEncoder, JwtUtil jwtUtil, @Lazy AuthenticationManager authenticationManager) { this.userRepository = userRepository; this.passwordEncoder = passwordEncoder; this.jwtUtil = jwtUtil; this.authenticationManager = authenticationManager; } // 其他方法保持不变... }
步骤3:确认AuthenticationManager的Bean定义(保持现有即可)
你当前通过AuthenticationConfiguration.getAuthenticationManager()获取AuthenticationManager的方式是Spring Security 5.7+推荐的写法,无需修改,确保@Lazy注解保留在该Bean上:
@Bean @Lazy public AuthenticationManager authenticationManager(AuthenticationConfiguration authenticationConfiguration) throws Exception { return authenticationConfiguration.getAuthenticationManager(); }
额外建议
- 拆分职责:如果业务复杂,建议将
UserDetailsService的逻辑单独抽成一个独立类(比如CustomUserDetailsService),让AuthenticationService专注于登录、注册等业务逻辑,进一步降低耦合度。 - 避免冗余注入:注入Bean前务必确认是否真的需要使用该实例,冗余注入是循环依赖的常见诱因。
内容的提问来源于stack exchange,提问作者Mehmet Karadana
相关产品推荐
相关产品推荐

