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




 

posted @ 2020-02-13 15:38  hxwang  阅读(1917)  评论(0编辑  收藏  举报