Spring学习笔记01-解决循环依赖

spring的循环依赖是什么,设计的时候怎么避免,而spring又是怎么解决的? 文章目录前言spring的循环依赖是什么,设计的时候怎么避免,而spring又是怎么解决的?01 spring是如何解决spring依赖的?02 问什么我们的spring循环依赖只支持单例?03 发生循环依赖的错误代码04 推荐下面几种方式解决循环依赖问题 前言   如果您觉得有用的话,记得给博主点个赞,评论,收藏一键三连啊,写作不易啊^ _ ^。   而且听说点赞的人每天的运气都不会太差,实在白嫖的话,那欢迎常来啊!!! spring的循环依赖是什么,设计的时候怎么避免,而spring又是怎么解决的? 阅读详情

A和B相互依赖,产生循环依赖问题:
        a对象注入b,b初始化需要注入a,此时a正在创建,由此形成循环依赖。

朴素的解决思路:
        引入一个 map(暂时命名myMap),该map记录半成品bean,然后a对象注入b时,发现b未创建,此时创建b,而创建时发现需要依赖a,那么此时不再直接创建a,而是去myMap中查找是否有a,如果有a则拿出。
        myMap中放的对象,其实就是半成品bean对象,其中的对象未经过AOP,也就不是AOP后产生的代理对象,而只是初步初始化出来的普通对象。

提前AOP:
        那么就有新的问题:如果a是一个引入了AOP的对象,那么b中引入a时,是从myMap中获取的未经过代理的普通对象,而不是a的代理对象,显然不符合正常要求。
综上,需要提前进行AOP,即在bean初始化前则进行AOP。


注:正常情况下AOP代理对象生成时间点: 是在bean初始化后,由BeanPostProcessor接口的postProcessAfterInitialization方法生成的。

整体解决循环依赖的流程如下:

一级缓存:singletonObjects
        主要存放最终完整的单例bean

二级缓存引入:earlySingletonObjects
        假设现在不仅有a和b相互依赖,a和c也相互依赖,根据以上的解决方法,有两条执行路径会先后进行:
(1)创建a -> 创建b -> 获取a半成品对象(半成品代理对象);
(2)创建a -> 创建c-> 获取a半成品对象(半成品代理对象);
        以上会生成两个a的半成品代理对象,出现冲突,因此需要在(1)执行时,记录入一个map中,然后(2)执行时,从这个map中取值,看是否存在,如果存在,则不执行,只使用已创建的a半成品代理对象,这个map就是二级缓存。
        因此,二级缓存主要作用:还是为了保证单例bean,只不过此时存储的是半成品bean对象,是个早期的单例bean对象,所以二级缓存在源码中称为earlySingletonObjects

三级缓存引入:singletonFactories
        以上一级二级缓存,其实并没有打破循环依赖,只是起到了对【单例】的控制,而打破循环依赖的关键点在于【生成半成品bean】,只有能生成bean,那么在这个bean被依赖时,才可以获取到,从而打破循环依赖。
        因此引入了三级缓存singletonFactories。
        只要bean是支持循环依赖且为单例的情况下,每个bean在创建过程中都会在三级缓存中加入相关内容,这个内容就是一个lambda表达式,是bean的factory,所以三级缓存命名为singletonFacotories。
        三级缓存未必都能用到,只有真的发生了循环依赖,二级缓存中未找到相应的半成品bean时,才会从三级缓存中取出lambda表达式并执行,执行后便产生半成品bean,然后将这个bean放入二级缓存,并在三级缓存中删除该bean对应的lambda表达式。

        附上一张经典图:

什么是循环依赖?Spring如何解决循环依赖? 阅读详情

相关推荐

Spring解决bean之间的循环依赖(循环引用)

Spring只能解决Setter方法注入的单例bean之间的循环依赖ClassA依赖ClassBClassB又依赖ClassA,形成依赖闭环。Spring在获取ClassA的实例时,不等ClassA完成创建就将其曝光加入正在创建的bean缓存中。在解析ClassA的属性时,又发现依赖于ClassB,再次去获取ClassB,当解析ClassB的属性时,又发现需要ClassA的属性,但此时的ClassA已经被提前曝光加入了正在创建的bean的缓存中,则无需创建新的的ClassA的实例,直接从缓存中获取即可。

九师兄 2906

Spring源码剖析-Spring如何处理循环依赖

前言 你是不是被这个骚气的标题吸引进来的,_ 喜欢我的文章的话就给个好评吧,你的肯定是我坚持写作最大的动力,来吧兄弟们,给我一点动力 Spring如何处理循环依赖?这是最近较为频繁被问到的一个面试题,在前面Bean实例化流程中,对属性注入一文多多少少对循环依赖有过介绍,这篇文章详细讲一下Spring中的循环依赖的处理方案。 什么是循环依赖 依赖指的是Bean与Bean之间的依赖关系,循环依赖指的是两个或者多个Bean相互依赖,如: 构造器循环依赖 代码示例: public class BeanA {

墨家巨子@俏如来 6185

Win10下Delphi 10.4.2 (RAD Studio 10.4.2 )安装教程图解

Win10下Delphi 10.4.2 (RAD Studio 10.4.2 )安装和破解教程图解

1万+

01-Spring中的循环依赖以及它是如何解决的

循环依赖是指在依赖注入过程中,Bean 之间相互依赖,形成一个闭环。@Component@Autowired@Component@Autowired在上述代码中,A 依赖于 B,B 又依赖于 A,形成了循环依赖。Q:这种 @Autowired 方式在什么时候出现循环依赖?A:使用 @Autowired 进行 setter 注入 或 属性注入 时,如果两个 Bean 相互依赖,就会在 Spring Bean 的初始化阶段 出现循环依赖。

無言的博客 1124

STM32串口调试踩坑记:HAL_UART_ErrorCallback里不先解锁,你的中断接收就废了

本文深入分析了STM32串口调试中HAL_UART_ErrorCallback的锁机制陷阱,指出在错误回调中不先解锁会导致中断接收失效的问题。通过解析HAL库源码,提出了正确的错误处理实现方法,并分享了预防措施与最佳实践,帮助开发者提升串口通信的可靠性。

weixin_33733810的博客 512

用户和实体行为分析(UEBA)基础指南及解决方案

用户和实体行为分析(UEBA)或异常检测是一种网络安全技术,它使用机器学习(ML)算法来检测网络中用户、主机和其他实体的异常活动。

ITmoster的博客 2892

Spring中的循环依赖问题

关于Spring中的循环依赖问题和Spring解决循环依赖的方法

Fvemim的博客 2521

2017阿里内推笔试题--算法工程师(运筹优化)

2017阿里内推笔试题–算法工程师(运筹优化)题目沐哲是一个菜鸟仓库的一个拣货员,但他有非常个怪异的习惯。每次拣货的重量都要比之前拣的一个轻,每次拣到货后都可以得到1块钱,沐哲想知道这样最多能赚多少钱 32 34 7 33 21 2 13 12 3 11 26 36 16 30 22 1 24 14 20 23 25 5 19 29 27 15 9 17 31 4 6 18 8 10 3

shawpan的专栏 1万+

如何解决Spring中的循环依赖问题

循环依赖是指类与类之间的依赖关系形成了闭环,例如类A依赖类B,类B也依赖类A,这种情况就会出现循环依赖。BeanABeanBBeanA当Spring上下文在加载所有的bean时,会尝试按照他们关联关系的顺序进行创建。BeanABeanBBeanC首先 A 完成初始化第一步并将自己提前曝光出来(通过 ObjectFactory 将自己提前曝光),在初始化的时候,发现自己依赖对象 B,此时就会去尝试 get(B),这个时候发现 B 还没有被创建出来;

S1ANS的博客 1018

OpenHarmony 4.1/5.0 Beta上手:如何用ArkUI在非华为设备上开发你的第一个“鸿蒙”应用

本文详细介绍了如何在非华为设备上使用ArkUI开发OpenHarmony应用,涵盖从设备选型、环境搭建到应用部署的全流程。通过实战案例展示ArkTS语言在开源鸿蒙生态中的应用,帮助开发者突破设备限制,构建跨平台鸿蒙应用。

weixin_33704234的博客 362

Multi-Agent

Multi-Agent System(MAS,多代理系统)是分布式人工智能(DAI)领域皇冠上的明珠,其核心思想是通过多个自主、交互、目标导向的智能体(Agent)的协同与竞争,解决单智能体无法或难以高效处理的复杂问题——包括大规模资源调度、多模态数据理解与决策、复杂软件架构的自治运维、甚至未来城市级的交通与能源管理。本文将以结构化分析推理和第一性原理思考。

AI智能探索者的博客 407

spring详解-循环依赖的解决

本文都快写完了,发现“丈夫” 的英文是… 在“②有AOP循环依赖” 改过来了,前面用到的位置太多了就没改。我是说怎么idea的hansband英文下面怎么有波浪线。各位能够理解意思就行,英文拼写不要过于在意.

okok__TXF的博客 1527

嵌入式STM32F407CET6移植OpenHarmony系统方法

文件末尾添加:export PATH=~/gcc-arm-none-eabi-10-2020-q4-major/bin:$PATH。编译完成文件输出在LiteOs源码目录下out/STM32F407_ATK_Explorer文件夹中。②点击connect to the target,下方会自动显示识别出来的芯片型号以及flash大小。⑤点击program verify并点击start,等待烧写并校验完成,你就能看到程序正在运行了。,在选择刚才我们说的Huawei_LiteOS.hex文件。

嵌入式技术开发 546

Spring的循环依赖

Spring循环依赖指的是两个或多个Bean之间相互依赖,形成一个环状依赖的情况。通俗的说,就是A依赖B,B依赖C,C依赖A,这样就形成了一个循环依赖的环。Spring循环依赖通常会导致Bean无法正确地被实例化,从而导致应用程序无法正常启动或者出现异常。因此,Spring循环依赖是一种需要尽量避免的情况。

zenbior的博客 1105

直流无刷电机FOC控制算法 理论到实践 —— 理论(二)

在上一章节,我们对于FOC大体有了一个介绍,本博文将详细描述有关Clark变化、Park变化、反Park变化以及SVPWM的理论实现原理,也即相关数学运算实现。

爱出名的狗腿子 1万+

VB摄像头监控

该VB模块可对摄像头捕获的画面进行录像等,可在创建的窗口进行控制

循环依赖报错.BeanCurrentlyInCreationException(Spring 不是解决了循环依赖嘛?)

(Bean A和B循环依赖,A中的方法带有@Async注解,系统环境不一样会出现本地启动OK,测试环境或其他环境无法启动,报错.BeanCurrentlyInCreationException) Controller和Service都包含了同一个Component!这个Bean中有@Async注解的方法,由于它与generateUtilbean循环依赖所致!

Be_insighted的博客 2053

win10 跳过U8环境检测的IE WebControls.rar

win10 安装u8的时候 提示IE WebControls 不通过,这个工具可以欺骗u8的检查。 跳过U8环境检测的IE WebControls。提示导入失败后,重新检测通过。

一文详解Spring Bean的循环依赖问题及解决方案(三级缓存)

Spring框架中循环依赖指Bean间相互引用(如A依赖B,B又依赖A)。Spring能解决单例模式下setter注入的循环依赖,通过将实例化和属性赋值分离,利用三级缓存机制提前曝光Bean实例。但无法解决原型作用域下的循环依赖或构造器注入导致的循环依赖。解决方案包括:使用setter注入、@Lazy延迟加载、ApplicationContext手动获取或ObjectProvider。核心机制是通过一级缓存(单例对象)、二级缓存(早期对象)和三级缓存(对象工厂)协同工作来打破循环依赖。

2301_79971360的博客 1317

老版QQ原生表情gif动态

这是老版的QQ表情,不过全是动态的的,Windows照片查看器是不会动的,可以右击用浏览器打开查看,再说一遍是老版的,只是分享给宁愿用老版也要动态的人。

大中型超市收银系统(可直接运行)

光步前台收银系统系统功能:商品销售、商品退货、挂单、收银员权限、会员销售、单品取消、整单取消、商品查询、脱机销售、脱机数据上传,基本资料下载,开钱箱、小票打印、收款结算,支持多币种付款方式(现金、储值卡、礼券、微信等),支持多种促销。运行环境:.net 4.0登陆信息用户名:1001 密码:123456内置商品信息,商品编码可输入00001000 - 00010000,测试效果相关功能键F5 结算 F9挂单 F11商品查询 F8退货 Insert单品取消 Del整单取消 F12开钱箱F2 会员 Ctrl+Z退出系统 Home 锁屏 相关源码待公开

01-Spring解决循环依赖的方法

所谓Spring的循环依赖,指的是这样一种场景: 当我们注入一个对象A时,需要注入对象A中标记了某些注解的属性,这些属性也就是对象A的依赖,把对象A中的依赖都初始化完成,对象A才算是创建成功。那么,如果对象A中有个属性是对象B,而且对象B中有个属性是对象A,那么对象A和对象B就算是循环依赖,如果不加处理,就会出现:创建对象A-->处理A的依赖B-->创建对象B-->处理B的对象A-->创建对象A-->处理A的依赖B-->创建对象B......这样无限的循环下去。 这事

q287573145的博客 179

spring如何解决循环依赖

多个bean之间相互依赖,形成了一个闭环。简单来说就是当我们注入一个对象A时,需要注入对象A中标记了某些注解的属性,这些属性也就是对象A的依赖,把对象A中的依赖都初始化完成,对象A才算是创建成功。那么,如果对象A中有个属性是对象B,而且对象B中有个属性是对象A,那么对象A和对象B就算是循环依赖,如果不加处理,就会出现:创建对象A-->处理A的依赖B-->创建对象B-->处理B的对象A-->创建对象A-->处理A的依赖B-->创建对象B......这样无限的循环下去。}}}}}}

weixin_49336701的博客 184

学习感悟,以及Spring中的循环依赖是如何解决的

循环依赖的定义很容易理解,假如有两个类:Demo01,Demo02,@Component}}@Component}}}可以看到,Demo01和Demo02互相依赖了对方,如果这样测试会发生什么呢@Test}}在进行测试的时候,会弹出这样的报错:意思是在 Demo01需要通过构造函数注入的Demo02实例(或者Demo02中声明的Bean),而Demo02需要通过构造函数注入的 Demo01的实例(或者 Demo01中声明的Bean)。

weixin_61789925的博客 431

Spring循环依赖源码解析

在这一过程中,serviceA会找到它依赖的serviceB这一属性,当发现依赖后,会调用DefaultListableBeanFactory的doResolveDependency方法,之后执行resolveCandidate方法,在该方法中,尝试使用beanFactory获取到serviceB的bean实例。回到doCreateBean的方法,可以看到serviceB的serviceA属性已经被注入了,但是serviceA中的serviceB属性还是null。

sjkflw121150的博客 738

Spring Boot 扩展:Spring 如何处理循环依赖

首先,我们先明确下依赖的定义。如果一个 Bean bar 的属性,引用了容器中的另外一个 Bean foo,那么称 foo 为 bar 的依赖,或称 bar 依赖 foo。其次,循环引用的概念是指多个 Bean 之间的依赖关系形成了环。接着上面的例子,如果 baz 依赖 foo 或 bar 都将形成循环依赖。

2301_76607156的博客 1107

spring 解决循环依赖

在看面试题的时候突然想到spring 是怎么解决相互依赖的问题的?模糊不清,赶紧记录下来。 一定要将bean的实例化(beanFactory完成的)和完成bean的创建(ObjectFactory返回的)区分开,bean的实例化仅仅是获得了bean的实例,该bean仍在继续创建之中,之后在该...

196

Spring Boot扩展:Spring 如何处理循环依赖

首先,我们先明确下依赖的定义。如果一个 Bean bar 的属性,引用了容器中的另外一个 Bean foo,那么称 foo 为 bar 的依赖,或称 bar 依赖 foo。其次,循环引用的概念是指多个 Bean 之间的依赖关系形成了环。接着上面的例子,如果 baz 依赖 foo 或 bar 都将形成循环依赖。

2301_76607156的博客 738

被问麻了,Spring 如何处理循环依赖?

点击关注公众号,利用碎片时间学习前言Spring如何处理循环依赖?这是最近较为频繁被问到的一个面试题,在前面Bean实例化流程中,对属性注入一文多多少少对循环依赖有过介绍,这篇文章详细讲一下Spring中的循环依赖的处理方案。什么是循环依赖依赖指的是Bean与Bean之间的依赖关系,循环依赖指的是两个或者多个Bean相互依赖,如:构造器循环依赖代码示例:publiccl...

Java笔记虾 534

【面试常问】Spring 如何处理循环依赖?

Spring如何处理循环依赖?这是最近较为频繁被问到的一个面试题,在前面Bean实例化流程中,对属性注入一文多多少少对循环依赖有过介绍,这篇文章详细讲一下Spring中的循环依赖的处理方案。依赖指的是Bean与Bean之间的依赖关系,循环依赖指的是两个或者多个Bean相互依赖代码示例: 配置文件 Setter循环依赖 代码示例 配置文件 循环依赖包括: 构造器注入循环依赖 set , 注入循环依赖 和 prototype模式Bean的循环依赖。Spring只解决了单例Bean的 sette

mxy_111的博客 461
上一篇: Pthread线程同步总结——APUE学习笔记
下一篇: Spring学习笔记02-Transactional注解原理及失效情况分析
Yancy Piggy
博客等级 码龄14年 27粉丝 22原创
评论
成就一亿技术人!
拼手气红包6.0元
还能输入1000个字符
 
 条评论被折叠 查看
添加红包

请填写红包祝福语或标题

个

红包个数最小为10个

元

红包金额最低5元

当前余额3.43元 前往充值 >
需支付:10.00元
成就一亿技术人!
领取后你会自动成为博主和红包主的粉丝 规则
hope_wisdom
发出的红包
实付元
使用余额支付
点击重新获取
扫码支付
钱包余额 0

抵扣说明:

1.余额是钱包充值的虚拟货币,按照1:1的比例进行支付金额的抵扣。
2.余额无法直接购买下载,可以购买VIP、付费专栏及课程。

余额充值