9、Spring Bean生命周期.md 8.6 KB

第九章: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 查找
<bean id="user" class="org.geekbang.thinking.in.spring.ioc.overview.domain.User">
    <property name="id" value="1"/>
    ...
</bean>

<bean id="superUser" class="org.geekbang.thinking.in.spring.ioc.overview.domain.SuperUser" parent="user"
      primary="true">
    <property name="address" value="杭州"/>
</bean>

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 安全控制 相关

if (System.getSecurityManager() != null) {
	return AccessController.doPrivileged((PrivilegedExceptionAction<Class<?>>) () ->
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 之前,对它们进行处理。

在依赖注入( byNamebyType )之后,在将配置的属性赋值给 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

CommonAnnotationBeanPostProcessorDestructionAwareBeanPostProcessor 的实现类之一

如果其他 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