本文主要講解Tomcat啟動和部署webapp時的原理和過程淑蔚,以及其使用的配置文件的詳解。主要有三大部分:
1.Tomcat的簡介和啟動過程
2.Tomcat部署webapp
3.Tomcat處理一個http請求的過程
【簡介】
Tomcat依賴/conf/server.xml這個配置文件啟動server(一個Tomcat實例,核心就是啟動容器Catalina)劳较。
Tomcat部署Webapp時后众,依賴context.xml和web.xml(/conf/目錄下的context.xml和web.xml在部署任何webapp時都會啟動,他們定義一些默認行為祟昭,而具體每個webapp的 ?META-INF/context.xml ?和 ?WEB-INF/web.xml ?則定義了每個webapp特定的行為)兩個配置文件部署web應用缕坎。
第一部分、Tomcat的簡介和啟動過程
一個標準TOMCAT結(jié)構(gòu)目錄如上圖所示:
BIN目錄主要存放各種平臺下啟動和關(guān)閉Tomcat的腳本文件.其中 有個檔是catalina.bat,打開這個windos配置文件,在非注釋行加入JDK路徑,例如 : SET? JAVA_HOME=C:\j2sdk1.4.2_06 保存后,就配置好tomcat環(huán)境了. startup.bat是windows下啟動tomcat的文件,shutdown.bat是關(guān)閉tomcat的文件.
conf:存放不同的配置文件(如:server.xml和web.xml)篡悟;?
server.xml文件:該文件用于配置和server相關(guān)的信息谜叹,比如tomcat啟動的端口號、配置host主機搬葬、配置Context?
web.xml文件:部署描述文件荷腊,這個web.xml中描述了一些默認的servlet,部署每個webapp時急凰,都會調(diào)用這個文件女仰,配置該web應用的默認servlet。
tomcat-users.xml文件:配置tomcat的用戶密碼與權(quán)限。
context.xml:定義web應用的默認行為疾忍。
/lib:存放Tomcat運行需要的庫文件(JARS)乔外;?
/logs:存放Tomcat執(zhí)行時的LOG文件;?
/temp:?臨時目錄
/webapps:Tomcat的主要Web發(fā)布目錄(包括應用程序示例)锭碳;?
/work:存放jsp編譯成Servlet后產(chǎn)生的class文件袁稽;
二、Tomcat啟動過程?
1擒抛、開啟Tomcat:可以在IDE中啟動Tomcat的服務器推汽,也可以手動在/bin/目錄下找到startup.bat并雙擊,然后程序就會依次執(zhí)行以下步驟:
(1)引導(Bootstrap)啟動:調(diào)用了org.apache.catalina.startup.Bootstrap.class中的main方法歧沪,開始啟動Tomcat容器歹撒;main方法如下:
publicstaticvoid main(String args[]) {
? ? ? ? if(daemon ==null) {
? ? ? ? ? ? daemon =newBootstrap();//創(chuàng)建了一個引導對象try{//引導對象初始化,即創(chuàng)建了Catalina容器? ? ? ? ? ? ? ? daemon.init();
? ? ? ? ? ? } catch (Throwable t) {
? ? ? ? ? ? ? ? t.printStackTrace();
? ? ? ? ? ? ? ? return;
? ? ? ? ? ? }
? ? ? ? }
? ? ? ? // 根據(jù)不同的命令參數(shù)執(zhí)行try {
? ? ? ? ? ? String command = "start";
? ? ? ? ? ? if(args.length > 0) {
? ? ? ? ? ? ? ? command = args[args.length - 1];
? ? ? ? ? ? }
? ? ? ? ? ? if(command.equals("startd")) {
? ? ? ? ? ? ? ? args[args.length - 1] = "start";
? ? ? ? ? ? ? ? daemon.load(args);
? ? ? ? ? ? ? ? daemon.start();
? ? ? ? ? ? } elseif(command.equals("stopd")) {
? ? ? ? ? ? ? ? args[args.length - 1] = "stop";
? ? ? ? ? ? ? ? daemon.stop();
? ? ? ? ? ? } elseif(command.equals("start")) {
? ? ? ? ? ? ? ? daemon.setAwait(true);
? ? ? ? ? ? ? ? daemon.load(args);
? ? ? ? ? ? ? ? daemon.start();
? ? ? ? ? ? } elseif(command.equals("stop")) {
? ? ? ? ? ? ? ? daemon.stopServer(args);
? ? ? ? ? ? } else {
? ? ? ? ? ? ? ? log.warn("Bootstrap: command \"" + command + "\" does not exist.");
? ? ? ? ? ? }
? ? ? ? } catch (Throwable t) {
? ? ? ? ? ? t.printStackTrace();
? ? ? ? }
? ? }publicvoid init()?
? ? ? ? throws Exception?
? ? {?
? ? ? ? // Set Catalina path?
? ? ? ? // 設置catalina_home屬性诊胞,tomcat啟動腳本里有通過-Dcatalina.home設置? ? ? ? ? setCatalinaHome();?
? ? ? ? // 設置catalina_base屬性暖夭,運行多實例的時候該目錄與catalina_home不同? ? ? ? ? setCatalinaBase();?
? ? ? ? // 初始化classloader,讀取conf/catalina.properties撵孤,根據(jù)指定的repository創(chuàng)建classloader?
? ? ? ? // 有三個classloader? 分別是common迈着、catalina、shared邪码,tomcat6中三個相同? ? ? ? ? initClassLoaders();?
? ? ? ? // 設置當前線程的classloader? ? ? ? ? Thread.currentThread().setContextClassLoader(catalinaLoader);?
? ? ? ? // 待研究? ? ? ? ? SecurityClassLoad.securityClassLoad(catalinaLoader);?
? ? ? ? // 以下通過反射調(diào)用Catalina中的方法?
? ? ? ? // Load our startup class and call its process() method? if (log.isDebugEnabled())?
? ? ? ? ? ? log.debug("Loading startup class");?
? ? ? ? Class startupClass =?
? ? ? ? ? ? catalinaLoader.loadClass?
? ? ? ? ? ? ("org.apache.catalina.startup.Catalina");?
? ? ? ? Object startupInstance = startupClass.newInstance();?
? ? ? ? // Set the shared extensions class loader? if (log.isDebugEnabled())?
? ? ? ? ? ? log.debug("Setting startup class properties");?
? ? ? ? String methodName = "setParentClassLoader";?
? ? ? ? Class paramTypes[] =newClass[1];?
? ? ? ? paramTypes[0] = Class.forName("java.lang.ClassLoader");?
? ? ? ? Object paramValues[] =newObject[1];?
? ? ? ? paramValues[0] = sharedLoader;?
? ? ? ? Method method =?
? ? ? ? ? ? startupInstance.getClass().getMethod(methodName, paramTypes);?
? ? ? ? method.invoke(startupInstance, paramValues);?
? ? ? ? catalinaDaemon = startupInstance;?
? ? }
2)調(diào)用Bootstrap中的init()裕菠,創(chuàng)建了Catalina對象(核心容器):主要進行了以下三步:
//設置tomcat實例的環(huán)境變量
①?Set up the environment variables required by this Tomcat instance
//實例化將用于運行Tomcat實例的通用類加載
②?Instantiate the general class loaders that will be used for our running? Tomcat instance
//初始化tomcat實例
③?Initialize this Tomcat instance
(3)調(diào)用Bootstrap中的load():實際上是通過反射調(diào)用了catalina的load方法。
①Parse the main configuration file for a Tomcat instance, server.xml,?converting each configuration element into the appropriate Tomcat?component1闭专。(找到config file(server.xml)奴潘;然后創(chuàng)建digester,解析server.xml影钉,生成各組件對象(Server画髓、Service、Container平委、Connector等)以及建立相互之間的關(guān)系奈虾。 )
(4)Start up our outermost Top Level Element—the Server instance。(最后start()廉赔,同樣是在Bootstrap中通過反射調(diào)用catalina對象的start方法肉微。接著啟動server.start()方法:((Lifecycle)?getServer()).start();?接著調(diào)用service.start()方法。接下來是一系列的container的start昂勉,后續(xù)在分析(會部署所有的項目)
三浪册、server.xml配置簡介:?下面講述這個文件中的基本配置信息,更具體的配置信息請參考tomcat的文檔