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. redis----------windows下安装redis以及PHP的redis扩展

    1.redis简介 redis是一个key-value存储系统.和Memcached类似,它支持存储的value类型相对更多,包括string(字符串).list(链表).set(集合).zset(s ...

  2. SV coverage

    covergroup是对coverage model的一种包装,每个covergroup可以包含: 1) sync event来触发采样, 2) 很多coverpoint, 3) cross cove ...

  3. tensorflow变量

    tensorflow变量: 1.神经网络中的参数权重,偏置等可以作为张量保存到tensorflow的变量中 2.tensorflow变量必须被初始化 3.可被保存到文件中,下次使用重新加载即可 ten ...

  4. j2ee高级开发技术课程第六周

    一.jsf(java server faces)的运行原理(工作方式) 1.jsf应用是事件驱动的,当一个事件发生时(比如用户单击一个按钮),事件通知通过HTTP发往服务器,服务器端使用叫做Faces ...

  5. 软件工程实践小项目之模拟wc.exe的小程序

    github源码和工程文件地址:https://github.com/Jackchenyu/Word_counts/tree/smart 基本要求:要实现wc的基本功能即文件中字符数.单词数.行数的统 ...

  6. MySQL插入命令_INSERT INTO

    MySQL允许将一个或多个元组插入已存在的table中. 格式:INSERT INTO  表名 (属性名1,属性名2,属性名3) VALUES (value1,value2,value3);     ...

  7. liteos 从入门到放弃

    这两天收到一份sdk,hisi 3516cv200 liteos的sdk 正好手头有硬件,就随便编译玩玩. 解压sdk. Hi3518E_SDK_V5.0.5.0 ll@ubuntu:~/work20 ...

  8. 获奖感想和python学习心得

    一,获奖感想 很荣幸能成为小黄杉的获得者,也很感谢老师对我的这份鼓励和期望.回顾本学期的python学习中,我从一名对编程一无所知的小白,成为一名刚入门的程序猿.首先,我要感谢我的任课老师娄嘉鹏老师, ...

  9. 剑指offer(41)和为S的连续正数序列

    题目描述 小明很喜欢数学,有一天他在做数学作业时,要求计算出9~16的和,他马上就写出了正确答案是100.但是他并不满足于此,他在想究竟有多少种连续的正数序列的和为100(至少包括两个数).没多久,他 ...

  10. mysql 5.7 运维命令

    MySQL安装 1)卸载旧版本 a) 停掉mysql #pkill -9 mysqld b) 查看rpm包 # rpm -qa|grep -i mysql c) 删除 #yum -y remove m ...