spring容器循环依赖包括构造器循环依赖和setter循环依赖,那Spring容器如何解决循环依赖呢?首先让我们来定义循环引用类:

在Spring中将循环依赖的处理分成了3种情况:

  1. 构造器循环依赖
  2. setter循环依赖
  3. prototype范围的依赖处理

构造器循环依赖

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

如在创建TestA类时,构造器需要TestB类,那将去创建TestB,在创建TestB类时又发现需要TestC类,则又去创建TestC,最终在创建TestC时发现又需要TestA,从而形成一个环,没办法创建。

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

setter循环依赖

通过setter注入方式构成的循环依赖。对于setter注入造成的依赖是通过Spring容器提前暴露刚完成构造器注入但未完成其他步骤(如setter注入)的bean来完成的,而且只能解决单例作用域的bean循环依赖。通过提前暴露一个单例工厂方法,从而使其他bean能引用到该bean。

  1. Spring容器创建单例"testA"bean,首先根据无参构造器创建bean,并暴露一个"ObjectFactory"用于返回一个提前暴露一个创建中的bean,并将"testA"标识符放到"当前创建bean池",然后进行setter注入"testB"。
  2. Spring容器创建单例"testB"bean,首先根据无参构造器创建bean,并暴露一个"ObjectFactory"用于返回一个提前暴露一个创建中的bean,并将"testB"标识符放到"当前创建bean池",然后进行setter注入"testC"。
  3. Spring容器创建单例"testC"bean,首先根据无参构造器创建bean,并暴露一个"ObjectFactory"用于返回一个提前暴露一个创建中的bean,并将"testC"标识符放到"当前创建bean池",然后进行setter注入"testA"。进行注入"testA"时由于提前暴露了"ObjectFactory"工厂,从而使用它返回提前暴露一个创建中的bean。
  4. 最后再依赖注入"testB"和"testA",完成setter注入。

prototype范围的依赖处理

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

对于"singleton"作用域bean,可以通过"setAllowCircularReferences(false);"来禁用循环引用。

Spring的循环依赖问题的更多相关文章

  1. Spring之循环依赖

    转:http://my.oschina.net/tryUcatchUfinallyU/blog/287936 概述 如何检测循环依赖 循环依赖如何解决 Spring如何解决循环依赖 主要的几个缓存 主 ...

  2. 再谈spring的循环依赖是怎么造成的?

    老生常谈,循环依赖!顾名思义嘛,就是你依赖我,我依赖你,然后就造成了循环依赖了!由于A中注入B,B中注入A导致的吗? 看起来没毛病,然而,却没有说清楚问题!甚至会让你觉得你是不清楚spring的循环依 ...

  3. Spring解决循环依赖

    1.Spring解决循环依赖 什么是循环依赖:比如A引用B,B引用C,C引用A,它们最终形成一个依赖环. 循环依赖有两种 1.构造器循环依赖 构造器注入导致的循环依赖,Spring是无法解决的,只能抛 ...

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

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

  5. Spring的循环依赖,学就完事了【附源码】

    目录 啥是循环依赖? Spring可以解决循环依赖的条件 Spring如何去解决循环依赖 SpringBean的创建流程 Spring维护的三级缓存 getSingleton getSingleton ...

  6. Spring的循环依赖

    本文简要介绍了循环依赖以及Spring解决循环依赖的过程 一.定义 循环依赖是指对象之间的循环依赖,即2个或以上的对象互相持有对方,最终形成闭环.这里的对象特指单例对象. 二.表现形式 对象之间的循环 ...

  7. Spring 的循环依赖问题

    什么是循环依赖 什么是循环依赖呢?可以把它拆分成循环和依赖两个部分来看,循环是指计算机领域中的循环,执行流程形成闭合回路:依赖就是完成这个动作的前提准备条件,和我们平常说的依赖大体上含义一致.放到 S ...

  8. 详解Spring DI循环依赖实现机制

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

  9. 【spring源码分析】spring关于循环依赖的问题

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

随机推荐

  1. javascript单例模式的理解

    javascript单例模式的理解 阅读目录 理解单例模式 使用代理实现单例模式 理解惰性单例 编写通用的惰性单例 单例模式使用场景 回到顶部 理解单例模式 单例模式的含义是: 保证一个类只有一个实例 ...

  2. C#常用函数--通用篇

    C#常用函数→通用篇转载地址→http://www.cnblogs.com/superfang/archive/2008/07/02/1233706.html以前我都是"原文地址" ...

  3. codevs1080线段树练习

    题目描述 Description 一行N个方格,开始每个格子里都有一个整数.现在动态地提出一些问题和修改:提问的形式是求某一个特定的子区间[a,b]中所有元素的和:修改的规则是指定某一个格子x,加上或 ...

  4. Linux 在 i 节点表中的磁盘地址表中,若一个文件的长度是从磁盘地址表的第 1 块到第 11 块 解析?

    面试题: 在 i 节点表中的磁盘地址表中,若一个文件的长度是从磁盘地址表的第 1 块到第 11块,则该文件共占有 B  块号.A 256 B 266 C 11 D 256×10 linux文件系统是L ...

  5. chrome打开本地文件目录

    chrome地址栏输入: file:///

  6. POJ 3083

    ---恢复内容开始--- http://poj.org/problem?id=3083 题目大意就是给你要你从S走到E,且只有.代表的地方才是可以走的,有三种方式的走法. 一.是向左优先转,从S到E的 ...

  7. 63.如何对单链表进行快排?和数组快排的分析与对比[quicksort of array and linked list]

    [本文链接] http://www.cnblogs.com/hellogiser/p/quick-sort-of-array-and-linked-list.html [题目] 单链表的特点是:单向. ...

  8. HTML标签自定义属性(转)

    HTML标签可以自定义属性 HTML标签可以自定义属性,但是我们要考虑其在IE.Firefox以及chrome下的兼容性问题.例如: <div id="newTest" my ...

  9. register

    register:这个关键字请求编译器尽可能的将变量存在CPU内部寄存器中,而不是通过内存寻址访问,以提高效率.注意是尽可能,不是绝对.你想想,一个CPU 的寄存器也就那么几个或几十个,你要是定义了很 ...

  10. Android之自定义控件深入

    本文主要讲述两个知识点:popwindow的使用和通过继承View实现一个自定义控件,实现点击,手动按钮的效果. popwindow的使用 //定义 popupWindow popWin = new ...