springboot(八) 嵌入式Servlet容器自动配置原理和容器启动原理

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

1.1 在spring-boot-autoconfigure-1.5.9.RELEASE.jar => springboot自动配置依赖 jar包下,EmbeddedServletContainerAutoConfiguration => 嵌入式servlet容器自动配置类

@AutoConfigureOrder(Ordered.HIGHEST_PRECEDENCE)
@Configuration
@ConditionalOnWebApplication  //如果是web应用,当前配置类生效
@Import(BeanPostProcessorsRegistrar.class) //Bean后置处理器的注册器;给容器中注入一些组件//导入了EmbeddedServletContainerCustomizerBeanPostProcessor//后置处理器功能:在bean初始化前后(刚创建完对象,还没属性赋值)执行初始化工作
public class EmbeddedServletContainerAutoConfiguration {

    /**
     * Nested configuration if Tomcat is being used.
     */
    @Configuration
    @ConditionalOnClass({ Servlet.class, Tomcat.class }) //判断当前是否引入了Tomcat依赖;
    @ConditionalOnMissingBean(value = EmbeddedServletContainerFactory.class, search = SearchStrategy.CURRENT)  //判断当前容器没有用户自定义的EmbeddedServletContainerFactory(嵌入式servlet容器工厂);作用:创建servlet容器;    
    public static class EmbeddedTomcat {

        @Bean
        public TomcatEmbeddedServletContainerFactory tomcatEmbeddedServletContainerFactory() {
            return new TomcatEmbeddedServletContainerFactory();
        }

    }

1.2 EmbeddedServletContainerFactory(嵌入式servlet容器工厂)

public interface EmbeddedServletContainerFactory {    //获取嵌入式servlet容器
    EmbeddedServletContainer getEmbeddedServletContainer(ServletContextInitializer... var1);
}

1.3 EmbeddedServletContainer(嵌入式servlet容器)

1.4 以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);
    }

1.4.1 我们对server的修改是怎么生效的呢?

ServerPorperties ,EmbeddedServletContainerCustomizer

EmbeddedServletContainerCustomizer帮我们修改了server配置,修改的原理是:

容器中也导入了EmbeddedServletContainerCustomizerBeanPostProcessor

//初始化之前    @Override
    public Object postProcessBeforeInitialization(Object bean, String beanName)
            throws BeansException {      //如果当前初始化的是一个ConfigurableEmbeddedServletContainer类型的组件
        if (bean instanceof ConfigurableEmbeddedServletContainer) {
            postProcessBeforeInitialization((ConfigurableEmbeddedServletContainer) bean);
        }
        return bean;
    }
private void postProcessBeforeInitialization(      ConfigurableEmbeddedServletContainer bean) {  //获取所有的定制器,调用每一个定制器的customize()方法来给servlet容器进行属性赋值   for (EmbeddedServletContainerCustomizer customizer : getCustomizers()) {      customizer.customize(bean);   }}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;}

2.嵌入式Servlet容器启动原理

2.1 获取嵌入式servlet容器工厂

2.1.1 springboot启动应用运行run方法

2.1.2 refreshContext(context);springboot刷新ioc容器【创建ioc容器对象,并初始化容器,创建容器中的每一个组件】;如果是web应用创建AnnotationConfigEmbeddedWebApplicationContext容器,否则创建默认的AnnotationConfigApplicationContext容器

2.1.3  refresh(context);刷新刚才创建好的ioc容器;

public void refresh() throws BeansException, IllegalStateException {
        Object var1 = this.startupShutdownMonitor;
        synchronized(this.startupShutdownMonitor) {
            this.prepareRefresh();
            ConfigurableListableBeanFactory beanFactory = this.obtainFreshBeanFactory();
            this.prepareBeanFactory(beanFactory);

            try {
                this.postProcessBeanFactory(beanFactory);
                this.invokeBeanFactoryPostProcessors(beanFactory);
                this.registerBeanPostProcessors(beanFactory);
                this.initMessageSource();
                this.initApplicationEventMulticaster();
                this.onRefresh();
                this.registerListeners();
                this.finishBeanFactoryInitialization(beanFactory);
                this.finishRefresh();
            } catch (BeansException var9) {
                if (this.logger.isWarnEnabled()) {
                    this.logger.warn("Exception encountered during context initialization - cancelling refresh attempt: " + var9);
                }

                this.destroyBeans();
                this.cancelRefresh(var9);
                throw var9;
            } finally {
                this.resetCommonCaches();
            }

        }
    }

2.1.4 onRefresh(); web的ioc容器重写了onRefresh()方法;

2.1.5 web ioc容器创建嵌入式servlet容器: createEmbeddedServletContainer();

2.1.6 获取嵌入式servlet容器工厂 getEmbeddedServletContainerFactory() =>从容器中获取EmbeddedServletContainerFactory组件

   TomcatEmbeddedServletContainerFactory创建对象,后置处理器一看是这个对象,就获取所有的定制器,先定制servlet容器的相关配置

2.1.7 使用容器工厂获取嵌入式servlet容器 this.embeddedServletContainer = containerFactory.getEmbeddedServletContainer(getSelfInitializer());

2.1.8 嵌入式servlet容器创建对象并启动ioc容器;

  先启动嵌入式servlet容器,再将ioc容器中没有创建的对象获取出来;ioc容器启动的时候创建嵌入式servlet容器。

原文地址:https://www.cnblogs.com/hlkawa/p/9736226.html

时间: 2024-10-15 13:10:32

springboot(八) 嵌入式Servlet容器自动配置原理和容器启动原理的相关文章

SpringBoot(七) -- 嵌入式Servlet容器

一.嵌入式Servlet容器 在传统的开发中,我们在完成开发后需要将项目打成war包,在外部配置好TomCat容器,而这个TomCat就是Servlet容器.在使用SpringBoot开发时,我们无需再外部配置Servlet容器,使用的是嵌入式的Servlet容器(TomCat).如果我们使用嵌入式的Servlet容器,存在以下问题: 1.如果我们是在外部安装了TomCat,如果我们想要进行自定义的配置优化,可以在其conf文件夹下修改配置文件来实现.在使用内置Servlet容器时,我们可以使用

手动、自动配置IP参数与启动/关闭网络接口:ifconfig、ifup、ifdown

这三个命令的用途都是启动网络接口,不过,ifup与ifdown仅能就/etc/sysconfig/network-scripts内的ifcfg-ethX(X为数字)进行启动或关闭的操作,并不能直接修改网络参数,除非手动调整ifcfg-ethX文件才行.至于ifconfig则可以直接手动为某个接口配置IP或调整其网络参数. 1.ifconfig ifconfig主要是可以手动启动.查看与修改网络接口的相关参数,可以修改的参数很多,包括IP参数以及MTU等,它的语法如下: [[email prote

SpringBoot 2.X集成 jdbc自动配置原理探究

前言 Springboot对于数据访问层,不管是 SQL还是 NOSQL,Spring Boot 底层都是采用 Spring Data 的方式统一处理.Spring Data 是 Spring 家族中与 Spring Boot.Spring Cloud 齐名且知名项目.想要更好的了解Sping Data,可以参考Sping Data 官网:https://spring.io/projects/spring-data 事实上,Springboot整合jdbc基本上企业都不会这么去使用,但是为什么要

Springboot学习~7:SpringMVC自动配置

Spring MVC auto-configuration Spring Boot 自动配置好了SpringMVC 以下是SpringBoot对SpringMVC的默认配置:==(WebMvcAutoConfiguration)== Inclusion of ContentNegotiatingViewResolver and BeanNameViewResolver beans. 自动配置了ViewResolver(视图解析器:根据方法的返回值得到视图对象(View),视图对象决定如何渲染(转

SpringBoot嵌入式Tomcat的自动配置原理

在读本篇文章之前如果你读过这篇文章SpringBoot自动装配原理解析应该会更加轻松 准备工作 我们知道SpringBoot的自动装配的秘密在org.springframework.boot.autoconfigure包下的spring.factories文件中,而嵌入Tomcat的原理就在这个文件中加载的一个配置类:org.springframework.boot.autoconfigure.web.servlet.ServletWebServerFactoryAutoConfiguratio

配置嵌入式Servlet容器

SpringBoot默认是用的是Tomcat作为嵌入式的Servlet容器:问题?1).如何定制和修改Servlet容器的相关配置:1.修改和server有关的配置(ServerProperties): server.port=8081 server.context-path=/crud server.tomcat.uri-encoding=UTF-8 //通用的Servlet容器设置 server.xxx //Tomcat的设置 server.tomcat.xxx 2.编写一个Embedded

3springboot:springboot配置文件(外部配置加载顺序、自动配置原理,@Conditional)

1.外部配置加载顺序 SpringBoot也可以从以下位置加载配置: 优先级从高到低 高优先级的配置覆盖低优先级的配置,所有的配置会形成互补配置  1.命令行参数 所有的配置都可以在命令行上进行指定 先打包在进行测试 java -jar spring-boot-02-config-02-0.0.1-SNAPSHOT.jar --server.port=8087 --server.context-path=/abc 指定访问的路径 多个配置用空格分开: --配置项=值 -- 由jar包外向jar包

SpringBoot源码分析----(二)SpringBoot自动配置原理

自动配置原理 1.SpringBoot启动的时候加载主配置类,开启了自动配置功能  @EnableAutoConfiguration [email protected] 功能的作用 @AutoConfigurationPackage @Import({AutoConfigurationImportSelector.class}) public @interface EnableAutoConfiguration { 利用  AutoConfigurationImportSelector  给容器

SpringBoot自动配置的实现原理

之前一直在用SpringBoot框架,一直感觉SpringBoot框架自动配置的功能很强大,但是并没有明白它是怎么实现自动配置的,现在有空研究了一下,大概明白了SpringBoot框架是怎么实现自动配置的功能,我们编写一个最简单的自动配置功能,大概的总结一下. 一,配置属性类 其实就是值对象注入的方式去配置一些Spring常用的配置,我们编写一个最简单的配置对象. @ConfigurationProperties(prefix = "hello") //@Component //如果这