Spring Boot-19-web容器启动解析

接下来了解一下 Spring Boot 中, web 环境启动的一些流程,比如 Spring Boot 是如何判断当前是否是 web 环境的,又是怎么启动 tomcat 容器的, 如何将 tomcat 替换成别的 web 容器等等

WebApplicationType

在 Spring Boot 中,一共有三种容器类型,分别是 NONE, SERVLET, REACTIVE, 我们通常用的 web 服务就是 SERVLET 环境

首先来关注一个问题, 容器是如何识别当前是那种环境的?

容器启动流程

Spring Boot 容器启动分两步, 先是 new 一个 SpringApplication 对象, 然后调用 run 方法, 在创建 SpringApplication 对象的这一步,就会决定我们的容器是哪种类型的, 我们先看一下 SpringApplication 的构造

SpringApplication 构造

image

如图这里调用了 WebApplicationType.deduceFromClasspath() 这个方法来判断容器是哪种类型的,点进去看一下

image

可以看到,这里就是通过判断几个类的存在或者不存在来确定是哪种容器类型的,默认就是 SERVLET 环境, 然后接下来再看一下 run 方法中跟容器相关的事情

run

image

进入这里的 createApplicationContext() 方法

image

这里这个方法主要作用就是通过容器类型,创建对应的 ApplicationContext

然后再来看一下我们熟悉的 refresh() 方法, 点进去

image

看一下这里的 onRefresh() 方法, 我们之前大致介绍过一下,这里详细来看一下 servlet 环境中做的事情,进入 ServletWebServerApplicationContext

image

这里进入下面的 createWebServer() 方法看一下

image

这个方法是我们重点关注的, 首先来看第一个 getWebServerFactory()

getWebServerFactory()

image

这里可以看到,我们的容器中只能有一个 ServletWebServerFactory 的实现类,多了少了都会报错.

以默认的 Tomcat 为例,接着往下看, 获取到 factory 之后,会调用 getWebServer() 这个方法, 点进去这个方法看一下,做了哪些事情

TomcatServletWebServerFactory$getWebServer

进入 TomcatServletWebServerFactorygetWebServer() 这个方法

image

这里首先 new 了一个 Tomcat 的实例,然后做了一些属性的配置,然后调用 getTomcatWebServer() 这个方法, 点进去继续往下看

image

image

这里也是做一些属性的配置,总之最后就是返回了一个 Tomcat 的实例

initPropertySources()

返回上面的 onRefresh() 方法中, 继续往下是调用了一个 initPropertySources() 方法, 点进去看一下这个方法做了些什么

image

image

image

这里就是去判断了两个环境变量,然后如果存在的话,做了个替换的操作

finishRefresh()

回到 refresh() 方法当中,再来看一下 finishRefresh() 这个方法

image

进入对应的实现类

image

这里做了两件事,先启动容器,然后推送事件

到这里整个容器启动的大致流程就完成了

总结

大致流程了解了之后,画画图来总结一下

首先是容器类型判断流程

image

然后是创建容器前的准备流程

image

容器创建流程图

image

容器启动流程图

image