深度解析 Spring Boot 循环依赖:原理、源码与解决方案

在 Spring Boot 开发中,循环依赖是一个常见且容易被忽视的技术点。当两个或多个 Bean 相互引用时,就会形成循环依赖(如 A 依赖 B,B 依赖 A)。初学者往往会困惑:Spring 为什么能自动处理这种看似矛盾的依赖关系?本文将从原理、源码实现到解决方案,全方位剖析 Spring Boot 的循环依赖机制。

一、什么是循环依赖?

循环依赖指的是两个或多个 Bean 之间存在相互引用的关系,形成闭环。例如:

// ServiceA依赖ServiceB
@Service
public class ServiceA {@Autowiredprivate ServiceB serviceB;
}// ServiceB依赖ServiceA
@Service
public class ServiceB {@Autowiredprivate ServiceA serviceA;
}

上述代码中,ServiceA需要注入ServiceB,而ServiceB同时需要注入ServiceA,形成了最简单的循环依赖。在传统的对象创建过程中,这种相互依赖会导致 "先有鸡还是先有蛋" 的悖论,但 Spring 通过特殊的机制解决了大部分场景下的循环依赖问题。

二、Spring Boot 如何处理循环依赖?

Spring 容器对循环依赖的处理能力,是其 Bean 管理机制的重要体现。核心解决方案可概括为:三级缓存 + 提前暴露半成品 Bean

1. 三级缓存的核心作用

Spring 通过三个缓存(实际上是三个 Map)来协调 Bean 的创建与依赖注入过程,这三个缓存定义在DefaultSingletonBeanRegistry中:

// 一级缓存:存储完全初始化完成的Bean
private final Map<String, Object> singletonObjects = new ConcurrentHashMap<>(256);// 二级缓存:存储半成品Bean(已实例化但未完成属性注入和初始化)
private final Map<String, Object> earlySingletonObjects = new HashMap<>(16);// 三级缓存:存储Bean的工厂对象,用于生成半成品Bean的代理对象
private final Map<String, ObjectFactory<?>> singletonFactories = new HashMap<>(16);
  • 一级缓存(singletonObjects):存放已完成所有初始化步骤的 Bean,是最终可被使用的成品 Bean。
  • 二级缓存(earlySingletonObjects):存放已实例化但尚未完成属性注入和初始化的半成品 Bean,用于解决循环依赖时的临时引用。
  • 三级缓存(singletonFactories):存放ObjectFactory对象,该工厂用于在需要时生成 Bean 的早期引用(可能是原始对象或代理对象)。

2. 循环依赖的解决流程

以ServiceA和ServiceB的循环依赖为例,Spring 的处理流程如下:

  1. 创建 ServiceA
    1. 调用getBean(ServiceA),检查一级缓存,未命中。
    2. 实例化ServiceA(通过构造方法创建对象,但未注入属性)。
    3. 将ServiceA的ObjectFactory放入三级缓存(singletonFactories)。
    4. 开始为ServiceA注入属性,发现依赖ServiceB。
  2. 创建 ServiceB
    1. 调用getBean(ServiceB),检查一级缓存,未命中。
    2. 实例化ServiceB,将其ObjectFactory放入三级缓存。</

本文来自互联网用户投稿,该文观点仅代表作者本人,不代表本站立场。本站仅提供信息存储空间服务,不拥有所有权,不承担相关法律责任。
如若转载,请注明出处:http://www.pswp.cn/bicheng/92897.shtml
繁体地址,请注明出处:http://hk.pswp.cn/bicheng/92897.shtml

如若内容造成侵权/违法违规/事实不符,请联系多彩编程网进行投诉反馈email:809451989@qq.com,一经查实,立即删除!

相关文章

数据库的基本操作(约束与DQL查询)

一、约束约束是在表上强制执行的数据规则&#xff0c;用于确保数据的完整性和一致性&#xff08;1&#xff09;约束类型MySQL中支持多种约束类型&#xff1a;①主键约束&#xff08;PRIMARY KEY&#xff09; ②自增约束&#xff08;AUTO_INCREMENT&#xff09;③非空约束…

HP Pavilion G6 笔记本安装Ubuntu开机后自动进入飞行模式的问题解决

问题一台HP Pavilion G6 笔记本 &#xff0c;安装了Ubuntu24.04版本&#xff0c;开机后&#xff0c;直接进入飞行模式&#xff0c;导致无法使用Wifi,且使用fnf10的组合键&#xff0c;也无法关闭飞行模式。使用fnf10键&#xff0c;可以看到提示显示飞行模式&#xff0c;但无法关…

LLM:MoE原理与实现探索

文章目录前言一、Deepseek Moe二. Moe架构1. Expert2. Gate3. MoE Module三、Auxiliary Loss总结前言 MoE&#xff08;Mixture of Experts) 已经逐渐在LLM中广泛应用&#xff0c;其工程部署相关目前也有了越来越多的支持&#xff0c;本文主要记录一下MoE的基本模块构造与原理。…

基于领域事件驱动的微服务架构设计与实践

引言&#xff1a;为什么你的微服务总是"牵一发而动全身"&#xff1f; 在复杂的业务系统中&#xff0c;你是否遇到过这样的困境&#xff1a;修改一个订单服务&#xff0c;却导致支付服务异常&#xff1b;调整库存逻辑&#xff0c;用户服务开始报错。这种"蝴蝶效应…

如何使用curl编程来下载文件

libcurl 是一个功能强大的跨平台网络传输库&#xff0c;支持多种协议。 本篇来介绍libcul的C语言编程&#xff0c;实现一个文件下载的功能。 1 curl基础介绍 1.1 核心数据结构 1.1.1 CURL句柄 CURL是libcurl 的核心句柄&#xff0c;每个请求对应一个 CURL 实例&#xff0c;…

大语言模型提示工程与应用:ChatGPT提示工程技术指南

ChatGPT提示工程 学习目标 在本课程中&#xff0c;我们将学习更多关于ChatGPT的最新提示工程技术。 相关知识点 ChatGPT提示工程 学习内容 1 ChatGPT提示工程 ChatGPT是OpenAI研发的新型对话模型&#xff0c;具备多轮对话能力。该模型通过人类反馈强化学习(RLHF)训练&am…

能力评估:如何系统评估你的技能和经验

能力评估&#xff1a;如何系统评估你的技能和经验 作为一名38岁的互联网研发老兵&#xff0c;你已经积累了丰富的经验&#xff0c;包括技术深度、项目管理、团队协作等。但能力评估不是一次性事件&#xff0c;而是持续过程&#xff0c;帮助你识别优势、短板&#xff0c;并为职业…

鸿蒙开发中所有自定义装饰器的完整案例解析--涵盖 16 个核心装饰器的详细用法和实战场景

以下是鸿蒙开发中 所有自定义装饰器的完整案例解析 和 终极总结指南&#xff0c;涵盖 16 个核心装饰器的详细用法和实战场景&#xff1a; 一、终极总结表&#xff1a;16大装饰器全景图 装饰器类别V1V2核心作用典型场景Component组件定义✅❌创建标准组件业务UI组件ComponentV2…

【C++】哈希表的实现(unordered_map和unordered_set的底层)

文章目录 目录 文章目录 前言 一、unordered_set和unordered_map介绍 二、哈希表的介绍 三、哈希冲突的解决方法 1.开放定址法 2.链地址法 四、两种哈希表代码实现 总结 前言 前面我们学习了红黑树&#xff0c;红黑树就是map和set的底层&#xff0c;本篇文章带来的是unordered…

欧拉公式的意义

欧拉公式的意义 欧拉公式&#xff08;Euler’s Formula&#xff09;是数学中最重要的公式之一&#xff0c;它将复数、指数函数和三角函数紧密联系在一起。其基本形式为&#xff1a; eiθcos⁡θisin⁡θ e^{i\theta} \cos \theta i \sin \theta eiθcosθisinθ 当 θπ\thet…

Linux Docker 运行SQL Server

在Linux操作系统&#xff0c;已安装docker&#xff0c;现在以docker compose方式&#xff0c;安装一个最新版SQL Server 2022的数据库。 # 建个目录&#xff08;请不要照抄&#xff0c;我的数据盘在/data&#xff0c;你可以改为/opt&#xff09; mkdir /data/sqlserver# 进入目…

C++:stack_queue(2)实现底层

文章目录一.容器适配器1. 本质&#xff1a;2. 接口&#xff1a;3. 迭代器&#xff1a;4. 功能&#xff1a;二.deque的简单介绍1.概念与特性2.结构与底层逻辑2.1 双端队列&#xff08;deque&#xff09;结构&#xff1a;2.2 deque的内部结构2.3 deque的插入与删除操作&#xff1…

Lightroom 安卓版 + Windows 版 + Mac 版全适配,编辑管理一站式,专业摄影后期教程

软件是啥样的​ Adobe Lightroom 这软件&#xff0c;在安卓手机、Windows 电脑和 Mac 电脑上都能用。不管是喜欢拍照的人&#xff0c;还是专门搞摄影的&#xff0c;用它都挺方便&#xff0c;能一站式搞定照片编辑、整理和分享这些事儿。 ****下载地址 分享文件&#xff1a;【Li…

office卸载不干净?Office356卸载不干净,office强力卸载软件下载

微软官方认可的卸载工具&#xff0c;支持彻底清除Office组件及注册表残留。需要以管理员身份运行&#xff0c;选择“移除Office”功能并确认操作。 Office Tool Plus安装地址获取 点击这里获取&#xff1a;Office Tool Plus 1、双击打开软件 image 2、选择左右的工具箱&…

互联网企业慢性死亡的招聘视角分析:从岗位割裂看战略短视

内容简介&#xff1a; 一个猎头和HR的简单拒绝&#xff0c;揭示了中国互联网企业人才观念的深层问题。通过分析岗位过度细分现象&#xff0c;本文探讨了战略短视、内斗文化和核心竞争力缺失如何导致企业慢性死亡&#xff0c;并提出了系统性的解决方案。#互联网企业 #人才招聘 #…

OpenBMC中phosphor-dbus-interfaces深度解析:架构、原理与应用实践

引言 在OpenBMC生态系统中&#xff0c;phosphor-dbus-interfaces作为D-Bus接口定义的核心组件&#xff0c;扮演着系统各模块间通信"契约"的关键角色。本文将基于OpenBMC源码&#xff0c;从架构设计、实现原理到实际应用三个维度&#xff0c;全面剖析这一基础组件的技…

驾驶场景玩手机识别准确率↑32%:陌讯动态特征融合算法实战解析

原创声明本文为原创技术解析文章&#xff0c;核心技术参数与架构设计参考自《陌讯技术白皮书》&#xff0c;转载请注明出处。一、行业痛点&#xff1a;驾驶场景行为识别的现实挑战根据交通运输部道路运输司发布的《驾驶员不安全行为研究报告》显示&#xff0c;驾驶过程中使用手…

Mysql——单表最多数据量多少需要分表

目录 一、MySql单表最多数据量多少需要分表 1.1、阿里开发公约 1.2、一个三层的B+树,它最多可以存储多少数据量 1.3、示例 1.3.1、示例表中一行的数据占多少字节数 1.3.2、示例表中一页里面最多可以存多少条记录 1.3.3、按示例表计算,一个三层的B+树,可以放多少条100字节的数…

scikit-learn/sklearn学习|岭回归解读

【1】引言 前序学习进程中&#xff0c;对用scikit-learn表达线性回归进行了初步解读。 线性回归能够将因变量yyy表达成由自变量xxx、线性系数矩阵www和截距bbb组成的线性函数式&#xff1a; y∑i1nwi⋅xibwTxby\sum_{i1}^{n}w_{i}\cdot x_{i}bw^T{x}byi1∑n​wi​⋅xi​bwTxb实…

基于Django的图书馆管理系统的设计与实现

基于Django的图书馆管理系统的设计与实现、