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


    回顾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的生命周期。

    用一张图表示
    在这里插入图片描述

    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)

    欢迎大家关注我的公众号【源码行动】,最新个人理解及时奉送。
    在这里插入图片描述

  • 相关阅读:
    OpenStack(queens)最小化搭建记录——控制与计算共两个节点
    CentOS7 minimal(最小化安装)后增加的软件安装
    redis
    layui 单击事件,选中 checkbox f
    DLL 引用查询工具
    自定义JS Map 函数
    修改MSSQL字段类型
    苹果ATS特性服务器配置指南 HTTPS 安卓可以用 IOS 报错。
    基础连接已经关闭: 未能为 SSL/TLS 安全通道建立信任关系。
    不能将多个项传入“Microsoft.Build.Framework.ITaskItem”类型的参数
  • 原文地址:https://www.cnblogs.com/smallstudent/p/11691358.html
Copyright © 2020-2023  润新知