Spring有两种方式加载配置,分别为xml文件、注解的方式,对于xml配置的方式相信大家都不陌生,往往通过new ClassPathXmlApplicationContext("*.xml")就能启动容器了,下面让我们来看看Spring的容器启动都做了哪些事情。

1、ClassPatchXmlApplicationContext的类图结构

从类图我们可以得到的信息:
  1,ClassPatchXmlApplicationContext是一个容器 ,是BeanFactory的子类;
  2,ClassPatchXmlApplicationContext是一个资源加载器,是ResourceLoader的子类。

2、ClassPatchXmlApplicationContext构造器

 1 public ClassPathXmlApplicationContext(
2 String[] configLocations, boolean refresh, @Nullable ApplicationContext parent)
3 throws BeansException {
4 // 调用父类构造方法
5 super(parent);
6 // 资源路径设置到当前上下文中
7 setConfigLocations(configLocations);
8 // 刷新容器
9 if (refresh) {
10 refresh();
11 }
12 }

2.1、调用父类构造器

  最终会调用到父类AbstractApplicationContext的构造方法。
  1、初始化AbstractApplicationContext的资源路径解析器resourcePatternResolver 属性;
  2、为当前上下文设置父上下文环境,若父上下文环境不为空,将父上下文环境合并到当前上下文环境中。
 1 // 构造器
2 public AbstractApplicationContext(@Nullable ApplicationContext parent) {
3 this();
4 setParent(parent);
5 }
6 // 初始化资源路径解析器
7 public AbstractApplicationContext() {
8 // 创建资源模式处理器
9 this.resourcePatternResolver = getResourcePatternResolver();
10 }
11 // 设置父容器
12 public void setParent(@Nullable ApplicationContext parent) {
13 this.parent = parent;
14 // 若父容器不为空,则将父容器的环境配置合并到当前容器中
15 if (parent != null) {
16 Environment parentEnvironment = parent.getEnvironment();
17 if (parentEnvironment instanceof ConfigurableEnvironment) {
18 getEnvironment().merge((ConfigurableEnvironment) parentEnvironment);
19 }
20 }
21 }

2.2、设置资源路径

  对父类AbstractRefreshableConfigApplicationContext的configLocations做赋值,将配置资源配置文件位置设置到当前应用程序上下文中。
 1 // 设置资源路径
2 public void setConfigLocations(@Nullable String... locations) {
3 if (locations != null) {
4 Assert.noNullElements(locations, "Config locations must not be null");
5 this.configLocations = new String[locations.length];
6 for (int i = 0; i < locations.length; i++) {
7 this.configLocations[i] = resolvePath(locations[i]).trim();
8 }
9 }
10 else {
11 this.configLocations = null;
12 }
13 }

2.3、刷新容器 - Spring的IOC容器的核心启动流程

 1 // 刷新容器的流程
2 @Override
3 public void refresh() throws BeansException, IllegalStateException {
4 synchronized (this.startupShutdownMonitor) {
5 // 容器刷新前的准备工作
6 prepareRefresh();
7 // 创建容器对象DefaultListableBeanFactory,加载xml配置文件的属性值到当前工厂中
8 ConfigurableListableBeanFactory beanFactory = obtainFreshBeanFactory();
9 // beanFactory的准备工作,对各种属性进行填充
10 prepareBeanFactory(beanFactory);
11
12 try {
13 // 子类覆盖方法做额外的处理,web中的代码有具体实现
14 postProcessBeanFactory(beanFactory);
15
16 // 调用各种beanFactory处理器
17 invokeBeanFactoryPostProcessors(beanFactory);
18
19 // 注册bean处理器,这里只是注册功能,真正调用的地方在getBean方法
20 registerBeanPostProcessors(beanFactory);
21
22 // 为上下文初始化message源,即不同语言的消息体,国际化处理,在springmvc的有实际应用
23 initMessageSource();
24
25 // 初始化事件监听多路广播器
26 initApplicationEventMulticaster();
27
28 // 留给子类来初始化其他的bean
29 onRefresh();
30
31 // 在所有注册的bean中查找listener bean,注册到消息广播器中
32 registerListeners();
33
34 // 初始化剩下的单实例(非懒加载的)
35 finishBeanFactoryInitialization(beanFactory);
36
37 // 完成刷新过程,通知生命周期处理器lifecycleProcessor刷新过程,同时发出ContextRefreshEvent通知
38 finishRefresh();
39 }
40
41 catch (BeansException ex) {
42 if (logger.isWarnEnabled()) {
43 logger.warn("Exception encountered during context initialization - " +
44 "cancelling refresh attempt: " + ex);
45 }
46
47 // 为防止bean资源占用,在异常处理中,销毁已经在前面过程中生成的单件bean
48 destroyBeans();
49
50 // 重置active标志
51 cancelRefresh(ex);
52
53 throw ex;
54 }
55 finally {
56 // 重置缓存
57 resetCommonCaches();
58 }
59 }
60 }

综上可见,Spring容器启动的核心方法,这些方法后序会做详细介绍

1、prepareRefresh()

  刷新容器前的准备工作

2、obtainFreshBeanFactory()

  创建容器,并加载配置并生成BeanDefinition,加载至缓存。为后续创建bean对象做准备工作。

3、prepareBeanFactory(beanFactory)

  beanFactory的准备工作,主要是用来为容器填充属性

4、postProcessBeanFactory(beanFactory)

  beanFactory容器的后置处理器

5、invokeBeanFactoryPostProcessors(beanFactory)

  调用各种BeanFactoryPostProcessors的后置处理器,实例化BeanFactoryPostProcessor类型的bean对象,包括ConfigurationClassPosyProcessor类对注解的处理,也是SpringBoot自动配置的基础。

6、registerBeanPostProcessors(beanFactory)

  调用各种BeanPostProcessor的后置处理器,实例化BeanPostProcessor类型的bean对象,包括对Spring AOP的自动代理创建器AspectJAwareAdvisorAutoProxyCreator的实例的创建。

7、finishBeanFactoryInitialization(beanFactory)

  初始化定义的bean实例。

8、finishRefresh()

  完成刷新过程,通知生命周期处理器lifecycleProcessor刷新过程

Spring IOC源码(一):IOC容器启动流程核心方法概览的更多相关文章

  1. Cocos2dx源码赏析(1)之启动流程与主循环

    Cocos2dx源码赏析(1)之启动流程与主循环 我们知道Cocos2dx是一款开源的跨平台游戏引擎,而学习开源项目一个较实用的办法就是读源码.所谓,"源码之前,了无秘密".而笔者 ...

  2. JVM源码分析之JVM启动流程

      原创申明:本文由公众号[猿灯塔]原创,转载请说明出处标注 “365篇原创计划”第十四篇. 今天呢!灯塔君跟大家讲: JVM源码分析之JVM启动流程 前言: 执行Java类的main方法,程序就能运 ...

  3. Spring Ioc源码分析系列--容器实例化Bean的四种方法

    Spring Ioc源码分析系列--实例化Bean的几种方法 前言 前面的文章Spring Ioc源码分析系列--Bean实例化过程(二)在讲解到bean真正通过那些方式实例化出来的时候,并没有继续分 ...

  4. 精尽Spring MVC源码分析 - WebApplicationContext 容器的初始化

    该系列文档是本人在学习 Spring MVC 的源码过程中总结下来的,可能对读者不太友好,请结合我的源码注释 Spring MVC 源码分析 GitHub 地址 进行阅读 Spring 版本:5.2. ...

  5. Tomcat源码分析之—具体启动流程分析

    从Tomcat启动调用栈可知,Bootstrap类的main方法为整个Tomcat的入口,在init初始化Bootstrap类的时候为设置Catalina的工作路径也就是Catalina_HOME信息 ...

  6. spring源码:web容器启动(li)

    web项目中可以集成spring的ApplicationContext进行bean的管理,这样使用起来bean更加便捷,能够利用到很多spring的特性.我们比较常用的web容器有jetty,tomc ...

  7. spring源码:web容器启动

    web项目中可以集成spring的ApplicationContext进行bean的管理,这样使用起来bean更加便捷,能够利用到很多spring的特性.我们比较常用的web容器有jetty,tomc ...

  8. Spring源码解析-Web容器启动过程

    Web容器启动过程,主要讲解Servlet和Spring容器结合的内容. 流程图如下: Web容器启动的Root Context是有ContextLoaderListener,一般使用spring,都 ...

  9. sping ioc 源码分析(一)-- register(componentClasses) 方法

    一.测试环境的搭建: public class Apple { } @Component public class MyComponet { } public class MyCondition im ...

  10. Fabric1.4源码解析: 链码容器启动过程

    想写点东西记录一下最近看的一些Fabric源码,本文使用的是fabric1.4的版本,所以对于其他版本的fabric,内容可能会有所不同. 本文想针对Fabric中链码容器的启动过程进行源码的解析.这 ...

随机推荐

  1. MySQL集群搭建(3)-MMM高可用架构

    1 MMM 介绍 1.1 简介 MMM 是一套支持双主故障切换以及双主日常管理的第三方软件.MMM 由 Perl 开发,用来管理和监控双主复制,虽然是双主架构,但是业务上同一时间只允许一个节点进行写入 ...

  2. 10. Fluentd部署:高可用配置

    对于高访问量的web站点或者服务,可以采用Fluentd的高可用配置模式. 消息分发语义 Fluentd设计初衷主要是用作事件日志分发系统的.这类系统支持几种不同的分发模式: 至多一次.消息被立即发送 ...

  3. JSP实现登录删除添加星座等(带样式)

    功能要求 1.完成两个页面 2.第一个登陆页面login. jsp 3.第二个用户管理页面useManage. jsp 4.有登录功能(能进行用户名密码的校验,用户名若为自己的学号密码为班级号,允许登 ...

  4. 深入理解AQS--jdk层面管程实现【管程详解的补充】

    什么是AQS 1.java.util.concurrent包中的大多数同步器实现都是围绕着共同的基础行为,比如等待队列.条件队列.独占获取.共享获取等,而这些行为的抽象就是基于AbstractQueu ...

  5. C++面向对象编程之reference

    1.声明 reference 一定要有初值,指针可以不用设初值 2. int& r = x; 表示 r 代表 x, r 用起来就是 x ,而且 reference 设完初值后再也不能代表其他变 ...

  6. Go素数筛选分析

    Go素数筛选分析 1. 素数筛选介绍 学习Go语言的过程中,遇到素数筛选的问题.这是一个经典的并发编程问题,是某大佬的代码,短短几行代码就实现了素数筛选.但是自己看完原理和代码后一脸懵逼(仅此几行能实 ...

  7. Java I/O(4):AIO和NIO中的Selector

    您好,我是湘王,这是我的博客园,欢迎您来,欢迎您再来- 在Java NIO的三大核心中,除了Channel和Buffer,剩下的就是Selector了.有的地方叫它选择器,也有叫多路复用器的(比如Ne ...

  8. 齐博x1直播神器聊天小插件

    下载地址如下:https://down.php168.com/livemsg.rar 本插件由论坛网友笨熊提供 非常感谢他给大家提供那么一个非常好用的直播必备神器. 如下图所示,大家在直播的时候,这个 ...

  9. 齐博X1到底是个什么鬼?

    什么是齐博/齐博CMS之X1? 齐博X1是齐博软件基于thinkphp5开发的内容管理系统,拓展性非常强,后台一键升级,后台提供丰富的频道模块云市插件市场.风格市场.钩子市场,所有都是一键在线安装. ...

  10. MRR和Hits@n

    使用 MRR/Hits@n 评估链路预测 平均倒数秩(Mean reciprocal rank,MRR) MRR是一种衡量搜索质量的方法.我们取一个未被破坏的节点,找到距离定义为相似性分数的" ...