Spring Boot v2.6.4启动出现Bean循环引用异常问题咨询
问题根因
报错是典型的Spring无法自动解析的循环引用问题,依赖闭环链路如下:
- 容器初始化
WebSecurityConfig这个配置Bean时,需要先注入它依赖的UserServiceImpl实例 - 初始化
UserServiceImpl时,需要先注入它依赖的BCryptPasswordEncoder实例 - 但
BCryptPasswordEncoder对应的@Bean定义在尚未初始化完成的WebSecurityConfig类中,Spring无法在配置类未完成实例化时提前产出该Bean,最终形成无法打破的依赖环。
你代码里注释提到BCryptPasswordEncoder用构造器注入会失败,本质也是这个循环依赖导致的。
修复方案
方案1:抽离密码编码器配置(最推荐,完全解耦)
把BCryptPasswordEncoder的Bean定义从WebSecurityConfig中移出去,放到独立的配置类中,从根源上切断依赖环:
- 新建独立配置类:
@Configuration public class PasswordEncoderConfig { @Bean public BCryptPasswordEncoder bCryptPasswordEncoder() { return new BCryptPasswordEncoder(); } }
- 删除
WebSecurityConfig中原有的encoder()方法,改为直接注入容器中已有的BCryptPasswordEncoder实例,修改全局用户配置逻辑:
@Autowired private BCryptPasswordEncoder bCryptPasswordEncoder; @Autowired public void globalUserDetails(AuthenticationManagerBuilder auth) throws Exception { auth.userDetailsService(userServiceImpl) .passwordEncoder(bCryptPasswordEncoder); }
修改完成后UserServiceImpl中的BCryptPasswordEncoder不管用字段注入还是构造器注入都可以正常工作,符合Spring推荐的组件解耦规范。
方案2:加延迟注解打破循环(改动量最小)
如果不想新增配置类,可以通过@Lazy注解延迟依赖加载,让Spring先完成Bean的实例化再注入依赖,任选一处加注解即可:
- 给
WebSecurityConfig中注入UserServiceImpl的字段加@Lazy:@Lazy @Autowired private UserServiceImpl userServiceImpl; - 或者给
UserServiceImpl中注入BCryptPasswordEncoder的字段加@Lazy:@Lazy @Autowired private BCryptPasswordEncoder bCryptEncoder;
这种方式改动量小,但本质是靠延迟加载绕过循环依赖,没有从设计上解耦,适合临时快速修复。
内容的提问来源于stack exchange,提问作者Ali Celebi
相关产品推荐
相关产品推荐

