Spring是如何解决bean循环依赖的问题的
在Spring框架中,循环依赖是指两个或多个Bean之间相互依赖,形成了一个闭环的依赖关系。当存在循环依赖时,Bean的创建过程会陷入死循环,导致应用程序无法启动或出现异常。
说到循环依赖,首先我先说说bean的三级缓存
在Spring框架中,Bean的三级缓存是指在Bean的创建过程中,Spring容器为了提高性能而采用的一种缓存机制。这个缓存机制包括三个级别的缓存,分别是singletonObjects、earlySingletonObjects和singletonFactories。
-
singletonObjects:这是最终的单例对象缓存。当一个Bean的创建过程完成后,它会被放入singletonObjects缓存中。以后如果再次请求获取该Bean,Spring将直接从singletonObjects缓存中返回已经创建好的实例。
-
earlySingletonObjects:这是早期的单例对象缓存。在Bean的创建过程中,当依赖关系解析完成但还未完成初始化时,Bean会被放入earlySingletonObjects缓存中。这样,当其他Bean需要引用该Bean时,可以提前获取到它的引用,避免循环依赖的问题。
-
singletonFactories:这是用于存储Bean工厂的缓存。当Bean正在创建过程中,它的工厂方法会被放入singletonFactories缓存中。这样,在工厂方法被调用时,可以直接从缓存中获取工厂实例,而不需要重新创建。
通过使用三级缓存,Spring能够有效地管理Bean的创建过程和依赖关系,提高应用程序的性能和效率。这种缓存机制在单例作用域的Bean中特别有用,因为单例Bean在整个应用程序中只会被创建一次,而且可能存在循环依赖的情况。
需要注意的是,三级缓存的使用是为了提高性能和解决循环依赖问题,而不是为了缓存大量的Bean实例。因此,对于非单例作用域的Bean,Spring不会使用三级缓存,而是每次请求都会创建一个新的实例。
看完了三级缓存,大概都知道循环依赖怎么解决的,那我们来具体看一下策略吧
为了解决循环依赖问题,Spring使用了三级缓存和"提前暴露对象"的策略。下面是Spring解决循环依赖问题的大致过程:
-
创建Bean对象:当Spring容器需要创建一个Bean时,会先检查singletonObjects缓存中是否已经存在该Bean的实例。如果存在,则直接返回实例;如果不存在,则继续下一步。
-
提前暴露对象:在Bean的创建过程中,当依赖关系解析完成但还未完成初始化时,Spring会将当前Bean实例提前暴露给其他正在创建的Bean。这样,其他Bean可以提前获取到该Bean的引用,避免循环依赖的问题。
-
三级缓存处理:当发现循环依赖时,Spring会使用三级缓存来处理。首先,将正在创建的Bean工厂方法放入singletonFactories缓存中。然后,继续创建Bean的依赖关系,并将已经解析完成的依赖放入earlySingletonObjects缓存中。最后,完成Bean的创建并放入singletonObjects缓存中。
-
依赖注入:当所有Bean的创建过程完成后,Spring会执行依赖注入操作,将Bean的依赖关系注入到对应的属性中。
通过以上步骤,Spring能够解决循环依赖问题。它通过提前暴露对象和三级缓存的机制,在Bean的创建过程中合理处理依赖关系,确保循环依赖时能够正确地获取到已经创建好的实例或工厂方法,从而避免死循环的情况发生。
需要注意的是,Spring对于构造函数注入的循环依赖无法解决,因为在构造函数阶段无法提前暴露对象。对于这种情况,可以考虑使用Setter方法注入或通过引入一个中间层来解决循环依赖。
相关文章:

Spring是如何解决bean循环依赖的问题的
在Spring框架中,循环依赖是指两个或多个Bean之间相互依赖,形成了一个闭环的依赖关系。当存在循环依赖时,Bean的创建过程会陷入死循环,导致应用程序无法启动或出现异常。 说到循环依赖,首先我先说说bean的三级缓存 在S…...

[移动通讯]【Carrier Aggregation-9】【 Radio Resource Control (RRC) Aspects】
前言: CA 分析辅助工具: UE Capabilities 目录: 总体流程 Radio Resource Control (RRC) Aspects SCell addition and removal Handover 一 总体流程 1.1 CA 总体流程 1.2 CA 和 NSA 区别 NSA 我理解也是一种特殊的CA 方案&…...

故障预测与健康管理(PHM)的由来以及当前面临的挑战
故障预测与健康管理(PHM)作为一项关键技术,旨在帮助企业在事故发生之前较长时间内实现故障预测与健康管理,达到“治未病”的效果。PHM的发展源于对设备可靠性和安全性的追求,以及对预测性维护的需求。然而,…...

【ChatGPT瀑布到水母】AI 在驱动软件研发的革新与实践
这里写目录标题 前言内容简介作者简介专家推荐读者对象目录直播预告 前言 计算机技术的发展和互联网的普及,使信息处理和传输变得更加高效,极大地改变了金融、商业、教育、娱乐等领域的运作方式。数据分析、人工智能和云计算等新兴技术,也在不…...
【Django】项目模型
Django的基本命令 django-admin 命令含义startproject启动Django项目startapp启动Django应用check检查项目完整性runserver本地运行项目shell进入Django项目的Python Shell环境test 进行Django用例测试makemigrations创建模型变更的迁移文件migrate执行makemigrations…...

字符集详解
常见字符集介绍 字符集基础知识: 计算机底层不可以直接存储字符的。 计算机中底层只能存储二进制(0、1) 。 二进制是可以转换成十进制的。 结论:计算机底层可以表示成十进制编号。计算机可以给人类字符进行编号存储,这套编号规则就是字符…...
Vert.x学习笔记-什么是Vert.x
Vert.x介绍 用官网的一句话来总结:Vert.x是用于在JVM上构建响应式应用程序的工具包,项目初期的目标是成为“JVM版的Node.js”,但是后续的发展逐渐偏离了初期的目标,变成了一个给JVM提供量身定制的异步编程基础框架的工具包。 Ver…...

AcWing 第127场周赛 构造矩阵
构造题目,考虑去除掉最后一行最后一列先进行考虑,假设除了最后一行和最后一列都已经排好了(你可以随便排),那么分析知最后一个数字由限制以外其他都已经确定了,无解的情况是k为-1 并且n,m的奇偶…...

Seata入门系列【15】@GlobalLock注解使用场景及源码分析
1 前言 在Seata 中提供了一个全局锁注解GlobalLock,字面意思是全局锁,搜索相关文档,发现资料很少,所以分析下它的应用场景和基本原理,首先看下源码中对该注解的说明: // 声明事务仅在单个本地RM中执行 //…...

Dubbo 路由及负载均衡性能优化
作者:vivo 互联网中间件团队- Wang Xiaochuang 本文主要介绍在vivo内部针对Dubbo路由模块及负载均衡的一些优化手段,主要是异步化缓存,可减少在RPC调用过程中路由及负载均衡的CPU消耗,极大提升调用效率。 一、概要 vivo内部Java…...

Python数据可视化入门指南
Matplotlib和Plotly是两个在Python中广泛使用的数据可视化库,它们具有丰富的API和功能,用于创建各种类型的图表和图形。在本篇博客中,我们将介绍它们的主要特点和基本用法。 Matplotlib 主要特点: 高度自定义: Matp…...

我的ChatGPT的几个使用场景
示例一,工作辅助、写函数代码: 这里展示了一个完整的代码,修正,然后最终输出的过程。GPT具备足够丰富的相关的小型代码生成能力,语法能力也足够好。这类应用场景,在我的GPT使用中,能占到65%以上…...

3 — NLP 中的标记化:分解文本数据的艺术
一、说明 这是一个系列文章的第三篇文章, 文章前半部分分别是: 1 — NLP 的文本预处理技术2 — NLP中的词干提取和词形还原:文本预处理技术 在本文中,我们将介绍标记化主题。在开始之前,我建议您阅读我之前介绍…...

C++-类与对象(上)
一、 auto关键字 1.自动识别数据类型 2.auto的初始化 3.auto简化for循环 nullptr的使用 二、类与对象 1.c中类的定义 2.c语言与c的比较 3.类的访问限定符以及封装 3.1访问限定符 3.2封装 3.3类的作用域 3.4类的声明与定义分离 🗡CSDN主页:d1ff1cult.&…...
多进程间通信学习之无名管道
无名管道:首先它是内核空间的实现机制;然后只能用于亲缘进程间通信;它在内核所占的大小是64KB;它采用半双工的通信方式;请勿使用lseek函数;读写特点:若读端存在写管道,那么有多少数据…...
flink常用的几种调优手段的优缺点
背景: 不管是基于减少反压还是基于减少端到端的延迟的目的,我们有时候都需要对flink进行调优,本文就整理下几种常见的调优手段以及他们的优缺点 flink调优手段 1.使用事件时间EventTime模式时,可以设置水位线发送的时间间隔,比…...

如何选择安全又可靠的文件数据同步软件?
数据实时同步价值体现在它能够确保数据在多个设备或系统之间实时更新和保持一致。这种技术可以应用于许多领域,如电子商务、社交媒体、金融服务等。在这些领域中,数据实时同步可以带来很多好处,如提高工作效率、减少数据不一致、提高用户体验…...
使用反射调用类的私有内部类的私有方法
文章目录 使用反射调用类的私有方法类实现方法实现代码 使用反射调用类的私有内部类的私有方法类实现方法实现代码 在进行单元测试时,我们往往需要直接访问某个类的内部类或者某个类的私有方法,此时正常的调用就无能为力了,因此我们可以使用反…...

记一次 AWD 比赛中曲折的 Linux 提权
前提背景: 今天一场 AWD 比赛中,遇到一个场景:PHP网站存在SQL注入和文件上传漏洞, MYSQL当前用户为ROOT,文件上传蚁剑连接SHELL是权限很低的用户。我需要想办法进行提权,才能读取到 /root 目录下的 flag。 一、sqlmap …...

[SpringCloud] Feign 与 Gateway 简介
目录 一、Feign 简介 1、RestTemplate 远程调用中存在的问题 2、定义和使用 Feign 客户端 3、Feign 自定义配置 4、Feign 性能优化 5、Feign 最佳实践 6、Feign 使用问题汇总 二、Gateway 网关简介 1、搭建网关服务 2、路由断言工厂 3、路由的过滤器配置 4、全局过…...
ES6从入门到精通:前言
ES6简介 ES6(ECMAScript 2015)是JavaScript语言的重大更新,引入了许多新特性,包括语法糖、新数据类型、模块化支持等,显著提升了开发效率和代码可维护性。 核心知识点概览 变量声明 let 和 const 取代 var…...

【OSG学习笔记】Day 16: 骨骼动画与蒙皮(osgAnimation)
骨骼动画基础 骨骼动画是 3D 计算机图形中常用的技术,它通过以下两个主要组件实现角色动画。 骨骼系统 (Skeleton):由层级结构的骨头组成,类似于人体骨骼蒙皮 (Mesh Skinning):将模型网格顶点绑定到骨骼上,使骨骼移动…...

Spring数据访问模块设计
前面我们已经完成了IoC和web模块的设计,聪明的码友立马就知道了,该到数据访问模块了,要不就这俩玩个6啊,查库势在必行,至此,它来了。 一、核心设计理念 1、痛点在哪 应用离不开数据(数据库、No…...
【生成模型】视频生成论文调研
工作清单 上游应用方向:控制、速度、时长、高动态、多主体驱动 类型工作基础模型WAN / WAN-VACE / HunyuanVideo控制条件轨迹控制ATI~镜头控制ReCamMaster~多主体驱动Phantom~音频驱动Let Them Talk: Audio-Driven Multi-Person Conversational Video Generation速…...

【JVM面试篇】高频八股汇总——类加载和类加载器
目录 1. 讲一下类加载过程? 2. Java创建对象的过程? 3. 对象的生命周期? 4. 类加载器有哪些? 5. 双亲委派模型的作用(好处)? 6. 讲一下类的加载和双亲委派原则? 7. 双亲委派模…...

elementUI点击浏览table所选行数据查看文档
项目场景: table按照要求特定的数据变成按钮可以点击 解决方案: <el-table-columnprop"mlname"label"名称"align"center"width"180"><template slot-scope"scope"><el-buttonv-if&qu…...

【LeetCode】算法详解#6 ---除自身以外数组的乘积
1.题目介绍 给定一个整数数组 nums,返回 数组 answer ,其中 answer[i] 等于 nums 中除 nums[i] 之外其余各元素的乘积 。 题目数据 保证 数组 nums之中任意元素的全部前缀元素和后缀的乘积都在 32 位 整数范围内。 请 不要使用除法,且在 O…...
区块链技术概述
区块链技术是一种去中心化、分布式账本技术,通过密码学、共识机制和智能合约等核心组件,实现数据不可篡改、透明可追溯的系统。 一、核心技术 1. 去中心化 特点:数据存储在网络中的多个节点(计算机),而非…...
Pydantic + Function Calling的结合
1、Pydantic Pydantic 是一个 Python 库,用于数据验证和设置管理,通过 Python 类型注解强制执行数据类型。它广泛用于 API 开发(如 FastAPI)、配置管理和数据解析,核心功能包括: 数据验证:通过…...

DAY 45 超大力王爱学Python
来自超大力王的友情提示:在用tensordoard的时候一定一定要用绝对位置,例如:tensorboard --logdir"D:\代码\archive (1)\runs\cifar10_mlp_experiment_2" 不然读取不了数据 知识点回顾: tensorboard的发展历史和原理tens…...