Tomcat 源碼分析[1]

[size=medium][color=red]水平有限,如有不足請留言交流,互相提高,謝謝!轉載請提供出處,http://treblesoftware.iteye.com/admin/blogs/515042
[/color][/size]


[quote]TOMCAT作爲世界上使用較爲廣泛的SERVLET容器被許多項目所應用。是很值得學習的。[/quote]

首先,我們先要下載TOMCAT的源碼,包括要引入TOMCAT的幾個依賴包。

1,到 http://tomcat.apache.org/download-60.cgi 下載 Source Code,我下載的是TOMCAT 6.X 版,可以到這裏直接下載:http://labs.xiaonei.com/apache-mirror/tomcat/tomcat-6/v6.0.20/src/apache-tomcat-6.0.20-src.tar.gz

2,下載這幾個依賴包:org.eclipse.jdt.core.jar (這裏可以到ECLIPES架包裏找到);wsdl4j.jar;jaxrpc.jar;junit-4.6.jar;ant.jar 。

OK,新建一個JAVA項目,之後把解壓好的tomcat源碼放入新建項目中,再把依賴包buildpath一下就可以了。

[img]http://dl.iteye.com/upload/attachment/166950/d3937deb-164e-342f-a694-679a42160caf.jpg[/img]

確保此項目可以正確被構建。

我們首先從 org.apache.catalina.startup; 包中的 Bootstrap 類開始。這個類中擁有一個

MAIN函數入口,我們可以把此入口當作TOMCAT的程序入口,並且在這個類裏擁有initClassLoaders,createClassLoader,init,load,start,stop,stopServer,destroy這些方法。

下面是一些源碼:

/**
* Start the Catalina daemon.
*/
public void start()
throws Exception {
if( catalinaDaemon==null ) init();

Method method = catalinaDaemon.getClass().getMethod("start", (Class [] )null);
method.invoke(catalinaDaemon, (Object [])null);

}


 /**
* Stop the Catalina Daemon.
*/
public void stop()
throws Exception {

Method method = catalinaDaemon.getClass().getMethod("stop", (Class [] ) null);
method.invoke(catalinaDaemon, (Object [] ) null);

}


/**
* Stop the standlone server.
*/
public void stopServer()
throws Exception {

Method method =
catalinaDaemon.getClass().getMethod("stopServer", (Class []) null);
method.invoke(catalinaDaemon, (Object []) null);

}



 /**
* Main method, used for testing only.
*
* @param args Command line arguments to be processed
*/
public static void main(String args[]) {

if (daemon == null) {
daemon = new Bootstrap();
try {
daemon.init();
} catch (Throwable t) {
t.printStackTrace();
return;
}
}

try {
String command = "start";
if (args.length > 0) {
command = args[args.length - 1];
}

if (command.equals("startd")) {
args[0] = "start";
daemon.load(args);
daemon.start();
} else if (command.equals("stopd")) {
args[0] = "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 {
log.warn("Bootstrap: command \"" + command + "\" does not exist.");
}
} catch (Throwable t) {
t.printStackTrace();
}

}


開始發現一點,反射被大量使用了。首先,這裏應該不應該使用反射,我想大家意見不一,不過報着學習源碼的態度,我們略過,因爲我是設置斷點進行調試學習的,所以可以更容易跟蹤程序的運行步驟。


首先,我們先看看這個Bootstrap類的設計。

public final class Bootstrap {

private static Bootstrap daemon = null;

public static void main(String args[]) {

if (daemon == null) {
daemon = new Bootstrap();
try {
daemon.init();
} catch (Throwable t) {
t.printStackTrace();
return;
}
}
…… …… ……


[quote]
首先可以看出,daemon做爲啓動TOMCAT的唯一對象,被設計成了單列。在我認爲,daemon 本身就應該爲單列對象,它控制着TOMCAT的初始化,本身就應該唯一存在,如果多個daemon 必然導致數據與操控上的問題[/quote]

除了使用了單列模式,這個類中還使用了類似於Template方法模式,這個應該算是一個簡單的Template Method,記得MARTIN FOWLER在《重構》中也有把沉長的代碼分解爲一個一個算法,之後拼裝在一起。在下面這個方法中體現的很好。

public void init()
throws Exception
{

// Set Catalina path
setCatalinaHome();
setCatalinaBase();

initClassLoaders();

…… …… ……


看完了設計,下面我們先搞清楚UML圖裏的一些屬性,它到底是幹什麼用的,包括深入這幾個方法,看看它們是怎麼初始化的,關閉的。

[img]http://dl.iteye.com/upload/attachment/166968/0656b154-32e0-3746-a37f-6e9012d59f34.jpg[/img]
發表評論
所有評論
還沒有人評論,想成為第一個評論的人麼? 請在上方評論欄輸入並且點擊發布.
相關文章