什么是循环依赖

循环依赖就是循环引用,就是两个或多个Bean相互之间的持有对方,比如CircleA引用CircleB,CircleB引用 CircleC,CircleC引用CircleA,则它们最终反映为一个环。此处不是循环调用,循环调用是方法之间的环调用。如图

循环调用是无法解决的,除非有终结条件,否则就是死循环,最终导致内存溢出错误。

Spring容器循环依赖包括构造器循环依赖和setter循环依赖,那Spring容器如何解决循环依赖呢?

首先让我们来定循环引用类:

Spring如何解决循环依赖

一、构造器循环依赖:

表示通过构造器注入构成的循环依赖,此依赖是无法解决的,只能抛出 BeanCurrentlyInCreationException异常表示循环依赖

问题所在:

如在创建CircleA类时,构造器需要CircleB类,

那将去创建CircleB,在创建CircleB类时又发现需要CircleC类,

则又去 创建CircleC,最终在创建CircleC时发现又需要CircleA;从而形成一个环,没办法创建。

Spring容器将每一个正在创建的Bean 标识符放在一个“当前创建Bean池”中,Bean标识符在创建过程中将一直保持 在这个池中,因此如果在创建Bean过程中发现自己已经在“当前创建Bean池”里时将抛出 BeanCurrentlyInCreationException异常表示循环依赖;而对于创建完毕的Bean将从“当前创建Bean池”中清除掉。

1)首先让我们看一下配置文件(circleInjectByConstructor.xml):

2)写段测试代码

让我们分析一下吧:

1、Spring容器创建“circleA” Bean,首先去“当前创建Bean池”查找是否当前Bean正在创建,如果没发现,则 继续准备其需要的构造器参数“circleB”,

并将“circleA” 标识符放到“当前创建Bean池”;

2、Spring容器创建“circleB” Bean,首先去“当前创建Bean池”查找是否当前Bean正在创建,如果没发现,则 继续准备其需要的构造器参数“circleC”,

并将“circleB” 标识符放到“当前创建Bean池”;

3、Spring容器创建“circleC” Bean,首先去“当前创建Bean池”查找是否当前Bean正在创建,如果没发现,则继续 准备其需要的构造器参数“circleA”,

并将“circleC” 标识符放到“当前创建Bean池”;

4、到此为止Spring容器要去创建“circleA”Bean,发现该Bean 标识符在“当前创建Bean池”中,因为表示循环依 赖,抛出BeanCurrentlyInCreationException。

二、setter循环依赖

表示通过setter注入方式构成的循环依赖。

对于setter注入造成的依赖是通过Spring容器提前暴露刚完成构造器注入但未完成其他步骤(如setter注入)的Bean来完成的,而且只能解决单例作用域的Bean循环依赖。

如下代码所示,通过提前暴露一个单例工厂方法,从而使其他Bean能引用到该Bean。

具体步骤如下:

1、Spring容器创建单例“circleA” Bean,首先根据无参构造器创建Bean,并暴露一个“ObjectFactory ”用于 返回一个提前暴露一个创建中的Bean,并将“circleA” 标识符放到“当前创建Bean池”;然后进行setter注入 “circleB”;

2、Spring容器创建单例“circleB” Bean,首先根据无参构造器创建Bean,并暴露一个“ObjectFactory”用于 返回一个提前暴露一个创建中的Bean,并将“circleB” 标识符放到“当前创建Bean池”,然后进行setter注入 “circleC”;

3、Spring容器创建单例“circleC” Bean,首先根据无参构造器创建Bean,并暴露一个“ObjectFactory ”用于 返回一个提前暴露一个创建中的Bean,并将“circleC” 标识符放到“当前创建Bean池”,然后进行setter注入 “circleA”;进行注入“circleA”时由于提前暴露了“ObjectFactory”工厂从而使用它返回提前暴露一个创建中的 Bean;

4、最后在依赖注入“circleB”和“circleA”,完成setter注入。

对于“prototype”作用域Bean,Spring容器无法完成依赖注入,因为“prototype”作用域的Bean,Spring容 器不进行缓存,因此无法提前暴露一个创建中的Bean。

对于“singleton”作用域Bean,可以通过“setAllowCircularReferences(false);”来禁用循环引用:

第三章 3.2 DI依赖循环 --《跟我学Spring》笔记 张开涛相关推荐

  1. c语言循环程序设计教案,10 《C语言程序设计》教案 第三章 程序的控制结构(6)—循环结构 while和do while.doc...

    10 <C语言程序设计>教案 第三章 程序的控制结构(6)-循环结构 while和do while.doc C 语言程序设计课程教案表 授课题目 第三章 程序的控制结构 (6) 循环结构 ...

  2. python第三章上机实践_《机器学习Python实践》读书笔记-第三章

    <机器学习Python实践>,第三章,第一个机器学习项目 以往目录:橘猫吃不胖:<机器学习Python实践>读书笔记-第一章​zhuanlan.zhihu.com 书中介绍了一 ...

  3. 第三章--Spring5.X与日志框架的整合以及Spring注入(injection)

    Spring与日志框架进行整合,日志框架就可以在控制台中,输出Spring框架运行过程中的一些重要的信息. 好处:便于了解Spring框架的运行过程,利于程序的调试. Spring如何整合日志框架 默 ...

  4. Java第三章习题3-4(for循环输出俄文字母表)

    Letter.java /** To change this template, choose Tools | Templates* and open the template in the edit ...

  5. c#面向对象与程序设计第三版第三章例题代码_C#程序设计教程 | 教与学(教学大纲)...

    <C#程序设计教程>课程教学大纲 执笔人:xxx,xxx,xxx 编写日期:年 月 一.课程基本信息 1.课程名称:C#程序设计教程 2.课程编号: 3.课程体系/类别: 4.课程性质: ...

  6. 【第三章】 C语言之牛客网刷题笔记 【点进来保证让知识充实你一整天】

  7. 【JAVA SE】第三章 运算符、条件语句、switch结构、while循环、do…while循环、for循环、break关键字以及break和continue关键字

    第三章 运算符.条件语句.switch结构.for循环.break关键字以及break和continue关键字 文章目录 第三章 运算符.条件语句.switch结构.for循环.break关键字以及b ...

  8. 沈阳师范大学大一上册C语言PTA题目集以及答案(第三章 循环结构程序设计 编程题篇)

    沈阳师范大学大一上册C语言PTA题目集以及答案(第三章 循环结构程序设计 编程题篇) 7-1 求阶乘序列前N项和 (15分) 本题要求编写程序,计算序列 1!+2!+3!+⋯ 的前N项之和. 输入格式 ...

  9. 手写Spring DI依赖注入,嘿,你的益达!

    手写DI 提前实例化单例Bean DI分析 DI的实现 构造参数依赖 一:定义分析 二:定义一个类BeanReference 三:BeanDefinition接口及其实现类 四:DefaultBean ...

  10. 第三章 8086微处理器

    目录 第三章 8086微处理器... 2 3.2 8086的存储器组织... 2 3.2.1寻址空间和数据存储格式... 2 3.2.2存储器的分段结构和物理地址形成... 3 3.3 8086微处理 ...

最新文章

  1. 京东API网关实践之路!
  2. AI公共政策成全球热点,美国ITI发布《人工智能政策原则》|AI观察
  3. 第二阶段小组冲刺第五天总结
  4. Shoppica OpenCart 商城自适应主题模板 ABC-0002
  5. Java配置多数据源access,java联接MS ACCESS,无需配置数据源
  6. mysql的配置和启动命令
  7. 使用MyBatis的Generator自动创建实体类和dao的接口与xml
  8. Linux的pcel问题-bash: pecl: command not found
  9. 纳税服务系统八【系统、子系统首页】
  10. 上汽乘用车-大数据岗位面试(失败经历)
  11. 程序在发布前就应该发现的一些错误
  12. 第四周作业(基础题)
  13. Cortex M3/M4 学习摘要(一)
  14. 区块链教程Fabric1.0源代码分析MSP成员关系服务提供者一
  15. ZigBee研究之旅(三)---CC2530的电源管理模块
  16. python 使用百度搜索推广API,获取账户基本信息
  17. 基于Canvas+React的高性能Table表格
  18. 乐观锁和悲观锁的含义-实现方式-应用场景
  19. 【尚硅谷Java笔记+踩坑】Git(分布式版本控制工具)
  20. java获取微秒时间,java获取当前时间微秒

热门文章

  1. java 读写acr122u_使用ACR122U 从NTAG203Chip 读取数据
  2. 最新!华为HCIA网络工程师题库精讲(01)
  3. idea 读取md文件卡死
  4. 程序员面试宝典(第三版).pdf
  5. 《编程之美》---求二叉树中节点的最大距离
  6. secureCRT 下载使用
  7. 如何在windows下把硬盘格式化成EXT3格式?
  8. qq机器人升级最新教程
  9. 怎么完全卸载赛门铁克_如何干净彻底卸载诺顿?
  10. 更改计算机睡眠时间注册表,如何通过修改注册表开启/关闭系统休眠?