一个对象引用另一个对象递归注入属性即可实现后续的实例化,同时如果两个或者两个以上的 Bean 互相持有对⽅,最终形成闭环即所谓的循环依赖怎么实现呢属性的互相注入呢?
    

  Spring bean生命周期具体流程如下:

    

  实际与bean实例化及初始化相关的流程如下(单例模式,其他模式不支持循环依赖):

    

    

    

  在DefaultSingletonBeanRegistry类中提供获得单例bean的方法getSingleton:

    

  对于Spring循环依赖使用三级缓存实现:一级singletonObjects一级缓存,存储单例对象,Bean 已经实例化,初始化完成;二级earlySingletonObjects,存储 singletonObject,这个 Bean 实例化了,还没有初始化;三级singletonFactories,存储 singletonFactory。

  实际上Spring在实例化前提前暴露所有需要实例化的Bean,提供BeanDefinition类专注于保存被识别的bean定义。Spring Bean加载全过程(注解配置) - 池塘里洗澡的鸭子 - 博客园 (cnblogs.com)中详细描述了BeanDefinitionMap的生产过程。

  bean定义都有了就剩下实例化,最复杂的莫过于循环依赖,三级缓存具体业务逻辑如下图:

    

  总结: 1)Spring 不⽀持原型 bean 的循环依赖。

     2)单例bean通过setXxx或者@Autowired进⾏循环依赖

  Spring 的循环依赖的理论依据基于 Java 的引⽤传递,当获得对象的引⽤时,对象的属性是可以延后设置的,但是构造器必须是在获取引⽤之前。Spring通过setXxx或者@Autowired⽅法解决循环依赖其实是通过提前暴露⼀个ObjectFactory对象来完成的,简单来说ClassA在调⽤构造器完成对象初始化之后,在调⽤ClassA的setClassB⽅法之前就把ClassA实例化的对象通过ObjectFactory提前暴露到Spring容器中。

 

详解Spring DI循环依赖实现机制的更多相关文章

  1. 用IDEA详解Spring中的IoC和DI(挺透彻的,点进来看看吧)

    用IDEA详解Spring中的IoC和DI 一.Spring IoC的基本概念 控制反转(IoC)是一个比较抽象的概念,它主要用来消减计算机程序的耦合问题,是Spring框架的核心.依赖注入(DI)是 ...

  2. 使用IDEA详解Spring中依赖注入的类型(上)

    使用IDEA详解Spring中依赖注入的类型(上) 在Spring中实现IoC容器的方法是依赖注入,依赖注入的作用是在使用Spring框架创建对象时动态地将其所依赖的对象(例如属性值)注入Bean组件 ...

  3. [跟我学spring学习笔记][DI循环依赖]

    循环依赖 什么是循环依赖? 循环依赖就是循环引用,就是两个或多个Bean相互之间的持有对方. Spring容器循环依赖包括构造器循环依赖和setter循环依赖,那Spring容器如何解决循环依赖呢? ...

  4. 五、spring之DI循环依赖

    什么是循环依赖 循环依赖就是循环引用,就是两个或多个Bean相互之间的持有对方,比如CircleA引用CircleB,CircleB引用CircleC,CircleC引用CircleA,则它们最终反映 ...

  5. 【转】详解spring 每个jar的作用

    spring.jar 是包含有完整发布模块的单个jar 包.但是不包括mock.jar, aspects.jar, spring-portlet.jar, and spring-hibernate2. ...

  6. 浅谈Spring解决循环依赖的三种方式

    引言:循环依赖就是N个类中循环嵌套引用,如果在日常开发中我们用new 对象的方式发生这种循环依赖的话程序会在运行时一直循环调用,直至内存溢出报错.下面说一下Spring是如果解决循环依赖的. 第一种: ...

  7. Java集合详解3:Iterator,fail-fast机制与比较器

    Java集合详解3:Iterator,fail-fast机制与比较器 今天我们来探索一下LIterator,fail-fast机制与比较器的源码. 具体代码在我的GitHub中可以找到 https:/ ...

  8. Spring的循环依赖问题

    spring容器循环依赖包括构造器循环依赖和setter循环依赖,那Spring容器如何解决循环依赖呢?首先让我们来定义循环引用类: 在Spring中将循环依赖的处理分成了3种情况: 构造器循环依赖 ...

  9. applicationContext.xml详解 spring+mybatis+struts

    今天给大家详细解释一项关于Spring的applicationContext.xml文件,这对于初学者来说,应该是很有帮助的, 以下是详解Spring的applicationContext.xml文件 ...

随机推荐

  1. 51 Nod 1091 线段的重叠 (贪心算法)

    原题链接:https://www.51nod.com/onlineJudge/questionCode.html#!problemId=1091 思路分析:通过读题不难发现这是一道涉及贪心算法的题,刚 ...

  2. Java基础(十)——枚举与注解

    一.枚举 1.介绍 枚举类:类的对象只有有限个,确定的.当需要定义一组常量时,强烈建议使用枚举类.如果枚举类中只有一个对象,则可以作为单例模式的实现. 使用 enum 定义的枚举类默认继承了 java ...

  3. python极简教程07:封装、多态和继承

    测试奇谭,BUG不见. 这一场主讲python的面向对象部分--封装.多态和继承. 目的:掌握Python面向对象的三个核心概念. 封装 01 什么是封装? 封装的目的是,保护隐私.通俗的讲:不想让别 ...

  4. [GKCTF2020]EZ三剑客-EzNode&[GYCTF2020]Ez_Express

    写在前面 Nodejs基础一点没有做题还是很难下手的,要学的还很多 [GKCTF2020]EZ三剑客-EzNode 知识点 1.settimeout溢出 2.沙盒逃逸 题解 打开题目,看源代码 app ...

  5. 热词cloud-EChart安装

    1.安装npm install echarts npm install echarts-wordcloud注意版本:echarts版本5只能和wordcloud版本2的一起使用 :echarts版本4 ...

  6. js复制标题和链接

    问题 常常在写博客和作业时候,需要附上参考链接. 希望可以一键得到标题和链接. 解决方案 普通元素 可以使用findid然后复制 但是标题无法使用 <!DOCTYPE html> < ...

  7. linux新分区无法新建文件夹

    问题 因为最初分区480g随便都给了home,后来发现备份以及导出系统至IOS都要另外插硬盘很麻烦.所以需要重新分区.使用装机U盘的live ubuntu20系统使用Gparted分区后,发现回到Ub ...

  8. 针对vue中请求数据对象新添加的属性不能响应式的解决方法

    1.需要给对象添加属性时,不能采用传统的obj.属性=值,obj[属性]=值 来添加属性,在vue页面时需要这样使用 this.$set(obj,"propertyName",&q ...

  9. C++实现switch匹配字符串string(map方法)

    如果语法中大量使用if...else语句会造成代码臃肿,if语句C++语法中switch...case中case只能是整形变量,这里提供了一种思路,用map方法使健与值对应,这样字符串string类型 ...

  10. Telegra.ph | 简洁的文章发布平台

    https://telegra.ph 自由 Telegraph 并不强调内容管理方这一概念,真正做到了「人人都是媒体」.通过 Telegraph 发布的文章,理论上来说不会存在删除的危险,并且由于会产 ...