SpringFramework 5.1.19.RELEASE

《IOC & DI》中以 FileSystemXmlApplicationContext 为例从源码角度见到剖析了 一个类(class) 解析加载到 IOC 容器中的全过程。

下面以IOC的管理流程剖析 类(class) 在 SpringFreamework 中的生命周期。

IOC(Inversion of Control) 完整的整个流程总的分为三个步骤

  • 步骤一:资源定位。即:定位需要被加载的 class 。
  • 步骤二:载入。即:将定位的 class 解析为 Spring 待处理的结构定义:BeanDefinition对象。
  • 步骤三:注册。即:(针对预实例化对象)将抽象为 BeanDefinition对象的 class信息实例化为 Spring Bean。

image.png

一、Spring Bean 生命周期

根据代码执行顺序 Spring Bean 的生命周期概括为六个阶段

  • 实例化(Instantiation)
  • 属性赋值(Populate)
  • 初始化(Initialization)
  • 销毁前置处理类注册(Register DisposableBean)
  • 使用中(In Use)
  • 销毁(Destruction)

image.png
《IOC&DI#懒加载实例》为例,查看Bean生命周期对应的源码 AbstractAutowireCapableBeanFactory#doCreateBean,代码如下:

  1. public abstract class AbstractAutowireCapableBeanFactory extends AbstractBeanFactory implements AutowireCapableBeanFactory {
  2. protected Object doCreateBean(String beanName, RootBeanDefinition mbd, @Nullable Object[] args) throws BeanCreationException {
  3. // Instantiate the bean.
  4. // 1、实例化对象
  5. BeanWrapper instanceWrapper = null;
  6. if (instanceWrapper == null) {
  7. // 构造函数注入,如:@Autowired 标注的构造函数
  8. instanceWrapper = createBeanInstance(beanName, mbd, args);
  9. }
  10. // 省略
  11. // Initialize the bean instance.
  12. Object exposedObject = bean;
  13. try {
  14. // 2、设置属性(填充bean)
  15. populateBean(beanName, mbd, instanceWrapper);
  16. // 3、初始化bean
  17. exposedObject = initializeBean(beanName, exposedObject, mbd);
  18. }
  19. // 省略
  20. // Register bean as disposable.
  21. try {
  22. // 4、设置销毁回调相关bean
  23. registerDisposableBeanIfNecessary(beanName, bean, mbd);
  24. }
  25. // 省略
  26. return exposedObject;
  27. }
  28. }

如上述代码所示,分别对应 Spring Bean 生命周期的四个阶段:实例化(Instantiation)属性赋值(Populate)初始化(Initialization)销毁前置处理类注册(Register DisposableBean)

针对 Bean 的使用无处不在,比如使用 @Autowired注入等方式使用。
针对 Bean的销毁(Destruction)在销毁 Spring IOC 过程中进行,相关代码在 AbstractApplicationContext#doClose中。

1.1、实例化(Instantiation)

1.2、属性赋值(Populate)

属性赋值,即对标注了 [@Autowired](https://docs.spring.io/spring-framework/docs/5.1.19.RELEASE/spring-framework-reference/core.html#beans-autowired-annotation)[@Resource](https://docs.spring.io/spring-framework/docs/5.1.19.RELEASE/spring-framework-reference/core.html#beans-resource-annotation)[@Value](https://docs.spring.io/spring-framework/docs/5.1.19.RELEASE/spring-framework-reference/core.html#beans-autowired-annotation) 的属性进行注入,以及 自定义初始化”@PostConstruct” 、销毁前置方法”@PreDestroy” 的设置。

代码入口为 AbstractAutowireCapableBeanFactory#populateBean,部分代码如下:
image.png
根据如上图代码,简单分析属性设置中关于 @Autowired@Value@Inject@Resource属性注入。
通过代码,以及官方文档@Autowired@Value@Inject@Resource属性注入由两个类负责

  • AutowiredAnnotationBeanPostProcessor
    处理 @Autowired@Value@Inject 属性注入
  • CommonAnnotationBeanPostProcessor
    处理 @Resource属性注入

    1.2.1、AutowiredAnnotationBeanPostProcessor 处理

    @Autowired@Inject 都支持三种方式的注入:构造函数注入、方法注入、属性注入 AutowiredAnnotationBeanPostProcessor# postProcessProperties方法注入属性注入处理逻辑入口在属性赋值流程中调用。 AutowiredAnnotationBeanPostProcessor#determineCandidateConstructors 用于获取构造注入操作数据,具体函数注入操作,介于 实例化和属性赋值之间的 createBeanInstance方法处理.

AutowiredAnnotationBeanPostProcessor处理 @Autowired@Value@Inject 属性注入。

1.2.1.1、支持的注解

AutowiredAnnotationBeanPostProcessor在实例化时即声明了类处理的注解,并缓存到集合中。
相关代码如下:
image.png
如代码所示,AutowiredAnnotationBeanPostProcessor支持 @Autowired@Value@Inject注解注入处理。

1.2.1.2、属性/方法 注入

在属性赋值流程中,会调用BeanPostProcessor#postProcessProperties方法,对应 AutowiredAnnotationBeanPostProcessor#postProcessProperties方法,关键代码如下:
image.png
属性注入的关键流程有两步

  • step1、找到需要注入的属性,并构建元数据对象 InjectionMetadata并对其进行缓存。
    注入方式处理包含:属性注入和方法注入。
    不同的方式构建不同的元数据结果
    • AutowiredMethodElement (方法注入元数据信息)
      基于源码能够知道:AutowiredAnnotationBeanPostProcessor#buildAutowiringMetadata
      • 方法不能标注 static
      • 方法参数不能为空
    • AutowiredFieldElement(属性注入元数据信息)
      基于源码知道:AutowiredAnnotationBeanPostProcessor#buildAutowiringMetadata
      • 属性不能标注 static
  • step2、进行属性的注入
    根据方法注入或者属性注入通过反射的方式进行属性设置。

1.2.2、CommonAnnotationBeanPostProcessor 处理

CommonAnnotationBeanPostProcessor 处理 @Resource

1.2.2.1、支持的注解

CommonAnnotationBeanPostProcessor 支持 除 @Resource 属性注入外的,支持由 @PostConstruct@PreDestory 标注的方法处理。
关于 @PostConstruct@PreDestroy在构造函数时即进行了声明。
image.png
而针对 @Resource的处理,写死在具体处理逻辑CommonAnnotationBeanPostProcessor#buildResourceMetadata中,代码如下:
image.png

1.2.2.2、属性/方法 注入

@Resource注解仅支持方法和属性注入,不支持构造函数注入。

image.png
属性注入的关键流程有两步

  • step1、找到需要注入的属性,并构建元数据对象 InjectionMetadata并对其进行缓存。
    注入方式处理包含:属性注入和方法注入。
    不同的方式构建相同的元数据 ResourceElement
    • ResourceElement (isField = false 表示属性注入元数据信息)
      基于源码能够知道:CommonAnnotationBeanPostProcessor#buildResourceMetadata
      • 方法不能标注 static
      • 方法参数不能为空且仅支持1个参数
    • ResourceElement (isField = true 表示方法注入元数据信息)
      基于源码知道:CommonAnnotationBeanPostProcessor#buildResourceMetadata
      • 属性不能标注 static
      • 属性不能是 javax.xml.ws.WebServiceContext
  • step2、进行属性的注入
    根据方法注入或者属性注入通过反射的方式进行属性设置。

    1.3、初始化(Initialization)

在四个阶段中,初始化(Initialization)最复杂,包含了4个处理模块,同时这四个模块的处理也给程序开发提供了扩展点。

根据上述 Spring Bean 生命周期图示 ,Bean 的初始化包含五大块操作逻辑

  • XXXAware 接口处理
  • BeanPostProcessor 前置处理
  • InitializingBean 处理
  • 自定义初始化方法处理
  • BeanPostProcessor 后置处理

通过源码了解到初始化的入口 AbstractAutowireCapableBeanFactory#initializeBean

  1. public abstract class AbstractAutowireCapableBeanFactory extends AbstractBeanFactory implements AutowireCapableBeanFactory {
  2. protected Object initializeBean(String beanName, Object bean, @Nullable RootBeanDefinition mbd) {
  3. // 省略
  4. // Aware 接口调用处理,包括:BeanNameAware、BeanClassLoaderAware、BeanFactoryAware
  5. invokeAwareMethods(beanName, bean);
  6. Object wrappedBean = bean;
  7. if (mbd == null || !mbd.isSynthetic()) {
  8. // BeanPostProcessor 前置处理
  9. wrappedBean = applyBeanPostProcessorsBeforeInitialization(wrappedBean, beanName);
  10. }
  11. try {
  12. // InitializingBean 接口类处理,以及自定义初始化方法处理
  13. invokeInitMethods(beanName, wrappedBean, mbd);
  14. }
  15. // 省略
  16. if (mbd == null || !mbd.isSynthetic()) {
  17. // BeanPostProcessor 后置处理
  18. wrappedBean = applyBeanPostProcessorsAfterInitialization(wrappedBean, beanName);
  19. }
  20. return wrappedBean;
  21. }
  22. }

1.3.1、XXXAware 接口处理

相关源码 AbstractAutowireCapableBeanFactory#invokeAwareMethods如下:

  1. public abstract class AbstractAutowireCapableBeanFactory extends AbstractBeanFactory implements AutowireCapableBeanFactory {
  2. private void invokeAwareMethods(String beanName, Object bean) {
  3. // Bean 必须实现了 Aware 接口
  4. if (bean instanceof Aware) {
  5. // Bean 如果实现了 BeanNameAware 接口处理
  6. if (bean instanceof BeanNameAware) {
  7. ((BeanNameAware) bean).setBeanName(beanName);
  8. }
  9. // Bean 如果实现了 BeanClassLoaderAware 接口处理
  10. if (bean instanceof BeanClassLoaderAware) {
  11. ClassLoader bcl = getBeanClassLoader();
  12. if (bcl != null) {
  13. ((BeanClassLoaderAware) bean).setBeanClassLoader(bcl);
  14. }
  15. }
  16. // Bean 如果实现了 BeanFactoryAware 接口处理
  17. if (bean instanceof BeanFactoryAware) {
  18. ((BeanFactoryAware) bean).setBeanFactory(AbstractAutowireCapableBeanFactory.this);
  19. }
  20. }
  21. }
  22. }

如代码所示,当 Bean 实现了 Aware接口会进入三个判断处理逻辑

  • 1、如果 Bean 实现了 BeanNameAware接口
    调用 BeanNameAware#setBeanName方法
  • 2、如果 Bean 实现了 BeanClassLoaderAware接口
    调用BeanClassLoaderAware#setBeanClassLoader方法
  • 3、如果 Bean 实现了 BeanFactoryAware接口
    调用 BeanFactoryAware#setBeanFactory方法

1.3.2、BeanPostProcessor 前置处理

相关源码 AbstractAutowireCapableBeanFactory#AbstractAutowireCapableBeanFactory 如下:

  1. public abstract class AbstractAutowireCapableBeanFactory extends AbstractBeanFactory implements AutowireCapableBeanFactory {
  2. @Override
  3. public Object applyBeanPostProcessorsBeforeInitialization(Object existingBean, String beanName) throws BeansException {
  4. Object result = existingBean;
  5. for (BeanPostProcessor processor : getBeanPostProcessors()) {
  6. Object current = processor.postProcessBeforeInitialization(result, beanName);
  7. if (current == null) {
  8. return result;
  9. }
  10. result = current;
  11. }
  12. return result;
  13. }
  14. }

如代码所示,遍历所有的 BeanPostProcessor并调用 BeanPostProcessor#postProcessBeforeInitialization

1.3.3、InitializingBean 接口及自定义初始化方法处理

相关源码 AbstractAutowireCapableBeanFactory#invokeInitMethods如下:

  1. public abstract class AbstractAutowireCapableBeanFactory extends AbstractBeanFactory implements AutowireCapableBeanFactory {
  2. protected void invokeInitMethods(String beanName, Object bean, @Nullable RootBeanDefinition mbd)
  3. throws Throwable {
  4. boolean isInitializingBean = (bean instanceof InitializingBean);
  5. if (isInitializingBean && (mbd == null || !mbd.isExternallyManagedInitMethod("afterPropertiesSet"))) {
  6. // 省略
  7. // 如果实现了 InitializingBean 接口,相关处理
  8. ((InitializingBean) bean).afterPropertiesSet();
  9. }
  10. // 自定义初始化方法处理
  11. if (mbd != null && bean.getClass() != NullBean.class) {
  12. String initMethodName = mbd.getInitMethodName();
  13. if (StringUtils.hasLength(initMethodName) &&
  14. !(isInitializingBean && "afterPropertiesSet".equals(initMethodName)) &&
  15. !mbd.isExternallyManagedInitMethod(initMethodName)) {
  16. invokeCustomInitMethod(beanName, bean, mbd);
  17. }
  18. }
  19. }
  20. }

如代码所示,分为两个处理逻辑

  • 1、如果 Bean 实现了 InitializingBean接口
    调用 InitializingBean#afterPropertiesSet方法
  • 2、如果存在自定义初始化方法
    调用自定义初始化方法。

    1.3.4、BeanPostProcessor 后置处理

    相关源码 AbstractAutowireCapableBeanFactory#applyBeanPostProcessorsAfterInitialization如下

    1. public abstract class AbstractAutowireCapableBeanFactory extends AbstractBeanFactory implements AutowireCapableBeanFactory {
    2. @Override
    3. public Object applyBeanPostProcessorsAfterInitialization(Object existingBean, String beanName) throws BeansException {
    4. Object result = existingBean;
    5. for (BeanPostProcessor processor : getBeanPostProcessors()) {
    6. Object current = processor.postProcessAfterInitialization(result, beanName);
    7. if (current == null) {
    8. return result;
    9. }
    10. result = current;
    11. }
    12. return result;
    13. }
    14. }

    BeanPostProcessor 后置和前置处理类似,调用的方法不同。BeanPostProcessor 后置处理调用的是 BeanPostProcessor#postProcessAfterInitialization

    1.4、销毁前置处理类注册(Register DisposableBean)

    相关的源码 AbstractAutowireCapableBeanFactory#registerDisposableBeanIfNecessary 入口,代码如下

    1. public abstract class AbstractAutowireCapableBeanFactory extends AbstractBeanFactory implements AutowireCapableBeanFactory {
    2. protected void registerDisposableBeanIfNecessary(String beanName, Object bean, RootBeanDefinition mbd) {
    3. // 省略
    4. new DisposableBeanAdapter(bean, beanName, mbd, getBeanPostProcessors(), acc));
    5. // 省略
    6. }
    7. }

    1.5、使用中(In Use)

    通过 BeanFactory直接获取 Bean实例,或者通过 @Autowired等方式使用 IOC 中的 Bean 。

1.6、销毁(Destruction)

继续跟 DisposableBeanAdapter,代码如下:

  1. class DisposableBeanAdapter implements DisposableBean, Runnable, Serializable {
  2. public DisposableBeanAdapter(Object bean, String beanName, RootBeanDefinition beanDefinition, List<BeanPostProcessor> postProcessors, @Nullable AccessControlContext acc) {
  3. // 省略
  4. this.destroyMethod = destroyMethod;
  5. this.beanPostProcessors = filterPostProcessors(postProcessors, bean);
  6. }
  7. @Nullable
  8. private List<DestructionAwareBeanPostProcessor> filterPostProcessors(List<BeanPostProcessor> processors, Object bean) {
  9. List<DestructionAwareBeanPostProcessor> filteredPostProcessors = null;
  10. if (!CollectionUtils.isEmpty(processors)) {
  11. filteredPostProcessors = new ArrayList<>(processors.size());
  12. for (BeanPostProcessor processor : processors) {
  13. if (processor instanceof DestructionAwareBeanPostProcessor) {
  14. DestructionAwareBeanPostProcessor dabpp = (DestructionAwareBeanPostProcessor) processor;
  15. if (dabpp.requiresDestruction(bean)) {
  16. filteredPostProcessors.add(dabpp);
  17. }
  18. }
  19. }
  20. }
  21. return filteredPostProcessors;
  22. }
  23. }

销毁的入口源码 AbstractApplicationContext#close,代码如下:

  1. public abstract class AbstractApplicationContext extends DefaultResourceLoader implements ConfigurableApplicationContext {
  2. public void close() {
  3. synchronized (this.startupShutdownMonitor) {
  4. doClose();
  5. }
  6. }
  7. protected void doClose() {
  8. // Check whether an actual close attempt is necessary...
  9. if (this.active.get() && this.closed.compareAndSet(false, true)) {
  10. try {
  11. // Publish shutdown event.
  12. publishEvent(new ContextClosedEvent(this));
  13. }
  14. if (this.lifecycleProcessor != null) {
  15. try {
  16. this.lifecycleProcessor.onClose();
  17. }
  18. }
  19. // Destroy all cached singletons in the context's BeanFactory.
  20. destroyBeans();
  21. // Close the state of this context itself.
  22. closeBeanFactory();
  23. // Let subclasses do some final clean-up if they wish...
  24. onClose();
  25. // Reset local application listeners to pre-refresh state.
  26. if (this.earlyApplicationListeners != null) {
  27. this.applicationListeners.clear();
  28. this.applicationListeners.addAll(this.earlyApplicationListeners);
  29. }
  30. // Switch to inactive.
  31. this.active.set(false);
  32. }
  33. }
  34. }

IOC 容器的关闭涉及到 发布关闭事件销毁单例Bean关闭IOC容器等操作。

关于 销毁操作的源码可以追述到 DefaultSingletonBeanRegistry#destroyBean中,具体代码如下:

  1. public class DefaultSingletonBeanRegistry extends SimpleAliasRegistry implements SingletonBeanRegistry {
  2. protected void destroyBean(String beanName, @Nullable DisposableBean bean) {
  3. // 省略
  4. // Actually destroy the bean now...
  5. if (bean != null) {
  6. try {
  7. // 调用 DisposableBean#destroy 方法
  8. bean.destroy();
  9. }
  10. }
  11. // 省略
  12. }
  13. }

关于 销毁操作具体可以追溯到 DisposableBeanAdapter#destroy方法中,代码如下:

  1. class DisposableBeanAdapter implements DisposableBean, Runnable, Serializable {
  2. @Override
  3. public void destroy() {
  4. // 销毁前置处理
  5. if (!CollectionUtils.isEmpty(this.beanPostProcessors)) {
  6. for (DestructionAwareBeanPostProcessor processor : this.beanPostProcessors) {
  7. processor.postProcessBeforeDestruction(this.bean, this.beanName);
  8. }
  9. }
  10. // 省略
  11. if (this.destroyMethod != null) {
  12. // 销毁自定义方法
  13. invokeCustomDestroyMethod(this.destroyMethod);
  14. }
  15. // 省略
  16. }
  17. }

二、案例测试 Bean 生命周期

code.zip.txt

通过案例验证 Spring Bean 生命周期,包括:

  • 实例化
  • 属性赋值
  • 初始化(各种扩展点的处理)
  • 使用中
  • DisposableBean 销毁前置处理
  • 销毁

整理代码三个类:

  • BeanLifecycleDemo
    用于测试的 class 类
  • BeanLifeCycleDemoConfig
    用于注册 class 到IOC的配置类
  • BeanPropertyDemo
    用于测试属性赋值的类

2.1、实例化 - 测试代码

在 BeanLifecycleDemo 中

image.png
构造函数即实例化时调用的函数方法。

2.2、属性赋值 - 测试代码

涉及到 BeanLifecycleDemo 和 BeanPropertyDemo,主要代码仍在 BeanLifecycleDemo 中

关键代码如下:
image.png
使用 setter 注入的方式,埋点打印日志。

2.3、初始化 - 测试代码

代码在 BeanLifecycleDemo 中。

通过实现对应接口,实现对应的方法,并打印日志进行测试,部分关键代码如下:
image.png

2.4、使用中 - 测试代码

关键代码在 Spring 容器启动测试代码中,代码逻辑在 BeanLifeCycleDemoConfig#main 方法逻辑中

关键代码如下:
image.png
在 Bean 初始化完成后,通过获取Bean 对象,测试其 ToString方法进行使用测试。

2.5、销毁前置设置 - 测试代码

同初始化处理,通过实现特点接口 DisposableBean 并实现其 DisposableBean#destroy 方法

关键代码如下:
image.png

2.6、销毁 - 测试

通过自定义销毁方法,测试自定义销毁方法的调用,代码在 BeanLifecyleDemo 以及 BeanLifeCycleDemoConfig 中,其中 BeanLifecycleDemo 中自定义了销毁方法,BeanLifeCycleDemoConfig 配置中指定消耗方法为自定义销毁方法。

关键代码如下:
image.png

2.7、测试结果

image.png