spring循环依赖过程
循环依赖过程
A->B B->A
1、doGetBean->getSingleton(A)先从一级缓存单例缓存singletonObjects获取,这个时候为空,
再判断singletonObject == null && isSingletonCurrentlyInCreation(beanName)也不是正在创建单例,故而不能从二级缓存earlySingletonObjects获取
2、第二个获取单例getSingleton(A,createBean(beanName, mbd, args)),beforeSingletonCreation(beanName)把A放入singletonsCurrentlyInCreation缓存中
3、再执行createBean->doCreateBean->createBeanInstance(beanName, mbd, args)
先创建对象beanInstance = getInstantiationStrategy().instantiate(mbd, beanName, this)实例化对象执行构造函数
4、实例化对象后doCreateBean——>addSingletonFactory(beanName, () -> getEarlyBeanReference(beanName, mbd, bean)),把A加入singletonFactories三级缓存中
5、然后doCreateBean -> populateBean(beanName, mbd, instanceWrapper)开始填充对象,这个时候发现有注入了B,然后要先实例化B,开始执行getBean
6、B重复动作1、2、3、发现要注入A,然后A再执行动作1,getSingleton(A)->singletonsCurrentlyInCreation有值然后把A放入二级缓存earlySingletonObjects中,
再把A从singletonFactories三级缓存删除。
7、A此时完成二级缓存earlySingletonObjects中半成本,返回给B,populateBean填充完属性,执行initializeBean初始化对象B,
执行applyBeanPostProcessorsBeforeInitialization(),invokeInitMethods(),applyBeanPostProcessorsAfterInitialization()三部曲,然后完成B的初始化
最后addSingleton()把B加入singletonObjects单例池中,把B从二级缓存earlySingletonObjects删除
8、然后主程序回到A执行的5中,完成了B的填充,A执行initializeBean初始化对象,
执行applyBeanPostProcessorsBeforeInitialization(),invokeInitMethods(),applyBeanPostProcessorsAfterInitialization()三部曲,然后完成B的初始化
最后addSingleton()把A加入singletonObjects单例池中,把A从二级缓存earlySingletonObjects删除
总结:
A->B B->A 过程是: A实例化->B实例化->B初始化->A初始化
1、一级缓存singletonObjects单例池,对象完成初始化时放入
2、二级缓存earlySingletonObjects半成品,提前暴露对象
3、三级缓存singletonFactories,解决循环依赖主要作用
实例化A -> A加入singletonFactories三级缓存中 -> 填充A,发现要注入B ->
实例化B -> B加入singletonFactories三级缓存中 -> 填充B,发现要注入A -> 创建中A加入earlySingletonObjects二级缓存,删除singletonFactories,返回半成品 ->
B拿到A半成品,initializeBean初始化对象 -> B初始化完成 -> B放入singletonObjects单例池,删除earlySingletonObjects
A拿到实例化的B,initializeBean初始化对象 -> A初始化完成 -> A放入singletonObjects单例池,删除earlySingletonObjects
在这个过程中发现B并没有生成earlySingletonObjects二级缓存,主要作用还是singletonFactories三级缓存。
@PostConstruct 、implements InitializingBean、xml配置init-mthon方法,执行顺序是@PostConstruct、InitializingBean、xml 取决代码执行initializeBean初始化对象,
执行applyBeanPostProcessorsBeforeInitialization(),invokeInitMethods(),applyBeanPostProcessorsAfterInitialization()三部曲