述
接下来了解一下 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 构造
如图这里调用了 WebApplicationType.deduceFromClasspath()
这个方法来判断容器是哪种类型的,点进去看一下
可以看到,这里就是通过判断几个类的存在或者不存在来确定是哪种容器类型的,默认就是 SERVLET
环境, 然后接下来再看一下 run
方法中跟容器相关的事情
run
进入这里的 createApplicationContext()
方法
这里这个方法主要作用就是通过容器类型,创建对应的 ApplicationContext
然后再来看一下我们熟悉的 refresh()
方法, 点进去
看一下这里的 onRefresh()
方法, 我们之前大致介绍过一下,这里详细来看一下 servlet 环境中做的事情,进入 ServletWebServerApplicationContext
这里进入下面的 createWebServer()
方法看一下
这个方法是我们重点关注的, 首先来看第一个 getWebServerFactory()
getWebServerFactory()
这里可以看到,我们的容器中只能有一个 ServletWebServerFactory
的实现类,多了少了都会报错.
以默认的 Tomcat 为例,接着往下看, 获取到 factory 之后,会调用 getWebServer()
这个方法, 点进去这个方法看一下,做了哪些事情
TomcatServletWebServerFactory$getWebServer
进入 TomcatServletWebServerFactory
的 getWebServer()
这个方法
这里首先 new 了一个 Tomcat 的实例,然后做了一些属性的配置,然后调用 getTomcatWebServer()
这个方法, 点进去继续往下看
这里也是做一些属性的配置,总之最后就是返回了一个 Tomcat 的实例
initPropertySources()
返回上面的 onRefresh()
方法中, 继续往下是调用了一个 initPropertySources()
方法, 点进去看一下这个方法做了些什么
这里就是去判断了两个环境变量,然后如果存在的话,做了个替换的操作
finishRefresh()
回到 refresh()
方法当中,再来看一下 finishRefresh()
这个方法
进入对应的实现类
这里做了两件事,先启动容器,然后推送事件
到这里整个容器启动的大致流程就完成了
总结
大致流程了解了之后,画画图来总结一下
首先是容器类型判断流程
然后是创建容器前的准备流程
容器创建流程图
容器启动流程图