Spring解决循环依赖问题-三级缓存

Spring能够轻松的解决属性的循环依赖正式用到了三级缓存,在AbstractBeanFactory中有详细的注释。

Spring解决循环依赖问题-三级缓存

一级缓存:singletonObjects,存放完全实例化属性赋值完成的Bean,直接可以使用。
二级缓存:earlySingletonObjects,存放早期Bean的引用,尚未属性装配的Bean
三级缓存:singletonFactories,三级缓存,存放实例化完成的Bean工厂。

假设A依赖B,B依赖A(注意:这里是set属性依赖)分以下步骤执行:

  • A依次执行doGetBean、查询缓存、createBean创建实例,实例化完成放入三级缓存singletonFactories中,接着执行populateBean方法装配属性,但是发现有一个属性是B的对象。
  • 因此再次调用doGetBean方法创建B的实例,依次执行doGetBean、查询缓存、createBean创建实例,实例化完成之后放入三级缓存singletonFactories中,执行populateBean装配属性,但是此时发现有一个属性是A对象。
  • 因此再次调用doGetBean创建A的实例,但是执行到getSingleton查询缓存的时候,从三级缓存中查询到了A的实例(早期引用,未完成属性装配),此时直接返回A,不用执行后续的流程创建A了,那么B就完成了属性装配,此时是一个完整的对象放入到一级缓存singletonObjects中。
  • B创建完成了,则A自然完成了属性装配,也创建完成放入了一级缓存singletonObjects中。

Spring三级缓存的应用完美的解决了循环依赖的问题,下面是循环依赖的解决流程图。

Spring解决循环依赖问题-三级缓存

上一篇:Spring调用对应参数构造器创建对象


下一篇:SpringBoot —— 复习