更新時間:2020-12-08 17:34:11 來源:動力節(jié)點 瀏覽1232次
Tomcat服務器的啟動流程很標準化,入口是 BootStrap,統(tǒng)一按照生命周期管理接口 Lifecycle的定義進行啟動。首先,調(diào)用 init()方法逐級初始化,接著調(diào)用 start()方法進行啟動,同時,每次調(diào)用伴隨著生命周期狀態(tài)變更事件的觸發(fā)。本文我們來介紹Tomcat啟動前的準備工作——Tomcat初始化。
當Tomcat啟動的時候 首先會加載 org.apache.ctalina.startup.BootStrap類。使用eclipse或idea啟動tomcat其實就是在啟動這個類的main方法,根據(jù)類的初始化首先會加載static靜態(tài)塊,然后進入main方法。
啟動的主要步驟可以圍繞BootStrap劃分為 static中的準備和main中的初始化(init)、加載 (load)、啟動(statrt)。下面我們來看看各個步驟的源碼:
1、 static
//靜態(tài)代碼塊的主要功能是設置工作目錄catalinaBaseFile和安裝目錄catalinaHomeFile
static {
// Will always be non-null
String userDir = System.getProperty("user.dir");
// Home first
String home = System.getProperty(Globals.CATALINA_HOME_PROP);
File homeFile = null;
if (home != null) {
File f = new File(home);
try {
homeFile = f.getCanonicalFile();
} catch (IOException ioe) {
homeFile = f.getAbsoluteFile();
}
}
if (homeFile == null) {
// First fall-back. See if current directory is a bin directory
// in a normal Tomcat install
File bootstrapJar = new File(userDir, "bootstrap.jar");
if (bootstrapJar.exists()) {
File f = new File(userDir, "..");
try {
homeFile = f.getCanonicalFile();
} catch (IOException ioe) {
homeFile = f.getAbsoluteFile();
}
}
}
if (homeFile == null) {
// Second fall-back. Use current directory
File f = new File(userDir);
try {
homeFile = f.getCanonicalFile();
} catch (IOException ioe) {
homeFile = f.getAbsoluteFile();
}
}
catalinaHomeFile = homeFile;
System.setProperty(
Globals.CATALINA_HOME_PROP, catalinaHomeFile.getPath());
// Then base
String base = System.getProperty(Globals.CATALINA_BASE_PROP);
if (base == null) {
catalinaBaseFile = catalinaHomeFile;
} else {
File baseFile = new File(base);
try {
baseFile = baseFile.getCanonicalFile();
} catch (IOException ioe) {
baseFile = baseFile.getAbsoluteFile();
}
catalinaBaseFile = baseFile;
}
System.setProperty(
Globals.CATALINA_BASE_PROP, catalinaBaseFile.getPath());
}
2、main
main方法主要是 init、laod、start (daemon = bootStrap),當start 方法加載完畢,就標志著tomcat啟動完成 。
(1)Init
//這里的主要功能是初始化了三個類加載器和創(chuàng)建了Catalina對象
//ClassLoader commonLoader = null;
//ClassLoader catalinaLoader = null;
//ClassLoader sharedLoader = null;
public void init() throws Exception {
//初始化三個類加載器
initClassLoaders();
Thread.currentThread().setContextClassLoader(catalinaLoader);
SecurityClassLoad.securityClassLoad(catalinaLoader);
// Load our startup class and call its process() method
if (log.isDebugEnabled())
log.debug("Loading startup class");
//通過反射創(chuàng)建Catalina對象
Class<?> startupClass = catalinaLoader.loadClass("org.apache.catalina.startup.Catalina");
Object startupInstance = startupClass.getConstructor().newInstance();
// Set the shared extensions class loader
if (log.isDebugEnabled())
log.debug("Setting startup class properties");
//為Catalina對象設置類加載器sharedLoader
String methodName = "setParentClassLoader";
Class<?> paramTypes[] = new Class[1];
paramTypes[0] = Class.forName("java.lang.ClassLoader");
Object paramValues[] = new Object[1];
paramValues[0] = sharedLoader;
Method method =
startupInstance.getClass().getMethod(methodName, paramTypes);
method.invoke(startupInstance, paramValues);
catalinaDaemon = startupInstance;
}
(2)laod :比較復雜 ,涉及server、service、connector、engin、可分為如下幾步 注意:load過程中并且有對 host、wapper 進行初始化
//這里是通過反射轉(zhuǎn)調(diào)Catalina對象的load方法
private void load(String[] arguments) throws Exception {
// Call the load() method
String methodName = "load";
Object param[];
Class<?> paramTypes[];
if (arguments==null || arguments.length==0) {
paramTypes = null;
param = null;
} else {
paramTypes = new Class[1];
paramTypes[0] = arguments.getClass();
param = new Object[1];
param[0] = arguments;
}
Method method =
catalinaDaemon.getClass().getMethod(methodName, paramTypes);
if (log.isDebugEnabled()) {
log.debug("Calling startup class " + method);
}
method.invoke(catalinaDaemon, param);
}
然后又重新定義了initInternal()抽象方法,server、service、engine、connector等各自間接或直接的實現(xiàn)了 LifeCycleBase類并實現(xiàn)了initlnernal()的方法,因此在他們進行初始化的時候會調(diào)用自己的initlnternal()實現(xiàn)。
以上就是通過源碼來對Tomcat初始化的分析,通過源碼我們能夠直截了當?shù)目闯鯰omcat服務器初始化過程中調(diào)用的方法以及各種內(nèi)部變化。Tomcat初始化也只是Tomcat服務器整體工作流程中的第一步,想要學習和了解整個過程的小伙伴請到本站的Tomcat服務器教程中一邊學習一邊思考。