SpringBoot2.x内置Tomcat自动配置原理
SpringBoot内嵌的tomcat是怎样自动配置的?
我们怎么修改内嵌tomcat的默认参数?
带着这2个问题,我们分析下SpringBoot的内置tomcat自动配置原理
我们知道SpringBoot的自动配置都在spring-boot-autoconfigure-xx.RELEASE.jar包下.
同时 SpringBoot对所支持的servlet web服务器实现做了建模抽象:
Servlet容器类型 | WebServer模型接口 | WebServer工厂实现类 |
Tomcat | TomcatWebServer | TomcatServletWebServerFactory |
Jetty | JettyWebServer | JettyServletWebServerFactory |
Undertow | UndertowWebServer | UndertowServletWebServerFactory |
基于此模型概念,在一个Web应用种,Springboot会使用上述web工厂组件生成相应的webserver实例。 而web工厂组件从哪里来,这就是自动配置类ServletWebServerFactoryAutoConfiguaration进行自动配置产生这个web工厂组件的任务了。
@Configuration @AutoConfigureOrder(-2147483648) @ConditionalOnClass({ServletRequest.class}) @ConditionalOnWebApplication( type = Type.SERVLET ) @EnableConfigurationProperties({ServerProperties.class}) @Import({ServletWebServerFactoryAutoConfiguration.BeanPostProcessorsRegistrar.class, EmbeddedTomcat.class, EmbeddedJetty.class, EmbeddedUndertow.class}) public class ServletWebServerFactoryAutoConfiguration { public ServletWebServerFactoryAutoConfiguration() { } @Bean public ServletWebServerFactoryCustomizer servletWebServerFactoryCustomizer(ServerProperties serverProperties) { return new ServletWebServerFactoryCustomizer(serverProperties); } @Bean @ConditionalOnClass( name = {"org.apache.catalina.startup.Tomcat"} ) public TomcatServletWebServerFactoryCustomizer tomcatServletWebServerFactoryCustomizer(ServerProperties serverProperties) { return new TomcatServletWebServerFactoryCustomizer(serverProperties); } public static class BeanPostProcessorsRegistrar implements ImportBeanDefinitionRegistrar, BeanFactoryAware { private ConfigurableListableBeanFactory beanFactory; public BeanPostProcessorsRegistrar() { } public void setBeanFactory(BeanFactory beanFactory) throws BeansException { if (beanFactory instanceof ConfigurableListableBeanFactory) { this.beanFactory = (ConfigurableListableBeanFactory)beanFactory; } } public void registerBeanDefinitions(AnnotationMetadata importingClassMetadata, BeanDefinitionRegistry registry) { if (this.beanFactory != null) { this.registerSyntheticBeanIfMissing(registry, "webServerFactoryCustomizerBeanPostProcessor", WebServerFactoryCustomizerBeanPostProcessor.class); this.registerSyntheticBeanIfMissing(registry, "errorPageRegistrarBeanPostProcessor", ErrorPageRegistrarBeanPostProcessor.class); } } private void registerSyntheticBeanIfMissing(BeanDefinitionRegistry registry, String name, Class<?> beanClass) { if (ObjectUtils.isEmpty(this.beanFactory.getBeanNamesForType(beanClass, true, false))) { RootBeanDefinition beanDefinition = new RootBeanDefinition(beanClass); beanDefinition.setSynthetic(true); registry.registerBeanDefinition(name, beanDefinition); } } } }
首先来看一下这个ServletWebServerFactoryAutoConfiguration自动配置类的几个注解:
两个 Condition 表示当前运行环境是基于 servlet 标准规范的 web 服务:ConditionalOnClass(ServletRequest.class) : 表示当前必须有 servlet-api 依赖存在ConditionalOnWebApplication(type = Type.SERVLET) :仅基于servlet的Web应用程序
1. @AutoConfigureOrder 这个注解是决定配置类的加载顺序的,当注解里的值越小越先加载
2.@EnableConfigurationProperties开启ServerProperties类的属性值配置。而这个类里面包含的就是webserver的配置
3. @Import其中内部类 BeanPostProcessorsRegistrar,这个类注册了两个bean:
WebServerFactoryCustomizerBeanPostProcessor和ErrorPageRegistarBeanPostProcess。关于这两个bean的作用稍后再详细介绍
4.@Import EmbeddedTomcat这个类
@Configuration @ConditionalOnClass({Servlet.class, Tomcat.class, UpgradeProtocol.class}) @ConditionalOnMissingBean( value = {ServletWebServerFactory.class}, search = SearchStrategy.CURRENT ) public static class EmbeddedTomcat { public EmbeddedTomcat() { } @Bean public TomcatServletWebServerFactory tomcatServletWebServerFactory() { return new TomcatServletWebServerFactory(); } }
这个类会在存在tomcat相关jar包时添加一个TomcatServletWebServerFactory bean
5. 除此之外,还注入了
ServletWebServerFactoryCustomizer和TomcatServletWebServerFactoryCustomizer