嵌入式Servlet容器自动配置原理

嵌入式Servlet容器自动配置原理:
在spring-boot自动配置包中,有一个web模块,里边有一个嵌入式自动配置容器的配置:ServletWebServerFactoryAutoConfiguration
于此模型概念,在一个Servlet Web应用中,Spring Boot会使用上表中所说的WebServer工厂组件生成相应的WebServer实例。而这里的WebServer工厂组件又是从哪里来的呢 ? 这就是自动配置类ServletWebServerFactoryAutoConfiguration的任务了。

自动配置类ServletWebServerFactoryAutoConfiguration首先通过注解声明自己的生效条件:类 ServletRequest 存在于 classpath 上时才生效,也就是要求javax.servlet-api包必须被引用;当前应用必须是Spring MVC应用才生效;在以上条件被满足时,ServletWebServerFactoryAutoConfiguration引入了如下三个配置类 :

EmbeddedTomcat

EmbeddedJetty

EmbeddedUndertow

这三个配置类是ServletWebServerFactoryConfiguration的嵌套配置类,它们会分别检测classpath上存在的类,从而判断当前应用使用的是Tomcat/Jetty/Undertow中的哪一个Servlet Web服务器,从而决定定义相应的工厂组件bean : TomcatServletWebServerFactory/JettyServletWebServerFactory/UndertowServletWebServerFactory。

**
* EnableAutoConfiguration Auto-configuration for servlet web servers.
*
*/
@Configuration
@AutoConfigureOrder(Ordered.HIGHEST_PRECEDENCE)
// 仅在类 ServletRequest 存在于 classpath 上时才生效
@ConditionalOnClass(ServletRequest.class)
// 仅在当前应用是 Servlet Web 应用时才生效
@ConditionalOnWebApplication(type = Type.SERVLET)
// 确保前缀为 server 的配置参数加载到 bean ServerProperties
@EnableConfigurationProperties(ServerProperties.class)
// 1. 导入 ServletWebServerFactoryAutoConfiguration.BeanPostProcessorsRegistrar 以注册
// BeanPostProcessor : WebServerFactoryCustomizerBeanPostProcessor 和
// ErrorPageRegistrarBeanPostProcessor
// 2. 导入 EmbeddedTomcat/EmbeddedJetty/EmbeddedUndertow 这三个属于
// ServletWebServerFactoryConfiguration 的嵌套配置类,这三个配置类会分别检测
// classpath上存在的类,从而判断当前应用使用的是 Tomcat/Jetty/Undertow,
// 从而决定定义哪一个 Servlet Web服务器的工厂 bean :
// TomcatServletWebServerFactory/JettyServletWebServerFactory/UndertowServletWebServerFactory
@Import({ ServletWebServerFactoryAutoConfiguration.BeanPostProcessorsRegistrar.class,
        ServletWebServerFactoryConfiguration.EmbeddedTomcat.class,
        ServletWebServerFactoryConfiguration.EmbeddedJetty.class,
        ServletWebServerFactoryConfiguration.EmbeddedUndertow.class })
public class ServletWebServerFactoryAutoConfiguration {
 
 
    // 定义 bean ServletWebServerFactoryCustomizer,这里与properties中serverProperties配置联系,解释了为什么配置文件也可修改servlet容器配置
    @Bean
    public ServletWebServerFactoryCustomizer servletWebServerFactoryCustomizer(
            ServerProperties serverProperties) {
        return new ServletWebServerFactoryCustomizer(serverProperties);
    }
 
 
    // 针对当前Servlet容器是Tomcat时定义该 bean,用于定制化 TomcatServletWebServerFactory
    @Bean
    // 仅在类 org.apache.catalina.startup.Tomcat 存在于 classpath 上时才生效
    @ConditionalOnClass(name = "org.apache.catalina.startup.Tomcat")
    public TomcatServletWebServerFactoryCustomizer tomcatServletWebServerFactoryCustomizer(
            ServerProperties serverProperties) {
        return new TomcatServletWebServerFactoryCustomizer(serverProperties);
    }
 
 
    /**
     * Registers a WebServerFactoryCustomizerBeanPostProcessor. Registered via
     * ImportBeanDefinitionRegistrar for early registration.
     * 这是一个 ImportBeanDefinitionRegistrar, 它会向容器注入两个 BeanPostProcessor :
     * 1. WebServerFactoryCustomizerBeanPostProcessor
     * 该 BeanPostProcessor 会搜集容器中所有的 WebServerFactoryCustomizer,对当前应用所采用的
     * WebServerFactory 被初始化前进行定制
     * 2. ErrorPageRegistrarBeanPostProcessor
     * 该 BeanPostProcessor 会搜集容器中所有的 ErrorPageRegistrar,添加到当前应用所采用的
     * ErrorPageRegistry 中,实际上,这里的 ErrorPageRegistry 会是 ConfigurableWebServerFactory,
     * 具体实现上来讲,是一个 ConfigurableTomcatWebServerFactory,ConfigurableJettyWebServerFactory
     * 或者 ConfigurableUndertowWebServerFactory,分别对应 Tomcat, Jetty, Undertow 这三种
     * Servlet Web 容器的工厂类
     */
    public static class BeanPostProcessorsRegistrar
            implements ImportBeanDefinitionRegistrar, BeanFactoryAware {
 
 
        private ConfigurableListableBeanFactory beanFactory;
 
 
        @Override
        public void setBeanFactory(BeanFactory beanFactory) throws BeansException {
            if (beanFactory instanceof ConfigurableListableBeanFactory) {
                this.beanFactory = (ConfigurableListableBeanFactory) beanFactory;
            }
        }
 
 
        @Override
        public void registerBeanDefinitions(AnnotationMetadata importingClassMetadata,
                                            BeanDefinitionRegistry registry) {
            if (this.beanFactory == null) {
                return;
            }
            registerSyntheticBeanIfMissing(registry,
                    "webServerFactoryCustomizerBeanPostProcessor",
                    WebServerFactoryCustomizerBeanPostProcessor.class);
            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);
            }
        }
 
 
    }

ServletWebServerFactoryConfiguration是一个针对ServletWebServerFactory进行配置的配置类。它通过检测应用classpath存在的类,从而判断当前应用要使用哪个Servlet容器:Tomcat,Jetty还是Undertow。检测出来之后,定义相应的Servlet Web服务器工厂组件bean

  • 0
    点赞
  • 0
    收藏
    觉得还不错? 一键收藏
  • 0
    评论
评论
添加红包

请填写红包祝福语或标题

红包个数最小为10个

红包金额最低5元

当前余额3.43前往充值 >
需支付:10.00
成就一亿技术人!
领取后你会自动成为博主和红包主的粉丝 规则
hope_wisdom
发出的红包
实付
使用余额支付
点击重新获取
扫码支付
钱包余额 0

抵扣说明:

1.余额是钱包充值的虚拟货币,按照1:1的比例进行支付金额的抵扣。
2.余额无法直接购买下载,可以购买VIP、付费专栏及课程。

余额充值