加入收藏 | 设为首页 | 会员中心 | 我要投稿 十堰站长网 (https://www.0719zz.com/)- 混合云存储、网络、视频终端、云计算、媒体处理!
当前位置: 首页 > 运营中心 > Tomcat > 正文

Springboot内嵌tomcat应用原理深入解析

发布时间:2023-02-20 10:56:15 所属栏目:Tomcat 来源:互联网
导读:springboot版本:2.2.9.RELEASE。 默认Servlet容器 springboot默认支持tomcat、jetty、undertow作为底层容器, 一旦引入spring-boot-starter-web模块,就默认使用tomcat。 dependency groupIdorg.springframework.boot/groupId artifactIdspring-boot-starte
  springboot版本:2.2.9.RELEASE。
 
 
  默认Servlet容器
  springboot默认支持tomcat、jetty、undertow作为底层容器,
 
  一旦引入spring-boot-starter-web模块,就默认使用tomcat。
 
 
  <dependency>
      <groupId>org.springframework.boot</groupId>
      <artifactId>spring-boot-starter-web</artifactId>
  </dependency>
 
  切换Servlet容器
  排除tomcat依赖;
 
  引入其它的容器。
 

  <dependency>
      <groupId>org.springframework.boot</groupId>
      <artifactId>spring-boot-starter-web</artifactId>
      <exclusions>
          <exclusion>
              <groupId>org.springframework.boot</groupId>
              <artifactId>spring-boot-starter-tomcat</artifactId>
          </exclusion>
      </exclusions>
  </dependency>
  <dependency>
      <groupId>org.springframework.boot</groupId>
      <artifactId>spring-boot-starter-undertow</artifactId>
  </dependency>
 
  内嵌tomcat自动配置原理
 
  tomcat自动配置类
  打开spring-boot-2.2.9.RELEASEspring-boot-projectspring-boot-autoconfiguresrcmainresourcesMETA-INFspring.factories,
 
  这个ServletWebServerFactoryAutoConfiguration就是tomcat的自动配置类,
 
 
 
  打开这个类,
 
 
 
  EmbeddedTomcat
 
 
 
 
  tomcat工厂类
  TomcatServletWebServerFactory,
 
  TomcatServletWebServerFactory有一个getWebServer方法,
 
  @Override
  public WebServer getWebServer(ServletContextInitializer... initializers) {
      if (this.disableMBeanRegistry) {
          Registry.disableRegistry();
      }
      // 实例化一个tomcat
      Tomcat tomcat = new Tomcat();
      File baseDir = (this.baseDirectory != null) ? this.baseDirectory : createTempDir("tomcat");
      // 设置tomcat的临时工作目录
      tomcat.setBaseDir(baseDir.getAbsolutePath());
      // 默认使用Http11NioProtocol实例化connector
      Connector connector = new Connector(this.protocol);
      connector.setThrowOnFailure(true);
      // 给service添加connector
      tomcat.getService().addConnector(connector);
      customizeConnector(connector);
      tomcat.setConnector(connector);
      // 关闭热部署
      tomcat.getHost().setAutoDeploy(false);
      // 配置engine
      configureEngine(tomcat.getEngine());
      for (Connector additionalConnector : this.additionalTomcatConnectors) {
          tomcat.getService().addConnector(additionalConnector);
      }
      prepareContext(tomcat.getHost(), initializers);
      // 实例化TomcatWebServer时会将DispatcherServlet以及一些Filter添加到tomcat
      return getTomcatWebServer(tomcat);
  }
  实例化tomcat,
 
  TomcatServletWebServerFactory#getTomcatWebServer
 
 
 
  TomcatWebServer#TomcatWebServer(org.apache.catalina.startup.Tomcat, boolean)
 
 
 
  TomcatWebServer#initialize
 
 
 
  到this.tomcat.start();这一步,tomcat就启动了。
 
  所以一旦TomcatServletWebServerFactory#getWebServer被调用,内嵌的tomcat就会创建并启动。
 
 
  何时被调用
  在刷新应用上下文的时候,
 
  SpringBootMytestApplication#main
 
  →
 
  SpringApplication#run(java.lang.Class<?>, java.lang.String...) → SpringApplication#run(java.lang.Class<?>[], java.lang.String[])
 
  →
 
  SpringApplication#run(java.lang.String…)
 
  →
 
  SpringApplication#refreshContext
 
  →
 
  SpringApplication#refresh
 
  →
 
  AbstractApplicationContext#refresh
 
  AbstractApplicationContext#refresh
 
 
 
 
  onRefresh()
  我们关注下onRefresh();这个方法,看ServletWebServerApplicationContext的实现,
 
 
 
  ServletWebServerApplicationContext#onRefresh
 
  
  @Override
  protected void onRefresh() {
      super.onRefresh();
      try {
          // 通过Servlet容器工厂TomcatServletWebServerFactory,获取Servlet容器tomcat
          createWebServer();
      }
      catch (Throwable ex) {
          throw new ApplicationContextException("Unable to start web server", ex);
      }
  }
  ServletWebServerApplicationContext#createWebServer
 
 
 
  可以看到这个类型是TomcatServletWebServerFactory,所以就是在这一步调用的。
 
 
  finishRefresh()
  AbstractApplicationContext#refresh
 
  →
 
  AbstractApplicationContext#finishRefresh
 
  →
 
  ServletWebServerApplicationContext#finishRefresh
 

  @Override
  protected void finishRefresh() {
      super.finishRefresh();
      // 实例化(在tomcat启动时就要完成实例化的Servlet:loadStartUp > 0),打印启动完成日志。
      WebServer webServer = startWebServer();
      if (webServer != null) {
          publishEvent(new ServletWebServerInitializedEvent(webServer, this));
      }
  }

(编辑:十堰站长网)

【声明】本站内容均来自网络,其相关言论仅代表作者个人观点,不代表本站立场。若无意侵犯到您的权利,请及时与联系站长删除相关内容!

    推荐文章
      热点阅读