• 【串线篇】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,调用定制器的定制方法

  • 相关阅读:
    认识“委托”
    程序员的修炼之道:从小工到专家(一)
    知识的使用 与 知识的内化
    VB.Net中 Module 的前世今生
    memcached
    C#知识
    Android之垂直显示TextView
    Android开发之各个语言
    Android之hint提示字体大小修改,显示完全
    Android 之计算控件颜色透明度
  • 原文地址:https://www.cnblogs.com/yanl55555/p/12091766.html
Copyright © 2020-2023  润新知