SpringApplication类的直接作用是在main方法中通过自有的run方法启动spring应用。

具体的run方法为:

public static ConfigurableApplicationContext run(Object source, String... args)

该方法最终会把source传给SpringApplication的构造方法中的初始化方法:

private void initialize(Object[] sources) {

   if (sources != null && sources.length > 0) {

      this.sources.addAll(Arrays.asList(sources));

   }

   this.webEnvironment = deduceWebEnvironment();

   setInitializers((Collection) getSpringFactoriesInstances(

         ApplicationContextInitializer.class));

   setListeners((Collection) getSpringFactoriesInstances(ApplicationListener.class));

   this.mainApplicationClass = deduceMainApplicationClass();

}

该初始化方法一共做了以下几件事:

一、判断sourse长度

首先,如果sources长度大于0(即是数组或容器),则把这些sources全部传到内置的hashset中。由此可见,run方法的第一个参数中是可以传入多个source的。

二、判断web环境是否正确

this.webEnvironment = deduceWebEnvironment();

判断整个环境中是否存在javax.servlet.Servlet类和

org.springframework.web.context.ConfigurableWebApplicationContext类这两个类,如果存在话,则表示web环境正常,返回true,否则返回false。

三、设置Initializers

首先会调getSpringFactoriesInstances方法加载ApplicationContextInitializer类,这个方法最终会运行SpringFactoriesLoader.loadFactoryNames方法,这个方法的目的是从“META-INF/spring.factories文件”中加载配置。

可实际上我们一般在开发springboot项目时并没有创建过spring.factories文件,可还是自动加载了各种配置,原因如下:

在项目的main方法上一般都会设置@SpringBootApplication注解,@SpringBootApplication注解中包含了多个注解,其中有一个@EnableAutoConfiguration注解尤为重要。

通过@EnableAutoConfiguration注解会将org.springframework.boot.autoconfigure.EnableAutoConfiguration这个包作为查找META-INF/spring.factories文件的根目录,即spring.factories文件会从org.springframework.boot.autoconfigure.EnableAutoConfiguration包中查找。而这个包里面自然有已经写好的spring.factories文件了。

整个springboot中会看到很多@Enable开头的注解,所有的@Enable开头的注解的作用都是通过@Import将“特定的bean”加载到Ioc容器中。@EnableAutoConfiguration的作用就是通过SpringFactoriesLoader将所有的标注了@Configuration注解的类加载(既有boot.autoconfigure包自带的标注了@Configuration的类,也可以是自己创建的标注了@Configration的类,都会被作为配置加载)

四、设置Listeners

listener的加载与之前的Initializers加载同理,都是寻找META-INF/spring.factories文件,然后被@EnableAutoConfiguration注解把路径转移到了org.springframework.boot.autoconfigure.EnableAutoConfiguration/META-INF/spring.factories中,之后就能找到已经提前写好的相关监听配置了。

五、设置mainApplicationClass

private Class<?> deduceMainApplicationClass() {

   try {

      StackTraceElement[] stackTrace = new RuntimeException().getStackTrace();

      for (StackTraceElement stackTraceElement : stackTrace) {

         if ("main".equals(stackTraceElement.getMethodName())) {

            return Class.forName(stackTraceElement.getClassName());

         }

      }

   }

   catch (ClassNotFoundException ex) {

      // Swallow and continue

   }

   return null;

}

该方法是通过遍历栈,找到main方法,从而找到启动类,并将其赋值给mainApplicationClass属性。

SpringApplication执行流程的更多相关文章

  1. Spring Boot程序的执行流程

    Spring Boot的执行流程如下图所示:(图片来源于网络) 上图为SpringBoot启动结构图,我们发现启动流程主要分为三个部分,第一部分进行SpringApplication的初始化模块,配置 ...

  2. Spring Security Oauth2 单点登录案例实现和执行流程剖析

    Spring Security Oauth2 OAuth是一个关于授权的开放网络标准,在全世界得到的广泛的应用,目前是2.0的版本.OAuth2在“客户端”与“服务提供商”之间,设置了一个授权层(au ...

  3. Spring Security 案例实现和执行流程剖析

    Spring Security Spring Security 是 Spring 社区的一个顶级项目,也是 Spring Boot 官方推荐使用的安全框架.除了常规的认证(Authentication ...

  4. 步步深入:MySQL架构总览->查询执行流程->SQL解析顺序

    前言: 一直是想知道一条SQL语句是怎么被执行的,它执行的顺序是怎样的,然后查看总结各方资料,就有了下面这一篇博文了. 本文将从MySQL总体架构--->查询执行流程--->语句执行顺序来 ...

  5. 第二天 ci执行流程

    第二天 ci执行流程 welcome 页面 this this->load 单入口框架index.php 两个文件夹 system application定义 定义常亮路径 载入 codeign ...

  6. 轻量级前端MVVM框架avalon - 执行流程2

    接上一章 执行流程1 在这一大堆扫描绑定方法中应该会哪些实现? 首先我们看avalon能帮你做什么? 数据填充,比如表单的一些初始值,切换卡的各个面板的内容({{xxx}},{{xxx|html}}, ...

  7. [Java编程思想-学习笔记]第4章 控制执行流程

    4.1  return 关键字return有两方面的用途:一方面指定一个方法结束时返回一个值:一方面强行在return位置结束整个方法,如下所示: char test(int score) { if ...

  8. ThinkPHP2.2框架执行流程图,ThinkPHP控制器的执行流程

    ThinkPHP2.2框架执行原理.流程图在线手册 ThinkPHP控制器的执行流程 对用户的第一次URL访问 http://<serverIp>/My/index.php/Index/s ...

  9. 深入浅出Mybatis系列(十)---SQL执行流程分析(源码篇)

    最近太忙了,一直没时间继续更新博客,今天忙里偷闲继续我的Mybatis学习之旅.在前九篇中,介绍了mybatis的配置以及使用, 那么本篇将走进mybatis的源码,分析mybatis 的执行流程, ...

随机推荐

  1. mysql的一些指令

    说起来mysql,mysql其实是特别简单操作的数据库.它有一下几方面的特点,亦或者是说优点,1,支持多语言:2.移植性比较好:3,我觉得最重要的一点就是它是开源的,因为开源,所以使用广泛,4.效率比 ...

  2. tiny6410的启动参数

    bootargs=root=/dev/mtdblock2 rootfstype=yaffs2 init=/linuxrc console=ttySAC0,115200 bootcmd=nand led ...

  3. js 图片无缝滚动

    html部分 <div id="roll"> <a href="javascript:void(0)" class="prev&qu ...

  4. Lucene的深入

    Lucene创建索引 第一.创建文档对象 第二.创建Field对象(各种类型)整数String.Text.Long.Float.Double等... Field对象 包含三大属性:是否分词,是否索引, ...

  5. CentOS7查看systemctl 控制的服务的相关配置

    例如,启动配置文件 [root@Docker_Machine_192.168.31.130 ~]# systemctl show --property=FragmentPath docker Frag ...

  6. keepalived + lvs

    Keepalived原理 Keepalived原理 keepalived也是模块化设计,不同模块复杂不同的功能,下面是keepalived的组件 core check vrrp libipfwc li ...

  7. CSS 标签选择器

    CSS 标签选择器 再<stype>标签内,通过指定输入标签来配置CSS样式 <html> <head> <!-- style 设置头部标签--> &l ...

  8. 2018-2019-1 20189206 《Linux内核原理与分析》第九周作业

    #linux内核分析学习笔记 --第八章 进程的切换和系统的一般执行过程 学习目标:重点关注进程切换的过程,进程调度的时机,操作系统的基本构成以及一般的执行过程. 进程调度的时机 因为进程的调度只发生 ...

  9. 1. Dubbo原理解析-Dubbo内核实现之SPI简单介绍 (转)

    转载自  斩秋的专栏  http://blog.csdn.net/quhongwei_zhanqiu/article/details/41577159 Dubbo采用 微内核 + 插件体系,使得设计优 ...

  10. ActiveReports 大数据分析报告:贸易争端与中国企业数字化转型

    2018年11月12日至18日,亚太经合组织(APEC)领导人非正式会议首次在南太平洋最大岛国巴布亚新几内亚的首都莫尔兹比港举行,本次会议的主题是:“把握包容性机遇,拥抱数字化未来”. 面对全球不断变 ...