spring boot 启动tomcat过程

  1. 从SpringApplication run方法开始
public ConfigurableApplicationContext run(String... args) {
		、、、
		try {
			ApplicationArguments applicationArguments = new DefaultApplicationArguments(args);
			ConfigurableEnvironment environment = prepareEnvironment(listeners, applicationArguments);
			configureIgnoreBeanInfo(environment);
			Banner printedBanner = printBanner(environment);
			// 创建 ServletWebServerApplicationContext  
			context = createApplicationContext();
			exceptionReporters = getSpringFactoriesInstances(SpringBootExceptionReporter.class,
					new Class[] { ConfigurableApplicationContext.class }, context);
			prepareContext(context, environment, listeners, applicationArguments, printedBanner);
			//tomcat 是真的在这里面启动的
			refreshContext(context);
			afterRefresh(context, applicationArguments);
			stopWatch.stop();
			if (this.logStartupInfo) {
				new StartupInfoLogger(this.mainApplicationClass).logStarted(getApplicationLog(), stopWatch);
			}
			listeners.started(context);
			callRunners(context, applicationArguments);
		}
		catch (Throwable ex) {
			handleRunFailure(context, ex, exceptionReporters, listeners);
			throw new IllegalStateException(ex);
		}

		、、、
	}
  1. 查看 SpringApplication refreshContext 方法
private void refreshContext(ConfigurableApplicationContext context) {
		refresh(context);
		if (this.registerShutdownHook) {
			try {
				context.registerShutdownHook();
			}
			catch (AccessControlException ex) {
				// Not allowed in some environments.
			}
		}
	}


protected void refresh(ApplicationContext applicationContext) {
		Assert.isInstanceOf(AbstractApplicationContext.class, applicationContext);
		((AbstractApplicationContext) applicationContext).refresh();
	}
  1. ServletWebServerApplicationContext 的refresh 方法
    public final void refresh() throws BeansException, IllegalStateException {
		try {
		    // 启动AbstractApplicationContext   spring  容器
			super.refresh();
		}
		catch (RuntimeException ex) {
			stopAndReleaseWebServer();
			throw ex;
		}
	}

   // AbstractApplicationContext  的refresh方法在创建容器后会回调子类的onRefresh方法
	@Override
	protected void onRefresh() {
		super.onRefresh();
		try {
		    //  真的开始创建tomcat 容器了
			createWebServer();
		}
		catch (Throwable ex) {
			throw new ApplicationContextException("Unable to start web server", ex);
		}
	}
  1. 创建tomcat 容器
private void createWebServer() {
		WebServer webServer = this.webServer;
		ServletContext servletContext = getServletContext();
		if (webServer == null && servletContext == null) {
		// 工厂在ServletWebServerFactoryConfiguration  配置类中配置
			ServletWebServerFactory factory = getWebServerFactory();
    // getSelfInitializer 获取初始化器,其中就有DispatcherServletRegistrationBean对
    // DispatcherServlet  进行初始化
    // getWebServer 创建tomcat 服务器
			this.webServer = factory.getWebServer(getSelfInitializer());
		}
		else if (servletContext != null) {
			try {
				getSelfInitializer().onStartup(servletContext);
			}
			catch (ServletException ex) {
				throw new ApplicationContextException("Cannot initialize servlet context", ex);
			}
		}
		initPropertySources();
	}
  1. 创建tomcat 服务器的过程
public WebServer getWebServer(ServletContextInitializer... initializers) {
		if (this.disableMBeanRegistry) {
			Registry.disableRegistry();
		}
		Tomcat tomcat = new Tomcat();
		File baseDir = (this.baseDirectory != null) ? this.baseDirectory : createTempDir("tomcat");
		tomcat.setBaseDir(baseDir.getAbsolutePath());
		// 创建连接器
		Connector connector = new Connector(this.protocol);
		connector.setThrowOnFailure(true);
		// 创建StandardServer 并添加connector
		tomcat.getService().addConnector(connector);
		customizeConnector(connector);
		tomcat.setConnector(connector);
		// 创建并获取StandardEngine
		// 创建并获取StandardHost 
		tomcat.getHost().setAutoDeploy(false);
		configureEngine(tomcat.getEngine());
		for (Connector additionalConnector : this.additionalTomcatConnectors) {
			tomcat.getService().addConnector(additionalConnector);
		}
		// 创建TomcatEmbeddedContext
		prepareContext(tomcat.getHost(), initializers);
		// tomcat StandardServer  初始化
		return getTomcatWebServer(tomcat);
	}
  1. org.springframework.boot.web.servlet.context.ServletWebServerApplicationContext#finishRefresh启动tomcat 服务器
protected void finishRefresh() {
		super.finishRefresh();
		 // 启动web服务器
		WebServer webServer = startWebServer();
		if (webServer != null) {
			publishEvent(new ServletWebServerInitializedEvent(webServer, this));
		}
	}


private WebServer startWebServer() {
		WebServer webServer = this.webServer;
		if (webServer != null) {
		// 启动
			webServer.start();
		}
		return webServer;
	}



	public void start() throws WebServerException {
		synchronized (this.monitor) {
			if (this.started) {
				return;
			}
			try {
			    // 启动connector ,及connector使用的线程池
				addPreviouslyRemovedConnectors();
				Connector connector = this.tomcat.getConnector();
				if (connector != null && this.autoStart) {
				  //  初始化servlet, 例如DispatcherServlet
					performDeferredLoadOnStartup();
				}
				checkThatConnectorsHaveStarted();
				this.started = true;
				logger.info("Tomcat started on port(s): " + getPortsDescription(true) + " with context path '"
						+ getContextPath() + "'");
			}
			catch (ConnectorStartFailedException ex) {
				stopSilently();
				throw ex;
			}
			catch (Exception ex) {
				if (findBindException(ex) != null) {
					throw new PortInUseException(this.tomcat.getConnector().getPort());
				}
				throw new WebServerException("Unable to start embedded Tomcat server", ex);
			}
			finally {
				Context context = findContext();
				ContextBindings.unbindClassLoader(context, context.getNamingToken(), getClass().getClassLoader());
			}
		}
	}
  • 0
    点赞
  • 0
    收藏
    觉得还不错? 一键收藏
  • 0
    评论

“相关推荐”对你有帮助么?

  • 非常没帮助
  • 没帮助
  • 一般
  • 有帮助
  • 非常有帮助
提交
评论
添加红包

请填写红包祝福语或标题

红包个数最小为10个

红包金额最低5元

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

抵扣说明:

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

余额充值