前言
我们使用SpringMVC开发Web工程的时候,除了配置文件比较繁琐之外,项目发布还需要手动挂载到一个Web容器中。这无疑给我们的项目开发带来了很多的不便利。那SpringBoot通过集成内嵌Web容器的方式,让我们省去了很多繁琐的配置以及手动发布的步骤。那么,SpringBoot是如何做到这一点的呢?下面我们结合SpringBoot实现内嵌Tomcat的逻辑来了解一下。
SpringBoot集成内嵌Tomcat
SpringBoot默认集成了三种Web服务器,分别是Tomcat、Undertow和Jetty。默认使用的是Tomcat。我们想要看看SpringBoot的实现步骤,首先要想到起点肯定是配置类。那结合SpringBoot自动装配的原理知识,我们知道SpringBoot在启动的时候会自动扫描所有spring.factories
文件中以 org.springframework.boot.autoconfigure.EnableAutoConfiguration
为key的所有自动配置类并根据条件进行加载。我们首先看一下源码中spring-boot-autoconfigure
模块下的spring.factories
文件中有没有关于Web服务器的配置选项。我们的查看结果如下图所示:

不出我们所料,果然有关于Web容器的两个配置类。我们先点开EmbeddedWebServerFactoryCustomizerAutoConfiguration
看一眼:

由于我们的web的starter是默认引入的tomcat的内嵌依赖包,所以上下文中肯定有Tomcat
类,所以会向容器中注入一个Tomcat服务器工厂的自定义配置器,点开配置器我们可以看到就是装配的Tomcat服务器的端口,堆内存等等设置项,这个不是重点,我们了解一下就行。
我们来看下一个配置类ServletWebServerFactoryAutoConfiguration
:

我们可以看到,该类引入了几个关键的配置类分别就是我们SpringBoot默认集成的Web服务器的配置类。我们点开EmbeddedTomcat
配置类看一下:

我们可以看到,这里注入了一个Tomcat服务器的工厂。看着到这里,我们就知道了SpringBoot在启动过程中肯定会使用该工厂来创建并启动一个内嵌的Tomcat容器。那么,是什么时候调用该类创建并启动的Tomcat服务呢?
我们应该知道,SpringBoot在启动过程中会有刷新容器的步骤,该步骤是调用的AbstractApplicationContext.refresh()
方法,如下图所示:

那 AbstractApplicationContext.refresh()
方法里面有一个预留的抽象方法onRefresh
是在实例化bean对象之前调用的。我们知道,SpringBoot的Web环境创建的上下文对象是AnnotationConfigServletWebServerApplicationContext
,我们看一下该对象:

我们看该对象没有重写onRefresh
方法,那么肯定是该对象的父类重写了该方法。我们向上找,在其父类ServletWebServerApplicationContext
中我们可以看到重写的onRefresh
方法:

我们可以看见调用了创建webServer的方法。而在finishRefresh
方法中启动了web容器:

以上就是我们SpringBoot自动创建并启动Web容器的流程。
总结
我们从自动装配的原理出发,找到了Web容器在SpringBoot初始化阶段会加载Web容器的定制器以及生产工厂。在完成refresh之后会自动的创建和启动对应的Web容器。
文章评论