题目
介绍下 Bean 的生命周期
答案
对于 Spring Bean 的生命周期来说,只有四个步骤:
- 实例化 Instantiation
- 属性赋值 Populate
- 初始化 Initialization
- 销毁 Destruction
整个生命周期相关的方法可以分类为以下三种:
- **Bean 自身的方法**:对应着上文说的实例化 -> 属性赋值 -> 初始化 -> 销毁四个阶段。
- **容器级生命周期方法**:主要是后处理器方法,比如 `InstantiationAwareBeanPostProcessor`、`BeanPostProcessor` 接口方法。这些接口的实现类是独立于 Bean 的,并且会注册到 Spring 容器中。在 Spring 容器创建任何 Bean 的时候,这些后处理器都会发生作用。
- **Bean 级生命周期方法**:可以理解为 Bean 类直接实现接口的方法,比如 `BeanNameAware`、`BeanFactoryAware`、`ApplicationContextAware`、`InitializingBean`、`DisposableBean` 等方法,这些方法只对当前 Bean 生效
具体过程如下面两张图所示,配合文字食用(下图中的 postProcessProperties 改为 `postProcessPropertyValues`):

1. 当调用者通过 `getBean(beanName)` 向容器请求某一个 Bean 时,如果容器注册了 `InstantiationAwareBeanPostProcessor` 接口,则在实例化 Bean(调用 Bean 的构造函数) 之前,将调用接口的 `postProcessBeforeInstantiation()` 方法
2. ⭐ **实例化 Instantiation**:根据配置情况调用 Bean 构造函数或工厂方法实例化 Bean
3. 如果容器注册了 `InstantiationAwareBeanPostProcessor` 接口,那么在实例化Bean之后,调用该接口的 `postProcessAfterInstantiation()` 方法,可在这里对已经实例化的对象进行一些“梳妆打扮”
4. 随后,在设置每个属性之前将先调用 `InstantiationAwareBeanPostProcessor` 接口的 `postProcessPropertyValues()` 方法
5. ⭐ **属性赋值 Populate**:调用 Bean 的 set 方法【设置属性值】
6. 如果 Bean 实现了 `BeanNameAware` 接口,则将调用 setBeanName() 接口方法,将配置文件中该 Bean 对应的名称设置到 Bean 中
7. 如果 Bean 实现了 `BeanClassLoaderAware` 接口,则将调用 setClassLoader() 接口方法,将类加载器设置到 Bean 中
8. 如果 Bean 实现了 `BeanFactoryAware` 接口,则将调用 setBeanFactory() 接口方法,将 BeanFactory 容器实例设置到 Bean 中
9. 如果 BeanFactory 装配了 `BeanPostProcessor` 后处理器,则将调用 `BeanPostProcessor` 的 `Object postProcessBeforeInitialization(Object bean, String beanName)` 接口方法对 Bean 进行加工操作。
其中,入参 bean 是当前正在处理的 Bean,而 beanName 是当前 Bean 的配置名,返回的对象为加工处理后的 Bean。用户可以使用该方法对某些 Bean 进行特殊的处理,甚至改变 Bean 的行为。
> BeanPostProcessor 在 Spring 框架中占有重要的地位,为容器提供对 Bean 进行后续加工处理的切入点,Spring 容器所提供的各种 “神奇功能”(如 AOP、动态代理等)都通过 BeanPostProcessor 实施。
10. 如果 Bean 实现了 `InitializingBean` 接口,则将调用接口的 `afterPropertiesSet()` 方法
11. ⭐ **初始化 Initialization**:如果在 `<bean>` 中通过 `init-method` 属性定义了初始化方法,则将执行这个方法
12. `BeanPostProcessor` 后处理器定义了两个方法:其一是 postProcessBeforeInitialization(),在第(9)步调用;其二是 `Object postProcessAfterInitialization(Object bean,String beanName)`,这个方法在此时调用,容器再次获得对 Bean 进行加工处理的机会
13. 如果在 `<bean>` 中指定 Bean 的作用范围为 `scope="prototype"`,则将 Bean 返回给调用者,调用者负责 Bean 后续生命的管理,Spring 不再管理这个 Bean的 生命周期。
如果将作用范围设置为 `scope="singleton"`,则将 Bean 放入 Spring IoC 容器的缓存池中,并将 Bean 引用返回给调用者,Spring 继续对这些 Bean 进行后续的生命管理
14. ⭐ **销毁 Destruction**:对于 scope="singleton" 的 Bean(默认情况),当容器关闭时,将触发 Spring 对 Bean 后续生命周期的管理工作。如果 Bean 实现了 `DisposableBean` 接口,则将调用接口的 destory() 方法,可以在此编写释放资源、记录日志等操作;随后,如果通过 `<bean>` 的 `destroy-method` 属性指定了 Bean 的销毁方法,那么 Spring 将执行 Bean 的这个方法,完成 Bean 资源的释放等操作
再来看张图理解下(下图中的 **BeanFactoryPostProcessor(工厂后处理器)** 可以忽略,在 IoC 启动过程 `refresh()` 中有涉及到,这里不提它也无所谓):

精简版的图示如下:

