Spring里面Bean的生命周期和循环依赖问题

1. 什么是Spring的循环依赖?

     循环依赖不是我们程序里面的死循环,它是一种对象之间的依赖关系。

2. Spring如何检测循环依赖?

    Spring在创建Bean的时候做一个标记,采用递归进行调用如果发现Bean还在创建中,就说明有循环依赖。

3. Spring循环依赖产生的时机?

    我们知道Spring注入的方式有三种 ,分别是构造方法,属性注入,自动注入,构造方法和属性注入是比较常用的。

    现在这样一个场景,A---》B-- >C ---》A,A依赖B,B依赖C,C依赖A,如果使用构造方法,将会产生错误,错误信息是正在制作的Bean。

   但是使用属性注入的方式,将不会产生错误,这是因为Spring采用构造方法先实例化Bean,然后把它放到对应CurrentHashMap中,但是没有设置属性值。也就是说我们可以得到未设置属性的bean,及可以得到实例化BeanA,但是A依赖B,这样就可以从map里面取出B的实例,这样就可以循环依赖问题。

4. 如何解决Spring循环依赖?

      那么需要在spring源码里面的看createBean() --- 》doCreateBean()方法

     分析:我们得到一个完整实例bean,需要通过上面三个步骤:

             1.  createBeanInstance方法: 得到一个实例bean,但是没有进行属性值的注入

             2.  populateBean方法:就是对bean进行属性值注入。

             3.  initializeBean方法:如果配置文件里面有init方法,需要执行init方法。

           可以看出第一步和第二部比较重要,这里面就是解决bean依赖的关键

     分析:我们可以看出进行createBeanInstance方法,得到了bean实例对象,但是没有属性注入。把没有完全实例化的bean,放到addSinletonFactory方法里面去,这样相当于就是提前暴露bean,接下来addSinletonFactory方法,这里面使用三个Map类型的,及三级缓存来解决循环依赖。接下我们看一下addSingletonFactory方法实现。

分析:这三个Map类型是什么呢?

         singleObjects--》单例对象的cache:一级缓存

          earlySingletonObjects --》提前暴光的单例对象的Cache :二级缓存

         singletonFactories --》单例对象工厂的cache :三级缓存

分析:这就是得到一个未完全实例化的bean,以及得到它的过程。

猜你喜欢

转载自blog.csdn.net/weixin_41629878/article/details/85105175