【SpringBoot】26 核心功能 - Web开发原理 - Spring Boot 中定制 Servlet 容器
文章目录
- 一、原理剖析
- 二、定制 Servlet 容器的多元方式
- 1. 切换嵌入式 Servlet 容器
- 2. 实现 `WebServerFactoryCustomizer<ConfigurableServletWebServerFactory>`
- 3. 直接自定义 `ConfigurableServletWebServerFactory`
一、原理剖析
在 Spring Boot 的生态体系中,当涉及到 Web 应用开发时,其内部对于 Servlet 容器的管理和运作有着一套精心设计的机制。
当我们引入 Spring Boot 的 web 场景包时,它会悄然将 Tomcat 相关依赖纳入项目。Spring Boot 应用启动伊始,会敏锐地察觉当前是 Web 应用场景,随后便将 web 场景包与 Tomcat 进行深度整合。
具体而言,Web 应用会构建一个特殊的 IOC 容器——ServletWebServerApplicationContext
。这个容器在启动过程中,肩负着一个关键使命:寻找 ServletWebServerFactory
。ServletWebServerFactory
就像是 Servlet 的 web 服务器工厂,它的核心职责是创建 Servlet 所依赖的 web 服务器。
在 Spring Boot 的底层架构中,默认支持多种流行的嵌入式 Servlet 容器,如 Tomcat、Jetty 或 Undertow。针对不同的容器,分别有对应的工厂类,例如 TomcatServletWebServerFactory
、JettyServletWebServerFactory
和 UndertowServletWebServerFactory
。
这一机制的背后,离不开自动配置类的默默支持。ServletWebServerFactoryAutoConfiguration
这个自动配置类,导入了 ServletWebServerFactoryConfiguration
配置类。ServletWebServerFactoryConfiguration
犹如一个智能的决策者,它会根据项目中实际引入的 Web 服务器包进行动态判断。默认情况下,由于 web - starter 会导入 tomcat 包,所以它会自动选择并配置 TomcatServletWebServerFactory
。以 TomcatServletWebServerFactory
为例,它会负责创建 Tomcat 服务器实例,并通过其构造器中的初始化方法 initialize
,调用 this.tomcat.start()
来启动内嵌的 Tomcat 服务器(前提是项目中存在 tomcat 核心 jar 包)。
二、定制 Servlet 容器的多元方式
1. 切换嵌入式 Servlet 容器
Spring Boot 赋予了我们灵活切换嵌入式 Servlet 容器的能力。默认支持 Tomcat、Jetty 或 Undertow 这几种常见的容器。ServletWebServerApplicationContext
容器在启动流程中,会主动寻找 ServletWebServerFactory
,并引导其创建对应的服务器实例。
在实际项目中,如果我们希望将默认的 Tomcat 容器切换为 Jetty,可以通过对项目依赖进行巧妙调整来实现。在 Maven 构建的项目的 pom.xml
文件中,我们可以利用 <exclusions>
标签,将 spring - boot - starter - tomcat
依赖排除在外,随后引入 spring - boot - starter - jetty
依赖。示例代码如下:
<dependency><groupId>org.springframework.boot</groupId><artifactId>spring - boot - starter - web</artifactId><exclusions><exclusion><groupId>org.springframework.boot</groupId><artifactId>spring - boot - starter - tomcat</artifactId></exclusion></exclusions>
</dependency>
<dependency><groupId>org.springframework.boot</groupId><artifactId>spring - boot - starter - jetty</artifactId>
</dependency>
通过这样的依赖配置调整,Spring Boot 在启动时就会识别到 Jetty 相关的依赖,进而使用 JettyServletWebServerFactory
来创建并启动 Jetty 服务器,实现容器的无缝切换。
2. 实现 WebServerFactoryCustomizer<ConfigurableServletWebServerFactory>
除了切换容器类型,我们还可以对 Servlet 容器进行更为细致的定制化配置。实现 WebServerFactoryCustomizer<ConfigurableServletWebServerFactory>
接口就是一种常见且有效的方式。
我们可以创建一个专门的配置类来实现该接口,在 customize
方法中对 ConfigurableServletWebServerFactory
进行个性化设置。例如,我们可以对服务器的端口、上下文路径、会话超时时间等参数进行调整。以下是一个示例代码:
import org.springframework.boot.web.server.ConfigurableServletWebServerFactory;
import org.springframework.boot.web.server.WebServerFactoryCustomizer;
import org.springframework.stereotype.Component;@Component
public class MyWebServerFactoryCustomizer implements WebServerFactoryCustomizer<ConfigurableServletWebServerFactory> {@Overridepublic void customize(ConfigurableServletWebServerFactory factory) {// 设置服务器端口为 8081factory.setPort(8081);// 设置应用的上下文路径为 /myappfactory.setContextPath("/myapp");// 设置会话超时时间为 1800 秒factory.setSessionTimeout(1800);}
}
在上述代码中,customize
方法接收一个 ConfigurableServletWebServerFactory
参数,通过调用其提供的一系列设置方法,我们可以轻松地对 Servlet 容器的各项参数进行定制。这种方式的好处在于,它能够以一种较为统一和便捷的方式,对容器的配置进行集中管理。
3. 直接自定义 ConfigurableServletWebServerFactory
对于一些更为复杂和特殊的定制需求,直接自定义 ConfigurableServletWebServerFactory
的实现类可能是更好的选择。
我们可以创建一个新的配置类,在其中通过 @Bean
注解定义一个 ConfigurableServletWebServerFactory
的实例,并进行详细的配置。例如,以下代码展示了如何创建一个自定义的 Tomcat 服务器工厂配置:
import org.springframework.boot.web.embedded.tomcat.TomcatServletWebServerFactory;
import org.springframework.boot.web.server.WebServerFactoryCustomizer;
import org.springframework.context.annotation.Bean;
import org.springframework.context.annotation.Configuration;@Configuration
public class WebServerConfig {@Beanpublic ConfigurableServletWebServerFactory webServerFactory() {TomcatServletWebServerFactory factory = new TomcatServletWebServerFactory();// 设置服务器端口为 8082factory.setPort(8082);// 设置应用的上下文路径为 /customappfactory.setContextPath("/customapp");// 可以在这里添加更多针对 Tomcat 的特殊配置,例如连接器配置等// 例如设置 Tomcat 的连接器属性// factory.addConnectorCustomizers(connector -> {// connector.setProperty("maxThreads", "200");// });return factory;}
}
在这个示例中,我们创建了一个 TomcatServletWebServerFactory
的实例,并对其端口和上下文路径进行了设置。此外,我们还可以通过 addConnectorCustomizers
等方法,对 Tomcat 的连接器等底层组件进行更为精细的配置,以满足一些特殊的业务需求。
通过以上多种方式,我们能够在 Spring Boot 项目中对嵌入式 Servlet 容器进行全方位、多层次的定制。无论是简单的容器类型切换,还是对容器参数的细致调整,亦或是针对特定容器的深度定制,Spring Boot 都提供了相应的机制和接口,帮助我们打造出符合项目需求的 Web 服务器环境。这使得我们在开发 Spring Boot Web 应用时,能够更加灵活地应对各种复杂的业务场景。