Spring单例竟然出现循环依赖错误??

我们知道Spring只支持单例的循环依赖,循环依赖有二种方式,一种是setter方式,一种是构造器方式,举个例子

 

 

二个类互相依赖,这种方式就是Setter方式的注入循环依赖 然后编写个测试类

 

可以发现是成功的。 那么接下来我们试试构造器的方式

 

 

还是这二个类,但是注入方式改成构造器形式的了,但是这二个类依然还是 单例 然后我们继续在测试类中测试

 

既然报循环依赖的错误???这是为什么???Spring不是说单例是可以解决循环依赖的嘛?????

既然想知道为什么那还是要去看下源码??

首先我们要知道在那个步骤会发生循环依赖。肯定是在类实例话的时候,因为实例化类的时候是需要注入属性的。所以我们直接进入到AbstractAutowireCapaableBeanFactory类的doCreateBean方法中,

 

红色箭头指向的这个方法就是实例化Bean的方法,它有三种方式实例化Bean,一种通过Bean工厂,一种有参数的构造器,一种是无参的构造器。

如果我们的单例子是以Setter方式循环注入的,那么在这里bean通过无参的构造器实例化之后,那么得到的Bean还是没有任何属性的Bean,接下来会一直执行下面这个方法

 

我们看下这个方法的源码

 

这个方法做了什么呢???我相信如果去百度Spring是如何解决循环依赖的那么得到的答案肯定是Spring在类未实例化完全之前(就是还没有进行属性赋值)就把创建这个Bean的ObjectFactory暴露出去。然后供其他类调用。所以这个方法的功能就是做这个的。Spring会将创建这个Bean的Objectfactory保存到缓存中去,也就是doGetBean方法的getSingleton()方法中的三级缓存中的第三层。

在将ObjectFactory暴露出去之后,Spring然后再进行属性注入,也就是populateBean方法,所以在注入属性的时候如果出现循环依赖,那么我们就可以通过暴露出去的ObjectFactory.getObject()获取实例,也就不会发生循环依赖的错误了。这就是为什么Setter方式的循环依赖注入不会报错的原因。

说完了Setter方式现在来说说构造器的循环注入,经过上面分析我们知道实例化一个完全的Bean在这个方法的步骤是:

1:通过构造器实例化(或者工厂方式,构造器有无参和有参二种方式)

2:将创建的Bean的Objectfactory暴露出去,也就是放到缓存中去

3:属性的赋值

在我们的这个例子中,如果通过构造器来进行循环依赖注入,那么在第一步的时候当我们要实例化BoyFriend这个类的时候就需要GirlFriend这个实例,但是在此之前我们还没有将创建bean的ObjectFactory暴露出去,BoyFriend根本就获取不到GirlFriend这个类的实例,哪怕是最原始的Bean。所以就会报循环依赖的错误了。这也就是为什么在Spring中单例只支持Setter方式的循环依赖注入方式。

评论
添加红包

请填写红包祝福语或标题

红包个数最小为10个

红包金额最低5元

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

抵扣说明:

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

余额充值