## 第九章: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`