spring的循环依赖(4)循环依赖的解决(源码级二)

上篇文章说到我们spring在创建bean的过程中经过一系列的调用,会执行到getBean方法去创建bean。而在创建bean的过程中我们又会对bean中依赖的其他bean进行注入。在注入的过程中发现需要注入的bean在我们的容器中没有,也就是说还没有被创建出来。这时候就会又调用getBean去创建我们需要注入的bean。现在我们假设有A类和B类,他们相互进行了依赖。那么我们上一篇的分析就创建A类。还没有创建完成,发现A类需要注入B类,又发现容器中没有B类。于是调用getBean,要去创建B类。
上次我们分析到这里,现在接着往下分析。
在这里插入图片描述
将getBean点进去发现是调用了doGetBean,这就和我们上篇文章一样了,上篇文章也有这个方法。只不过我们的name值不一样了。假设上次传的是A,那么这次要去创建B了,就应该传的是B
在这里插入图片描述
由于中间过程和上篇文章一样,只是传的参数有A变成了B,此处不再一一介绍了。直到调用populateBean(beanName, mbd, instanceWrapper);
在这里插入图片描述
这里需要填充的属性是B类的属性,而B里面有个属性是A。由于A我们刚刚创建一半,还没有放到容器中所以,在这里注入A的时候仍然拿不到A的实例。就会和上篇一样经历一系列调用最终又调用到getBean
在这里插入图片描述
而这个时候传的bean又变回了A,这时就又回到了doGetBean方法。我们重点看这个方法。
里面getSingleton(beanName);点进去。
看着似乎比较复杂,细细看来里面的变量我们又似乎见过
在这里插入图片描述
还记得上篇文章的这张图吗?
其实singletonObjects就是我们所说的一级缓存,我们在这里曾经把我们需要创建的实例放到singletonFactories集合中value是一个代码块。当singletonObjects等于空的时并且是正在创建中时就会进入if里,经过三次的getBean调用,又回到了我们刚开始调用getBean创建的对象,其中有一步往singletonsCurrentlyInCreation集合中放对象表示我们的对象正在创建中
进入if里earlySingletonObjects中取数据,之前我们也remove过,肯定是个null。然后取出我们放在singletonFactories中的代码块取执行,其实就是生产我们的bean,放到earlySingletonObjects中。于是singletonFactories的使命已经完成了,就从中移除掉。
在这里插入图片描述
在这里插入图片描述
doGetBean拿到返回singletonObject对象(其实就是A实例的半成品),就说明这个对象创建存在了,将这个对象注入到B类的属性中,这样B类就完成了属性的注入。接下来就是B类的一些其他操作,最终创建完成放入容器中。随着B类的完成,那么创建A类时调用的getBean方法也完成了,也就是我们上篇提到的第二次调用的getBean完成,并返回实例。然后第一次调用的getBean就可以继续往下执行。最终A类也创建完成了。
到这里spring的循环依赖就完美的解决了,小伙伴们有木有理解呢?没有理解的也没关系,多看几遍,深入思考,相信你一定能够理解的。毕竟作者也是看了好几遍才有这么一点点的理解和总结。spring框架可谓是把java运用的非常完美。让我们一起学习更深奥的spring吧。

  • 0
    点赞
  • 1
    收藏
    觉得还不错? 一键收藏
  • 0
    评论

“相关推荐”对你有帮助么?

  • 非常没帮助
  • 没帮助
  • 一般
  • 有帮助
  • 非常有帮助
提交
评论
添加红包

请填写红包祝福语或标题

红包个数最小为10个

红包金额最低5元

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

抵扣说明:

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

余额充值