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

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

  1. @AutoConfigureOrder(Ordered.HIGHEST_PRECEDENCE)
  2. @Configuration
  3. @ConditionalOnWebApplication //如果是web应用,当前配置类生效
  4. @Import(BeanPostProcessorsRegistrar.class) //Bean后置处理器的注册器;给容器中注入一些组件
    //导入了EmbeddedServletContainerCustomizerBeanPostProcessor
    //后置处理器功能:在bean初始化前后(刚创建完对象,还没属性赋值)执行初始化工作
  5. public class EmbeddedServletContainerAutoConfiguration {
  6.  
  7. /**
  8. * Nested configuration if Tomcat is being used.
  9. */
  10. @Configuration
  11. @ConditionalOnClass({ Servlet.class, Tomcat.class }) //判断当前是否引入了Tomcat依赖;
  12. @ConditionalOnMissingBean(value = EmbeddedServletContainerFactory.class, search = SearchStrategy.CURRENT) //判断当前容器没有
    用户自定义的EmbeddedServletContainerFactory(嵌入式servlet容器工厂);作用:创建servlet容器;
        
  13. public static class EmbeddedTomcat {
  14.  
  15. @Bean
  16. public TomcatEmbeddedServletContainerFactory tomcatEmbeddedServletContainerFactory() {
  17. return new TomcatEmbeddedServletContainerFactory();
  18. }
  19.  
  20. }

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

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

1.3 EmbeddedServletContainer(嵌入式servlet容器)

1.4 以TomcatEmbeddedServletContainerFactory为例

  1. @Override
  2. public EmbeddedServletContainer getEmbeddedServletContainer(
  3. ServletContextInitializer... initializers) {
          // 创建Tomcat
  4. Tomcat tomcat = new Tomcat();
          //配置Tomcat的基本环境
  5. File baseDir = (this.baseDirectory != null ? this.baseDirectory
  6. : createTempDir("tomcat"));
  7. tomcat.setBaseDir(baseDir.getAbsolutePath());
  8. Connector connector = new Connector(this.protocol);
  9. tomcat.getService().addConnector(connector);
  10. customizeConnector(connector);
  11. tomcat.setConnector(connector);
  12. tomcat.getHost().setAutoDeploy(false);
  13. configureEngine(tomcat.getEngine());
  14. for (Connector additionalConnector : this.additionalTomcatConnectors) {
  15. tomcat.getService().addConnector(additionalConnector);
  16. }
  17. prepareContext(tomcat.getHost(), initializers);
          //将配置好的Tomcat传入进去。返回一个EmbeddedServletContainer 并且启动tomcat容器
  18. return getTomcatEmbeddedServletContainer(tomcat);
  19. }

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

  1. ServerPorperties ,EmbeddedServletContainerCustomizer

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

容器中也导入了EmbeddedServletContainerCustomizerBeanPostProcessor

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

  1. public void refresh() throws BeansException, IllegalStateException {
  2. Object var1 = this.startupShutdownMonitor;
  3. synchronized(this.startupShutdownMonitor) {
  4. this.prepareRefresh();
  5. ConfigurableListableBeanFactory beanFactory = this.obtainFreshBeanFactory();
  6. this.prepareBeanFactory(beanFactory);
  7.  
  8. try {
  9. this.postProcessBeanFactory(beanFactory);
  10. this.invokeBeanFactoryPostProcessors(beanFactory);
  11. this.registerBeanPostProcessors(beanFactory);
  12. this.initMessageSource();
  13. this.initApplicationEventMulticaster();
  14. this.onRefresh();
  15. this.registerListeners();
  16. this.finishBeanFactoryInitialization(beanFactory);
  17. this.finishRefresh();
  18. } catch (BeansException var9) {
  19. if (this.logger.isWarnEnabled()) {
  20. this.logger.warn("Exception encountered during context initialization - cancelling refresh attempt: " + var9);
  21. }
  22.  
  23. this.destroyBeans();
  24. this.cancelRefresh(var9);
  25. throw var9;
  26. } finally {
  27. this.resetCommonCaches();
  28. }
  29.  
  30. }
  31. }

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容器。

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

  1. 尚硅谷springboot学习26-嵌入式servlet容器自动配置、启动原理

    EmbeddedServletContainerAutoConfiguration:嵌入式的Servlet容器自动配置 @AutoConfigureOrder(Ordered.HIGHEST_PREC ...

  2. 嵌入式Servlet容器自动配置和启动原理

    EmbeddedServletContainerAutoConfiguration:嵌入式的Servlet容器自动配置? @AutoConfigureOrder(Ordered.HIGHEST_PRE ...

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

    EmbeddedServletContainerAutoConfiguration:嵌入式的Servlet容器自动配置? @AutoConfigureOrder(Ordered.HIGHEST_PREC ...

  4. 4_7.springboot2.x嵌入式servlet容器自动配置原理

    概述 Spring Boot对所支持的Servlet Web服务器实现做了建模抽象: Servlet容器类型  WebServer模型接口 WebServer工厂实现类 Tomcat    Tomca ...

  5. java框架之SpringBoot(8)-嵌入式Servlet容器

    前言 SpringBoot 默认使用的嵌入式 Servlet 容器为 Tomcat,通过依赖关系就可以看到: 问题: 如何定制和修改 Servlet 容器相关配置? SpringBoot 能否支持其它 ...

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

    一.嵌入式Servlet容器 在传统的开发中,我们在完成开发后需要将项目打成war包,在外部配置好TomCat容器,而这个TomCat就是Servlet容器.在使用SpringBoot开发时,我们无需 ...

  7. SpringBoot | 4.1 SpringMVC的自动配置

    目录 前言 1. SpringMVC框架的设计与流程 1.1 SpringMVC框架的示意图 1.2 SpringMVC的组件流程 2. *自动配置的源码分析 2.1 导入Web场景启动器 2.2 找 ...

  8. SpringBoot入门(四)——自动配置

    本文来自网易云社区 SpringBoot之所以能够快速构建项目,得益于它的2个新特性,一个是起步依赖前面已经介绍过,另外一个则是自动配置.起步依赖用于降低项目依赖的复杂度,自动配置负责减少人工配置的工 ...

  9. 接管SpringBoot对Activiti的数据源自动配置

    SpringBoot的自动配置真的让人又爱又恨,但还是爱更多一点. SpringBoot想要帮我们自动配置好一切,但是有时候配置的却并不是我们需要的,甚至有时候会默默的坑我们. 我的项目是一个多数据源 ...

随机推荐

  1. C. Nearest vectors--cf598C(极角排序)

    http://codeforces.com/problemset/problem/598/C 题目大意: 给你你个向量  向量的起点都是从(0,0)开始的   求哪个角最小  输出这两个向量 这是第一 ...

  2. springboot使用过程中遇到的问题

    一.工具Intellij IDEA 二.基本问题 1.数据库语句 Caused by: java.lang.IllegalStateException: Cannot load driver clas ...

  3. 重装JDK后Tomcat和Eclipse的配置

    比如JDK之前是1.8.0_31的,升级之后变成了1.8.0_131之后,Tomcat需要做如下配置: 对于Eclipse中之前配置的Tomcat需要删除后重新添加一个.

  4. iOS设计模式 - (1)概述

    近期可自由安排的时间比較多, iOS应用方面, 没什么好点子, 就先放下, 不写了.花点时间学学设计模式. 之后将会写一系列博文, 记录设计模式学习过程. 当然, 由于我自己是搞iOS的, 所以之后设 ...

  5. SQL 主机

    SQL 主机 SQL 主机 如果您想要您的网站存储数据在数据库并从数据库显示数据,您的 Web 服务器必须能使用 SQL 语言访问数据库系统. 如果您的 Web 服务器托管在互联网服务提供商(ISP, ...

  6. Project Euler:Problem 61 Cyclical figurate numbers

    Triangle, square, pentagonal, hexagonal, heptagonal, and octagonal numbers are all figurate (polygon ...

  7. Android中的动画具体解释系列【2】——飞舞的蝴蝶

    这一篇来使用逐帧动画和补间动画来实现一个小样例,首先我们来看看Android中的补间动画. Android中使用Animation代表抽象的动画类,该类包含以下几个子类: AlphaAnimation ...

  8. FancyCoverFlow

    https://github.com/davidschreiber/FancyCoverFlow

  9. 修改linux环境变量配置文件

    发现error ImportError: dynamic module does not define module export function (PyInit_cv_bridge_boost) ...

  10. java方法返回值的变量类型困惑

    一.java program progress of excuting:show in next picture        How about the java virtual machine i ...