Spring ApplicationContext(一)初始化过程

时间:2022-02-26 09:04:11

Spring 容器 ApplicationContext(一)初始化过程

Spring 系列目录(https://www.cnblogs.com/binarylei/p/10198698.html)

1. Spring ApplicationContext(一)初始化过程

2. Spring ApplicationContext(二)环境准备

3. Spring ApplicationContext(三)BeanFactory 初始化

4. Spring ApplicationContext(四)BeanFactory 功能扩展

5. Spring ApplicationContext(五)BeanFactoryPostProcessor

6. Spring ApplicationContext(六)BeanPostProcessor

7. Spring ApplicationContext(七)Message 源

8. Spring ApplicationContext(八)事件监听机制

9. Spring ApplicationContext(九)初始化非延迟的 bean

10. Spring ApplicationContext(十)finishRefresh

我们以 ClassPathXmlApplicationContext 作为切入点研究 ApplicationContext 的初始化过程。

public ClassPathXmlApplicationContext(String configLocation) throws BeansException {
this(new String[] {configLocation}, true, null);
} public ClassPathXmlApplicationContext(String[] configLocations, boolean refresh, ApplicationContext parent)
throws BeansException {
// 1. 设置父容器
super(parent);
// 2. 设置配置文件路径,调用 getEnvironment().resolveRequiredPlaceholders(path) 方法解析路径中的占位符
setConfigLocations(configLocations);
// 3. 刷新容器,即重新初始化 bean 工厂
if (refresh) {
refresh();
}
}

一、refresh

下面我们重点关注 refresh() 方法都作了那些事。

public void refresh() throws BeansException, IllegalStateException {
synchronized (this.startupShutdownMonitor) {
// 1. 刷新上下文环境
prepareRefresh(); // 2. 初始化 beanFactory,对配置文件进行解读
ConfigurableListableBeanFactory beanFactory = obtainFreshBeanFactory(); // 3. 对 beanFactory 进行功能扩展
prepareBeanFactory(beanFactory); try {
// 4. 专门留给子类作扩展用,这是一个空的方法
postProcessBeanFactory(beanFactory); // 5. 注册并执行 BeanFactoryPostProcessor 后置处理器
invokeBeanFactoryPostProcessors(beanFactory); // 6. 注册 BeanPostProcessor 后置处理器,在 getBean() 创建 bean 时调用
registerBeanPostProcessors(beanFactory); // 7. 初始化 Message 源,即不同语言消息体,国际化处理
initMessageSource(); // 8. 注册多播器,事件监听器的管理者
initApplicationEventMulticaster(); // 9. 专门留给子类初始化其它 bean 用,这是一个空的方法
onRefresh(); // 10. 注册监听器
registerListeners(); // 11. 初始化剩余的 bean (部分在 invokeBeanFactoryPostProcessors 已经初始化)
finishBeanFactoryInitialization(beanFactory); // 12. 完成刷新,通知生命周期处理器 LifecycleProcessor 刷新过程,同时发布 ContextRefreshedEvent 通知别人
finishRefresh();
} catch (BeansException ex) {
destroyBeans();
cancelRefresh(ex);
throw ex;
} finally {
resetCommonCaches();
}
}
}

下面概括一下 ClassPathXmlApplicationContext 初始化的步骤,并从中解释一下它为我们提供的功能。

(1) 初始化前的准备工作,例如对系统属性或者环境变量进行准备及验证。

在某种情况下项目的使用需要读取某些系统变量,而这个变量的设置很可能会影响着系统的正确性,那么 ClassPathXmlApplicationContext 为我们提供的这个准备函数就显得非常必要,它可以在 Spring 启动的时候提前对必须的变量进行存在性验证

(2) 初始化 BeanFactory,并进行 XML 文件读取。

之前有提到 ClassPathXmlApplicationContext 包含着 BeanFactory 所提供的一切特征,那么在这一步骤中将会复用 BeanFactory 中的配置文件读取解析及其他功能,这一步之后,ClassPathXmlApplicationContext 实际上就已经包含了 BeanFactory 所提提供的功能,也就是可以进行 Bean 的提取等基础操作了。

(3) 对 BeanFactory 进行各种功能填充。

@Qualifier 与 @Autowired 应该是大家非常熟悉的注解,那么这两个注解正是在这一步骤中增加的支持。

(4) 子类覆盖方法做额外的处理。

Spring 之所以强大,为世人所推崇,除了它功能上为大家提供了便例外,还有一方面是它的完美架构,开放式的架构让使用它的程序员很容易根据业务需要扩展已经存在的功能。这种开放式的设计在 Spring 中随处可见,例如在本例中就提供了一个空的函数实现 postProcessBeanFactory 来方便程序员在业务上做进一步扩展。

(5) 激活各种 BeanFactory 处理器。

(6) 注册拦截 bean 创建的 bean 处理器,这里只是注册,真正的调用是在 getbean 时候。

(7) 为上下文初始化 Message 源,即对不同语言的消息体进行国际化处理。

(8) 初始化应用消息广播器,并放人 "applicationeventMulticaster" bean中。

(9) 留给子类来初始化其他的 bean。

(10) 在所有注册的 bean 中查找 listener bean,注册到消息广播器中。

(11) 初始化剩下的单实例(非惰性的)。

(12) 完成刷新过程,通知生命周期处理器 lifecycleProcessor 刷新过程,同时发出 ContextRefreshEvent 通知别人。


每天用心记录一点点。内容也许不重要,但习惯很重要!

Spring ApplicationContext(一)初始化过程的更多相关文章

  1. Spring IoC容器初始化过程学习

    IoC容器是什么?IoC文英全称Inversion of Control,即控制反转,我么可以这么理解IoC容器: 把某些业务对象的的控制权交给一个平台或者框架来同一管理,这个同一管理的平台可以称为I ...

  2. Spring Ioc 容器初始化过程

    IOC 是如何工作的? 通过 ApplicationContext 创建 Spring 容器,容器读取配置文件 "/beans.xml" 并管理定义的 Bean 实例对象.   通 ...

  3. 【初探Spring】------Spring IOC(三):初始化过程---Resource定位

    我们知道Spring的IoC起到了一个容器的作用,其中装得都是各种各样的Bean.同时在我们刚刚开始学习Spring的时候都是通过xml文件来定义Bean,Spring会某种方式加载这些xml文件,然 ...

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

    回顾Bean与BeanDefinition的关系. BeanFactory容器. ApplicationContext上下文. 首先总结下: 开发人员定义Bean信息:分为XML形式定义:注解式定义 ...

  5. [心得体会]Spring容器的初始化

    1. Spring容器的初始化过程 public AnnotationConfigApplicationContext(Class<?>... annotatedClasses) {   ...

  6. 03&period;Spring IoC 容器 - 初始化

    基本概念 Spring IoC 容器的初始化过程在监听器 ContextLoaderListener 类中定义. 具体由该类的的 configureAndRefreshWebApplicationCo ...

  7. spring容器的启动过程

    spring的启动过程: 首先,对于一个web应用,其部署在web容器中,web容器提供其一个全局的上下文环境,这个上下文就是ServletContext,其为后面的spring IoC容器提供宿主环 ...

  8. 【初探Spring】------Spring IOC(二):初始化过程---简介

    首先我们先来看看如下一段代码 ClassPathResource resource = new ClassPathResource("bean.xml"); DefaultList ...

  9. Spring IoC容器的初始化过程

    Spring IoC容器的初始化包括 BeanDefinition的Resource定位.载入和注册 这三个基本的过程.IoC容器的初始化过程不包含Bean依赖注入的实现.Bean依赖的注入一般会发生 ...

随机推荐

  1. &lbrack;转&rsqb; nodemon 基本配置与使用

    在开发环境下,往往需要一个工具来自动重启项目工程,之前接触过 python 的 supervisor,现在写 node 的时候发现 supervisior 在很多地方都有他的身影,node 也有一个 ...

  2. 【bzoj2049】&lbrack;Sdoi2008&rsqb;Cave 洞穴勘测 link-cut-tree

    2016-05-30  11:04:51 学习了link-cut-tree 二中神犇封禹的讲义感觉讲的超级清晰易懂啊(没有的可以q窝 算是模板吧 #include<bits/stdc++.h&g ...

  3. jenkins maven svn 部署web项目到本地Tomcat

    查了N多网页,折腾了几个小时,终于部署成功,部署的过程比较坎坷,遇到各种问题,记录一下,不管大家是否会遇到的同样的问题,希望有所帮助: 常规操作: 1.下载jenkins,必须要做的一步,http:/ ...

  4. 关于High-Resolution Timer&lpar;了解&rpar;

    如果一个系统包含高精度性能计数器(HRPC,high-resolution performance counter)则此系统提供高精度定时器.你可以使用API函数QueryPerformanceFre ...

  5. Android中BroadCast与Activity之间的通信

    在看本文之前,假设你对于Android的广播机制不是非常了解.建议先行阅读我转载的一篇博文:图解 Android 广播机制. 因为本案例比較简单,故直接在此贴出代码,不做过多的阐述. 先上效果截图: ...

  6. &lbrack;笔记&rsqb;ACM笔记 - 排序小技巧

    Description 一个数组,要求先对前n个数字排序(以方便后续操作):又要求对前n+i个数字排序:又要求对前n+j - 前n+k个数字排序(i.j.k的大小远小于n,且i.j.k间没有大小关系) ...

  7. 在linux上安装dotnetcore

    dotnet core已经出来有一段时间了,不是什么新名词了.但这个技术,目前还是比较新的,企业也没有普遍应用.它最大的亮点就是跨平台,也就是我们写的c#代码,可以运行在linux上. 在国内学习do ...

  8. PS与PL协同设计

    https://blog.csdn.net/Fei_Yang_YF/article/details/79676172 什么是PS和PL ZYNQ-7000是Xilinx推出的一款全可编程片上系统(Al ...

  9. Python分页转Mybatis pagehelper格式分页

    最近工作里遇到一个需求要把之前用Java写的一个http接口替换成用Python写的,出参是带了mybatis pageHelper中PageInfo信息的一个JSON串,而Python这边分页不会涉 ...

  10. Python中,os&period;listdir遍历纯数字文件乱序如何解决

    Python中,os.listdir遍历纯数字文件乱序如何解决 日常跑深度学习视觉相关代码时,常常需要对数据集进行处理.许多图像文件名是利用纯数字递增的方式命名.通常所用的排序函数sort(),是按照 ...