spring解决循环依赖原理

Spring的Bean的Scope分为Singleton和其它(Prototype,Session等),Singleton支持属性循环依赖,不支持构造函数循环依赖,其它Scope构造函数和属性循环依赖均不支持。

Singleton循环依赖

构造函数循环依赖(无法解决)

假设需要创建A B 两个对象,这两个对象的构造函数参数互相依赖,Spring创建对象过程如下:在执行A的构造函数之前,先将A标记为正在创建中,标记做法为将A的beanName放入singletonsCurrentlyInCreation(一个set)中,当发现A的构造方法的参数需要B时,则解析B,将B标记为正在创建中,然后执行B的构造函数,这时候发现B的构造函数的入参需要A,则解析A,但是这时候通过singletonsCurrentlyInCreation发现A正在创建中,即产生了循环依赖,此时会抛出BeanCurrentlyInCreationException。

属性循环依赖(可以解决)

假设需要创建A B 两个对象,A对象有个b属性依赖B,B对象有个a属性依赖A,Spring创建对象过程如下:先将A标记为正在创建中,标记做法为将beanName放入singletonsCurrentlyInCreation(一个set)中,然后执行A的构造函数,如果执行构造函数成功,则将A放入singletonFactories(一个map,key为A的beanName,value为一个ObjectFactory,后面可以通过ObjectFactory的getObject()方法得到A对象)中,然后进行A对象的属性填充,发现A的b属性依赖B对象,则解析B,首先将B标记为正在创建中,然后执行B的构造函数,之后将B放入singletonFactories,然后进行B对象的属性填充,发现B的a属性依赖A对象,则解析A,这时候发现在singletonFactorie中存在A对象,则通过ObjectFactory的getObject()方法返回A对象的引用,接着B填充属性完成,返回B的引用,A填充属性完成,返回A的引用。

其它Scope循环依赖

构造函数循环依赖(无法解决)

假设需要创建A B 两个对象,这两个对象的构造函数参数互相依赖,Spring创建对象过程如下(Scope为非Singleton):在执行A的构造函数之前,先将A标记为正在创建中,标记做法为将A的beanName放入prototypesCurrentlyInCreation(一个ThreadLocal)中,当发现A的构造方法的参数需要B时,则解析B,将B标记为正在创建中,然后执行B的构造函数,这时候发现B的构造函数的入参需要A,则解析A,但是这时候通过prototypesCurrentlyInCreation发现A正在创建中,即产生了循环依赖,此时会抛出BeanCurrentlyInCreationException。

属性循环依赖(无法解决)

假设需要创建A B 两个对象,A对象有个b属性依赖B,B对象有个a属性依赖A,Spring创建对象过程如下:先将A标记为正在创建中,标记做法为将beanName放入prototypesCurrentlyInCreation(一个ThreadLocal)中,然后执行A的构造函数,执行构造函数成功之后,进行A对象的属性填充,发现A的b属性依赖B对象,则解析B,首先将B标记为正在创建中,然后执行B的构造函数,接着进行B对象的属性填充,发现B的a属性依赖A对象,则解析A,但是这时候通过prototypesCurrentlyInCreation发现A正在创建中,即产生了循环依赖,此时会抛出BeanCurrentlyInCreationException。

评论
添加红包

请填写红包祝福语或标题

红包个数最小为10个

红包金额最低5元

当前余额3.43前往充值 >
需支付:10.00
成就一亿技术人!
领取后你会自动成为博主和红包主的粉丝 规则
hope_wisdom
发出的红包
实付
使用余额支付
点击重新获取
扫码支付
钱包余额 0

抵扣说明:

1.余额是钱包充值的虚拟货币,按照1:1的比例进行支付金额的抵扣。
2.余额无法直接购买下载,可以购买VIP、付费专栏及课程。

余额充值