1. 程式人生 > >tomcat的啟動過程(從startup.bat談起)

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);

 }