Преглед изворни кода

增加了spring核心学习第九章:Spring Bean生命周期

seamew пре 2 година
родитељ
комит
0d56403cf3

+ 248 - 0
后端/Spring/spring源码学习/spring核心编程思想/9、Spring Bean生命周期.md

@@ -0,0 +1,248 @@
+## 第九章: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
+<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 安全控制 相关
+
+```java
+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 之前,对它们进行处理。
+
+在依赖注入( `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`