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的一个 ...
随机推荐
- 集成Unity3D到iOS应用程序中
如果想让原生平台(例如 Java/Android.Objective C/iOS 或 Windows Win32/UWP)包含 Unity 功能,可以通过Unity 生成UnityFramework静 ...
- Docker从认识到实践再到底层原理(二-1)|容器技术发展史+虚拟化容器概念和简介
前言 那么这里博主先安利一些干货满满的专栏了! 首先是博主的高质量博客的汇总,这个专栏里面的博客,都是博主最最用心写的一部分,干货满满,希望对大家有帮助. 高质量博客汇总 然后就是博主最近最花时间的一 ...
- Collectors.toMap的暗坑与避免方式
使用Java的stream中的Collectors可以很方便地做容器间的转换,可以少写很多代码.但是其中有暗含的坑需要注意和避免,本文探讨Collectors.toMap(JDK8版本). Colle ...
- Pandas 人口密度案例分析
from turtle import left import pandas as pd """ 需求: 1.导入文件,查看原始数据 2.将人口数据和各州简称数据进行合并 ...
- JS 保姆级贴心,从零教你手写实现一个防抖debounce方法
壹 ❀ 引 防抖在前端开发中算一个基础但很实用的开发技巧,在对于一些高频操作例如监听输入框值变化触发更新之类,会有奇效.除了实际开发,在面试中我们也可能偶遇手写防抖节流的问题,鉴于不同公司考核要求不一 ...
- JS leetcode 移除元素 题解分析
壹 ❀ 引 又到了每日一道算法题的环节,今天做的题同样非常简单,题目来源leetcode27. 移除元素,题目描述如下: 给你一个数组 nums 和一个值 val,你需要 原地 移除所有数值等于 va ...
- Linux下磁盘管理工具:hdparm/iostat/parted/fdiisk/badblocks/smartctl/losetup/sg3_utils/sqinfo/smp_utils/udevadm
一.hdparm: hdparm可以检测,显示与设定IDE,SCSI,SATA,SAS硬盘的硬件参数, 如: hdparm -I /dev/sdc 可以获取sdc的硬件信息 ...
- phpBB3在Nginx反向代理中的X-Forwarded-For IP检查
记录一下phpBB3对反向代理中的IP处理机制 处理几个phpBB3项目迁移, 部分运行场景转移到内网, 需要外网通过nginx/openresty之类的网关反向代理进行访问. 在网关处已经正确配置了 ...
- Python中文件读写操作
1 txt文件 1.1 写操作 import numpy as np def write(fileName,data): file=open(fileName,'w') row,col=data.sh ...
- 易语言读取Mysql表数据
源码下载: https://download.csdn.net/download/IndexMan/12029860 1.界面设计 2.效果展示 3.源码展示 程序集变量: 读取数据按钮: 读取数据子 ...