引言
对于一个 SpringBoot web 工程来说,一个主要的依赖标志就是有 spring-boot-starter-web 这个 starter ,spring-boot-starter-web 模块在 spring boot 中其实并没有代码存在,只是在 pom.xml 中携带了一些依赖,包括 web、webmvc、tomcat 等:
org.springframework.boot spring-boot-starter org.springframework.boot spring-boot-starter-json org.springframework.boot spring-boot-starter-tomcat org.hibernate.validator hibernate-validator org.springframework spring-web org.springframework spring-webmvc 复制代码
Spring Boot 默认的 web 服务容器是 tomcat ,如果想使用 Jetty 等来替换 Tomcat ,可以自行参考官方文档来解决。
web、webmvc、tomcat 等提供了 web 应用的运行环境,那 spring-boot-starter 则是让这些运行环境工作的开关(因为 spring-boot-starter 中会间接引入 spring-boot-autoconfigure )。
WebServer 自动配置
在 spring-boot-autoconfigure 模块中,有处理关于 WebServer 的自动配置类 ServletWebServerFactoryAutoConfiguration 。
ServletWebServerFactoryAutoConfiguration
代码片段如下:
@Configuration@AutoConfigureOrder(Ordered.HIGHEST_PRECEDENCE)@ConditionalOnClass(ServletRequest.class)@ConditionalOnWebApplication(type = Type.SERVLET)@EnableConfigurationProperties(ServerProperties.class)@Import({ ServletWebServerFactoryAutoConfiguration.BeanPostProcessorsRegistrar.class,ServletWebServerFactoryConfiguration.EmbeddedTomcat.class,ServletWebServerFactoryConfiguration.EmbeddedJetty.class,ServletWebServerFactoryConfiguration.EmbeddedUndertow.class })public class ServletWebServerFactoryAutoConfiguration复制代码
两个 Condition 表示当前运行环境是基于 servlet 标准规范的 web 服务:
- ConditionalOnClass(ServletRequest.class) : 表示当前必须有 servlet-api 依赖存在
- ConditionalOnWebApplication(type = Type.SERVLET) :仅基于servlet的Web应用程序
@EnableConfigurationProperties(ServerProperties.class):ServerProperties 配置中包括了常见的 server.port 等配置属性。
通过 @Import 导入嵌入式容器相关的自动配置类,有 EmbeddedTomcat、EmbeddedJetty 和EmbeddedUndertow。
综合来看,ServletWebServerFactoryAutoConfiguration 自动配置类中主要做了以下几件事情:
- 导入了内部类 BeanPostProcessorsRegistrar,它实现了 ImportBeanDefinitionRegistrar,可以实现ImportBeanDefinitionRegistrar 来注册额外的 BeanDefinition。
- 导入了 ServletWebServerFactoryConfiguration.EmbeddedTomcat 等嵌入容器先关配置(我们主要关注tomcat 相关的配置)。
- 注册了ServletWebServerFactoryCustomizer、TomcatServletWebServerFactoryCustomizer 两个WebServerFactoryCustomizer 类型的 bean。
下面就针对这几个点,做下详细的分析。
BeanPostProcessorsRegistrar
BeanPostProcessorsRegistrar 这个内部类的代码如下(省略了部分代码):
public static class BeanPostProcessorsRegistrar implements ImportBeanDefinitionRegistrar, BeanFactoryAware { // 省略代码 @Override public void registerBeanDefinitions(AnnotationMetadata importingClassMetadata, BeanDefinitionRegistry registry) { if (this.beanFactory == null) { return; } // 注册 WebServerFactoryCustomizerBeanPostProcessor registerSyntheticBeanIfMissing(registry, "webServerFactoryCustomizerBeanPostProcessor