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
