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

Spring框架如何解决循环依赖

目录

  • 一,什么是循环依赖
  • 二、什么是三级缓存
  • 三、Spring框架如何解决循环依赖

一,什么是循环依赖

例:类与类之间的依赖关系形成了闭环,例如A依赖了B,B依赖了C,C又依赖了A。

二、什么是三级缓存

在 Spring 框架中,三级缓存是解决循环依赖问题的核心机制,这三级缓存本质上是三个不同作用的 Map 集合,用于存储 bean 的不同状态

  • 一级缓存(singletonObjects):存储完全初始化完成的单例 Bean(即经过实例化、属性注入、初始化方法执行后的最终成品)
    时机:当 bean 完全初始化后,会从二级缓存或三级缓存移至此缓存
  • 二级缓存(earlySingletonObjects):存储半成品 Bean(已实例化,但未完成属性注入、初始化)
    注意:此缓存中的 bean 是 “半成品”,仅能被其他 bean 引用,自身还需继续完成初始化流程。
  • 三级缓存(singletonFactories):存储 Bean 的工厂(ObjectFactory),用于 “按需创建” 半成品 Bean。当其他 Bean 首次需要引用当前 Bean 时,通过工厂生成 Bean 的早期引用(可能是原始对象或 AOP 代理对象)。

三、Spring框架如何解决循环依赖

A类依赖B类,B类依赖A类咋样解决?

我的思路:

首先创建A的时候创建一个A类工厂存入三级缓存中,然后注入B时,B还没创建,所以去创建B,先创建一个B类工存到三级缓存中,然后B又依赖A,从三级缓存中拿到A的工厂创建A的半成品,放到二级缓存中,并从三级缓存移除,B此时就可以注入A,B完成创建并放到一级缓存中,A此时也可以注入了B,A完成了创建也放到一级缓存中,并从二级缓存移除A。

注意:三级缓存中存放的工厂可以处理 AOP 代理场景,确保 B 依赖的 A 和最终生成的 A 是同一个对象(可能是代理对象),代理对象可以在AOP增强方法时使用。

A类依赖B类,B类依赖C类,C类又依赖了A咋样解决?
我的思路:
1.创建 A:
Spring 创建 A 时,将 A 的工厂对象存入三级缓存,此时 A 是 “半成品”(未完成属性注入)。
A 需要依赖 B,Spring 转而开始创建 B。
2.创建 B:
实例化 B 后,将 B 的工厂存入三级缓存。
B 需要依赖 C,Spring 转而开始创建 C。
3.创建 C:
实例化 C 后,将 C 的工厂存入三级缓存。
C 需要依赖 A,此时 Spring 尝试获取 A:
从三级缓存中获取 A 的工厂,通过工厂生成 A 的早期引用(可能是原始对象或代理对象),并将 A 移至二级缓存,同时删除三级缓存中的 A 工厂。
C 成功注入 A,完成属性注入和初始化,最终 C 被存入一级缓存。
4.继续创建 B:
B 依赖的 C 已存在于一级缓存,B 注入 C 后完成初始化,存入一级缓存。
5.继续创建 A:
A 依赖的 B 已存在于一级缓存,A 注入 B 后完成初始化,A从早期的二级缓存移除,并放到一级缓存中。
注意:无论循环依赖的链条多长,只要是单例 Bean 且使用 setter 注入,Spring 都能通过这种三级缓存的协作机制来解决,核心是通过提前暴露对象引用并合理管理不同状态的 Bean 缓存。

http://www.lryc.cn/news/618737.html

相关文章:

  • vue3 两种方法实现 按钮级别权限控制
  • vue3中el-upload使用http-request方式自定义上传文件
  • 支持任意 MCP 协议的客户端
  • Redis面试题及详细答案100道(16-32) --- 数据类型事务管道篇
  • 一,设计模式-单例模式
  • 2025年中科院2区红杉优化算法Sequoia Optimization Algorithm-附Matlab免费代码
  • VBS 字符串处理
  • 腾讯云服务器账户转移操作详解
  • Ceph存储池参数中pg_num和pgp_num的关系
  • 【Docker项目实战】使用Docker部署Vikunja任务管理工具
  • 熟悉并使用Spring框架 - XML篇
  • 破译真实感:渲染参数进阶指南——告别塑料感,唤醒材质生命力
  • 98、【OS】【Nuttx】【构建】cmake 配置问题定位:menuconfig.dir/build.make
  • 【力扣494】目标和
  • 笔试——Day36
  • Unity-VR插件AutoHand
  • Day 10-2: Mini-GPT完整手写实战 - 从组件组装到文本生成的端到端实现
  • 武汉火影数字|VR红色文化馆打造 沉浸式体验红色文化
  • Coze开源 Agent 的“乐高时代”
  • 【19】万集科技——万集科技嵌入式,校招 一面,二面,面试问答记录
  • Java 编程每日一题:实现一个简易的 LRU 缓存
  • 站在Vue的角度,对比鸿蒙开发中的递归渲染
  • C++单继承虚函数表探索
  • 什么是跨域访问问题,如何解决?
  • 使用 rsync 上传下载文件:详解原理、目录同步和常见问题
  • 间隙锁(Gap Lock)
  • 【C++】5. 内存管理
  • 卫生间装修防水怎么做合适?
  • redis原理篇--Dict
  • 《Linux基础知识-1》