tomcat深入學習(二)(1) ---- tomcat初始化

架構路上發表於2020-11-10

tomcat的初始化流程:

現階段,我們使用tomcat有兩種方式:

  1. 官網下載tomcat,將web專案打成war包部署到tomcat的webapps目錄下,具體使用請參考新增連結描述
    這種方式啟動時通過點選startup.bat,其底層是呼叫名為Bootstrap.class的main方法。
public final class Bootstrap {
	public static void main(String args[]) {
	        synchronized (daemonLock) {
	            if (daemon == null) {
	                // Don't set daemon until init() has completed
	                Bootstrap bootstrap = new Bootstrap();
	                try {
	                    bootstrap.init();
			...省略	                    
	}
}		                    

有興趣的童鞋可以跟進看看。這裡我們主要強調下面這種方式,也是目前使用最多的方式。

  1. springboot內建tomcat。

在深入之前,我想說的是,內建的tomcat其底層實現與官網tomcat有些許差異,但架構層面還是一樣的,是springboot官方做了許多優化。簡單列舉一下:
原:server:service:engine:host:context:wrapper
1 : n : n : n2 : n3 : n4 (這個有點不確定)
springboot:server:service:engine:host:context:wrapper
1 : 1 : 1 : 1 : 1: 1
這種優化有利有弊吧。

接下來進入正題:

  1. springboot是如何建立tomcat server的?
// spring容器在初始化時會 有個重新整理容器的操作
public abstract class AbstractApplicationContext extends DefaultResourceLoader
		implements ConfigurableApplicationContext {
@Override
	public void refresh() throws BeansException, IllegalStateException {
		synchronized (this.startupShutdownMonitor) {
			// Prepare this context for refreshing.
			prepareRefresh();

			// Tell the subclass to refresh the internal bean factory.
			ConfigurableListableBeanFactory beanFactory = obtainFreshBeanFactory();

			// Prepare the bean factory for use in this context.
			prepareBeanFactory(beanFactory);

			try {
				// Allows post-processing of the bean factory in context subclasses.
				postProcessBeanFactory(beanFactory);

				// Invoke factory processors registered as beans in the context.
				invokeBeanFactoryPostProcessors(beanFactory);

				// Register bean processors that intercept bean creation.
				registerBeanPostProcessors(beanFactory);

				// Initialize message source for this context.
				initMessageSource();

				// Initialize event multicaster for this context.
				initApplicationEventMulticaster();

				// Initialize other special beans in specific context subclasses.
				//	容器在這裡被建立
				onRefresh();

				// Check for listener beans and register them.
				registerListeners();

				// Instantiate all remaining (non-lazy-init) singletons.
				finishBeanFactoryInitialization(beanFactory);

				// Last step: publish corresponding event.
				finishRefresh();
			}
			...省略
		}
	}
}

//1. ServletWebServerApplicationContext # onRefresh()
//2. ServletWebServerApplicationContext # createWebServer()
//3. TomcatServletWebServerFactory # getWebServer()

@Override
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 connector = new Connector(this.protocol);
	connector.setThrowOnFailure(true);
	
//  1.建立 tomcat server / service,並設定層級關係	; 並給 service 繫結 connector
	tomcat.getService().addConnector(connector);
	customizeConnector(connector);
	tomcat.setConnector(connector);
//  2. 建立 engine / host,並設定層級關係 ; 並關閉自動部署 setAutoDeploy(false) ,提高效能	
	tomcat.getHost().setAutoDeploy(false);
	configureEngine(tomcat.getEngine());
	for (Connector additionalConnector : this.additionalTomcatConnectors) {
		tomcat.getService().addConnector(additionalConnector);
	}
	prepareContext(tomcat.getHost(), initializers);
	return getTomcatWebServer(tomcat);
}
//4. TomcatServletWebServerFactory # getTomcatWebServer()
protected TomcatWebServer getTomcatWebServer(Tomcat tomcat) {
		return new TomcatWebServer(tomcat, getPort() >= 0, getShutdown());
}
  1. tomcat裡面的元件是如何初始化的?


// 在 TomcatWebServer 建構函式中 呼叫了初始化方法 initialize();

暫未完成

相關文章