当前位置: 首页 > news >正文

如何解决spring循环依赖

这个错误提示表明Spring应用程序中存在循环依赖问题,即两个或多个Bean之间相互依赖,形成了一个闭环。在你的案例中,dataGenerationImplRegisterVersionSourceImpl这两个Bean互相引用,导致Spring无法正常创建它们。

什么是循环依赖?

当Bean A依赖于Bean B,而Bean B又依赖于Bean A时,就形成了循环依赖。例如:

// Bean A依赖B
class DataGenerationImpl {@Autowiredprivate RegisterVersionSourceImpl registerVersionSource;// ...
}// Bean B依赖A
class RegisterVersionSourceImpl {@Autowiredprivate DataGenerationImpl dataGeneration;// ...
}

Spring在创建Bean时,需要先实例化依赖的Bean。但在循环依赖的情况下,两个Bean都需要对方先创建,导致创建过程陷入死循环

为什么会报错?

从Spring Boot 2.6开始,默认禁止循环依赖spring.main.allow-circular-references=false),因为循环依赖会导致以下问题:

  1. 依赖关系不清晰:代码结构混乱,难以理解和维护。
  2. 潜在的运行时错误:可能导致空指针异常或其他意外行为。
  3. 初始化顺序问题:Bean的初始化顺序变得不可预测。

如何解决循环依赖?

1. 重构代码,消除循环依赖

这是最推荐的方法,通过以下方式解耦:

  • 提取公共逻辑到第三方Bean:将两个Bean共同依赖的逻辑提取到新的组件中。
  • 使用接口回调:通过接口定义回调方法,避免直接依赖具体实现类。
  • 调整设计:重新审视业务逻辑,确保Bean之间的依赖是单向的。

示例重构:

// 1. 创建公共服务
class CommonService {public void sharedMethod() { /* ... */ }
}// 2. 让两个类依赖公共服务
class DataGenerationImpl {@Autowiredprivate CommonService commonService;// 移除对RegisterVersionSourceImpl的直接依赖
}class RegisterVersionSourceImpl {@Autowiredprivate CommonService commonService;// 移除对DataGenerationImpl的直接依赖
}
2. 使用Setter注入或构造器注入(结合@Lazy

如果确实无法避免循环依赖,可以使用以下方式:

Setter注入:

class DataGenerationImpl {private RegisterVersionSourceImpl registerVersionSource;@Autowiredpublic void setRegisterVersionSource(RegisterVersionSourceImpl registerVersionSource) {this.registerVersionSource = registerVersionSource;}
}class RegisterVersionSourceImpl {private DataGenerationImpl dataGeneration;@Autowiredpublic void setDataGeneration(DataGenerationImpl dataGeneration) {this.dataGeneration = dataGeneration;}
}

构造器注入+@Lazy

class DataGenerationImpl {private final RegisterVersionSourceImpl registerVersionSource;@Autowiredpublic DataGenerationImpl(@Lazy RegisterVersionSourceImpl registerVersionSource) {this.registerVersionSource = registerVersionSource;}
}class RegisterVersionSourceImpl {private final DataGenerationImpl dataGeneration;@Autowiredpublic RegisterVersionSourceImpl(@Lazy DataGenerationImpl dataGeneration) {this.dataGeneration = dataGeneration;}
}

@Lazy注解会告诉Spring在运行时才注入依赖,而不是在初始化时,从而打破循环。

3. 配置允许循环依赖(不推荐)

作为最后的手段,可以在application.propertiesapplication.yml中配置:

spring.main.allow-circular-references=true

但这种方法只是掩盖了问题,并没有真正解决依赖设计的缺陷,可能导致运行时问题。

总结

循环依赖通常是代码设计不合理的信号,优先通过重构消除依赖关系。只有在无法避免的情况下,才考虑使用@Lazy或配置允许循环依赖。良好的设计应该遵循单向依赖原则,使代码更清晰、可维护。

相关文章:

  • 1.36公里外的毫米级视界:遥感技术的革命性突破
  • 天机学堂(我的课表)
  • Opencl
  • 池化层-机器学习
  • 嵌入式Linux之RK3568
  • C++11 defaulted和deleted函数从入门到精通
  • Hadoop大数据集群深度实践:源码分析、参数调优与自动化运维平台选型全解
  • 基于LangChain构建高效RAG问答系统:向量检索与LLM集成实战
  • CS144 - Lecture 3
  • P3156 【深基15.例1】询问学号
  • 解决Required request part ‘file‘ is not present
  • 《操作系统真相还原》——初探内存
  • 虚拟斯德哥尔摩症候群:用户为何为缺陷AI辩护?
  • 涂胶协作机器人解决方案 | Kinova Link 6 Cobot在涂胶工业的方案应用与价值
  • ArcGIS Pro 3.4 二次开发 - 共享
  • 近几年字节飞书测开部分面试题整理
  • hadoop集群启动没有datanode解决
  • 自动化生产线,IT部署一站式解决方案-Infortrend KS私有云安全,一机多用
  • CortexON:开源的多代理AI系统无缝自动化和简化日常任务
  • 拉深工艺模块——回转体拉深件毛坯尺寸的确定(二)
  • 做网站好的公司/如何查看百度搜索指数
  • 用psd做的买书网站/竞价代运营公司
  • 北京网站高端建设/刚刚北京传来重大消息
  • 怎么做网站关键词库排名/专门的网页制作工具有
  • 5网站建站/中国三大搜索引擎
  • 深圳门户网站开发/深圳网站优化平台