Springboot 启动详解
1.前言
最近一直在看Springboot和springcloud代码,看了将近20多天,对这两个系统的认知总算是入了门。后续应该会有一个系列的文章,本文就先从Springboot的启动入手.
2.容器初始化

上面的代码是Springboot的入口,现在从run方法进去

点击进来后到了这里就会分成两步
1.生成一个SpringApplication对象
2.调用生成的对象的run方法
【2.1】我们先看SpringApplication的构造器是如何生成一个SpringApplication对象

1.推断程序类型,推断规则在2.1.1
2.查找ApplicationContextInitializer的实现类,ApplicationContextInitializer是Spring框架的接口,在ApplicationContext的初始化之前,需要逐一调用ApplicationContextInitializer的实现类的initialize方法。

3.查找中ApplicationListener的实现类,Springboot大量的采用了事件监听机制,ApplicationListener负责将监听事件并广播出去。后续我们会详细讲解
【2.1.1】判断程序类型

至此SpringApplication构造初始化就完成了。
3.容器启动
调用生成的对象的run方法

【3.1】记录时间
Springboot内部记录流程节点花费时间的工具类
【3.2】获取ApplicationRunListener

这里通过SpringApplicationRunListeners 封装了多个SpringApplicationRunListener。在容器的启动过程中,springboot将这个过程分为了五步

started(run方法执行的时候立马执行;对应事件的类型是ApplicationStartedEvent)
environmentPrepared(ApplicationContext创建之前并且环境信息准备好的时候调用;对应事件的类型是ApplicationEnvironmentPreparedEvent)
contextPrepared(ApplicationContext创建好并且在source加载之前调用一次;没有具体的对应事件)
contextLoaded(ApplicationContext创建并加载之后并在refresh之前调用;对应事件的类型是ApplicationPreparedEvent)
finished(run方法结束之前调用;对应事件的类型是ApplicationReadyEvent或ApplicationFailedEvent)
同时,SpringApplicationRunListener 只有一个实现类 EventPublishingRunListener,所以上述5个步骤的最终实现都会在 EventPublishingRunListener中。
我们看看start方法

这里的 ApplicationStartedEvent 继承 SpringApplicationEvent

再看publishEvent是如何把Event推送出去的

看到这边,发现最后发送event的还是ApplicationListener

这里一整套的封装,就是为了这边发送事件

【3.3】创建容器

【3.3.1】创建Environment

【3.3.2】创建容器

【3.3.3】SpringApplication的init

找到所有ApplicationContextInitializer的实现类,调用他们的initialize方法。
【3.3.4】加载mainsource到容器
【3.3.5】refresh,BeanFactory的设置,BeanFactoryPostProcessor接口的执行、BeanPostProcessor接口的执行、自动化配置类的解析、条件注解的解析、国际化的初始化
【3.4】容器创建之后

【3.4.1】Runer实现类
调用ApplicationRunner和CommandLineRunner的实现类

4.Springboot启动的扩展
上述讲了springboot的启动流程,那如果我们想在启动的时候自定义一些操作,可以考虑以下几种方式。
【4.1】对容器的操作
实现 ApplicationContextInitializer 接口,重写initialize方法

需要注意的是,这个bean需要在META-INF/spring.factories中注册上才可以被扫描到

【4.2】监听5大事件
实现 ApplicationListener

【4.3】实现 ApplicationRunner 或者 CommandLineRunner

以上,就是Springboot的启动流程,里面还有几处细节,后续会慢慢更新
Springboot 启动详解的更多相关文章
- springboot配置详解
springboot配置详解 Author:SimpleWu properteis文件属性参考大全 springboot默认加载配置 SpringBoot使用两种全局的配置文件,全局配置文件可以对一些 ...
- 深入浅出mybatis之启动详解
深入浅出mybatis之启动详解 MyBatis功能丰富,但使用起来非常简单明了,今天我们来追踪一下它的启动过程. 目录 如何启动MyBatis 如何使用MyBatis MyBatis启动过程 如何启 ...
- springboot项目--传入参数校验-----SpringBoot开发详解(五)--Controller接收参数以及参数校验----https://blog.csdn.net/qq_31001665/article/details/71075743
https://blog.csdn.net/qq_31001665/article/details/71075743 springboot项目--传入参数校验-----SpringBoot开发详解(五 ...
- SpringBoot @ConfigurationProperties详解
文章目录 简介 添加依赖关系 一个简单的例子 属性嵌套 @ConfigurationProperties和@Bean 属性验证 属性转换 自定义Converter SpringBoot @Config ...
- Spring Boot2 系列教程 (二) | 第一个 SpringBoot 工程详解
微信公众号:一个优秀的废人 如有问题或建议,请后台留言,我会尽力解决你的问题. 前言 哎呦喂,按照以往的惯例今天周六我的安排应该是待在家学学猫叫啥的.但是今年这种日子就可能一去不复返了,没法办法啊.前 ...
- Linux 启动详解之init
1.init初探 init是Linux系统操作中不可缺少的程序之一.init进程,它是一个由内核启动的用户级进程,然后由它来启动后面的任务,包括多用户环境,网络等. 内核会在过去曾使用过init的几个 ...
- Linux启动详解
<概述> Linux启动大致分为一下几个步骤,详细的启动步骤在<启动分析>中详解. 1:首先bios加电自检,初始化(这个过程会检测相关硬件(cpu,内存,显卡,硬盘等)) 2 ...
- Linux开机启动详解
Linux开机启动程序详解 我们假设大家已经熟悉其它操作系统的引导过程,了解硬件的自检引导步骤,就只从Linux操作系统的引导加载程序(对个人电脑而言通常是LILO)开始,介绍Linux开机引导的步骤 ...
- Hadoop- 集群启动详解
NameNode启动过程详解 第一次启动:HDFS格式化后,生成fsimage文件 hdf
随机推荐
- Educational Codeforces Round 58 (Rated for Div. 2) F dp + 优化(新坑) + 离线处理
https://codeforces.com/contest/1101/problem/F 题意 有n个城市,m辆卡车,每辆卡车有起点\(s_i\),终点\(f_i\),每公里油耗\(c_i\),可加 ...
- centos7安装配置nfs
操作系统版本:3.10.0-123.el7.x86_64 192.168.137.11 nfs服务端 192.168.137.10 nfs客户端 一.安装nfs服务端(在192.168.137.1 ...
- Toggle组件切换开关,控制开关图片显示与隐藏
UGUI_Image 组件简单笔记 Rect Transform:用于控制 UI 物体的基本属性 Image 基本使用 1.Image 组件是用于显示图片资源的.使用方式有两种:1.显示纯粹的颜色:2 ...
- REdis zset和double
平台:x86_64 结论:Zset的最大分数不要超过18014398509481982(17位数字,54位二进制),否则不会得到期望的值. REdis:5.0.4 Zset采用double存储分数值( ...
- noip第27课资料
- Oracle 12c client with .NET legacy Oracle driver
如果使用Oracle 12c Client和.NET的Oracle driver,你很可能会碰到跟下面一样的问题: https://www.codeproject.com/Questions/8767 ...
- RabbitMQ 适用于云计算集群的远程调用(RPC)
在云计算环境中,很多时候需要用它其他机器的计算资源,我们有可能会在接收到Message进行处理时,会把一部分计算任务分配到其他节点来完成.那么,RabbitMQ如何使用RPC呢?在本篇文章中,我们将会 ...
- 【腾讯Bugly干货分享】Android 新一代多渠道打包神器
关于作者: 李涛,腾讯Android工程师,14年加入腾讯SNG增值产品部,期间主要负责手Q动漫.企鹅电竞等项目的功能开发和技术优化.业务时间喜欢折腾新技术,写一些技术文章,个人技术博客:www.lt ...
- Senparc.Weixin.TenPay 正式发布
微信支付刚出来的时候,和公众号的绑定关系很深(甚至旧版本使用的就是公众号的appId),随着微信生态的逐步丰富,微信支付越来越成为一个独立的平台,同时服务于公众号.小程序.开放平台.企业号/企业微信等 ...
- JVM之虚拟机类加载机制
有兴趣可以先参考前面的几篇JVM总结: JVM自动内存管理机制-Java内存区域(上) JVM自动内存管理机制-Java内存区域(下) JVM垃圾收集器与内存分配策略(一) 我们知道,在编写一 ...