一:循环依赖介绍
首先来看下spring官网有关于spring的IOC容器里关于循环依赖的描述
一:spring的三级缓存
- 一级缓存(也叫单利池)singletonObjects:存放已近经历了完整周期的Bean对象
- 二级缓存earlySingletonObjects:存放早期暴露出来的Bean对象,Bean的生命周期未结束
- 三级缓存singletonFactories:存放可以生成的Bean的工厂
只有单利的bean会通过三级缓存提前暴露来解决循环依赖的问题。而非单利的bean,每次从容器中获取都是一个新的对象,都会重新创建,所以非单利的bean是没有缓存的。
利用三级缓存解决循环依赖的基本思路:
三:源码分析
容器的初始化: this.finishBeanFactoryInitialization(beanFactory);
- 获取Singleton
从一级缓存里获取缓存
- createBean第一次没有从缓存里获取到缓存 sharedInstance==null,所以开始创建Bean
doCreateBean开始干活了
缓存利用起来了!一级缓存没有,先singletonFactory造出来放入三级缓存(缺啥造啥),然后从二级缓存中删除,这个时候二级缓存里跟没有东西,所以是一个空删
- 填充属性:populateBean
未完待续...
四: 为什么不用两级缓存,而使用三级缓存呢?
基本步骤:
- 创建A对象初始化完成后,会执行后置处理器创建动态代理a,同时在工厂池中创建Factory(a),这个Factory(a)只有A被引用的时候才会做前置处理
- 给B填充属性的时候引用A,这个时候将动态代理a放入半成品中,然后将半成品a填充到B中去
- 然后B进行后置处理
- B进行后置处理后将动态代理b放入单利池中,这个时候也添加一个Factory(b)到工厂池中
- 当A应用B的时候,直接在单利池中拿b就行了
- 当A再次初始化之后再去执行动态代理,但是这个时候半品池中已经有了动态代理a,所以就没必要要去调用动态代理去创建a了,只需要将半成品池中的a移动到单利池中去,最后删除工厂池中的Factory(a)