Spring Bean生命周期关键触发时机

  任何对象都有生命周期,那么Spring Bean对象创建、管理、销毁的整个生命周期个关键触发时机如何体现呢?先说结论,后续案例验证结论。

    Spring Bean生命周期关键触发时机

   根据上图可知,实际bean对象涉及生命周期的主要是一个构造器和两个后置处理器(BeanFactoryPostProcessor和BeanPostProcessor)。我们以Dubbo框架为例验证上述结论,注解版配置类如下:

  Spring Bean生命周期关键触发时机

  关注@EnableDubbo中涉及bean生命周期的部分,跟踪发现涉及的后置处理器:

  beanFactoryPostProcessor有:

    DubboConfigAliasPostProcessor

    DubboConfigEarlyInitializationPostProcessor

  实例化:

   Spring Bean生命周期关键触发时机

   时序图:

Spring Bean生命周期关键触发时机

   实例化成功后,在beanfactory单例对象中保存:

    Spring Bean生命周期关键触发时机

   那么调用呢?首先看下BeanFactoryPostProcessor接口的具体内容:

    Spring Bean生命周期关键触发时机

  那么确定postProcessBeanFactory的调用点即可。调试跟踪如下:

    Spring Bean生命周期关键触发时机

   以上跟踪调试分析,可知beanFactoryPostProcessor的实例化及调用均在refresh#invokeBeanFactoryPostProcessors中。

  类似,跟踪调试可分析出beanPostProcessor的实例化在refresh#registerBeanPostProcessors中,时序亦类似于beanFactoryPostProcessor。不同于beanFactoryPostProcessor之处在于invokeBeanFactoryPostProcessors中是解析配置文件将待注入到容器中的Bean全部依赖识别暴露出来的过程中进行,而beanPostProcessor是在以上基础上直接实例化——即beanPostProcessor实例化的过程中不在需要识别bean(个人理解)。

  关于beanPostProcessor的调用,首先看下BeanPostProcessor接口的具体内容:

    Spring Bean生命周期关键触发时机

  其调用在哪里呢?以DubboConfigDefaultPropertyValueBeanPostProcessor这个bean后置处理器为例调试跟踪如下:

    Spring Bean生命周期关键触发时机

   上图总在finishBeanFactoryInitialization中初始化registryConfig的过程中调用了beanPostProcessor。

  为什么在finishBeanFactoryInitialization中呢?因为此过程的功能就是初始化所有剩下的非懒加载的单例bean,填充属性等。上图中registryConfig就是利用beanPostProcessor赋值填充属性。

  BeanPostProcessor的调用可以参考责任链设计模式的相关内容(三、责任链模式 - 池塘里洗澡的鸭子 - 博客园 (cnblogs.com))。

  BeanPostProcessor与BeanFactoryPostProcessor的初始化、调用的不同时机,正是由于它们的作用不同导致作用域不同决定的。BeanPostProcessor是针对Bean级别的处理,可以针对某个具体的Bean;而BeanFactoryPostProcessor针对整个Bean的工厂(BeanFactory)进⾏处理。可以具化想象成一个是对产品颜色、大小的修饰,一个是对生成产品的流水线进行修饰,比如添加润滑剂使半成品更快流向下一个环节。
  关于构造器的使用就赘述了——单例新建的时候都需要用到私有的构造器,这个应该比较容易理解。


  

    

 

上一篇:Spring核心概念 - BeanFactoryPostProcessor


下一篇:spring IOC的理解,原理与实现?