一文说透 Spring 循环依赖问题
https://zhuanlan.zhihu.com/p/62382615
循环依赖发生的时机
Bean 实例化主要分为三步,如图:

问题出现在:第一步和第二步的过程中,也就是填充属性 / 方法的过程中
Spring 如何解决的
- Spring 为了解决单例的循环依赖问题,使用了 三级缓存 ,递归调用时发现 Bean 还在创建中即为循环依赖
- 单例模式的 Bean 保存在如下的数据结构中:
/** 一级缓存:用于存放完全初始化好的 bean **/
private final Map<String, Object> singletonObjects = new ConcurrentHashMap<String, Object>(256);
/** 二级缓存:存放原始的 bean 对象(尚未填充属性),用于解决循环依赖 */
private final Map<String, Object> earlySingletonObjects = new HashMap<String, Object>(16);
/** 三级级缓存:存放 bean 工厂对象,用于解决循环依赖 */
private final Map<String, ObjectFactory<?>> singletonFactories = new HashMap<String, ObjectFactory<?>>(16);
/**
bean 的获取过程:先从一级获取,失败再从二级、三级里面获取
创建中状态:是指对象已经 new 出来了但是所有的属性均为 null 等待被 init
*/
检测循环依赖的过程如下:
- A 创建过程中需要 B,于是 A 将自己放到三级缓里面 ,去实例化 B
- B 实例化的时候发现需要 A,于是 B 先查一级缓存,没有,再查二级缓存,还是没有,再查三级缓存,找到了!
- 然后把三级缓存里面的这个 A 放到二级缓存里面,并删除三级缓存里面的 A
- B 顺利初始化完毕,将自己放到一级缓存里面(此时B里面的A依然是创建中状态)
- 然后回来接着创建 A,此时 B 已经创建结束,直接从一级缓存里面拿到 B ,然后完成创建,并将自己放到一级缓存里面
- 如此一来便解决了循环依赖的问题
一文说透 Spring 循环依赖问题的更多相关文章
- spring循环依赖问题分析
新搞了一个单点登录的项目,用的cas,要把源码的cas-webapp改造成适合我们业务场景的项目,于是新加了一些spring的配置文件. 但是在项目启动时报错了,错误日志如下: 一月 , :: 下午 ...
- 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循环依赖的博客太多了,有很多都分析的很深入,写的很用心,甚至还画了时序图.流程图帮助读者理解,我看了后,感觉自己是懂了,但是闭上眼睛,总觉得还没有完全理解,总觉得还有一两个坎过不去 ...
- spring 循环依赖的一次 理解
前言: 在看spring 循环依赖的问题中,知道原理,网上一堆的资料有讲原理. 但今天在看代码过程中,又产生了疑问. 疑问点如下: // 疑问点: 先进行 dependon 判断String[] de ...
随机推荐
- Linux 补丁 的简单使用: 制作补丁,打补丁,撤销补丁
背景: 补丁的使用对于嵌入式开发人员来说,在维护或者开发中都比较方便. 制作补丁: diff - 逐行比较文件. 格式: diff 参数 旧文件/旧文件夹 新文件/新文件夹 (注意顺序 新旧文件夹 ...
- 解决使用还原卡的PC在2个月后要重新加入域的问题
客户端正确操作: 1. 启动注册表编辑器. 要这样做, 请依次单击 开始 . 运行 , 类型 regedit 在 打开, 框, 然后单击 确定 . 2. 找到并单击以下注册表子项: HKEY_LOCA ...
- uboot源码分析1-启动第一阶段
1.不简单的头文件包含 #include <config.h>:这个文件的内容其实是包含了一个头文件:#include <configs/x210_sd.h>". # ...
- 012.Oracle数据库,字符串文本大小写转换,转大写,转小写,首字母大写
/*转大写*/ SELECT UPPER(TITLE_EN) FROM ME_EO WHERE ( ISSUE_DATE BETWEEN to_date( '2017-02-04', 'yyyy-MM ...
- ShowDialog()之后,主窗体失去焦点
开发wince的时候遇到这个问题,简单搞定了. ...... form.ShowDialog(); this.focus();
- 移动 web 开发问题和优化小结
1.前言 到目前为止,互联网行业里,手机越来越智能化,移动端占有的比例越来越高,尤其实在电商,新闻,广告,游戏领域.用户要求越来越高,网站功能越来越好,效果越来越炫酷,这就要求我们产品质量越来越高,w ...
- JAVA实现数组的反转--基础
直接上代码 这个算法比较简单,唯一需要注意的就是第8行和第9行.一定要多减去1 因为for循环从0开始,而数组长度是从0到length-1的. class ArrReverse { //实现数组元素的 ...
- kali linux终端快捷键设置
kali里面是没有终端快捷键的,需要自己设置. 打开设置->设备->keyboard,拉到最下面点击加号来新建一个快捷键. 名称:打开终端 命令:gnome-terminal 快捷键:Ct ...
- svn全局设置过滤文件没有作用的解决办法
svn全局设置过滤文件,网上教程文章很多, 都说了怎么配置,没有强调配置内容的格式 导致用惯了git的人,上手配置后,不起作用. 下面是我的配置内容: .classpath .project .set ...
- git commit -m 和 git commit -am 区别
git commit -m 和 git commit -am 通常修改一个文件 并且将文件提交到本地分支的命令是: git add . git commit -m 'update' 以上两个命令其实可 ...