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

Spring是怎么处理循环依赖的

Spring框架处理循环依赖主要依赖于其容器的设计和几个关键的缓存机制,这里所说的“三级缓存”是一个广为流传的概念,用于简化描述Spring处理循环依赖的过程。实际上,Spring处理循环依赖的核心策略可以概括为以下几个步骤,主要针对 singleton scope 的bean:

  1. 实例化(First Level Cache): 当Spring容器创建一个bean时,首先会在一级缓存(单例对象缓存)中查找该bean是否已经存在。如果不存在,容器开始实例化该bean,并将其ObjectFactory(一个能够返回bean实例的工厂对象,而不是直接的bean实例)放入一个临时的缓存(可以认为是第二级缓存的前身)中,这个操作发生在bean实例被完全初始化之前。

  2. 早期暴露(Second Level Cache): 在bean实例化之后,但属性注入完成之前,Spring会将一个可使用的(尽管尚未完成依赖注入)bean实例(或者更准确地说,是前面提到的ObjectFactory)提前暴露到一个专门的缓存(即第二级缓存)中,这个缓存允许其他正在被创建且依赖于它的bean获取到这个bean的引用。这个步骤是解决循环依赖的关键,因为它打破了依赖创建的顺序限制。

  3. 完成依赖注入(Third Level Cache 或 Singleton Factories Cache): 当所有必要的bean实例都已存在于第二级缓存中,Spring会完成这些bean的依赖注入过程。对于那些已经被部分构造并存在于第二级缓存中的bean,它们会被从ObjectFactory转换成实际的bean实例,并最终存储到一级缓存中,此时bean被视为完全初始化。这个转换过程涉及从第二级缓存取出ObjectFactory并调用它来获得完整的bean实例,然后这个实例会被放入第三级缓存,即单例工厂缓存,最后再移到一级缓存中。

注意,这个过程中构造器注入的循环依赖是不能解决的,因为构造器注入要求所有依赖项在对象创建时就必须存在,这会导致直接抛出BeanCurrentlyInCreationException异常。而setter注入或者字段注入(基于@Autowired)的循环依赖可以在上述机制下得到解决,前提是这些bean都是单例的。

另外,非单例(prototype)scope的bean由于每次请求都会创建新的实例,因此Spring不会解决它们之间的循环依赖问题。

相关文章:

  • 【车载以太网测试从入门到精通】——SOME/IP协议测试
  • 聊聊Python中的lambda函数的使用以及模块和包是什么?
  • F28034中断
  • 深入理解内联函数(C语言)
  • YOLO系列模型疑问
  • python:__set_name__使用
  • Algoriddim djay Pro Ai for Mac:AI引领,混音新篇章
  • windows 下nginx常用命令
  • 本地图片先压缩,再上传
  • 中国电子学会(CEIT)2023年09月真题C语言软件编程等级考试四级(含详细解析答案)
  • 【Shell】sed编辑器实例
  • 上下文视觉提示实现zero-shot分割检测及多visual-prompt改造
  • SpringBoot中如何在服务器进行校验?
  • 基于51单片机的盆栽自动浇花系统
  • STM32F103 标准库介绍及PWM波控制LED亮度
  • 9月CHINA-PUB-OPENDAY技术沙龙——IPHONE
  • 10个最佳ES6特性 ES7与ES8的特性
  • 2019年如何成为全栈工程师?
  • Android Studio:GIT提交项目到远程仓库
  • Angular 响应式表单之下拉框
  • Apache Spark Streaming 使用实例
  • gf框架之分页模块(五) - 自定义分页
  • Java 网络编程(2):UDP 的使用
  • Next.js之基础概念(二)
  • Quartz实现数据同步 | 从0开始构建SpringCloud微服务(3)
  • spring boot下thymeleaf全局静态变量配置
  • vagrant 添加本地 box 安装 laravel homestead
  • win10下安装mysql5.7
  • 对JS继承的一点思考
  • 目录与文件属性:编写ls
  • 我这样减少了26.5M Java内存!
  • 消息队列系列二(IOT中消息队列的应用)
  • 策略 : 一文教你成为人工智能(AI)领域专家
  • 如何正确理解,内页权重高于首页?
  • ​​​​​​​sokit v1.3抓手机应用socket数据包: Socket是传输控制层协议,WebSocket是应用层协议。
  • ​油烟净化器电源安全,保障健康餐饮生活
  • # Redis 入门到精通(一)数据类型(4)
  • # 移动硬盘误操作制作为启动盘数据恢复问题
  • #git 撤消对文件的更改
  • #ifdef 的技巧用法
  • #Z2294. 打印树的直径
  • #我与Java虚拟机的故事#连载19:等我技术变强了,我会去看你的 ​
  • (12)目标检测_SSD基于pytorch搭建代码
  • (13)Hive调优——动态分区导致的小文件问题
  • (2)(2.4) TerraRanger Tower/Tower EVO(360度)
  • (2009.11版)《网络管理员考试 考前冲刺预测卷及考点解析》复习重点
  • (AngularJS)Angular 控制器之间通信初探
  • (二)丶RabbitMQ的六大核心
  • (力扣)1314.矩阵区域和
  • (论文阅读31/100)Stacked hourglass networks for human pose estimation
  • (七)Knockout 创建自定义绑定
  • (亲测)设​置​m​y​e​c​l​i​p​s​e​打​开​默​认​工​作​空​间...
  • (三分钟了解debug)SLAM研究方向-Debug总结
  • (一)WLAN定义和基本架构转
  • (已更新)关于Visual Studio 2019安装时VS installer无法下载文件,进度条为0,显示网络有问题的解决办法