详解Spring DI循环依赖实现机制


  一个对象引用另一个对象递归注入属性即可实现后续的实例化,同时如果两个或者两个以上的 Bean 互相持有对?,最终形成闭环即所谓的循环依赖怎么实现呢属性的互相注入呢?
    

  Spring bean生命周期具体流程如下:

    

  实际与bean实例化及初始化相关的流程如下(单例模式,其他模式不支持循环依赖):

  在DefaultSingletonBeanRegistry类中提供获得单例bean的方法getSingleton:

  对于Spring循环依赖使用三级缓存实现:一级singletonObjects一级缓存,存储单例对象,Bean 已经实例化,初始化完成;二级earlySingletonObjects,存储 singletonObject,这个 Bean 实例化了,还没有初始化;三级singletonFactories,存储 singletonFactory。

   实际上Spring在实例化前提前暴露所有需要实例化的Bean,提供BeanDefinition类专注于保存被识别的bean定义。Spring Bean加载全过程(注解配置) - 池塘里洗澡的鸭子 - 博客园 (cnblogs.com)中详细描述了BeanDefinitionMap的生产过程。

  bean定义都有了就剩下实例化,最复杂的莫过于循环依赖,三级缓存具体业务逻辑如下图:

   总结: 1)Spring 不?持原型 bean 的循环依赖。

     2)单例bean通过setXxx或者@Autowired进?循环依赖

  Spring 的循环依赖的理论依据基于 Java 的引?传递,当获得对象的引?时,对象的属性是可以延后设置的,但是构造器必须是在获取引?之前。Spring通过setXxx或者@Autowired?法解决循环依赖其实是通过提前暴露?个ObjectFactory象来完成的,简单来说ClassA在调?构造器完成对象初始化之后,在调?ClassAsetClassB?法之前就把ClassA实例化的对象通过ObjectFactory提前暴露到Spring容器中。