题目
介绍下 Bean 的生命周期
答案
对于 Spring Bean 的生命周期来说,只有四个步骤: - 实例化 Instantiation - 属性赋值 Populate - 初始化 Initialization - 销毁 Destruction 整个生命周期相关的方法可以分类为以下三种: - **Bean 自身的方法**:对应着上文说的实例化 -> 属性赋值 -> 初始化 -> 销毁四个阶段。 - **容器级生命周期方法**:主要是后处理器方法,比如 `InstantiationAwareBeanPostProcessor`、`BeanPostProcessor` 接口方法。这些接口的实现类是独立于 Bean 的,并且会注册到 Spring 容器中。在 Spring 容器创建任何 Bean 的时候,这些后处理器都会发生作用。 - **Bean 级生命周期方法**:可以理解为 Bean 类直接实现接口的方法,比如 `BeanNameAware`、`BeanFactoryAware`、`ApplicationContextAware`、`InitializingBean`、`DisposableBean` 等方法,这些方法只对当前 Bean 生效 具体过程如下面两张图所示,配合文字食用(下图中的 postProcessProperties 改为 `postProcessPropertyValues`): ![](https://cs-wiki.oss-cn-shanghai.aliyuncs.com/img/image-20220721190638078.png) 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()` 中有涉及到,这里不提它也无所谓): ![](https://cs-wiki.oss-cn-shanghai.aliyuncs.com/img/image-20220721190703487.png) 精简版的图示如下: ![](https://cs-wiki.oss-cn-shanghai.aliyuncs.com/img/image-20220721190721000.png)