spring循环依赖过程
循环依赖过程
A->B B->A
1、doGetBean->getSingleton(A)先从一级缓存单例缓存singletonObjects获取,这个时候为空,
再判断singletonObject == null && isSingletonCurrentlyInCreation(beanName)也不是正在创建单例,故而不能从二级缓存earlySingletonObjects获取
2、第二个获取单例getSingleton(A,createBean(beanName, mbd, args)),beforeSingletonCreation(beanName)把A放入singletonsCurrentlyInCreation缓存中
3、再执行createBean->doCreateBean->createBeanInstance(beanName, mbd, args)
先创建对象beanInstance = getInstantiationStrategy().instantiate(mbd, beanName, this)实例化对象执行构造函数
4、实例化对象后doCreateBean——>addSingletonFactory(beanName, () -> getEarlyBeanReference(beanName, mbd, bean)),把A加入singletonFactories三级缓存中
5、然后doCreateBean -> populateBean(beanName, mbd, instanceWrapper)开始填充对象,这个时候发现有注入了B,然后要先实例化B,开始执行getBean
6、B重复动作1、2、3、发现要注入A,然后A再执行动作1,getSingleton(A)->singletonsCurrentlyInCreation有值然后把A放入二级缓存earlySingletonObjects中,
再把A从singletonFactories三级缓存删除。
7、A此时完成二级缓存earlySingletonObjects中半成本,返回给B,populateBean填充完属性,执行initializeBean初始化对象B,
执行applyBeanPostProcessorsBeforeInitialization(),invokeInitMethods(),applyBeanPostProcessorsAfterInitialization()三部曲,然后完成B的初始化
最后addSingleton()把B加入singletonObjects单例池中,把B从二级缓存earlySingletonObjects删除
8、然后主程序回到A执行的5中,完成了B的填充,A执行initializeBean初始化对象,
执行applyBeanPostProcessorsBeforeInitialization(),invokeInitMethods(),applyBeanPostProcessorsAfterInitialization()三部曲,然后完成B的初始化
最后addSingleton()把A加入singletonObjects单例池中,把A从二级缓存earlySingletonObjects删除
总结:
A->B B->A 过程是: A实例化->B实例化->B初始化->A初始化
1、一级缓存singletonObjects单例池,对象完成初始化时放入
2、二级缓存earlySingletonObjects半成品,提前暴露对象
3、三级缓存singletonFactories,解决循环依赖主要作用
实例化A -> A加入singletonFactories三级缓存中 -> 填充A,发现要注入B ->
实例化B -> B加入singletonFactories三级缓存中 -> 填充B,发现要注入A -> 创建中A加入earlySingletonObjects二级缓存,删除singletonFactories,返回半成品 ->
B拿到A半成品,initializeBean初始化对象 -> B初始化完成 -> B放入singletonObjects单例池,删除earlySingletonObjects
A拿到实例化的B,initializeBean初始化对象 -> A初始化完成 -> A放入singletonObjects单例池,删除earlySingletonObjects
在这个过程中发现B并没有生成earlySingletonObjects二级缓存,主要作用还是singletonFactories三级缓存。
@PostConstruct 、implements InitializingBean、xml配置init-mthon方法,执行顺序是@PostConstruct、InitializingBean、xml 取决代码执行initializeBean初始化对象,
执行applyBeanPostProcessorsBeforeInitialization(),invokeInitMethods(),applyBeanPostProcessorsAfterInitialization()三部曲
spring循环依赖过程的更多相关文章
- 3.3 Spring5源码---循环依赖过程中spring读取不完整bean的最终解决方案
根据之前解析的循环依赖的源码, 分析了一级缓存,二级缓存,三级缓存的作用以及如何解决循环依赖的. 然而在多线程的情况下, Spring在创建bean的过程中, 可能会读取到不完整的bean. 下面, ...
- Spring 循环依赖
循环依赖就是循环引用,就是两个或多个Bean相互之间的持有对方,比如CircleA引用CircleB,CircleB引用CircleC,CircleC引用CircleA,则它们最终反映为一个环.此处不 ...
- Springboot源码分析之Spring循环依赖揭秘
摘要: 若你是一个有经验的程序员,那你在开发中必然碰到过这种现象:事务不生效.或许刚说到这,有的小伙伴就会大惊失色了.Spring不是解决了循环依赖问题吗,它是怎么又会发生循环依赖的呢?,接下来就让我 ...
- Spring 循环依赖的三种方式(三级缓存解决Set循环依赖问题)
本篇文章解决以下问题: [1] . Spring循环依赖指的是什么? [2] . Spring能解决哪种情况的循环依赖?不能解决哪种情况? [3] . Spring能解决的循环依赖原理(三级缓存) 一 ...
- Spring循环依赖的解决
## Spring循环依赖的解决 ### 什么是循环依赖 循环依赖,是依赖关系形成了一个圆环.比如:A对象有一个属性B,那么这时候我们称之为A依赖B,如果这时候B对象里面有一个属性A.那么这时候A和B ...
- 这个 Spring 循环依赖的坑,90% 以上的人都不知道
1. 前言 这两天工作遇到了一个挺有意思的Spring循环依赖的问题,但是这个和以往遇到的循环依赖问题都不太一样,隐藏的相当隐蔽,网络上也很少看到有其他人遇到类似的问题.这里权且称他非典型Spring ...
- Spring — 循环依赖
读完这篇文章你将会收获到 Spring 循环依赖可以分为哪两种 Spring 如何解决 setter 循环依赖 Spring 为何是三级缓存 , 二级不行 ? Spring 为啥不能解决构造器循环依赖 ...
- spring 循环依赖的一次 理解
前言: 在看spring 循环依赖的问题中,知道原理,网上一堆的资料有讲原理. 但今天在看代码过程中,又产生了疑问. 疑问点如下: // 疑问点: 先进行 dependon 判断String[] de ...
- 3.1 spring5源码系列--循环依赖 之 手写代码模拟spring循环依赖
本次博客的目标 1. 手写spring循环依赖的整个过程 2. spring怎么解决循环依赖 3. 为什么要二级缓存和三级缓存 4. spring有没有解决构造函数的循环依赖 5. spring有没有 ...
- Spring循环依赖原理
Spring循环依赖的原理解析 1.什么是循环依赖? 我们使用Spring的时候,在一个对象中注入另一个对象,但是另外的一个对象中也包含该对象.如图: 在Student中包含了teacher的一个 ...
随机推荐
- mac接入两根网线
mac机接了USB扩展槽之后,扩展槽可以接入一根网线,机器自带一个网线口,这样就可以同时接入两根网线,为什么要这样做? 因为我所在的公司是分内外网的,研发的机器是内网环境,而打包机有时候需要联网,那么 ...
- C++ CryptoPP使用AES加解密
Crypto++ (CryptoPP) 是一个用于密码学和加密的 C++ 库.它是一个开源项目,提供了大量的密码学算法和功能,包括对称加密.非对称加密.哈希函数.消息认证码 (MAC).数字签名等.C ...
- C/C++ x64 Inline Hook 代码封装
Hook 技术常被叫做挂钩技术,挂钩技术其实早在DOS时代就已经存在了,该技术是Windows系统用于替代DOS中断机制的具体实现,钩子的含义就是在程序还没有调用系统函数之前,钩子捕获调用消息并获得控 ...
- LyScript 自实现汇编搜索功能
通过对LyScript自动化插件进行二次封装,实现从内存中读入目标进程解码后的机器码,并通过Python代码在这些机器码中寻找特定的十六进制字符数组,或直接检索是否存在连续的反汇编指令片段等功能. 插 ...
- 10、数据库学习规划:MySQL - 学习规划系列文章
MySQL数据库是笔者认识的几个流行的数据库之一.类似于Linux重装系统,其也是开源的,最主要是有很多的社区支持,众多的开发者对其能够进行使用,所以其功能也挺强大,便于使用.通过对MySQL数据库的 ...
- P2216 [HAOI2007] 理想的正方形 题解
题目链接:理想的正方形 比较明显的,我们可以用二维 ST 表解决,具体的二维 ST 表的实现,只需要知道一点: 对于 \(st[i][j][t]=max(i \sim i+2^t,j \sim j+2 ...
- Python Fire:更加灵活的命令行参数
之前介绍过Python的Fire库,一个用来生成命令行工具的的库.请参考:Python Fire:自动生成命令行接口 今天,针对命令行参数,补充两种更加灵活的设置方式. 1. *args 型参数 *a ...
- 19c RAC 告警日志报错 ORA 7445 [pevm_icd_call_common()+225]
问题现象: 在一套2节点的19c RAC 环境下,节点2 alert告警 ORA 7445,且频度固定为每分钟报一次:期间有重启实例,但故障依旧: ========================== ...
- 长沙IT技术圈百万年薪大佬?是否存在?
引子 不知不觉,IT技术圈开始流传起"百万年薪"的故事,有人问我,长沙有百万大佬么?其实我也不知道. 一 背景 长沙自古以来就是文风鼎盛之地,在今天也同样如此. 目前长沙有211. ...
- 从零开始的react入门教程(七),react中的状态提升,我们为什么需要使用redux
壹 ❀ 引 在前面的文章中,我们了解到react中的数据由props与State构成,数据就像瀑布中的水自上而下流动,属于单向数据流.而这两者的区别也很简单,对于一个组件而言,如果说props是外部传 ...