Spring IOC循环依赖问题

什么是循环依赖

循环依赖其实就是循环引用, 也就是两个或者两个以上的Bean互相持有对方,形成闭环,例如:A依赖B,B依赖C,C又依赖于A.

Spring中循环依赖的场景有:

  • 构造器的循环依赖(构造器注入)
  • Field属性的循环依赖(Set注入)

其中,构造器的循环依赖问题是无法解决的,只能抛出异常BeanCurrentlyInCreationException异常,在解决属性循环依赖时.Spring采用的是提前暴露对象的方法. 这也就解决了其中一个依赖的问题,继而解决了循环依赖的问题.

Spring IOC处理循环依赖的方式

在Spring IOC中主要是通过三级缓存机制来处理循环依赖问题.

  • 第一季缓存singletonObjects:单例池(key->beanName, value->Bean)

    • 这个缓存中都是一些已经实例化好的对象,不存在依赖问题.
  • 第二季缓存:earlySingletonObjects(key->beanName, value->Bean)
    • 已经实例化但还没有进行属性注入的Bean,由三级缓存放入.
  • 第三季缓存:singletonFactories(key->beanName, value->ObjectFacotry)
    • singletonFactory.getObject()出来的对象.该对象还未开始依赖或者暂未依赖完全.

示例:ClassA依赖ClassB,ClassB依赖ClassA,这样就构成了循环依赖,Spring IOC的解决方案如下:

Spring IOC解决循环依赖的理论依据是基于Java的引用传递,当获得对象的引用时,对象的属性可以延后设置.

但是,构造器必须时在获取引用之前,Spring通过Set或者@Autowired方法解决循环依赖其实是通过提前暴露一个ObjectFactory对象来完成的,简单来说ClassA在调用构造器完成初始化之后,在调用setClassB方法之前就把ClassA实例化的对象通过ObjectFactory提前暴露到Spring容器中.

  • Spring容器初始化ClassA通过构造器初始化对象后提前暴露到Spring容器中

  • ClassA调用setClassB方法,Spring首先尝试从容器中获取ClassB, 此时ClassB不在Spring容器中
  • Spring容器开始初始化ClassB,同时也会将ClassB提前暴露在Spring容器中
  • ClassB调用setClassA方法,Spring从容器中获取ClassA,因为ClassA已经暴露,此时可以从第三级缓存中获取到ClassA,这样就完成了ClassB的实例化.
  • ClassA这个时候通过Spring容器获取ClassB实例,完成ClassA的实例化.

这个时候,ClassA和ClassB都完成对象的初始化,解决了循环依赖的问题.

什么情况下无法解决循环依赖

  • 单例Bean

    • 构造器注入形成的循环依赖无法解决
    • Set注入形成的循环依赖可以解决
    • @Autowired注解方式注入形成的循环依赖可以解决
  • prototype原型的Bean(多例)
    • 对于原型bean的初始化过程中不论是那种情况产生的循环依赖,Spring都会直接报错处理.

参考: Spring IOC循环依赖问题_蹦跶的蜗牛的博客-CSDN博客_springioc循环依赖Spring IOC循环依赖问题_蹦跶的蜗牛的博客-CSDN博客_springioc循环依赖Spring IOC循环依赖问题_蹦跶的蜗牛的博客-CSDN博客_springioc循环依赖

Spring IOC循环依赖问题相关推荐

  1. Spring IOC循环依赖

    Spring IOC循环依赖 什么是循环依赖 Spring中Bean实例的创建流程 Spring三级缓存 ClassA创建流程 思考 什么是循环依赖 ClassA中依赖ClassB ClassB中依赖 ...

  2. Spring IOC循环依赖解决方案分析

    Spring IOC循环依赖解决方案分析 这里Spring主要用了三层缓存来完成对循环依赖的实现. 下面的属性来源于DefaultSingletonBeanRegistry类 /** Cache of ...

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

    点击关注公众号,利用碎片时间学习 前言 Spring如何处理循环依赖?这是最近较为频繁被问到的一个面试题,在前面Bean实例化流程中,对属性注入一文多多少少对循环依赖有过介绍,这篇文章详细讲一下Spr ...

  4. Spring 如何处理循环依赖?

    Spring 如何处理循环依赖? 文章目录 Spring 如何处理循环依赖? 项目环境 1.什么是循环依赖? 2.Spring 如何来处理循环依赖? 2.1 allowCircularReferenc ...

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

    前言 你是不是被这个骚气的标题吸引进来的,_ 喜欢我的文章的话就给个好评吧,你的肯定是我坚持写作最大的动力,来吧兄弟们,给我一点动力 Spring如何处理循环依赖?这是最近较为频繁被问到的一个面试题, ...

  6. 图解Spring解决循环依赖

    点击上方蓝色"方志朋",选择"设为星标"回复"666"获取独家整理的学习资料! 来源:juejin.cn/post/684490412216 ...

  7. spring 循环依赖_简单说说 Spring 的循环依赖

    作者 | 田伟然 回首向来萧瑟处,归去,也无风雨也无晴. 杏仁工程师,关注编码和诗词. 前言 本文最耗时间的点就在于想一个好的标题, 既要灿烂夺目,又要光华内敛,事实证明这比砍需求还要难! 由于对象之 ...

  8. Spring当中循环依赖很少有人讲,今天让我们来看看吧

    网上关于Spring循环依赖的博客太多了,有很多都分析的很深入,写的很用心,甚至还画了时序图.流程图帮助读者理解,我看了后,感觉自己是懂了,但是闭上眼睛,总觉得还没有完全理解,总觉得还有一两个坎过不去 ...

  9. Spring当中循环依赖很少有人讲,今天一起来学习!

    网上关于Spring循环依赖的博客太多了,有很多都分析的很深入,写的很用心,甚至还画了时序图.流程图帮助读者理解,我看了后,感觉自己是懂了,但是闭上眼睛,总觉得还没有完全理解,总觉得还有一两个坎过不去 ...

最新文章

  1. 要想成功 需要了解的东西
  2. VMware学习使用笔记
  3. Java内置函数的理解和加减乘除四个函数的学习
  4. 停课不停学,大型网课直播翻车现场合集,你别笑,哈哈哈哈哈哈哈哈哈哈哈哈哈哈哈哈哈啊哈...
  5. python假设产品列表如下请首先打印出商品列表_Python列表练习题
  6. (转)iOS 各种控件默认高度(图示)
  7. 程序员常见的坏习惯,你躺枪了吗?
  8. 百度前端学院-基础学院-第四课
  9. hive 时间转字符串_大数据面试杀招——Hive高频考点,还不会的进来挨打
  10. git拉取项目以及提交项目
  11. 人机交互大作业_人机交互专业:多领域交叉的高能学科
  12. aws rds监控慢sql_AWS RDS SQL Server恢复模型,备份和还原
  13. Linux修改时区(tzselect) 【例子:修改时区 为 中国 东8区 的时间】
  14. java 导出word_java导出生成word
  15. matlab无法打开wps的xls文件,WPS无法打开XLS文件怎么办 XLS文件出现异常无法打开怎么处理...
  16. 孩子小学总喜欢用计算机做数学,数学到底该怎样学?真实用!
  17. 歌词big big no_编程的第二个十年:Big Iron
  18. 论文笔记:BahdanauAttention和LuongAttention(注意力机制详解)
  19. 什么是SAP ECC企业控制中心系统 ECC简介
  20. 使用moment计算两个日期的相差天数

热门文章

  1. 5g无线图传信号测试软件,5G时代,移动无线图传网络构架和无线图传传输技术...
  2. 网页制作经典技巧24条
  3. html中title内实现换行
  4. 从瀑布开发模式到敏捷开发模式(scrum)的思路转换
  5. Minecraft Paper 1.18.1 版开服教程,我的世界开服教程,MCSManager9面板使用教程
  6. pandas 入门:DataFrame的创建,读写,插入和删除
  7. python adb开发-adb常见用法
  8. 嵌入式在军工卫星应用手持终端领域的应用
  9. 忧喜交加的宜家,这些年到底错过了什么?
  10. mtp usb驱动 v4.9 最新版