一,三级缓存
源码:类DefaultSingletonBeanRegistry
- singletonObjects 一级缓存:负责存储单例bean对象,完备的,属性填充完成的对象。
- earlySingletonObjects 二级缓存:存储提前暴露的对象,对象完成实力化,但是未初始化。
- singletonFactories 三级缓存:存储bean的单例工厂。
我们所创建的对象也是从三级缓存移到一级缓存则完成对象的创建。三级缓存出现的场景是Spring从beanDefinition构建bean对象的过程,其核心方法也是在AbstractBeanFactory的doGetBean方法中。
二,构建bean对象的流程
(1)从三级缓存中获取bean
从源码中可以看出是先从一级缓存查找,没有则从二级缓存中查找,再没有则从三级缓存获取bean的工厂对象,并调用getObject()方法获取bean对象,并将其放入二级缓存,移除三级缓存。
(2)注册当前bean的依赖bean
图中所调用的getBean方法最终也会调用doGetBean方法。
(3)创建bean对象
此处截图中展示了两种bean的创建形式,第一种是我们常说的单例模式,也是会产生循环依赖的地方。
从图中可以看出
createBean是具体的创建方法,点进去可以进入AbstractAutowireCapableBeanFactory.createBean
1). 从BeanDefinition 获取bean的class对象
2). 准备方法重写
3). resolveBeforeInstantiation 代理机会
此处有
applyBeanPostProcessorsBeforeInstantiation方法负责根据class类型构建bean对象,applyBeanPostProcessorsAfterInitialization则提供了bean对象再次处理的机会。
spring容器中的代理对象则是通过此处提供接口实现。
4)doCreateBean 创建bean对象
- 构建bean对象实例
- 允许后处理器修改合并的 Bean 定义。
可以通过实现接口MergedBeanDefinitionPostProcessor修改bean定义 - addSingletonFactory
加入到三级缓存中,提前暴露自身 - 属性填充
- InstantiationAwareBeanPostProcessor
让任何 InstantiationAwareBeanPostProcessor 有机会在设置属性之前修改 Bean 的状态。例如,这可用于支持字段注入样式。
- 属性注入
通过名称或者类型来注入依赖对象,内部通过调用doGetBean方法获取/创建依赖的bean对象;循环依赖
循环依赖: 若此处出现依赖的对象也依赖自身,即所谓的循环依赖现象。
当前对象A在构建bean对象实例之后,立即放入了第三集缓存中,在属性填充中创建的依赖对象B,B在属性填充A的时候,可以直接从第三级缓存中获取A的半成品对象,将其移到二级缓存中,此时B先完成了初始化,并将自身放入一级缓存中。递归回到上一级A属性填充的时刻,此时A获取到了B对象,也完成了初始化,将自身移到了一级缓存中。
- 初始化
- invokeAwareMethods
BeanNameAware,BeanClassLoaderAware,BeanFactoryAware 若bean实现了这三个接口的一个或多个,则回调其实现方法 - applyBeanPostProcessorsBeforeInitialization
调用BeanPostProcessor的前置方法 - invokeInitMethods
InitializingBean的回调方法 - applyBeanPostProcessorsAfterInitialization
调用BeanPostProcessor的后置方法
5)addSingleton
将当前对象加入到一级缓存中
总结:
- 解决三级缓存前提是 对象的创建和初始化要分开,所以不支持构造器注入的循环依赖