博客
关于我
强烈建议你试试无所不能的chatGPT,快点击我
Spring 源码阅读-循环依赖
阅读量:6041 次
发布时间:2019-06-20

本文共 2663 字,大约阅读时间需要 8 分钟。

hot3.png

#Spring 源码阅读-循环依赖

##一. 循环依赖

Spring中产生循环依赖有三种情况

1.构造器循环依赖

代码示例

public class ModelA {private ModelB modelB;public ModelA(ModelB modelB){    this.modelB=modelB;}public ModelB getModelB() {    return modelB;}public void setModelB(ModelB modelB) {    this.modelB = modelB;}}		public class ModelB {private ModelC modelC;public ModelB(ModelC modelc){    this.modelC=modelc;}public ModelC getModelC() {    return modelC;}public void setModelC(ModelC modelC) {    this.modelC = modelC;}}public class ModelC {private ModelA modelA;public ModelA getModelA() {    return modelA;}public void setModelA(ModelA modelA) {    this.modelA = modelA;}public ModelC(ModelA modelA){    this.modelA=modelA;}}//配置文件
//ClientApplicationContext context=new ClassPathXmlApplicationContext ("/spring/spring-mvc.xml");ModelC modelC=(ModelC)context.getBean("modelc");

错误信息 Caused by: org.springframework.beans.factory.BeanCurrentlyInCreationException: Error creating bean with name 'modela': Requested bean is currently in creation: Is there an unresolvable circular reference?

分析

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

1、Spring容器创建“modelA” Bean,首先去“当前创建Bean池”查找是否当前Bean正在创建,如果没发现,则继续准备其需要的构造器参数“modelB”,并将“modelA” 标识符放到“当前创建Bean池”;

2、Spring容器创建“modelB” Bean,首先去“当前创建Bean池”查找是否当前Bean正在创建,如果没发现,则继续准备其需要的构造器参数“modelC”,并将“modelB” 标识符放到“当前创建Bean池”;

3、Spring容器创建“modelC” Bean,首先去“当前创建Bean池”查找是否当前Bean正在创建,如果没发现,则继续准备其需要的构造器参数“modelA”,并将“modelC” 标识符放到“当前创建Bean池”;

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

2.Setter循环依赖

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

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

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

4、最后再依赖注入“modelB”和“modelA”,完成setter注入。

3.prototype循环依赖

//配置文件	 

错误信息 Caused by: org.springframework.beans.factory.BeanCurrentlyInCreationException: Error creating bean with name 'modela': Requested bean is currently in creation: Is there an unresolvable circular reference?

原因

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

转载于:https://my.oschina.net/u/2265027/blog/733097

你可能感兴趣的文章
python3存入redis是bytes
查看>>
laravel 集合接口
查看>>
C/C++二进制读写png文件
查看>>
thymleaf 常用th 标签
查看>>
RTB 广告系统
查看>>
Linux signal 那些事儿(2)【转】
查看>>
InfluxDB安装及配置
查看>>
Dynamics CRM Microsoft SQL Server 指定的数据库具有更高的版本号
查看>>
PAT Perfect Sequence (25)
查看>>
java.exe进程来源排查录
查看>>
点滴记录——Ubuntu 14.04中Solr与Tomcat整合安装
查看>>
C++实现KMP模式匹配算法
查看>>
ubuntu linux下建立stm32开发环境: GCC安装以及工程Makefile建立
查看>>
记录锁
查看>>
JSONObject与JSONArray的使用
查看>>
[SQL Server] 数据库日志文件自动增长导致连接超时的分析
查看>>
【常见Web应用安全问题】---6、Script source code disclosure
查看>>
<html:form>标签
查看>>
除了《一无所有》,我一无所有
查看>>
每日英语:China Seeks to Calm Anxiety Over Rice
查看>>