Spring怎么解决循环依赖问题?

1.什么是循环依赖?

循环依赖是指一个或多个对象之间存在直接或间接的依赖关系,这种依赖关系构成一个环形调用 , 举个例子 : A 依赖B , B依赖C , C依赖A , 这样就形成了循环依赖;

 

2.spring对循环依赖的处理有三种情况:

①构造器的循环依赖:这种依赖spring是处理不了的,直接拋出BeanCurrentlyInCreationException异常。
②单例模式下的setter循环依赖:通过"三级缓存”处理循环依赖。
③非单例循环依赖:无法处理。

三级缓存的执行逻辑

  • 先从“第一级缓存”找对象,有就返回,没有就找“二级缓存”
  • 找“二级缓存”,有就返回,没有就找“三级缓存”
  • 找“三级缓存”,找到了,就获取对象,放到“二级缓存”,从“三级缓存”移除

3.下面分析单例模式下的setter循环依赖如何解决

Spring的单例对象的初始化主要分为三步:

(1)createBeanInstance:实例化,其实也就是调用对象的构造方法实例化对象

(2)populateBean:填充属性,这一步主要是多bean的依赖属性进行填充

(3)initializeBean:调用spring xml中的init 方法.

从上面讲述的单例bean初始化步骤我们可以知道,循环依赖主要发生在第一,第二部.也就是构造器循 环依赖和field循环依赖.

 举例:A的某个field或者setter依赖了B的实例对象,同时B的某个field或者setter依赖了A的实例对象”这种循环依赖的情况.

A首先完成了 初始化的第一步(createBeanINstance实例化),并且将自己提前曝光到singletonFactories中.

此时进行初始化的第二步,发现自己依赖对象B,此时就尝试去get(B),发现B还没有被create,所以走 create流程,B在初始化第一步的时候发现自己依赖了对象A,于是尝试get(A),尝试一级缓存 singletonObjects(肯定没有,因为A还没初始化完全),尝试二级缓存earlySingletonObjects(也没 有),尝试三级缓存singletonFactories,由于A通过ObjectFactory将自己提前曝光了,所以B能够通过 ObjectFactory.getObject拿到A对象(虽然A还没有初始化完全,但是总比没有好呀),B拿到A对象后顺利 完成了初始化阶段1,2,3,完全初始化之后将自己放入到一级缓存singletonObjects中.

此时返回A中,A此时能拿到B的对象顺利完成自己的初始化阶段2,3,最终A也完成了初始化,进去了 一级缓存singletonObjects中,而且更加幸运的是,由于B拿到了A的对象引用,所以B现在hold住的A对 象完成了初始化.

热门相关:如果能少爱你一点   嫡嫁千金   重生之将门毒后   慕少,你老婆又重生了   名门盛婚:首席,别来无恙!