【串线篇】spring boot嵌入式Servlet容器自动配置原理

EmbeddedServletContainerAutoConfiguration:嵌入式的Servlet容器自动配置?

    @AutoConfigureOrder(Ordered.HIGHEST_PRECEDENCE)
    @Configuration
    @ConditionalOnWebApplication
    @Import(BeanPostProcessorsRegistrar.class)
    //导入BeanPostProcessorsRegistrar:Spring注解版;给容器中导入一些组件
    //导入了EmbeddedServletContainerCustomizerBeanPostProcessor:
    //后置处理器:bean初始化前后(创建完对象,还没赋值赋值)执行初始化工作
    public  class  EmbeddedServletContainerAutoConfiguration  { 
    @Configuration
    @ConditionalOnClass({  Servlet.class,  Tomcat.class  })//判断当前是否引入了Tomcat依赖;
    @ConditionalOnMissingBean(value  =  EmbeddedServletContainerFactory.class,  search  =
SearchStrategy.CURRENT)//判断当前容器没有用户自己定义EmbeddedServletContainerFactory:嵌入式的
Servlet容器工厂;作用:创建嵌入式的Servlet容器
    public  static  class  EmbeddedTomcat  { 14
    @Bean
    public  TomcatEmbeddedServletContainerFactory  tomcatEmbeddedServletContainerFactory()
{
    return  new  TomcatEmbeddedServletContainerFactory(); 18    }

    }

    /**
    * Nested configuration if Jetty is being used. 24    */
    @Configuration
    @ConditionalOnClass({  Servlet.class,  Server.class,  Loader.class,
    WebAppContext.class  })
    @ConditionalOnMissingBean(value  =  EmbeddedServletContainerFactory.class,  search  = SearchStrategy.CURRENT)
    public  static  class  EmbeddedJetty  { 30
    @Bean
    public  JettyEmbeddedServletContainerFactory  jettyEmbeddedServletContainerFactory()  {
    return  new  JettyEmbeddedServletContainerFactory(); 34    }

    }


/**
    * Nested configuration if Undertow is being used. 40    */
    @Configuration
    @ConditionalOnClass({  Servlet.class,  Undertow.class,  SslClientAuthMode.class  })
    @ConditionalOnMissingBean(value  =  EmbeddedServletContainerFactory.class,  search  = SearchStrategy.CURRENT)
    public  static  class  EmbeddedUndertow  

@Bean
public  UndertowEmbeddedServletContainerFactory undertowEmbeddedServletContainerFactory()  {
return  new  UndertowEmbeddedServletContainerFactory();
}
}

一、EmbeddedServletContainerFactory(嵌入式Servlet容器工厂)

public  interface  EmbeddedServletContainerFactory  {

//获取嵌入式的Servlet容器
EmbeddedServletContainer  getEmbeddedServletContainer(
ServletContextInitializer...  initializers);


}

二、EmbeddedServletContainer:(嵌入式的Servlet容器)

三、以TomcatEmbeddedServletContainerFactory为例

    @Override
    public  EmbeddedServletContainer  getEmbeddedServletContainer(
    ServletContextInitializer...  initializers)  {
    //创建一个Tomcat
    Tomcat  tomcat  =  new  Tomcat(); 
//配置Tomcat的基本环节
File  baseDir  =  (this.baseDirectory  !=  null  ?  this.baseDirectory:  createTempDir("tomcat"));
tomcat.setBaseDir(baseDir.getAbsolutePath()); 
Connector connector
= new Connector(this.protocol);
tomcat.getService().addConnector(connector);
customizeConnector(connector); tomcat.setConnector(connector);
tomcat.getHost().setAutoDeploy(false);
configureEngine(tomcat.getEngine());
for (Connector additionalConnector : this.additionalTomcatConnectors) { tomcat.getService().addConnector(additionalConnector); } prepareContext(tomcat.getHost(), initializers); //将配置好的Tomcat传入进去,返回一个EmbeddedServletContainer;并且启动Tomcat服务器 return getTomcatEmbeddedServletContainer(tomcat); }

四、我们对嵌入式容器的配置修改是怎么生效?

ServerProperties、EmbeddedServletContainerCustomizer

EmbeddedServletContainerCustomizer:定制器帮我们修改了Servlet容器的配置? 怎么修改的原理?

五、容器中导入了EmbeddedServletContainerCustomizerBeanPostProcessor

//初始化之前
    @Override
    public  Object  postProcessBeforeInitialization(Object  bean,  String  beanName)
    throws BeansException {
    //如果当前初始化的是一个ConfigurableEmbeddedServletContainer类型的组件
    if  (bean  instanceof  ConfigurableEmbeddedServletContainer)  { 7        //
        postProcessBeforeInitialization((ConfigurableEmbeddedServletContainer)  bean); 9    }
        return bean; 11    }

    private  void  postProcessBeforeInitialization(
    ConfigurableEmbeddedServletContainer  bean)  {
    //获取所有的定制器,调用每一个定制器的customize方法来给Servlet容器进行属性赋值;
    for  (EmbeddedServletContainerCustomizer  customizer  :  getCustomizers())  {
    customizer.customize(bean); 18    }
    }

    private  Collection<EmbeddedServletContainerCustomizer>  getCustomizers()  {
    if  (this.customizers  ==  null)  {
    // Look up does not include the parent context

    this.customizers  =  new  ArrayList<EmbeddedServletContainerCustomizer>(

this.beanFactory
//从容器中获取所有这葛类型的组件:EmbeddedServletContainerCustomizer
//定制Servlet容器,给容器中可以添加一个EmbeddedServletContainerCustomizer类型的组件
.getBeansOfType(EmbeddedServletContainerCustomizer.class, false, false)
.values());
Collections.sort(this.customizers,  AnnotationAwareOrderComparator.INSTANCE); this.customizers  =  Collections.unmodifiableList(this.customizers);

}
return  this.customizers;

}
ServerProperties也是定制器

步骤:

1)、SpringBoot根据导入的依赖情况,给容器中添加相应的

EmbeddedServletContainerFactory【TomcatEmbeddedServletContainerFactory】

2)、容器中某个组件要创建对象就会惊动后置处理器; EmbeddedServletContainerCustomizerBeanPostProcessor;

只要是嵌入式的Servlet容器工厂,后置处理器就工作;

3)、后置处理器,从容器中获取所有的EmbeddedServletContainerCustomizer,调用定制器的定制方法

原文地址:https://www.cnblogs.com/yanl55555/p/12091766.html