8

Spring Bean 生命周期概述

 3 years ago
source link: https://www.diguage.com/post/spring-bean-lifecycle-overview/
Go to the source link to view the article. You can view the picture content, updated content and better typesetting reading experience. If the link is broken, please click the button below to view the snapshot at that time.

在Spring 启动流程概述 中,分析了 Spring 的启动流程。本文就来说明一下 Spring Bean 整个生命周期。如果有不清楚的地方,可以参考上文的“附录:启动日志”。

直接上图:Spring Bean 生命周期流程图。内容较多,图片文字偏小,请放大看(矢量图,可以任意放大):

UBr2qqu.png!web

Figure 1. Spring Bean 生命周期流程图

下面是文字说明。

Bean 生命周期

getBean() 方法获取 Bean 时,如果缓存中没有对应的 Bean,则会创建 Bean,整个流程如下:

  1. InstantiationAwareBeanPostProcessor#postProcessBeforeInstantiation — 目前有如下四个:

    ImportAwareBeanPostProcessor
    AnnotationAwareAspectJAutoProxyCreator
    CommonAnnotationBeanPostProcessor
    AutowiredAnnotationBeanPostProcessor
    
  2. 构造函数

  3. MergedBeanDefinitionPostProcessor#postProcessMergedBeanDefinition — 目前有如下三个:

    1. CommonAnnotationBeanPostProcessor — 收集 @Resource 依赖信息, initMethodsdestroyMethods 等信息。(就是 @PostConstruct@PreDestroy 标注的方法。)

    2. AutowiredAnnotationBeanPostProcessor — 收集 @Autowired 的依赖信息。

    3. ApplicationListenerDetector — 判断 Bean 是否是一个 ApplicationListener ,是则保留,在后面的 postProcessAfterInitialization 方法中,加入到容器的 applicationListeners 中。

  4. InstantiationAwareBeanPostProcessor#postProcessAfterInstantiation — 与上面的 postProcessBeforeInstantiation 方法对应,目前有如下四个:

    ImportAwareBeanPostProcessor
    AnnotationAwareAspectJAutoProxyCreator
    CommonAnnotationBeanPostProcessor
    AutowiredAnnotationBeanPostProcessor
    
  5. InstantiationAwareBeanPostProcessor#postProcessProperties — 目前有如下三个:

    1. ImportAwareBeanPostProcessor — 如果 Bean 是 EnhancedConfiguration (它继承了 BeanFactoryAware ) 的实现类,则注入 BeanFactory

    2. AnnotationAwareAspectJAutoProxyCreator — 无所事事。

    3. CommonAnnotationBeanPostProcessor — 完成 @Resource 依赖注入。

      在这里会递归创建所依赖 Bean。调试代码,弄清楚。

    4. AutowiredAnnotationBeanPostProcessor — 完成 @Autowired@Value 注入

  6. InstantiationAwareBeanPostProcessor#postProcessPropertyValues — 从 5.1 开始废弃,使用上面方法代替。

    Warning

    这里要注意,并不是执行完四个类的 postProcessProperties 方法,再去执行四个类的 postProcessPropertyValues 方法。而是以类为顺序的,执行完一个类的 postProcessProperties 方法,然后去执行 postProcessPropertyValues 方法。执行完一个类,再去执行下一个类。这个现象在下面的日志中有反应。
  7. AutowiredAnnotationBeanPostProcessor#setBeanFactory(DefaultListableBeanFactory) — 通过 AbstractAutowireCapableBeanFactory#invokeAwareMethods 方法如下 Aware 注入:

    BeanNameAware
    BeanClassLoaderAware
    BeanFactoryAware
    
  8. BeanPostProcessor#postProcessBeforeInitialization — 目前有

    1. 用户手动添加的 BeanPostProcessor

    2. ApplicationContextAwareProcessor — 完成如下六个 Aware 的注入:

      EnvironmentAware
      EmbeddedValueResolverAware
      ResourceLoaderAware
      ApplicationEventPublisherAware
      MessageSourceAware
      ApplicationContextAware
      
    3. ImportAwareBeanPostProcessor — 如果实现了 ImportAware 接口,则注入 importMetadata 信息。

    4. BeanPostProcessorChecker — 无所事事。

    5. AnnotationAwareAspectJAutoProxyCreator — 无所事事。

    6. CommonAnnotationBeanPostProcessor — 要调用 LifecycleMetadata#invokeInitMethods 方法,但是,里面去没有任何实现,似乎调用了全局设置的初始化操作。需要找文档确认一下。

    7. AutowiredAnnotationBeanPostProcessor — 继承父类实现,无所事事。

    8. ApplicationListenerDetector — 无所事事。

  9. InitializingBean#afterPropertiesSet()

  10. init-method

  11. BeanPostProcessor#postProcessAfterInitialization 方法 — 目前有

    1. 用户手动添加的 BeanPostProcessor

    2. ApplicationContextAwareProcessor — 继承默认实现,无所事事。

    3. ImportAwareBeanPostProcessor — 继承默认实现,无所事事。

    4. BeanPostProcessorChecker — 如果 Bean 是 BeanPostProcessor 子类,则检查 BeanPostProcessor 数量。

    5. AnnotationAwareAspectJAutoProxyCreator — 检查 Bean 和提前暴露的引用是否相同,不同则重新生成代理对象。

    6. CommonAnnotationBeanPostProcessor — 继承父类实现,无所事事。

    7. AutowiredAnnotationBeanPostProcessor — 继承父类实现,无所事事。

    8. ApplicationListenerDetector — 将 ApplicationListener 类型的 Bean,加入到容器的 applicationListeners 中,方便容器开始监听。

初始化之前,似乎可以设置全局的初始化操作。忘了具体在哪个类中了?

Bean 生命周期补充说明

下面对创建 Bean 的流程做进一步说明:

.1. InstantiationAwareBeanPostProcessor#postProcessBeforeInstantiation

通过 AbstractAutowireCapableBeanFactory#resolveBeforeInstantiation 方法,调用 InstantiationAwareBeanPostProcessor#postProcessBeforeInstantiation 方法。遍历 InstantiationAwareBeanPostProcessor 列表( getBeanPostProcessorCache().instantiationAware 变量)时,如果返回值不为空,则立即返回,不再继续调用。不为空,则表示创建了 Bean 对象,然后马上调用 BeanPostProcessor#postProcessAfterInitialization 方法。如果这里创建对象,则直接返回该对象,不再进行下面的调用。有四个 InstantiationAwareBeanPostProcessor 对象:

ConfigurationClassPostProcessor
AnnotationAwareAspectJAutoProxyCreator
CommonAnnotationBeanPostProcessor
AutowiredAnnotationBeanPostProcessor

.2. Bean 的构造函数

.3. MergedBeanDefinitionPostProcessor#postProcessMergedBeanDefinition

通过 AbstractAutowireCapableBeanFactory#applyMergedBeanDefinitionPostProcessors 调用 MergedBeanDefinitionPostProcessor#postProcessMergedBeanDefinition 方法。变量: getBeanPostProcessorCache().mergedDefinition 这个方法主要干什么?通过 CommonAnnotationBeanPostProcessor#applyMergedBeanDefinitionPostProcessors 调用 CommonAnnotationBeanPostProcessor#findResourceMetadata 可以看出,这个地方可以获取依赖信息。带验证。 系统中有如下四个类:

CommonAnnotationBeanPostProcessor
AutowiredAnnotationBeanPostProcessor
ApplicationListenerDetector
InitDestroyAnnotationBeanPostProcessor

.4. InstantiationAwareBeanPostProcessor#postProcessAfterInstantiation

有一点重要的信息,日志中没有体现出来。设置 Bean 的属性是在执行 BeanPostProcessor 调用之前完成的。在 AbstractAutowireCapableBeanFactory#doCreateBean 方法中,调用了 AbstractAutowireCapableBeanFactory#populateBean 方法来设置属性,然后去调用的 BeanPostProcessorinit 方法。 populateBean 方法是通过调用 InstantiationAwareBeanPostProcessor#postProcessProperties 方法来完成注入,其中 CommonAnnotationBeanPostProcessorAutowiredAnnotationBeanPostProcessor 分别处理不同的注解。下面是 populateBean 方法更详细的说明。

在注入 Bean 属性之前,调用 InstantiationAwareBeanPostProcessor#postProcessAfterInstantiation 。(从变量 getBeanPostProcessorCache().instantiationAware 中获取列表。)容器完成初始化后,有 ImportAwareBeanPostProcessorAnnotationAwareAspectJAutoProxyCreatorCommonAnnotationBeanPostProcessorAutowiredAnnotationBeanPostProcessor 四个 InstantiationAwareBeanPostProcessor 对象。但是,这四个类,没有做任何操作。如果返回值为 false 则中断,不再继续遍历 InstantiationAwareBeanPostProcessor 列表。

ConfigurationClassPostProcessor
AnnotationAwareAspectJAutoProxyCreator
CommonAnnotationBeanPostProcessor
AutowiredAnnotationBeanPostProcessor

.5. InstantiationAwareBeanPostProcessor#postProcessProperties

接着调用 InstantiationAwareBeanPostProcessor#postProcessProperties 方法来完成属性注入。

.6. InstantiationAwareBeanPostProcessor#postProcessPropertyValues

然后再执行 InstantiationAwareBeanPostProcessor#postProcessPropertyValues 。这个方法马上从 5.1 开始要废弃掉,使用上述 postProcessProperties 代替。

到这里 populateBean 方法结束。

.7. AutowiredAnnotationBeanPostProcessor#setBeanFactory(DefaultListableBeanFactory)

.8. BeanPostProcessor#postProcessBeforeInitialization

调用 BeanPostProcessor#postProcessBeforeInitialization 方法。

.9. InitializingBean#afterPropertiesSet()

.10. init-method

init 方法。

.11. BeanPostProcessor#postProcessAfterInitialization

调用 BeanPostProcessor#postProcessAfterInitialization 方法。

Bean 销毁流程

  1. 调用 beanFactory.destroyBean(bean) 方法,开始销毁 Bean。

  2. 调用 DestructionAwareBeanPostProcessor#postProcessBeforeDestruction(Object bean, String beanName)ApplicationListenerDetector 就是一个 DestructionAwareBeanPostProcessor 。但是,Bean 销毁时,不知道为什么没有被调用。

  3. 调用 DisposableBean#destroy() 方法

  4. 如果还有 destroy-method ,接着通过反射调用 destroy-method 方法。


About Joyk


Aggregate valuable and interesting links.
Joyk means Joy of geeK