2.0之前 EmbeddedServletContainerCustomizerAutoConfiguration
2.0之后
EmbeddedWebServerFactoryCustomizerAutoConfiguration
ServletWebServerFactoryAutoConfiguration
嵌入式Servlet容器自动配置
1)EmbeddedWebServerFactoryCustomizerAutoConfiguration
判断容器中引入的依赖 来导入不容的Servlet容器
主要引入了ServerProperties.class 配置文件类

@Configuration
@ConditionalOnWebApplication
@EnableConfigurationProperties({ServerProperties.class})//配置文件类
public class EmbeddedWebServerFactoryCustomizerAutoConfiguration {

	//Tomcat为例
    @Configuration
    @ConditionalOnClass({Tomcat.class, UpgradeProtocol.class})//判断当前是否引入了Tomcat依赖
    public static class TomcatWebServerFactoryCustomizerConfiguration {
        public TomcatWebServerFactoryCustomizerConfiguration() {
        }

		//配置tomcat的主要信息
		//包含remoteIpValue、connector(最大/最小可接收线程、最大可接收头部大小等等)、uriEncoding、connectionTimeout、maxConnection等属性
        @Bean
        public TomcatWebServerFactoryCustomizer tomcatWebServerFactoryCustomizer(Environment environment, ServerProperties serverProperties) {
            return new TomcatWebServerFactoryCustomizer(environment, serverProperties);
        }
    }

2)ServletWebServerFactoryAutoConfiguration
具体的Servlet容器的配置

@Configuration
@AutoConfigureOrder(-2147483648)
@ConditionalOnClass({ServletRequest.class})
@ConditionalOnWebApplication(
    type = Type.SERVLET
)
@EnableConfigurationProperties({ServerProperties.class})
@Import({ServletWebServerFactoryAutoConfiguration.BeanPostProcessorsRegistrar.class, EmbeddedTomcat.class, EmbeddedJetty.class, EmbeddedUndertow.class})
//BeanPostProcessorsRegistrar.class 给容器中导入一些组件
//导入了WebServerFactoryCustomizerBeanPostProcessor.class
//BeanPostProcessor 后置处理器 :bean初始化前后(刚创建完对象,还没属性赋值) 执行初始化工作

public class ServletWebServerFactoryAutoConfiguration {
	
	//主要配置tomcat的servlet的信息,
	//包含端口、上下文路径、应用名、Session配置、Servlet携带的初始变量等等
	//他是继承WebServerFactoryCustomizer的 也就是上一个博客说的个性化定制配置信息的时候提到的
    @Bean
    public ServletWebServerFactoryCustomizer  servletWebServerFactoryCustomizer(ServerProperties serverProperties) {
        return new ServletWebServerFactoryCustomizer(serverProperties);
    }
	
	// 配置tomcat的额外信息
	//redirectContextRoot(是否在请求根上下文时转发,true则转发路径为/demoWeb/)和useRelativeRedirects(是否使用相对路径)等路径跳转问题处理
    @Bean
    @ConditionalOnClass(
        name = {"org.apache.catalina.startup.Tomcat"}
    )
    public TomcatServletWebServerFactoryCustomizer tomcatServletWebServerFactoryCustomizer(ServerProperties serverProperties) {
        return new TomcatServletWebServerFactoryCustomizer(serverProperties);
    }


TomcatWebServerFactoryCustomizer
ServletWebServerFactoryCustomizer
TomcatServletWebServerFactoryCustomizer
这三个类基本完成了Tomcat的配置,他们都是WebServerFactoryCustomizer的实现类,
那么谁来统一调用以完成上述的配置呢?

  1. 引入了WebServerFactory工厂类,创建了TomcatServletWebServerFactory的tomcat容器

@EnableConfigurationProperties({ServerProperties.class})
@Import({ServletWebServerFactoryAutoConfiguration.BeanPostProcessorsRegistrar.class, EmbeddedTomcat.class, EmbeddedJetty.class, EmbeddedUndertow.class})
public class ServletWebServerFactoryAutoConfiguration {
 
//上边 EmbeddedTomcat.class
@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();
        }
    }
  1. 通过beanPostProcessor接口来完成相应的容器初始化,
    注册了webServerFactoryCustomizerBeanPostProcessor类来完成相应的tomcat个性化配置
@EnableConfigurationProperties({ServerProperties.class})
@Import({ServletWebServerFactoryAutoConfiguration.BeanPostProcessorsRegistrar.class, EmbeddedTomcat.class, EmbeddedJetty.class, EmbeddedUndertow.class})
public class ServletWebServerFactoryAutoConfiguration {
 
//上边ServletWebServerFactoryAutoConfiguration.BeanPostProcessorsRegistrar.class
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);
            }

        }
    }

WebServerFactoryCustomizerBeanPostProcessor:

public class WebServerFactoryCustomizerBeanPostProcessor implements BeanPostProcessor, BeanFactoryAware {
    private ListableBeanFactory beanFactory;
    private List<WebServerFactoryCustomizer<?>> customizers;

    public WebServerFactoryCustomizerBeanPostProcessor() {
    }

    public void setBeanFactory(BeanFactory beanFactory) {
        Assert.isInstanceOf(ListableBeanFactory.class, beanFactory, "WebServerCustomizerBeanPostProcessor can only be used with a ListableBeanFactory");
        this.beanFactory = (ListableBeanFactory)beanFactory;
    }
    //调用所有实现了WebServerFactoryCustomizer接口的对象 可能会包含自己定制的
    public Object postProcessBeforeInitialization(Object bean, String beanName) throws BeansException {
        if (bean instanceof WebServerFactory) {
            this.postProcessBeforeInitialization((WebServerFactory)bean);
        }

        return bean;
    }
	//  // 查找当前bean工厂中所有类型为WebServerFactoryCustomizer接口对象集合
    public Object postProcessAfterInitialization(Object bean, String beanName) throws BeansException {
        return bean;
    }

    private void postProcessBeforeInitialization(WebServerFactory webServerFactory) {
        ((Callbacks)LambdaSafe.callbacks(WebServerFactoryCustomizer.class, this.getCustomizers(), webServerFactory, new Object[0]).withLogger(WebServerFactoryCustomizerBeanPostProcessor.class)).invoke((customizer) -> {
            customizer.customize(webServerFactory);
        });
    }

    private Collection<WebServerFactoryCustomizer<?>> getCustomizers() {
        if (this.customizers == null) {
            this.customizers = new ArrayList(this.getWebServerFactoryCustomizerBeans());
            this.customizers.sort(AnnotationAwareOrderComparator.INSTANCE);
            this.customizers = Collections.unmodifiableList(this.customizers);
        }

        return this.customizers;
    }

    private Collection<WebServerFactoryCustomizer<?>> getWebServerFactoryCustomizerBeans() {
        return this.beanFactory.getBeansOfType(WebServerFactoryCustomizer.class, false, false).values();
    }
}

步骤:

  1. SpringBoot根据导入依赖情况 ,给容器中添加相应的嵌入式工厂
    SpringBoot自学好几天 中途开始写笔记 SpringBoot Web开发 嵌入式Servlet容器自动配置原理 20190130
  2. ServletWebServerFactoryAutoConfiguration
    ServletWebServerFactoryCustomizer 和 TomcatServletWebServerFactoryCustomizer 配置其他配置
  3. WebServerFactoryCustomizerBeanPostProcessor 后置处理器
    从容器中获取所有的ConfigurableListableBeanFactory

有有有有有点儿乱 就是简单了解以下

嵌入式Servlet容器启动原理

什么时候创建嵌入式的Servlet容器工厂 什么时候获取嵌入式的Servlet容器并启动Tomcat

  1. SpringBoot应用启动运行run方法
  2. refreshContext 刷新IOC容器【创建IOC容器对象 并初始化容器 创建容器中每一个组件】
  3. refresh刷新刚才创建的IOC容器
  4. onRefresh();web的ioc容器 重写了onRefresh方法
  5. WEB IOC容器创建嵌入式Servlet容器 createEmbededServletContainer
    6.获取嵌入式Servlet容器工厂 这个工厂就是上边自动注入放进去的
  6. Servlet容器工厂创建了 就会配置相关配置 然后会触发后置处理器 ,后置处理器会获取所有定制器 定制Servlet相关配置
  7. 容器工厂获取完 用容器工厂获取嵌入式的Servlet容器
  8. 嵌入式Servlet容器创建Tocmat对象 并启动
    先启动嵌入式Servlet容器 再将IOC容器中剩下没有创建的对象获取出来

相关文章:

  • 2021-09-19
  • 2021-06-02
  • 2021-04-11
  • 2021-07-08
  • 2021-09-07
  • 2022-01-06
  • 2021-12-25
猜你喜欢
  • 2021-07-10
  • 2021-05-22
  • 2021-08-26
  • 2021-07-26
  • 2021-12-30
  • 2021-07-31
  • 2021-06-30
相关资源
相似解决方案