升级Spring Boot到2.6.0启动报循环引用错误如何解决?
问题根因
Spring Boot 2.6.0相关变动
Spring Boot 2.6.0 最核心的相关变动是默认禁用了循环引用的自动处理,对应配置项spring.main.allow-circular-references的默认值从true改为了false。
2.6.0之前的版本会自动处理容器中存在的隐式循环依赖,所以你的代码在2.5.x版本可以正常运行,升级后直接触发循环依赖报错。
代码中的循环依赖链
你的代码存在如下隐式循环依赖:
ConfigurazioneSpringSecurity(Spring Security配置类)初始化时,需要先注入GestioneUtentiSpringSecurity(UserDetailsService实现类)的实例- 初始化
GestioneUtentiSpringSecurity的过程中,会触发Spring Security认证相关组件的初始化逻辑 - Spring Security的认证组件初始化又依赖
ConfigurazioneSpringSecurity中的配置(包括PasswordEncoder实例、UserDetailsService绑定规则等),需要ConfigurazioneSpringSecurity完成初始化才能继续
三者形成了闭环依赖,之前被容器自动处理隐藏,升级2.6.0后直接暴露报错。
解决方案
方案1:快速兼容
直接在项目的application.properties或application.yml中添加配置,重新开启循环依赖自动处理即可正常启动:
spring.main.allow-circular-references=true
方案2:根治循环依赖
可以任选以下一种方式拆解循环:
- 延迟注入依赖:给
ConfigurazioneSpringSecurity类中注入的GestioneUtentiSpringSecurity添加@Lazy注解,延迟该Bean的初始化时机:
@Autowired @Lazy GestioneUtentiSpringSecurity gestioneUtentiSpringSecurity;
- 拆分配置类:将
BCryptPasswordEncoder的Bean定义移到独立的配置类中,避免Security配置类的初始化同时依赖内部Bean和外部服务:
@Configuration public class PasswordEncoderConfig { @Bean public BCryptPasswordEncoder metodoCrittografia() { return new BCryptPasswordEncoder(); } }
内容的提问来源于stack exchange,提问作者Federico Galimberti
相关产品推荐
相关产品推荐

