Spring Bean 的一生
Spring Bean 的一生包括其从创建到消亡的整个过程:
实例创建 => 填充 => 初始化 => 使用 => 销毁。
这里需要注意的是,从 bean 实例的创建到可以使用之间还包括【填充】和【初始化】两个步骤。
AbstractAutowireCapableBeanFactory::createBean:bean 创建核心方法,包含创建、填充 bean 实例及应用 post-processors 等逻辑。
一、实例创建
1、实例化前置处理
InstantiationAwareBeanPostProcessor 为 BeanPostProcessor 子接口,用以提供【创建实例】前后回调处理。
如果有实现 InstantiationAwareBeanPostProcessor 接口,则应用此接口,返回结果如果不为 null,则直接返回作为 bean 实例。
2、doCreateBean
实际用于执行 bean 创建的方法,所有的创建、填充、初始化、注册销毁等逻辑都在此处处理。
BeanWrapper
:Spring 底层 JavaBean 结构核心接口,提供了分析和管理 JavaBean 的相关操作。不直接使用,通常隐式的通过 BeanFactory 或者 DataBinder 来使用。此处执行逻辑即为使用 BeanWrapper 对象。
factoryBeanInstanceCache
:存储 FactoryBean name --> BeanWrapper 键值映射。执行实例创建伊始,会先从 factoryBeanInstanceCache 查询获取,存在则直接获取(获取后删除)使用。
好吧,这里有个问题,为什么会有个 factoryBeanInstanceCache 缓存?
源头在于对单例 FactoryBean 类型操作,getSingletonFactoryBeanForTypeCheck。
创建 bean 实例 createBeanInstance:
优先级顺序:
通过 InstanceSupplier 创建(5.0以后)
通过工厂方法创建
构造函数创建
至此,bean 实例已创建完毕。
此处还有一个 post-processor 处理:MergedBeanDefinitionPostProcessor,用于 bean 定义修改(只针对 RootBeanDefinition:merge 了多个来源 BeanDefinition 的运行时视图)。
3、单例实例提前暴露
为了解决单例循环依赖问题,提前将未完全创建好的单例实例缓存起来。
这里说的未完全创建好是指还不能正常使用。
earlySingletonExposure 条件:
单例:scope 为 “singleton” 或者 ”“。
允许自动处理循环依赖:allowCircularReferences 默认 true
单例 bean 处于创建中:DefaultSingletonBeanRegistry:singletonsCurrentlyInCreation 存储所有处于创建中的 bean 名称。
addSingletonFactory:
将 singletonFactory 添加到 singletonFactories 缓存中,以备解决循环依赖使用。
singletonFactories 是什么呢?
字面意思为单例工厂缓存(bean name -> ObjectFactory ):即所谓的第三级缓存,存储目标 bean 所对应的 bean 工厂对象键值。
那 ObjectFactory 这个对象是怎么获取的呢?
SmartInstantiationAwareBeanPostProcessor::getEarlyBeanReference
SmartInstantiationAwareBeanPostProcessor 是 InstantiationAwareBeanPostProcessor 的扩展接口。
InstantiationAwareBeanPostProcessor 我们说过,是作用在创建实例前后。此处为创建实例后情景。
ObjectFactory 虽名为工厂,其实际为用以在 bean 创建早期,访问相应 bean 的一个引用。
什么是早期呢?
就是这会儿,刚创建完实例,还没有进行相应的填充、初始化等后续操作。
那为什么是暴露个引用,而不是直接给出目标对象呢?
因为目标 bean 可能还会经过其它 post-processors 处理。像 AbstractAutoProxyCreator::getEarlyBeanReference 中的代理逻辑处理。
二、填充
属性填充,作用于 AbstractAutowireCapableBeanFactory::populateBean。
1、属性填充前置处理
continueWithPropertyPopulation:是否继续处理属性填充判断。
这里的说明是在执行属性填充前给予任何 InstantiationAwareBeanPostProcessors 一个机会来变更 bean 的状态。
什么意思呢?
就是 InstantiationAwareBeanPostProcessors 的 postProcessAfterInstantiation 处理,对目标 bean 做相应的变更。
做什么变更呢?
这个节点在 Spring 自动注入操作之前,可以执行个性化的属性注入。同时,方法返回值会赋予 continueWithPropertyPopulation,以决定是否执行后续的逻辑。
这里有一个点需要注意:
如果当前 InstantiationAwareBeanPostProcessors::postProcessAfterInstantiation 返回 false,那么 bean 属性填充步骤则就此终止,不会再执行其它的 InstantiationAwareBeanPostProcessors 及后续的 Spring bean 属性填充过程。
2、属性填充
MutablePropertyValues
PropertyValues 接口的一个实现,提供对属性的各种操作,同时提供相应的构造函数来支持深度复制及基于 Map 的构造。
自动注入方式:按顺序 BY_NAME => BY_TYPE
BY_NAME
autowireByName 根据名称填充
填充什么呢?
unsatisfiedNonSimpleProperties。
什么是 unsatisfiedNonSimpleProperties 呢?
可写的:即拥有写方法。
需要依赖检查的:基于 ignoredDependencyTypes 属性设置判断。
非本身类型的。
非简单类型属性的:属性本身类型及数组元素类型为非简单类型。包括(基本类型及其包装类型,如 int、Integer 等)
注入:
首先根据属性名称判断 bean 存在:
即是否包含在 bean 工厂及外部注册单例 bean。
alias 的,会做相应的名称转换。
存在继承关系的,会级联向上查询。
根据属性名称获取 bean:AbstractBeanFactory::getBean。
属性设置。
注册 bean 依赖:dependentBeanMap beanName -> Set<BeanName>,即记录 bean 及其依赖 bean 关系。
BY_TYPE
autowireByName 根据类型填充。
一个 BeanFactory 里必须恰好只有一个匹配需要类型。
同样,首先获取需要填充的属性:unsatisfiedNonSimpleProperties。
排除 Object 类型属性,填充没有意义。
处理依赖。
属性设置
注册 bean 依赖。
3、依赖检查
依赖检查分为两部分:一个基于 InstantiationAwareBeanPostProcessor::postProcessPropertyValues 处理。一个基于 AbstractBeanDefinition::dependencyCheck 处理。
InstantiationAwareBeanPostProcessor:
对特定的属性进行依赖检查及处理;对特定属性值进行替换,添加或者删除。
如 RequiredAnnotationBeanPostProcessor、 AutowiredAnnotationBeanPostProcessor、CommonAnnotationBeanPostProcessor、MockitoPostProcessor等。
dependencyCheck
检查所有暴露的属性是否都已赋值。
4、属性赋值
将上述处理过的属性值填充到 bean 实例。
三、初始化
应用工厂回调,定义的初始化方法及post-processors。
1、Aware 处理
Aware 代表了各种各样的资源,处理 Aware 即为将相应的资源添加到 bean 实例中。
如 BeanNameAware、BeanClassLoaderAware、BeanFactoryAware 等。
2、BeanPostProcessorsBeforeInitialization
顾名思义,这里的 BeanPostProcessors 是初始化之前的处理。
如 AbstractAdvisingBeanPostProcessor 检查。
3、执行初始化方法
a)实现了 InitializingBean 接口的 bean,执行相应的 afterPropertiesSet 方法。
b)定义了 initMethod 的,触发相应的方法调用。
两者是否可以同时存在呢?
可以,如果同时存在,但是初始化方法名称不能为 afterPropertiesSet。执行顺序为先 a 后 b。
4、BeanPostProcessorsAfterInitialization
同 2,此处为初始化之后的处理。
如 BeanValidationPostProcessor、ApplicationListenerDetector 等。
其实很多 PostProcessor 是既有 Before 处理逻辑,亦有 After 处理逻辑的,此处不再赘述。
四、disposable bean 注册
bean 工厂维护了一个 disposable bean 列表(bean name --> disposable instance)。在工厂关闭销毁时,同时销毁相应的 bean 实例对象。
定义销毁可以通过实现 DisposableBean 或者 AutoCloseable 接口或者自定义销毁方法。
如果使用一个定义了相应销毁方法的对象,又不想其执行销毁方法时怎么办呢?
注解或者配置其销毁方法为空,如:@Bean(destroyMethod = "")。
DestructionAwareBeanPostProcessor:实例销毁前,用户可以自定义执行特定的操作。如:ApplicationListenerDetector 移除相应的 Listener;ScheduledAnnotationBeanPostProcessor 移除定时任务等。