[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这些方法。
下面是一些源码:
开始发现一点,反射被大量使用了。首先,这里应该不应该使用反射,我想大家意见不一,不过报着学习源码的态度,我们略过,因为我是设置断点进行调试学习的,所以可以更容易跟踪程序的运行步骤。
首先,我们先看看这个Bootstrap类的设计。
[quote]
首先可以看出,daemon做为启动TOMCAT的唯一对象,被设计成了单列。在我认为,daemon 本身就应该为单列对象,它控制着TOMCAT的初始化,本身就应该唯一存在,如果多个daemon 必然导致数据与操控上的问题[/quote]
除了使用了单列模式,这个类中还使用了类似于Template方法模式,这个应该算是一个简单的Template Method,记得MARTIN FOWLER在《重构》中也有把沉长的代码分解为一个一个算法,之后拼装在一起。在下面这个方法中体现的很好。
看完了设计,下面我们先搞清楚UML图里的一些属性,它到底是干什么用的,包括深入这几个方法,看看它们是怎么初始化的,关闭的。
[img]http://dl.iteye.com/upload/attachment/166968/0656b154-32e0-3746-a37f-6e9012d59f34.jpg[/img]
[/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]