最近和小伙伴探讨Spring的对象管理问题的时候,讨论到了Spring的循环依赖问题,之前在书上有看到过,但是当时没认真看,忘得一干二净,现在捡起来再学一遍。
我们知道Spring是有一个容器 的概念,但是容器中注入对象的时候,遇到循环依赖注入的情况,Spring是有自己的解决方案的。
首先Spring的循环依赖包括构造器循环依赖和setter循环依赖两种,前者是无法解决的,遇到这种情况Spring会抛出BeanCurrentlyInCreationException异常,这个没啥说的。
下面讲下另一个循环依赖问题Setter问题。
对于setter注入方式的循环依赖,Spring容器是通过提前暴露刚完成构造器注入但未完成其他步骤,如setter注入的Bena方式来解决的,而且只能解决单例作用域的bean的循环依赖问题,通过提前暴露一个单例工厂方法,从而使其他bean能够引用到该bean。
这里先补充下一点前提知识点:https://blog.csdn.net/f641385712/article/details/85067006 这篇文章是讲的beanfactory和factorybean以及objectfactory的区别,讲的很详细,点个赞。
在Spring的抽象类AbstractAutowireCapableBeanFactory中doCreateBean方法中有这么一段代码:
这个地方就是解决循环依赖的开始,如果这个单例对象是提前暴露的单例,即这个对象属于循环依赖的对象,并且需要依赖的对象正在创建中,这是Spring的Bean创建状态,那么就会将一个实现了ObjectFactory的普通工厂类注入到依赖对象中,这个工厂类提供了对正在创建中的需要依赖对象的一个工厂实现。
上面是Spring给的注入单例的源码,针对循环依赖的情况就是调用的第二个方法, 第一个方法就是直接注入对象,第二种前面讲到了因为其属于循环依赖,被依赖对象正在创建状态,所以将ObjcetFactory工厂类导入,当Spring创建完毕这些循环对象后,调用ObjectFactory的getObject方法进行属性注入。这样就解决了循环依赖的问题。