SpringBoot内置Servlet源码解析:容器自动配置

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 所 示。
SpringBoot内置Servlet源码解析:容器自动配置文章插图
图 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 tProcessorQ//导入 ServletwebServerFactoryConfiguration 的三个内部类 ,用来判断应用服务器类型@Import({ ServletWebServerFactoryAutoConfiguration . BeanPostProcessorsRegistrar.class,ServletwebServerFactoryConfiguration. EmbeddedTomcat . class,ServletWebServerFactoryConfiguration. EmbeddedJetty . class,ServletWebServerFactoryConfiguration. EmbeddedUndertow. class })public class ServletWebServerFactoryAutoConfiguration {}注解中常规的项就不多说了 , 我们重点看一下@lmport 注解中引入的内容 。 该注解引入了当前类的内部类 BeanPostProcessorsRegistrar 和 ServletWebServerFactoryConfiguration 的3 个内部类: EmbeddedTomcat、EmbeddedJetty、EmbeddedUndertow 。
先来看 ServletWebServerFactoryConfiguration 类 , 它是 Servlet Web 服务器的配置类 , 目前该类中包含了内置 Tomcat. Jetty 和 Undertow 的配置 ,重点作用就是实例化图 7-1 中的工厂类 。
ServletWebServerFactoryConfiguration 类中定义的 3 个内部类 , -般通过@Import 注解在其 他 自 动 配 置 类 中 引 入 使 用,并 确 保 其 执 行 顺 序。在ServletWebServerFactoryAutoCon-figuration 中的使用便是实例 。
ServletWebServerFactoryConfiguration 中具体工厂"Bean 的初始化操作基本相同 , 都是在方法内通过 new 创建对应的工厂类 , 设置其初始化参数 , 然后注入 Spring 容器中 。 下面我们以其中最常用的 Tomcat 容器为例来进行源码层面的讲解 。
EmbeddedTomcat 内部类的代码如下 。
@Configuration(proxyBeanMethods = false)@ConditionalOnClass({ Servlet. class, Tomcat. class, UpgradeProtocol.class })@ConditionalOnMissingBean(value = http://kandian.youth.cn/index/ServletWebServerFactory.class, search = SearchStrategy . CURRENT)public static class EmbeddedTomcat {@Beanpublic TomcatServletWebServerF actory tomcatServletWebServerFactory(ObjectProvider connectorCustomizers,ObjectProvider contextCustomizers,ObjectProvider> protocolHandlerCustomizers) {TomcatServletWebServerFactory factory = new TomcatServletWebServerFactory();factory . getTomcatConnectorCustomizers(). addAll( connectorCustomizers . orderedStream( ) . collect(Collectors.tolist()));factory . getTomcatContextCustomizers(). addAll( contextCustomizers . orderedStream( ). collect(Collectors. toList()));factory . getTomcatProtocolHandlerCustomizers(). addAll(protocolHandlerCustomizers . orderedStream(). collect(Collectors .tolist()));return factory;}}