tomcat的啟動過程(從startup.bat談起)
前言
自己在做後臺開發時,每次都是直接執行startup.sh(伺服器是linux環境)。但是執行之後tomcat到底幹了啥,自己也是一臉懵逼。於是專門去研究了研究tomcat啟動過程。下面縮寫的是基於Windows環境下的,linux的執行流程也是一樣的
執行startup.bat
在windows作業系統中,我們執行tomcat只需要執行startup.bat指令碼就好,startup.bat檔案的主要操作有:
1.對環境變數的檢查(OS,CATALINA_HOME)從而採取不同的操作,對一些全域性變數賦值(CURRENT_DIR,EXECUTABL)
2.就是找到catalina.bat檔案,然後把引數傳遞給它,在startup.bai中,呼叫catalina.bat的命令call “%EXECUTABLE%” start %CMD_LINE_ARGS%,其中”%EXECUTABLE%”這個就是catalina.bat檔案這個命令至少向catalina.bat傳遞一個引數–start.
執行catalina.bat
在catalina.bat中,主要進行的操作有:
1.對java的執行環境進行校驗和java環境變數的設定,,如果操作失敗,則退出程式
2.將tomcat-juli.jar和bootstrap.jar的全路徑最佳到CLASSPATH中,設定一些log選項,jdpa的操作,如果指定引數-securify,這載入安全策略檔案
3.設定Bootstrap中主函式引數,然後呼叫Bootstrap主函式( MAINCLASS=org.apache.catalina.startup.Bootstrap,Bootstrap )
(ps:在catalina.bat中,有這樣一段程式碼:if not “”%1”” == “”run”” goto mainEntry,意思是如果接收到的第一個引數是run那麼到:mainEntry節點,事實是我們從startup.bat呼叫的時候傳遞的第一個引數無疑是start, 那什麼時候第一個引數才是run呢?事情是這樣的,因為並不是所有人都是跟我們一樣直接使用startup.bat檔案啟動,因為startup.bat檔案也只不過就是找到catalina.bat檔案,然後照樣傳遞引數,其實有經驗的人大可直接使用catalina.bat檔案來啟動tomcat。這就是第一個引數為run的產生情況。接下來我們順序執行到第89行。)
Bootstrap的main方法
在Boootstrap的main函式主要有兩個功能:
1.初始化一個守護程序變數;
2.載入引數,解析命令,並執行
關於main方法的第一個功能,之後我會寫一篇有關tomcat的類載入機制的部落格,在其中會詳細介紹
關於main方法的第二個功能,程式碼如下:
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();
} else if (command.equals("stopd")) {
args[args.length - 1] = "stop";
daemon.stop();
} else if (command.equals("start")) {
daemon.setAwait(true);
daemon.load(args);
daemon.start();
} else if (command.equals("stop")) {
daemon.stopServer(args);
} else if (command.equals("configtest")) {
daemon.load(args);
if (null==daemon.getServer()) {
System.exit(1);
}
System.exit(0);
} else {
log.warn("Bootstrap: command \"" + command + "\" does not exist.");
}
其中load方法是將命令列定義的引數傳遞給 catalinaDaemon.load方法(通過反射呼叫)。接下來執行的start,stop等方法就是呼叫catalinaDaemon中的對應方法(也是通過反射呼叫),例如stop方法:
/**
* Stop the Catalina Daemon.
*/
public void stop()
throws Exception {
Method method = catalinaDaemon.getClass().getMethod("stop", (Class [] ) null);
method.invoke(catalinaDaemon, (Object [] ) null);
}