spring bean的循环依赖

news2024/9/20 20:45:22

在Spring框架中,Bean的循环依赖是一个常见的问题,它指的是两个或多个Bean之间通过构造函数、Setter方法或字段注入等方式形成了相互依赖的闭环。Spring框架提供了强大的依赖注入功能,同时也提供了多种机制来处理循环依赖的情况,确保应用能够正确启动和运行。

要进行了解spring的循环依赖,我们先来进行看下spring的生命周期

1.Spring Bean生命周期概述

spring的生命周期主要包含以下几个阶段

• 容器启动阶段

•Bean对象实例化阶段

•bean属性的注入阶段

•bean的初始化阶段

•bean缓存阶段

•bean销毁阶段

2.生命周期各阶段详解

2.1 容器启动阶段

我们程序员通过XML配置或Java配置(如使用@Configuration注解的类)定义Spring应用的上下文配置。配置中指定了组件扫描的包路径(通过@ComponentScan<context:component-scan>

扫描和实例化BeanDefinition对象。并将BeanDefinition对象放入到BeanDefinitionMap中。注册BeanPostProcessor,验证BeanDefinition对象是否合格。

2.2 Bean对象实例化阶段

推测Bean对象的实例化方法,并进行实例化操作。

2.3 bean属性的注入阶段

查找注入信息,完成注解解析和属性注入

2.4 bean的初始化阶段

各种Aware的回调,各种初始化方法的回调,对bean的扩展例如aop

2.5 bean缓存阶段

各种临时变量的删除操作,缓存到单例池中

2.6 bean销毁阶段

销毁方法的回调,移除单例池。

3.创建bean方法的主要逻辑

4.循环依赖

spring中的循环依赖主要是依赖的是三级缓存。这个三级缓存是我们程序员给取的名字,并不是spring官方起的名字。这个三级缓存分别是singletonObjects(一级缓存),earlySingletonObjects(二级缓存),singletonFactories(三级缓存)。

singletonObjects:也称作单例池,主要是存放的最终形态的单例bean,一般获取一个bean都是从这个集合中进行获取。

singletonFactories:二级缓存,主要存放的是ObjectFactory,作用主要是为了进行创建一个对象,这个缓存中存放的是一个工厂。

earlySingletonObjects:三级缓存,主要进行存放的是过渡的bean

假设我们现在有两个类 一个M类 一个N类,M依赖N,N同时也依赖M

@Component
public class N {

    @Autowired
    private  N n;
}

@Component
public class M {

    @Autowired
    private  N n;

}


我们接下来进行分析一下创建M,N类的时候,这三个集合的数据变化的逻辑 这里指进行分析M,N这两个对象的情况,spring内置的那些就不在考虑的范围内。

M类和N类的循环依赖流程如下所示:

1.首先我们进行M对象的创建操作,当创建M对象执行到populateBean方法的时候,此时的各个集合的情况如下:

2.当进行执行populateBean方法需要对M里的n属性进行复制的时候,会从容器中进行获取n 此时发现容器中不存在n属性,那么就会接着走上面进行创建bean的流程。这个也会走到populateBean方法,此时这三个集合的情况就如下所示:

3.在给N类的m属性进行赋值的时候,需要进行获取m属性值的时候这个时候会进行调用getSingleton方法。里面进行删除了一些代码。

protected Object getSingleton(String beanName, boolean allowEarlyReference) {
   //从单例池中获取对象信息
    Object singletonObject = this.singletonObjects.get(beanName);
    //此时进行设置N类中的m对象 这个时候从单例池中获取m对象发现对象为空
    if (singletonObject == null && isSingletonCurrentlyInCreation(beanName)) {
      synchronized (this.singletonObjects) {
        // 从二级缓存中进行获取m对象,发现缓存中也没有对象信息
         singletonObject = this.earlySingletonObjects.get(beanName);
	 if (singletonObject == null && allowEarlyReference) {
               //从三级缓存中进行进行获取factory工厂
	       ObjectFactory<?> singletonFactory = this.singletonFactories.get(beanName);
		if (singletonFactory != null) {
                    //factory工厂不为null 进行创建对象信息
		    singletonObject = singletonFactory.getObject();
                    // 将创建好的对象信息 存放到二级缓存中
		    this.earlySingletonObjects.put(beanName, singletonObject);
		     //三级缓存中删除工厂类对象
                    this.singletonFactories.remove(beanName);
		 }
	   }
	}
   }
   return singletonObject;
}

这个时候的三个集合就会发生变化,变化之后的情况如下:

4. N类初始化完成之后的情况

5.问题与反思

为何需要三级缓存,二级缓存(singletonFactories)只进行存放一个半成品的bean为何不可以。二级缓存(singletonFactories)有什么用呢,二级缓存(singletonFactories)中存放的是一个工厂类,这个工厂类可以进行创建对象,那spring为啥要在二级缓存(singletonFactories)中存放一个工厂呢,这块有什么别的深意呢,笔者目前认为这块是在spring Aop的时候可以通过二级缓存(singletonFactories)进行创建一个代理对象。

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

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

相关文章

【SCI论文写作】工程类论文写作(二)引言

写在前面&#xff1a; &#x1f31f; 欢迎光临 清流君 的博客小天地&#xff0c;这里是我分享技术与心得的温馨角落。&#x1f4dd; 个人主页&#xff1a;清流君_CSDN博客&#xff0c;期待与您一同探索 移动机器人 领域的无限可能。 &#x1f50d; 本文系 清流君 原创之作&…

护眼灯对眼睛有伤害吗?防止三大禁忌隐患

护眼灯对眼睛有伤害吗&#xff1f;护眼灯是现代生活中非常常见的照明工具&#xff0c;它在家庭和办公场所都得到了广泛应用。然而&#xff0c;随着人们对眼睛健康的关注日益增加&#xff0c;关于护眼灯是否可能对眼睛造成伤害的疑问也随之产生。这些疑问不仅涉及到人们的视力健…

黄晓娟:钱输光了她还伺候你?赵本山:她不伺候谁伺候?

黄晓娟&#xff1a;钱输光了她还伺候你&#xff1f;赵本山&#xff1a;她不伺候谁伺候&#xff1f; --小品《麻将豆腐》&#xff08;中1&#xff09;的台词与解说 &#xff08;接上&#xff09; 赵本山&#xff08;饰演大姐夫&#xff09;&#xff1a;诈和了 瞅好啊整不好让…

工作任务紧急程度如何快速区分?

在繁忙的工作中&#xff0c;我们每天都需要处理大量的工作任务。如果不将这些任务仔细区分&#xff0c;就很难保证按时完成所有任务。面对如此多的任务&#xff0c;仅凭脑力很难将它们一一整理和区分。这时&#xff0c;选择一款高效的待办事项管理软件&#xff0c;就成了一个不…

深度学习入门-01

1、安装Anaconda 创建一个虚拟环境&#xff0c;在Anaconda Prompt中创建&#xff0c;环境名称叫做pytorch&#xff0c;使用的python版本是3.10 conda create -n pytorch python3.10在这环境中需要安装的包&#xff0c;选择yes 激活环境&#xff1a; conda activate pytorch如…

排序算法之--插入排序

文章目录 一、简介二、算法思路分析三、算法复杂度分析&#xff1a;3.1、时间复杂度方面&#xff1a;3.2、空间复杂度方面&#xff1a; 四、代码实现&#xff1a; 一、简介 插入排序是一种简单直观的排序算法&#xff0c;‌它的工作原理是通过构建有序序列&#xff0c;‌该算法…

MySQL:查询(万字超详细版)

&#x1f48e;所属专栏&#xff1a; MySQL &#x1f48e;1. 单表查询 &#x1f48e;1.1 全列查询和指定列查询 全列查询&#xff1a; select * from exam; 在实际开发中不要使用 * 来进行查询&#xff0c;因为数据库会很大&#xff0c;影响效率 指定列查询&#xff1a; se…

低代码开发平台通过钉钉API实现流程管理数据对接

实例背景&#xff1a; CRM项目虽然实现了报价转订单的功能&#xff0c;但是客户还是遇到使用不方便的问题&#xff0c;客户的业务流程中&#xff0c;审核报价的时候是需要提供销售人员与客户的聊天记录截图&#xff0c;这都是在手机上的&#xff0c;电脑操作不方便&#xff0c…

WEB渗透免杀篇-MSF+shellcode免杀

nps_payload >python nps_payload.py正常生成 >msfconsole -r msbuild_nps.rc开启监听 >%windir%\Microsoft.NET\Framework\v4.0.30319\msbuild.exe xx.xml >wmiexec.py <USER>:<PASS><RHOST> cmd.exe /c start %windir%\Microsoft.NET\Framewo…

Python之字符串的函数和方法

字符串的函数和方法 字符串函数字符串方法方法链可选参数方法的嵌套 函数可以看做是执行特定任务的小程序。程序被打包或封装起来&#xff0c;提供给用户使用。**函数可以接受输人值&#xff0c;通过执行语句和判定表达式来完成任务&#xff0c;在完成时可能会返回值。**函数非…

基于STM32开发的智能家居温控系统

目录 引言环境准备工作 硬件准备软件安装与配置系统设计 系统架构硬件连接代码实现 初始化代码控制代码应用场景 家庭智能温控办公室环境监测常见问题及解决方案 常见问题解决方案结论 1. 引言 智能家居温控系统通过整合温度传感器、湿度传感器、风扇和加热器等硬件&#xf…

SQL进阶技巧:断点缝合问题【如何按照业务规则对相邻行数据进行合并】

目录 0 需求描述 1 数据准备 2 数据分析 3 小结 0 需求描述 如下图所示,按照定义的规则进行数据变换 注意:b中的数值只有0和1 1 数据准备 with data as( select 2010 a,0 b union all select 2011 a,1 b union all select 2012 a,0 b union all select 2013 a,1 b un…

吴恩达机器学习-C2W1L3-简单神经网络

在本实验中&#xff0c;我们将使用Numpy构建一个小型神经网络。它将是你在Tensorflow中实现的相同的“咖啡烘焙”网络。 import numpy as np import matplotlib.pyplot as plt plt.style.use(./deeplearning.mplstyle) import tensorflow as tf from lab_utils_common import…

ACL主席:ACL不是AI会议

敲响警钟还是走向封闭&#xff1f; 点击访问我的技术博客https://ai.weoknow.comhttps://ai.weoknow.com 「ACL 不是 AI 会议&#xff08;ACL is not an Al conference&#xff09;」&#xff0c;在泰国曼谷举办的 ACL 2024 上&#xff0c;今年的 ACL 主席 Emily M. Bender 抛出…

实训日记day29

MySQL读写分离 1、读写分离的目的 数据库负载均衡&#xff1a; 当数据库请求增多时&#xff0c;单例数据库不能够满足业务 需求。需要进行数据库实例的扩容。多台数据库同时相 应请求。也就是说需要对数据库的请求&#xff0c;进行负载均衡 但是由于数据库服务特殊原因&#…

读零信任网络:在不可信网络中构建安全系统20攻击者视图

1. 攻击者视图 1.1. IETF要求所有提交的RFC都必须包含“安全风险考虑" 1.1.1. 明确指出了潜在陷阱、危险和警告&#xff0c;这对系统的实现和部署至关重要&#xff0c;有助于运营者确保最终的系统不会偏离设计之初的安全特性 1.1.2. 表明系统设计者对于可能存在的攻击进…

leetcode387. 字符串中的第一个唯一字符,哈希表

leetcode387. 字符串中的第一个唯一字符 给定一个字符串 s &#xff0c;找到 它的第一个不重复的字符&#xff0c;并返回它的索引 。如果不存在&#xff0c;则返回 -1 。 示例 1&#xff1a; 输入: s “leetcode” 输出: 0 示例 2: 输入: s “loveleetcode” 输出: 2 示例…

可能是全网最好用的 5 款免费数据恢复软件

不小心将 USB 中的文件删除了&#xff0c;这个时候要怎么办&#xff1f;首先我们不要保存 USB 磁盘上的任何新数据&#xff0c;否则丢失的数据文件将被覆盖。然后再利用专业的数据恢复工具进行恢复&#xff0c;这里为大家整理了全网最被推荐的5款免费的数据恢复软件。 1.福昕数…

vmware虚拟机玩GPU显卡直通

安装好exsi以后&#xff0c;找到管理----硬件-----PCI设备&#xff0c;勾选想要直通的显卡&#xff0c;然后点击“切换直通” 切换以后可以看到列表中的直通列显示为活动就对了。 然后编辑虚拟机设置&#xff0c;CPU关闭硬件虚拟化&#xff08;向客户机操作系统公开硬件辅助的…

【python】在Windows中定时执行Python脚本的详细用法教学

✨✨ 欢迎大家来到景天科技苑✨✨ &#x1f388;&#x1f388; 养成好习惯&#xff0c;先赞后看哦~&#x1f388;&#x1f388; &#x1f3c6; 作者简介&#xff1a;景天科技苑 &#x1f3c6;《头衔》&#xff1a;大厂架构师&#xff0c;华为云开发者社区专家博主&#xff0c;…