欢迎您访问程序员文章站本站旨在为大家提供分享程序员计算机编程知识!
您现在的位置是: 首页  >  IT编程

spring源码分析系列5:ApplicationContext的初始化与Bean生命周期

程序员文章站 2023-11-13 13:48:04
回顾 "Bean与BeanDefinition的关系" . BeanFactory容器. ApplicationContext上下文. 首先总结下: 1. 开发人员定义Bean信息:分为XML形式定义;注解式定义 2. ApplicationContext搜集Bean的定义;存储到BeabFacto ......

回顾bean与beandefinition的关系. beanfactory容器. applicationcontext上下文.

首先总结下:

  1. 开发人员定义bean信息:分为xml形式定义;注解式定义
  2. applicationcontext搜集bean的定义;存储到beabfactory容器的中。
  3. beanfactory根据这些beandefinition创建bean.缓存起来供我们使用。

[开发人员]--标注-->[bean定义] ---搜集 -->[beandefinition]---创建-->[bean]

此节:我们从代码层面分析此过程.

refresh()

refresh()方法描述了applicationcontext的初始化过程,这个过程大部分工作都是执行bean定义到beandefinition到bean的过程。

refresh()大致可以分为五部分来看:

1.beandefinition入库前准备阶段

  • preparerefresh();:主要工作环境属性的初始化,校验。
  • obtainfreshbeanfactory();: 准备一个beanfactory()(注:xml配置形式的bean大多在此时执行了搜集入库)
  • preparebeanfactory(beanfactory);:配置beanfactory的相关信息,包括类加载;类加载器,解析器,需要的依赖和需要忽略的依赖,早期的bean级别后处理器,创建环境相关bean
  • postprocessbeanfactory(beanfactory); 该方法只要是针对web类型的上下文中的增加配置beanfactory的相关属性。

总的的来说,此阶段是在做beanfactory的相关配置。

2.beandefinition搜集入库阶段

  • invokebeanfactorypostprocessors(beanfactory):此方法主要了搜集注解型beandefinition,注册这些beandefinition, 执行beanfactorypostprocessor.postprocessbeanfactory()方法,做入库时的修改操作。

此过程非常的精妙。由postprocessorregistrationdelegate.invokebeanfactorypostprocessors()全全负责,
postprocessorregistrationdelegate.invokebeanfactorypostprocessors()方法上本质就干了两件事

  1. 执行注册型beanfactorypostprocessor:此时有个重要的configurationclasspostprocessor注册器,此类会将注解配置型的beandefinition找到,并注册到beanfactory中。
  2. 执行普通类型的beanfactorypostprocessor:做入库的修改操作。

3.部分特殊功能的bean提前创建
此阶段把少部分特殊用处的beandefinition先创建bean供使用。

  • registerbeanpostprocessors(beanfactory);实例化一些beanpostprocessor为将来的beandefinition生成bean时做准备。。
  • initmessagesource(); 初始化applicationcontext的国际化相关组件bean,消息绑定,消息解析
  • initapplicationeventmulticaster();:初始化广播器组件bean,用于初始化过程中广播阶段性事件。
  • onrefresh(); 初始化子类中特殊beans(也算是一个扩展点)
  • registerlisteners();:将容器中的监听器bean,设置到广播器中去。

4.普通beandefinition生成bean阶段
此阶段是大部分beandefinition生成bean的阶段。

  • finishbeanfactoryinitialization(beanfactory);:
    此过程,就是上篇文章说的 ,applicationcontext上下文触发beanfactory内部的beandefinition创建bean

    我们想象一个场景: 先往一个机器内先放入原料beandefinition后,然后再按下开关开始制造.applicationcontext在此处就好比按下开关.开始bean的制造,bean的制作过程是一条流水线,流水线上有不同类型的机器对原料做不同的处理,最终得到bean

applicationcontext调用defaultlistablebeanfactory.preinstantiatesingletons()开始触发bean的创建:

dogetbean:

  1. 首先检查仓库中是否已经创建过此bean,有取出来
  2. 没有就准备走流水线创建bean创建.
  3. 创建前先检查物料有没有?有,标记当前bean在创建中
  4. 检查是否有依赖,有的话,先去加载创建依赖bean. 又回到了1
  5. 判断作用域,上createbean()流水线准备执行。

dogetbean->createbean:

  1. 加载bean的class类
  2. 验证以及准备需要覆盖的方法

dogetbean->createbean->代理对象: 返回代理对象

  1. 创建代理对象:给beanpostprocessors 一个机会来返回代理对象来代替真正的实例(此处返回的是针对自定义targetsource的bean)

dogetbean->createbean->docreatebean:没有创建自定义代理对象继续执行

  1. 使用合适的实例化策略来创建bean(工厂方法、构造函数自动注入、简单初始化),并得到bean包装类beanwrapper对象。
  2. 调用beandefinitionpostprocessor后置处理器,修改 beandefinition
  3. 解决单例模式的循环依赖:解决办法是尽早暴露bean的引用到缓存中,让其他对象可以能引用到他
  4. populatebean设置bean的属性
  5. initializebean:

dogetbean->createbean->docreatebean->initializebean 实例化bean

  1. invokeawaremethods:执行_awre类型的方法
  2. applybeanpostprocessorsbeforeinitialization执行beanpostprocessor的前置方法
  3. invokeinitmethods: 执行initializingbean接口的afterpropertiesset ,invokecustominitmethod执行自定义的init-method方法
  4. applybeanpostprocessorsafterinitialization:执行beanpostprocessor的后置方法
  5. 返回bean. 至此beandefinition到bean的生产过程完成。

5.applicationcontext的收尾阶段

  • finishrefresh();
    收尾阶段其实也算是applicationcontext的扩展点。lifecycle接口生命周期接口,

    (1.首先会从bean容器中获取lifecycleprocessor类型的bean,如果没有则创建一个默认的defaultlifecycleprocessor。lifecycleprocessor是干嘛用的?lifecycleprocessor是用来处理lifecycle接口的bean的。

    (2.使用获得lifecycleprocessor执行实现了lifecycle接口的bean的start()方法

    (3.发布上下文初始化完成事件

    (4.participate in livebeansview mbean, if active.不是很清楚干嘛的。

bean的生命周期

看完了refresh()方法。我们再来总结下bean的生命周期。

用一张图表示
spring源码分析系列5:ApplicationContext的初始化与Bean生命周期

bean的完整生命周期分为四个阶段:

  1. 第一阶段:实例化阶段。
    从bean定义的收集到beandefinition的入库顺序执行
    beandefinitionregistrypostprocessor注册处理器,注册一些beandefinition
    beanfactorypostprocessor,对入库的beandefinition进行定义的修改。
    beanwrapper的产生,beanwrapper是bean的早期产品。
    populatebean()执行属性的设置
    总结:此阶段是beandefinition->beanwrapper ,各种属性的设置

  2. 第二阶段:初始化阶段:主要是执行各种初始化方法
    invokeawaremethods(beanname, bean);执行aware属性的相关设置。
    beanpostprocessor.postprocessbeforeinitialization前置方法的执行,
    如果实现了initializingbean.afterpropertiesset()则执行此方法
    执行自定义的initmethod方法。
    beanpostprocessor.postprocessbeforeinitialization后置方法的执行,

  3. 第三阶段:使用阶段
    getbean从容器的缓存中取出bean

  4. 第四阶段:销毁阶段
    执行disposablebean.distroy方法
    执行自定义detry-method

总结:

整个spring初始化过程可以看做是

  • 物料(beandefinition)的搜集入库(beanfactory)
  • 生产线(getbean())取出物料创建成品(bean)
  • 成品(bean)入库(beanfactory)

欢迎大家关注我的公众号【源码行动】,最新个人理解及时奉送。
spring源码分析系列5:ApplicationContext的初始化与Bean生命周期