一、引言

Spring Boot 的启动虽然仅仅是执行了一个main方法,但实际上,运行流程还是比较复杂的,其中包含几个非常重要的事件回调机制。在实际生产开发中,有时候也会利用这些启动流程中的回调机制,做一些项目初始化的工作,比如内存初始化等。所以,学习Spring Boot启动流程非常重要。

二、启动流程概述

SpringApplication.run(Object, String...)方法的执行中包括以下一些关键步骤:

1、准备环境

  1. 执行ApplicationContextInitializer.initialize()
  2. 监听器SpringApplicationRunListener回调contextPrepared()
  3. 加载主配置类(启动类)定义信息
  4. 监听器SpringApplicationRunListener回调contextLoaded()

2、刷新启动IOC容器

  1. 扫描加载所有容器中的组件
  2. 从META-INF/spring.factories中获取所有的EnableAutoConfiguration组件

3、回调容器中所有的 ApplicationRunner 、CommandLineRunner 的 run() 方法

4、监听器 SpringApplicationRunListener 回调 finished()方法

三、详细流程剖析

Spring Boot的启动方法调用流程为两步:1、创建SpringApplication对象;2、执行run()方法

这句代码是一个中间的调用过程,接下来,我们将深度讲解创建SpringApplication对象和执行run()方法具体都做了哪些工作。

1、创建SpringApplication对象

通过SpringApplication的构造器,调用initialize()方法,对SpringApplication中的一些属性初始化默认值,同时,从META-INF/spring.factories找到所有ApplicationContextInitializer和ApplicationListener保存起来。

@SuppressWarnings({ "unchecked", "rawtypes" })
private void initialize(Object[] sources) {// 保存主配置类if (sources != null && sources.length > 0) {this.sources.addAll(Arrays.asList(sources));}// 判断当前应用是否为一个WEB应用this.webEnvironment = deduceWebEnvironment();// 从类路径下找到META-INF/spring.factories配置的所有ApplicationContextInitializer,然后保存起来setInitializers((Collection) getSpringFactoriesInstances(ApplicationContextInitializer.class));// 从类路径下找到META-INF/spring.factories配置的所有ApplicationListenersetListeners((Collection) getSpringFactoriesInstances(ApplicationListener.class));// 从多个主配置类中找到有main方法的主配置类this.mainApplicationClass = deduceMainApplicationClass();
}

2、运行run(String...)方法

主要做了两件事:

  • 回调:ApplicationContextInitializer和SpringApplicationRunListener;
  • 回调:ApplicationRunner和CommandLineRunner。

详细流程注释如下:

/*** Run the Spring application, creating and refreshing a new* {@link ApplicationContext}.* * @param args*            the application arguments (usually passed from a Java main*            method)* @return a running {@link ApplicationContext}*/
public ConfigurableApplicationContext run(String... args) {StopWatch stopWatch = new StopWatch();stopWatch.start();ConfigurableApplicationContext context = null;FailureAnalyzers analyzers = null;configureHeadlessProperty();// 获取SpringApplicationRunListeners,从类路径下META-INF/spring-factoriesSpringApplicationRunListeners listeners = getRunListeners(args);// 循环所有的listener,回调starting()方法listeners.starting();try {// 封装命令行参数ApplicationArguments applicationArguments = new DefaultApplicationArguments(args);/** 准备环境:* 创建环境完成后回调SpringApplicationRunListener.environmentPrepared()方法,表示* 环境准备完成。*/ConfigurableEnvironment environment = prepareEnvironment(listeners, applicationArguments);// 打印控制台的Spring 字符画Banner printedBanner = printBanner(environment);// 创建IOC容器:ApplicationContext;决定创建web IOC还是普通的IOC容器。context = createApplicationContext();// 创建错误分析对象analyzers = new FailureAnalyzers(context);/** 准备上下文环境,将environment保存到IOC容器中; 而且applyInitializers(),* 回调之前保存的所有的applicationContextInitializer的initialize()方法;* 回调所有的SpringApplicationRunListener的contextPrepareded();最后回调* 所有的SpringApplicationRunListener的contextLoaded()方法*/prepareContext(context, environment, listeners, applicationArguments, printedBanner);/** 刷新容器:IOC容器的初始化(扫描所有的配置类、@Bean等,加载并创建IOC容器中所有的组件。如果是web应用,* 还会创建嵌入式的tomcat),当执行完refreshContext()后,IOC容器即创建完毕*/refreshContext(context);/** 从IOC容器中获取所有的ApplicationRunner和CommandLineRunner,* 然后先回调ApplicationRunner 再回调 CommandLineRunner*/afterRefresh(context, applicationArguments);// 所有的SpringApplicationRunListener回调finished()方法listeners.finished(context, null);stopWatch.stop();if (this.logStartupInfo) {new StartupInfoLogger(this.mainApplicationClass).logStarted(getApplicationLog(), stopWatch);}// 整个Spring Boot应用启动完成后,返回IOC容器return context;} catch (Throwable ex) {handleRunFailure(context, listeners, analyzers, ex);throw new IllegalStateException(ex);}
}

四、总结

Spring Boot 的启动流程是:

1、准备环境

2、刷新启动IOC容器

3、回调容器中所有的 ApplicationRunner 、CommandLineRunner 的 run() 方法

4、监听器 SpringApplicationRunListener 回调 finished()方法

在“详细启动流程” 中,已经将run()方法中实际执行流程用注释的方式标记出来了,里面的方法都通过调用的方式完成了一些特定的功能,最主要的是把握他们的执行顺序和完成内容,可以通过debug的方式,并观察控制台输出和参数内容来进行追踪学习。

综上,就是关于Spring Boot启动的完整流程,欢迎文末留言。

Spring Boot————Spring Boot启动流程分析相关推荐

  1. springboot中获得app_Spring Boot 应用程序启动流程分析

    SpringBoot 有两个关键元素: @SpringBootApplication SpringApplication 以及 run() 方法 SpringApplication 这个类应该算是 S ...

  2. Spring Boot 应用程序启动流程分析

    SpringBoot 有两个关键元素: @SpringBootApplication SpringApplication 以及 run() 方法 SpringApplication 这个类应该算是 S ...

  3. spring boot 启动流程分析

    spring boot 框架凭借极简配置,一键运行和强大的第三方框架集成等特点,受到广大开发者的青睐,基本成为java开发中必不可少的基础的框架.spirng boot带给我们这么多便利的背后,它都做 ...

  4. Boot Loader的启动流程和开发经验总结

    Windows CE最大程度继承了桌面版Windows的丰富功能,但是Windows CE并不是一个通用的安装版操作系统.在形形色色的嵌入式设备世界里,一款CE系统通常只会针对某一种硬件平台生成.  ...

  5. SpringBoot启动流程分析(四):IoC容器的初始化过程

    SpringBoot系列文章简介 SpringBoot源码阅读辅助篇: Spring IoC容器与应用上下文的设计与实现 SpringBoot启动流程源码分析: SpringBoot启动流程分析(一) ...

  6. SpringBoot(十二)启动流程分析之创建应用上下文AnnotationConfigServletWebServerApplicationContext

    SpringBoot版本:2.1.1      ==>启动流程分析汇总 接上篇博客Spring Boot 2.1.1(十一)启动流程分析之设置系统属性spring.beaninfo.ignore ...

  7. Alian解读SpringBoot 2.6.0 源码(八):启动流程分析之刷新应用上下文(中)

    目录 一.背景 1.1.刷新的整体调用流程 1.2.本文解读范围 二.调用后处理器 2.1.调用在上下文中注册为beanFactory的后置处理器 2.2.invokeBeanFactoryPostP ...

  8. Alian解读SpringBoot 2.6.0 源码(七):启动流程分析之准备应用上下文

    目录 一.背景 1.1.run方法整体流程 1.2.本文解读范围 二.准备应用上下文 2.1.整体流程 2.2.设置环境 2.3.应用上下文进行后置处理 2.4.应用所有初始化器 2.5.发布应用上下 ...

  9. Alian解读SpringBoot 2.6.0 源码(六):启动流程分析之创建应用上下文

    目录 一.背景 1.1.run方法整体流程 1.2.本文解读范围 二.创建应用上下文 2.1.初始化入口 2.2.初始化AbstractApplicationContext 2.3.初始化Generi ...

  10. Alian解读SpringBoot 2.6.0 源码(八):启动流程分析之刷新应用上下文(下)

    目录 一.背景 1.1.刷新的整体调用流程 1.2.本文解读范围 二.初始化特定上下文子类中的其他特殊bean 2.1.初始化主体资源 2.2.创建web服务 三.检查监听器bean并注册它们 四.实 ...

最新文章

  1. PyTorch中的MIT ADE20K数据集的语义分割
  2. NPM 3 Beta为Windows用户带来利好消息
  3. 网络推广外包中如何让网络推广外包专员充分运用网站的市场价值?
  4. iOS学习笔记14-网络(三)WebView
  5. Java中sc在哪里关闭_node 中设置的session,在javasc 怎么获取
  6. zblog php搜索页面,Z-Blog PHP实现搜索分页
  7. HDU 2003 求绝对值
  8. 王道 —— 中断和异常
  9. nacos 本地测试_本地调试和服务器调试都无法连通-问答-阿里云开发者社区-阿里云...
  10. 网易互娱2020游戏研发实习生笔经面经
  11. 一墙之隔-看向世界和直面速度与激情
  12. 传统营销与网络营销的整合
  13. 2022计算机保研经历
  14. nvm安装成功后npm命令'npm' 不是内部或外部命令,也不是可运行的程序 或批处理文件。
  15. 2016校招面试题汇总
  16. hive报错return code 2 from org.apache.hadoop.hive.ql.exec.mr.MapRedTask
  17. linux中ifconfig无法显示ip地址
  18. 詹姆斯高斯林_詹姆斯·高斯林(James Gosling)警告《银翼杀手》的未来
  19. 2.1立即数的判断方法一
  20. Schlemm管内荧光素钠造影术/活化PⅡb/Ⅲa配体MRI显影剂/肝素标记超顺磁氧化铁粒子(Hep-SPIO)

热门文章

  1. 循环语句与条件语句_在PHP中混合条件语句和循环
  2. setname_Python线程类| setName()方法与示例
  3. 解放双手!推荐一款阿里开源的低代码工具,YYDS!
  4. 11个小技巧,玩转Spring!
  5. 第 5-7 课:Java 中的各种锁和 CAS + 面试题
  6. 漫画:什么是归并排序?
  7. CentOS7 源码编译安装NodeJS 最新版本Shell脚本
  8. maya批量操作mel_MAYA对多个模型使用当前设置批量渲染并保存图片的MEL脚本
  9. 华为手机鸿蒙系统怎么样_华为自研操作系统“鸿蒙”已用于华为手机
  10. android activity动态显示不出来,uiautomatorviewer 获取不到动态页面解决办法