Spring-5-IoC循环依赖

getBean的粗略分步

  • 三个步骤
    • createBeanInstance:实例化
    • populateBean:依赖处理
    • initializeBean:初始化

处理方式

  • 非构造器
    • 在缓存那个地方,有三级缓存架构
      • 一级缓存:singletonObjects
      • 二级缓存:earlySingletonObjects
      • 三级缓存:singletonFactories
    • 在postProcessMergedBeanDefinition之后,populateBean之前,有一个操作DefaultSingletonBeanRegistry.addSingletonFactory,也就是说加入三级缓存
    • 案例:Bean1依赖Bean2,Bean2依赖Bean1;先获取Bean1
    • Bean1在三个缓存中都找不到,创建Bean1,加入三级缓存;populateBean的时候,依赖Bean2,所以先去获取Bean2
    • Bean2在三个缓存中都找不到,创建Bean2,加入三级缓存;populateBean的时候,依赖Bean1,所以又去获取Bean1
    • 首先,一级缓存中没有,isSingletonCurrentlyInCreation为true,进入同步块(这儿采用一级缓存作为同步对象)
    • 然后在二级缓存中查找下Bean1,也没有
    • allowEarlyReference,这个变量什么情况下会变成false???
    • 查找三级缓存,找到了singletonFactory(AbstractAutowireCapableBeanFactory),调用singletonFactory.getObject,得到了不完整的Bean1,加入二级缓存,从三级缓存中移除
    • 那么这个时候,Bean2的依赖注入就可以完成了,虽然里面的Bean1是个不完整的;Bean2先走完getBean
    • 回到Bean1的populateBean中,Bean1的getBean也走完了
    • 这个时候:一级缓存有Bean1和Bean2;二级缓存没有,二级缓存中是什么时候被移除的呢
    • AbstractBeanfactory的mbd.isSingleton()下面的getSingleton(beanName, new ObjectFactory()那里
    • 构造器
      • Bean1在构造器中依赖Bean2,Bean2也在构造器中依赖Bean1,跪
      • Bean1在构造器中依赖Bean2,Bean2在属性依赖Bean1,不会有问题的
        • Bean1在获取构造器参数的时候,会去调用getBean(Bean2),原理上和populateBean是一致的,只是时间点有区别,在createBeanInstance里面
    • prototype也能处理循环依赖吗?how?
    • 你可能感兴趣的:(Spring-5-IoC循环依赖)