Spring Boot是如何启动Tomcat的

本文详细阐述了SpringBoot启动过程中如何通过条件判断和定制化配置,创建并初始化Tomcat服务器,从BeanFactory到WebServer的完整流程。

摘要生成于 C知道 ,由 DeepSeek-R1 满血版支持, 前往体验 >

Spring Boot是如何启动Tomcat的

  • ⾸先,SpringBoot在启动时会先创建⼀个Spring容器

  • 在创建上下文的时候判断是否是内嵌的web服务类型,选择不同是上下文加载方式

  • refreshContext()刷新上下文,IOC容器的创建过程的调用BeanFactoryPostProcessors -> BeanFactory后置处理器

  • BeanFactory后置处理器中加载spring.factories内的自动配置类

  • 生成一个EmbeddedWebServerFactoryCustomizerAutoConfiguration

    • 嵌入式web服务器工厂定制自动配置类
  • 利⽤@ConditionalOnClass技术来判断当前ClassPath中是否存在Tomcat依赖

  • 是否存在Tomcat.calss文件,加载一个Tomcat的定制器,生成一个Tomcat的服务器类

  • 调用getWebServer()方法,创建Tomcat对象,并绑定端⼝等,然后初始化启动Tomcat

    • EmbeddedWebServerFactoryCustomizerAutoConfiguration -> TomcatWebServerFactoryCustomizerConfiguration -> TomcatServletWebServerFactory -> TomcatWebServer

    • ServletWebServerFactory -> TomcatWebServer

      @Override
      public WebServer getWebServer(ServletContextInitializer... initializers) {
          //创建Tomcat实例
          Tomcat tomcat = new Tomcat();
          //创建Tomcat工作目录
          File baseDir = (this.baseDirectory != null) ? this.baseDirectory
              : createTempDir("tomcat");
          tomcat.setBaseDir(baseDir.getAbsolutePath());
          //创建连接对象(Connector是Tomcat重要组件,主要负责处理客户端连接,以及请求处理,这里简单解释下)
          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);
          }
          //准备tomcat context
          prepareContext(tomcat.getHost(), initializers);
          //返回WebServer实现TomcatWebServer
          return getTomcatWebServer(tomcat);
        }
      
      • getTomcatWebServer中会启动tomcat
      	private void initialize() throws WebServerException {
      		logger.info("Tomcat initialized with port(s): " + getPortsDescription(false));
      		synchronized (this.monitor) {
      			try {
      				addInstanceIdToEngineName();
      
      				Context context = findContext();
      				context.addLifecycleListener((event) -> {
      					if (context.equals(event.getSource()) && Lifecycle.START_EVENT.equals(event.getType())) {
      						// Remove service connectors so that protocol binding doesn't
      						// happen when the service is started.
      						removeServiceConnectors();
      					}
      				});
      
      				// 启动服务器以触发初始化侦听器
      				this.tomcat.start();
      
      				// We can re-throw failure exception directly in the main thread
      				rethrowDeferredStartupExceptions();
      
      				try {
      					ContextBindings.bindClassLoader(context, context.getNamingToken(), getClass().getClassLoader());
      				}
      				catch (NamingException ex) {
      					// Naming is not enabled. Continue
      				}
      
      				// Unlike Jetty, all Tomcat threads are daemon threads. We create a
      				// blocking non-daemon to stop immediate shutdown
      				startDaemonAwaitThread();
      			}
      			catch (Exception ex) {
      				stopSilently();
      				destroySilently();
      				throw new WebServerException("Unable to start embedded Tomcat", ex);
      			}
      		}
      	}
      

截屏2021-04-24 下午5.31.48.png

评论
添加红包

请填写红包祝福语或标题

红包个数最小为10个

红包金额最低5元

当前余额3.43前往充值 >
需支付:10.00
成就一亿技术人!
领取后你会自动成为博主和红包主的粉丝 规则
hope_wisdom
发出的红包
实付
使用余额支付
点击重新获取
扫码支付
钱包余额 0

抵扣说明:

1.余额是钱包充值的虚拟货币,按照1:1的比例进行支付金额的抵扣。
2.余额无法直接购买下载,可以购买VIP、付费专栏及课程。

余额充值