## 第九章:Spring Bean生命周期(Bean Lifecycle)
### Spring Bean 元信息配置阶段
BeanDefinition 配置
- 面向资源
- XML 配置
- Properties 资源配置
- 面向注解
- 面向 API
### Spring Bean 元信息解析阶段
BeanDefinition 解析
- 面向资源 BeanDefinition 解析 -BeanDefinitionReader
- XML 解析器 - `XmlBeanDefinitionReader`
- Properties 解析器 - `PropertiesBeanDefinitionReader`
- 面向注解 BeanDefinition 解析 - `AnnotatedBeanDefinitionReader`
### Spring Bean 注册阶段
BeanDefinition 注册接口 --- BeanDefinitionRegistry
### Spring BeanDefinition 合并阶段
BeanDefinition 合并
父子 BeanDefinition 合并
- 当前 BeanFactory 查找
- 层次性 BeanFactory 查找
```xml
...
```
`XmlBeanDefinitionReader#loadBeanDefinitions` 加载 XML 文件时,赋值 `DefaultListableBeanFactory#beanDefinitionMap`,这个 Map 中的 `BeanDefinition` 还没有合并,也就是说 superUser 的属性值还没有从 user 中继承过来。
`AbstractBeanFactory#getBean` 获取 bean 时,执行 `AbstractBeanFactory#getMergedBeanDefinition` ,对 superUser 进行合并,放入 `AbstractBeanFactory#mergedBeanDefinitions` 中。
### Spring Bean Class 加载阶段
- ClassLoader 类加载
- Java Security 安全控制
- ConfigurableBeanFactory 临时 ClassLoader
`AbstractBeanDefinition#beanClass` 被定义为 Object ,有两种形式,一种是 全类名 的 String,另一种是 Class 对象
Java Security 安全控制 相关
```java
if (System.getSecurityManager() != null) {
return AccessController.doPrivileged((PrivilegedExceptionAction>) () ->
doResolveBeanClass(mbd, typesToMatch), getAccessControlContext());
}
```
临时 ClassLoader 与 load-time weaving 技术有关,用于进行类型检查时(即尚未创建实际实例)
#### Spring Bean 实例化前阶段
- 非主流生命周期 - Bean 实例化前阶段
- `InstantiationAwareBeanPostProcessor#postProcessBeforeInstantiation`
返回非 null 时,阻止 bean 的默认实例化过程及以下生命周期
唯一可以进一步生命周期处理的是 `BeanPostProcessor#postProcessAfterInitialization`
### Spring Bean 实例化阶段
- 传统实例化方式
- 实例化策略 - InstantiationStrategy
- 构造器依赖注入
**实例化阶段,如果使用构造器注入,将解析构造器注入的依赖**
```
AbstractAutowireCapableBeanFactory#createBeanInstance
```
#### Spring Bean 实例化后阶段
- Bean 属性赋值(Populate)判断
- `InstantiationAwareBeanPostProcessor#postProcessAfterInstantiation`
在给 bean 实例做属性赋值的方法 `AbstractAutowireCapableBeanFactory#populateBean` 的最开始调用,如果返回 false ,阻止 bean 的属性赋值及以下生命周期
### Spring Bean 属性赋值前阶段
- Bean 属性值元信息
- PropertyValues
- Bean 属性赋值前回调
- Spring 1.2 - 5.0:`InstantiationAwareBeanPostProcessor#postProcessPropertyValues`
此方法已过期,使用 `postProcessProperties` 替代,为了兼容,只有在 `postProcessProperties` 返回 null 时(默认实现),才会调用此方法
- Spring 5.1:`InstantiationAwareBeanPostProcessor#postProcessProperties`
在工厂将给定属性值应用于给定 bean 之前,对它们进行处理。
在依赖注入( `byName` 或 `byType` )之后,在将配置的属性赋值给 bean 实例 `AbstractAutowireCapableBeanFactory#applyPropertyValues` 之前执行此阶段方法
### Spring Bean 初始化阶段
```
AbstractAutowireCapableBeanFactory#initializeBean
```
#### Spring Bean Aware 接口回调阶段
Spring Aware 接口,执行顺序从上到下
- `BeanNameAware`
- `BeanClassLoaderAware`
- `BeanFactoryAware`
依赖于 `ApplicationContext` :
- `EnvironmentAware`
- `EmbeddedValueResolverAware`
- `ResourceLoaderAware`
- `ApplicationEventPublisherAware`
- `MessageSourceAware`
- `ApplicationContextAware`
在初始化 Bean 实例 `AbstractAutowireCapableBeanFactory#initializeBean` 的最开始执行此阶段,前三个接口直接调用,而依赖于 ApplicationContext 的几个 Aware 接口,在 ApplicationContext 的生命周期中,会在 beanFactory 中加入 `ApplicationContextAwareProcessor` ,在其 `postProcessBeforeInitialization` 方法中执行调用
`ApplicationContextAwareProcessor` 是包权限的
#### Spring Bean 初始化前阶段
已完成
- Bean 实例化
- Bean 属性赋值
- Bean Aware 接口回调
方法回调
- `BeanPostProcessor#postProcessBeforeInitialization`
#### Spring Bean 初始化阶段
Bean 初始化(Initialization)
- `@PostConstruct` 标注方法 -- 该方法在初始化前阶段执行
- 实现 `InitializingBean` 接口的 `afterPropertiesSet()` 方法
- 自定义初始化方法
对 `@PostConstruct` 的处理需要依赖于注解驱动,`CommonAnnotationBeanPostProcessor#postProcessBeforeInitialization`
#### Spring Bean 初始化后阶段
方法回调
- `BeanPostProcessor#postProcessAfterInitialization`
#### Spring Bean 初始化完成阶段
方法回调
- Spring 4.1 +:`SmartInitializingSingleton#afterSingletonsInstantiated`
`SmartInitializingSingleton` 通常在 Spring ApplicationContext 场景使用
使用 `BeanFactory` 时,需要显式的调用此方法;在 `ApplicationContext` 启动时,调用了此方法 `AbstractApplicationContext#finishBeanFactoryInitialization` ,这个方法做了两件事情:
1. 将已注册的 `BeanDefinition` 初始化成 Spring Bean
2. 调用所有 `SmartInitializingSingleton#afterSingletonsInstantiated`
### Spring Bean 销毁前阶段
- 方法回调
- `DestructionAwareBeanPostProcessor#postProcessBeforeDestruction`
执行 `ConfigurableBeanFactory#destroyBean` 时,触发 Bean 前销毁阶段
对 `@PreDestroy` 的处理需要依赖于注解驱动,`CommonAnnotationBeanPostProcessor#postProcessBeforeDestruction`
### Spring Bean 销毁阶段
Bean 销毁(Destroy)
- `@PreDestroy` 标注方法
- 实现 `DisposableBean` 接口的 `destroy()` 方法
- 自定义销毁方法
对 `@PreDestroy` 的处理需要依赖于注解驱动,`CommonAnnotationBeanPostProcessor#postProcessBeforeDestruction`
`CommonAnnotationBeanPostProcessor` 是 `DestructionAwareBeanPostProcessor` 的实现类之一
如果其他 `DestructionAwareBeanPostProcessor` 排序在 `CommonAnnotationBeanPostProcessor` 后,会先执行 `@PreDestroy` 标注方法,后执行其他 `DestructionAwareBeanPostProcessor` 销毁前阶段方法
### Spring Bean 垃圾收集
Bean 垃圾回收(GC)
- 关闭 Spring 容器(应用上下文)
- 执行 GC
- Spring Bean 覆盖的 `finalize()` 方法被回调
## 面试题
### BeanPostProcessor 的使用场景有哪些?
答:`BeanPostProcessor` 提供 Spring Bean 初始化前和初始化后的生命周期回调,分别对应 `postProcessBeforeInitialization` 以及 `postProcessAfterInitialization` 方法,允许对关心的 Bean 进行扩展,甚至是替换。
加分项:其中,`ApplicationContext` 相关的 `Aware` 回调也是基于 `BeanPostProcessor` 实现,即 `ApplicationContextAwareProcessor` 。
### BeanFactoryPostProcessor 与 BeanPostProcessor 的区别
答:`BeanFactoryPostProcessor` 是 Spring `BeanFactory`(实际为 `ConfigurableListableBeanFactory`) 的后置处理器,用于扩展 `BeanFactory`,或通过 `BeanFactory` 进行依赖查找和依赖注入。
加分项:`BeanFactoryPostProcessor` 必须有 Spring `ApplicationContext` 执行,`BeanFactory` 无法与其直接交互。而 `BeanPostProcessor` 则直接与 `BeanFactory` 关联,属于 N 对 1 的关系。
### BeanFactory 是怎样处理 Bean 生命周期?
`BeanFactory` 的默认实现为 `DefaultListableBeanFactory`,其中 Bean生命周期与方法映射如下:
- BeanDefinition 注册阶段 - `registerBeanDefinition`
- BeanDefinition 合并阶段 - `getMergedBeanDefinition`
- Bean 实例化前阶段 - `resolveBeforeInstantiation`
- Bean 实例化阶段 - `createBeanInstance`
- Bean 实例化后阶段 - `populateBean`
- Bean 属性赋值前阶段 - `populateBean`
- Bean 属性赋值阶段 - `populateBean`
- Bean Aware 接口回调阶段 - `initializeBean`
- Bean 初始化前阶段 - `initializeBean`
- Bean 初始化阶段 - `initializeBean`
- Bean 初始化后阶段 - `initializeBean`
- Bean 初始化完成阶段 - `preInstantiateSingletons`
- Bean 销毁前阶段 - `destroyBean`
- Bean 销毁阶段 - `destroyBean`