powerdesign怎么画分析类图_Spring容器是怎么初始化的

Spring容器是怎么初始化的

原创声明

本人署名原创文章,未经许可不支持转载。本公众号所有文章均原创,为了容易理解和记忆,文章以图解为主、代码为辅。如果您感兴趣,欢迎关注!

文/吴潇(Java Senior)

本文分析Spring容器初始化过程。在Spring Framework中,所有类型的容器都是由ApplicationContext接口表示的,而AbstractApplicationContext是这个接口的第一个实现,包含适用于各类容器的公共代码。所以我们分析容器初始化过程,主要是分析AbstractApplicationContext中跟初始化相关的代码。

a33dcef943ac4d824f9b8a3cfd3afeef.png

类结构

如果从Web应用中常用的XmlWebApplicationContext容器开始,不断查找父类,可以得知Spring容器的主体代码在AbstractApplicationContext这个类中。Spring容器类的继承关系如下图所示。

88b33e01ea712254628f11b9e278500b.png

AbstractApplicationContext的父类DefaultResourceLoader只负责加载资源,AbstractApplicationContext在内部维护一个BeanFactory(负责管理bean definition,今后将单独撰文分析),并且管理由这个BeanFactory创建的bean,并且AbstractApplicationContext还负责检测在BeanFactory中定义的特殊bean,从而实现容器自身功能以及支持扩展。

顺便讲一个用Idea快速看UML类图的技巧

Spring除提供多种类型的容器,还为Bean定义提供xml、注解、Java等多种配置方式,涉及类比较多,我们可能对ApplicationContext、BeanFactory等的关系感到困惑,其实可用一张图概括如下。

d003813ce56ccb4b8ae6739052ff1b62.png

上图看不清没关系,用Intellij IDEA打开任何一个使用到Spring的项目,找到XmlWebApplicationContext类,把光标移到类名上,使用以下功能即可立即生成UML。

382a0f64b0386eff7ec93095d2393b8f.png

特殊作用的Bean

接着前面,我们说到AbstractApplicationContext内部包含一个BeanFactory,它负责为容器创建bean;而AbstractApplicationContext负责检测BeanFactory中定义的bean是不是特殊bean,并且使用这些特殊bean完成相关的功能。例如,类型为MessageSource的bean负责为Spring翻译文本(名称必须为messageSource),类型为ApplicationEventMulticaster的bean负责为Spring容器发送事件(名称必须定义为applicationEventMulticaster)。

比较常用的特殊bean包括BeanFactoryPostProcessor和BeanPostProcessor,其中,BeanFactoryPostProcessor负责对容器整体进行一些修改或功能扩展,而BeanPostProcessor则负责对每一个普通的bean进行一个修改或扩展。用户只要把实现了这两个接口的bean部署在容器中,就可以对Spring容器进行扩展了。

初始化过程(refresh)

AbstractApplicationContext的初始化过程就体现在refresh方法中。

1)首先,把容器定义中的占位符变量(以$符号开头的属性变量)替换为真正的值(AbstractApplicationContext只定义了一个算法框架,具体实现在子类中),然后检查必须解析的占位符变量替换成功没有,如果有$变量未解析,则抛出MissingRequiredPropertiesException,停止初始化。

2)然后,刷新内部的bean factory(即调用refreshBeanFactory),并且返回刷新后的bean factory。这一步操作所做的主要工作,用通俗的语言来描述就是,让bean factory重新加载bean definition配置。

3)得到bean factory之后,对这个bean factory进行一系列配置,例如设置bean class loader等,把bean factory所依赖的组件传给bean factory,例如BeanExpressionResolver和PropertyEditorRegistrar。同时,在bean factory标记一些特殊的类,让他们不参与到autowiring,注册一些特殊的singleton对象到bean factory。

4)在bean definition加载完成后(实例化所有bean之前),配置BeanPostProcessors,把它们注册到bean factory中。

5)调用BeanFactoryPostProcessor,对容器进行一些处理。

6)实例化并调用BeanPostProcessor。

7)创建MessageSource。

8)创建ApplicationEventMulticaster。

9)创建其他特殊bean。

10)注册事件监听器。

11)实例化所有非lazy-init的singleton bean。

12)清理掉容器中的资源缓存等。

13)创建LifecycleProcessor类型的特殊bean,再去调用这个bean的onRefresh方法,去执行其他与refresh相关的工作。

14)在容器中发布ContextRefreshedEvent事件,代表容器已刷新(初始化)完成。

以上就是AbstractApplicationContext中refresh的执行动作。

以上我们分析了Spring容器的初始化过程,希望对您的工作和面试都有帮助。如果对互联网编程技术、Java、Spring、Android、C/C++、Linux、个性化推荐、Community Detection、Machine Learning、Deep Learning、Data Mining、Gnuplot、LaTeX等技术感兴趣的话,欢迎关注本公众号(不限于Java)。

25ad91717f2066616a1e3f52192b1476.png
  • 0
    点赞
  • 0
    收藏
    觉得还不错? 一键收藏
  • 0
    评论
评论
添加红包

请填写红包祝福语或标题

红包个数最小为10个

红包金额最低5元

当前余额3.43前往充值 >
需支付:10.00
成就一亿技术人!
领取后你会自动成为博主和红包主的粉丝 规则
hope_wisdom
发出的红包
实付
使用余额支付
点击重新获取
扫码支付
钱包余额 0

抵扣说明:

1.余额是钱包充值的虚拟货币,按照1:1的比例进行支付金额的抵扣。
2.余额无法直接购买下载,可以购买VIP、付费专栏及课程。

余额充值