Bean创建流程
- 获取对象的BeanDefinition
- 通过反射创建空对象
- 填充属性
- 调用init方法
Bean创建关键方法(按顺序)
- getBean
- doGetBean
- createBean
- doCreateBean
- createBeanInstance
- populateBean
解决循环依赖:三级缓存
循环依赖原因
单例,每个类只有一个对象。A引用B,B又引用A。创建A时,需要把B塞入A中,此时B还没有创建,需要创建B。但B创建又需要A,形成一个死循环。
流程
doGetBean -> getSingleton
- 从一级缓存singletonObjects拿A,拿不到,需要创建A
- 将A放入Set: singletonsCurrentlyInCreation
- 实例化A
- createBean -> doCreateBean (A)
- doGetBean (B)
- createBean -> doCreateBean (A)
- 将A从Set: singletonsCurrentlyInCreation中删除
- 将A放入一级缓存singletonObjects,同时从二级缓存、三级缓存中删除
- 结束
doCreateBean
- 反射创建A对象
- 若A在Set: singletonsCurrentlyInCreation里,则放入三级缓存singletonFactories
- populateBean A,填充A属性
- applyPropertyValues -> resolveValueIfNecessary (此时B是RuntimeBeanReference) -> resolveReference -> beanFactory.getBean -> doGetBean (B)
- 依次从一级缓存 -> 二级缓存 尝试拿A,拿到A
- 结束
关键差异流程
- 当B getSingleton(A) 时,从三级缓存里拿A的ObjectFactory(此时A已经在三级缓存里)
- 一旦从三级缓存中能拿到值,则立马调用从三级缓存中取出来的ObjectFactory.getObject,并把生成出的半成品放入二级缓存earlySingletonObjects中,最后从三级缓存中删去
学习到的代码知识
- SetFromMap 用于借助ConcurrentHashMap来实现线程安全的Set