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. ThinkPHP自动获取关键词(调用第三方插件)

    ThinkPHP自动获取关键词调用在线discuz词库 先按照下图路径放好插件 方法如下 /** * 自动获取关键词(调用第三方插件) * @return [type] [description] * ...

  2. Oulipo (kmp)

    Oulipo Time Limit: 1000MS   Memory Limit: 65536K Total Submissions: 26857   Accepted: 10709 Descript ...

  3. cocos2d调度器(定时执行某函数)

    调度器(scheduler) 继承关系 原理介绍 Cocos2d-x调度器为游戏提供定时事件和定时调用服务.所有Node对象都知道如何调度和取消调度事件,使用调度器有几个好处: 每当Node不再可见或 ...

  4. ZeroMQ(java)中监控Socket

    基本上ZeroMQ(java)中基本的代码都算是过了一遍了吧,不过觉得它在日志这一块貌似基本没有做什么工作,也就是我们通过日志来知道ZeroMQ都发生了什么事情.. 而且由于ZeroMQ中将连接的建立 ...

  5. 百度图片爬虫-python版-如何爬取百度图片?

    上一篇我写了如何爬取百度网盘的爬虫,在这里还是重温一下,把链接附上: http://www.cnblogs.com/huangxie/p/5473273.html 这一篇我想写写如何爬取百度图片的爬虫 ...

  6. Vmware怎样使用nat和桥接方式解决虚拟机联网问题

    对于很多的linux初学者来说,最开始学习linux时通常是在虚拟机上进行的,然而对于新手来说虚拟机联网会对他们来说是比较困难的.这里我根据自己的经验写了一篇文档分享给大家.下面对几种连接方式进行简单 ...

  7. Centos 7 安装LAMP环境

    一.安装Centos 官网下载Centos 7刻录成光盘后安装 二.安装apache yum install httpd #根据提示,输入Y安装即可成功安装 systemctl start httpd ...

  8. poj3026(bfs+prim)

    The Borg is an immensely powerful race of enhanced humanoids from the delta quadrant of the galaxy. ...

  9. HDOJ 1875

    畅通工程再续 Time Limit: 2000/1000 MS (Java/Others)    Memory Limit: 32768/32768 K (Java/Others) Total Sub ...

  10. BZOJ 1058

    服气!我果然就是个傻逼. 傻兮兮地感觉两个数之间的差距无需删除一些答案,妈个鸡就只加入了一些新的答案忘记了去掉无效的答案.我果然是傻逼,经验不足脑子笨... 这么水的题...不说了,说多了都是泪. 自 ...