springboot核心原理:
  1.基于springmvc无配置文件完全注解化 + 内置web容器实现springboot框架。main函数方式的启动
  2.通过maven快速整合第三方框架
springboot两个核心
  内置的Tomcat(ServletWebServerFactoryAutoConfiguration)
  dispatcherServlet(DispathcerServletAutoConfiguration)
springboot启动流程
  1.创建SpringApplication对象
  2.调用SpringApplication.run()方法启动项目,同时返回当前容器的上下文
流程:
  1.判断当前应用的启动类型(webApplicationType):servlet?reactive?none?
  2.加载spring.factories中所有的ApplicationContextInitializer的实现类,存到集合中
  3.加载spring.factories中所有的ApplicationListener的实现类,存到集合中
  4.推断当前项目的启动main函数:在方法中抛出一个运行时异常,获取异常栈信息中main方法对应的className
启动:
  1.记录当前项目的启动耗时
  2.加载spring.factories文件中SpringApplicationRunListener的实现类EventPublishingRunListener(在后面,spring会通过多事件派发器来通知所有的事件监听器)
  3.发布starting事件
  4.发布prepareEnvironment事件:在这里,会获取到spring的配置文件,并按照优先级进行覆盖;该方法主要是完成了将application.properties配置文件配置的内容赋值到spring容器中的作用(优先级的覆盖),最后,会调用MutablePropertySources.addLast()方法
  5.根据webApplicationType来创建上下文环境(ConfigurableApplicationContext)
  6.刷新容器:在刷新容器中,会调用子类的onRefresh()方法,早onRefresh()方法中初始化dispatcherServlet、启动Tomcat容器
  8.发布started事件和running事件 
 
 public SpringApplication(ResourceLoader resourceLoader, Class<?>... primarySources) {
this.resourceLoader = resourceLoader;
Assert.notNull(primarySources, "PrimarySources must not be null");
this.primarySources = new LinkedHashSet<>(Arrays.asList(primarySources));
//判断当前应用是什么哪种类型的 none/servlet/reaction
this.webApplicationType = WebApplicationType.deduceFromClasspath();
//从META-INF/spring.factories中读取ApplicationContextInitializer的实现类,放到集合中
setInitializers((Collection) getSpringFactoriesInstances(ApplicationContextInitializer.class));
//从META-INF/spring.factories中读取ApplicationListener的实现类,放到集合中
setListeners((Collection) getSpringFactoriesInstances(ApplicationListener.class));
//获取到当前应用的启动函数 main方法
this.mainApplicationClass = deduceMainApplicationClass();
}
 public ConfigurableApplicationContext run(String... args) {
//获取时间戳,用来计算启动时间
StopWatch stopWatch = new StopWatch();
stopWatch.start();
ConfigurableApplicationContext context = null;
Collection<SpringBootExceptionReporter> exceptionReporters = new ArrayList<>();
configureHeadlessProperty();
/**
* 获取spring.factories文件中SpringApplicationRunListener的实现类
* 在调用starting的时候,会通过multicastEvent(多事件派发器)发送事件消息,会通知所有的事件监听器,让监听器判断是否对当前发布的事件感兴趣,如果感兴趣,就调用当前监听器的onApplicationEvent()方法
* 那是如何判断当前监听器是否对多事件派发器发送的事件感兴趣呢?
* supportsSourceType
* 和supportsEventType这两个方法
*/
SpringApplicationRunListeners listeners = getRunListeners(args);
listeners.starting();
try {
ApplicationArguments applicationArguments = new DefaultApplicationArguments(args);
//发布prepareEnviroment事件,在这个事件中,org.springframework.boot.context.config.ConfigFileApplicationListener#onApplicationEvent会完成spring
//boot配置文件优先级的读取和覆盖
ConfigurableEnvironment environment = prepareEnvironment(listeners, applicationArguments);
configureIgnoreBeanInfo(environment);
Banner printedBanner = printBanner(environment);
//初始化容器上下文,根据webApplicationType类型来判断
context = createApplicationContext();
exceptionReporters = getSpringFactoriesInstances(SpringBootExceptionReporter.class,
new Class[] { ConfigurableApplicationContext.class }, context);
prepareContext(context, environment, listeners, applicationArguments, printedBanner);
//刷新spring容器,在这个方法里面完成了Tomcat的初始化和dispatcherServlet的初始化
refreshContext(context);
afterRefresh(context, applicationArguments);
stopWatch.stop();
if (this.logStartupInfo) {
new StartupInfoLogger(this.mainApplicationClass).logStarted(getApplicationLog(), stopWatch);
}
listeners.started(context);
callRunners(context, applicationArguments);
}
catch (Throwable ex) {
handleRunFailure(context, ex, exceptionReporters, listeners);
throw new IllegalStateException(ex);
} try {
listeners.running(context);
}
catch (Throwable ex) {
handleRunFailure(context, ex, exceptionReporters, null);
throw new IllegalStateException(ex);
}
return context;
}

这个是springboot启动流程的源码,其中有两个点是比较重要的:

1.prepareEnviroment事件的发布(springboot配置文件的解析)

2.刷新spring容器,完成Tomcat的初始化和dispatcherServlet的初始化

springboot启动原理解析的更多相关文章

  1. SpringBoot启动原理及相关流程

    一.springboot启动原理及相关流程概览 springboot是基于spring的新型的轻量级框架,最厉害的地方当属自动配置.那我们就可以根据启动流程和相关原理来看看,如何实现传奇的自动配置 二 ...

  2. Spring Boot干货系列:(三)启动原理解析

    Spring Boot干货系列:(三)启动原理解析 2017-03-13 嘟嘟MD 嘟爷java超神学堂 前言 前面几章我们见识了SpringBoot为我们做的自动配置,确实方便快捷,但是对于新手来说 ...

  3. Spring Boot启动原理解析

    Spring Boot启动原理解析http://www.cnblogs.com/moonandstar08/p/6550758.html 前言 前面几章我们见识了SpringBoot为我们做的自动配置 ...

  4. SpringBoot启动原理

    SpringBoot启动原理 我们开发任何一个Spring Boot项目,都会用到如下的启动类: @SpringBootApplication public class Application { p ...

  5. 5、Spring Boot 2.x 启动原理解析

    1.5 Spring Boot 启动原理解析 前言 前面几章我们见识了SpringBoot为我们做的自动配置,确实方便快捷,但是对于新手来说,如果不大懂SpringBoot内部启动原理,以后难免会吃亏 ...

  6. springboot之启动原理解析

    前言 SpringBoot为我们做的自动配置,确实方便快捷,但是对于新手来说,如果不大懂SpringBoot内部启动原理,以后难免会吃亏.所以这次博主就跟你们一起一步步揭开SpringBoot的神秘面 ...

  7. springboot之启动原理解析及源码阅读

    前言 SpringBoot为我们做的自动配置,确实方便快捷,但是对于新手来说,如果不大懂SpringBoot内部启动原理,以后难免会吃亏.所以这次博主就跟你们一起一步步揭开SpringBoot的神秘面 ...

  8. SpringBoot 2.1.6 启动原理解析(一)

    小白第一次写博客,如果有不足之处烦请各位大佬指正. 用了好久的SpringBoot了,一直不清楚它内部的一些启动原理,如何加载yml文件.如何初始化bean的,今天就记录一下,新建了一个springb ...

  9. SpringBoot启动流程解析

    写在前面: 由于该系统是底层系统,以微服务形式对外暴露dubbo服务,所以本流程中SpringBoot不基于jetty或者tomcat等容器启动方式发布服务,而是以执行程序方式启动来发布(参考下图ke ...

随机推荐

  1. HDFS之NameNode

    NameNode&Secondary NameNode工作机制 1)第一阶段:namenode启动 (1)第一次启动namenode格式化后,创建fsimage和edits文件.如果不是第一次 ...

  2. 运用python实现冒泡排序算法

    冒泡排序,一个经典的排序算法,因在算法运行中,极值会像水底的气泡一样逐渐冒出来,因此而得名. 冒泡排序的过程是比较两个相邻元素的大小,然后根据大小交换位置,这样从列表左端开始冒泡,最后最大值会依次从右 ...

  3. 基于xtrabackup实现mysql备份还原

    简介 Xtrabackup2.2版之前包括4个可执行文件: innobackupex: Perl 脚本 xtrabackup: C/C++ 编译的二进制 xbstream: 支持并发写的流文件格式 x ...

  4. linux awk(gawk)

    awk的前世今生: awk名字的由来:分别取三个创始人Ah,Weiberger,Kernighan三个人的首字母. awk是一个报告生成器可以格式化输出文本内容.模式扫描和处理语言(pattern s ...

  5. Nginx服务器部署 负载均衡 反向代理

    Nginx服务器部署负载均衡反向代理 LVS Nginx HAProxy的优缺点 三种负载均衡器的优缺点说明如下: LVS的优点: 1.抗负载能力强.工作在第4层仅作分发之用,没有流量的产生,这个特点 ...

  6. easyui textbox 赋值

    $('#fireInfo').textbox('setValue', tempData.fireInfo); $('#fireStartTime').datetimebox('setValue', t ...

  7. 侠梦说pinpoint--左侧服务地图调用量和WasOn过滤

    前言 这篇文章主要是从pinpoint-web界面入手,我们的目标是弄清楚两个问题: 1. pinpoint左侧服务地图上的调用量数据是怎么查询的? 2.界面查询条件WasOnly是什么意思? 左侧服 ...

  8. Python的特有的参数传递(*和**)

    目录 值传递 引用传递 python的传递方式具有两种值传递和引用传递.除此之外,python中还允许包裹方式的参数传递,这未不确定参数个数和参数类型的函数调用提供了基础: 值传递 int.float ...

  9. luogu P4065 [JXOI2017]颜色 |随机化+前缀和

    题目描述 可怜有一个长度为 n 的正整数序列 Ai,其中相同的正整数代表着相同的颜色. 现在可怜觉得这个序列太长了,于是她决定选择一些颜色把这些颜色的所有位置都删去. 删除颜色 i 可以定义为把所有满 ...

  10. C语言I作业12-学期总结

    一.我学到的内容 二.我的收获 我完成的作业: 第一次作业 C语言I博客作业02 C语言I作业004 C语言I博客作业05 C语言I博客作业06 C语言I博客作业07 C语言I博客作业08 C语言I博 ...