SpringBoot内置Servlet容器源码解析
我们都知道,在使用 Spring Boot 时可以内嵌 Tomcat 等 Servlet 容器,通过直接执行 jar -jar命令即可启动。那么 Spring Boot 是如何检测到对应的 Servlet 容器,又如何进行自动配置的呢?对于之前自动配置的 DispatcherServlet 又是如何获取并注册的?本章就带大家来学习Spring Boot 集成 Servlet Web 容器及 DispatcherServlet 的加载过程。
Web容器自动配置
Servlet Web 服务器概述
在学习源代码之前,先来看一个结构图, 从整体上了解一下Spring Boot 对Servlet Web的支持 , 以及都包含哪些核心部分, 如图 7-1 所 示 。
图 7-1 中,第一列为 Servlet 容器名称, 表示 Spring Boot 内置支持的 Web 容器类型,目前包括 Tomcat、Jetty、 Undertow。 第列为针对不同的 Web 容器的 WebServer 实现类,用于控制 Web 容器的启动和停止等操作。第三列为创建第二列中具体 WebServer 的工厂方法类。
以上 Servlet 容器相关支持类均位于 spring-boot 项目的 org. springframework.boot.web 包下,而以上容器的具体实现位于
org.springframework.boot.web.embedded 下。
以 Tomcat 为例,通过自动配置先初始化
TomcatServletWebServerFactory 工厂类,在Spring Boot 启动过程中,该工厂类会通过其 getWebServer 方法创建 TomcatWebServer实例,启动 Tomcat 等一 系列操作。 我们先从整体上有个概念,下面再继续分析具体源码实现。
自动配置源码分析
在 Spring Boot 中,Servlet Web 容器的核心配置就是上面提到的 3 个工厂方法的实例化和BeanPostProcessor 的注册。在讲
DispatcherServletAutoConfiguration 自动配置时,我们并没有详细讲
解 其 中 的 @AutoConfigureAfter 注 解 , 该 注 解 内 指 定 的 类 为
ServletWebServerFactoryAuto-Configuration,即在完成了 Web Server 容器的自动配置之后 , 才 会 进 行 DispatcherServlet 的 自 动 配 置 。 而 本 节 要 讲 的 内 容 就 是 从ServletWebServerFactoryAutoConfiguration 开始的。
ServletWebServerFactoryAutoConfiguration 是用来自动配置 Servlet 的 Web 服务的。先看其注册部分的源代码。
@Configuration(proxyBeanMethods=false)
@AutoConf igureOrder(Ordered.HIGHEST PRECEDENCE)
//需要存在 ServletRequest 类
@ConditionalOnClass (ServletRequest.class)
//需要 web 类型为 Servlet 类型
@ConditionalOnWebApplication(type = Type . SERVLET)
//加戴 ServerProperties 中的配置
@EnableConfigurat ionProperties (ServerProperties.class)
//导入内部类 BeanPostProcessorsRegistrar 用来注 BeanPos tProcessor
Q
//导入 ServletwebServerFactoryConfiguration 的三个内部类, 用来判断应用服务器类
型
@Import({ ServletWebServerFactoryAutoConfiguration . BeanPostProcessorsRegist
rar.class,
ServletwebServerFactoryConfiguration. EmbeddedTomcat . class,
ServletWebServerFactoryConfiguration. EmbeddedJetty . class,
ServletWebServerFactoryConfiguration. EmbeddedUndertow. class })
public class ServletWebServerFactoryAutoConfiguration {
}
注解中常规的项就不多说了,我们重点看一下@lmport 注解中引入的内容。该注解引入了当前类的内部类
BeanPostProcessorsRegistrar 和 Servl