Tomcat源码--服务启动
对Tomcat感兴趣是由于《深入理解Tomcat》这本书,之前仅仅是使用到了Tomcat,这本书却让我对Tomcat的实现更了解了,在这里希望记录一些自己对Tomcat的理解。由于这本书是基于tomcat4的,所以我的文章也是基于tomcat4的,但是tomcat的思想应该是是没有变,主要的两个组件还是连接器和容器。主要为了学习,就不管是新版本还是旧版本了。
为了后面的理解,先大致说一下Tomcat的整体架构,Tomcat主要只有两个东西,连接器和容器,所谓连接器就是一个http请求过来了,连接器负责接收这个请求,然后转发给容器。(本来想弄张图的,但是不知道csdn怎么搞的,插不进去.),实际上一个简单的tomcat只要这两个东西就可以了,tomcat的实现为了统一管理连接器和容器等组件,额外添易做图务器组件(server)和服务组件(service),添加这两个东西的原因我个人觉得就是为了方便统一管理连接器和容器等各种组件。一个server可以有多个service,一个service包含多个连接器和一个容器,当然还有一些其他的东西,这些被统一管理的组件都实现了Lifecycle接口,只要一个组件启动了,那么他的所有子组件也会跟着启动,比如一个server启动了,它地下的所有service都会跟着启动,service启动了,它地下的连接器和容器等其他组件也跟着启动了,这样,tomcat要启动,只要启动server就行了,其他的组件都会跟随着启动,那么server是如何启动的?再让我们从头来看...
一般启动Tomcat会是运行startup.bat或者startup.sh文件,实际上这两个文件最后会调用org.apache.catalina.startup.Bootstrap类的main方法,这个main方法主要做了两件事情,1:定义和初始化了tomcat自己的类加载器,2:通过反射调用了org.apache.catalina.startup.Catalina的process方法;关键代码如下:
[java]
ClassLoader commonLoader = null;
ClassLoader catalinaLoader = null;
ClassLoader sharedLoader = null;
..............................初始化以上三个类加载器
Class startupClass =catalinaLoader.loadClass("org.apache.catalina.startup.Catalina");
Object startupInstance = startupClass.newInstance();
......................................
methodName = "process";//方法名
paramTypes = new Class[1];
paramTypes[0] = args.getClass();
paramValues = new Object[1]
paramValues[0] = args;
method =startupInstance.getClass().getMethod(methodName, paramTypes);
<span style="color: rgb(255, 0, 0); "> method.invoke(startupInstance, paramValues);</span>//调用process方法
org.apache.catalina.startup.Catalina的process方法很短,就是下面一点东西:
[java]
public void process(String args[]) {
setCatalinaHome();
setCatalinaBase();
try {
if (arguments(args))
<span style="color: rgb(255, 0, 0); ">execute();</span>
} catch (Exception e) {
e.printStackTrace(System.out);
}
}
process的功能也很简单,1:如果catalina.home和catalina.base两个属性没有设置就设置一下,2:参数正确的话就调用execute方法,execute的方法就是简单的调用start方法,其中在判断参数正确的方法arguments中会设置starting标识为true,这样在execute方法中就能调用start方法,start方法是重点,在它里面启动了我们的Tomcat所有的服务,下面是start方法里面一些关键的代码:
[java]
protected void start() {
Digester digester = <span style="color: rgb(255, 0, 0); ">createStartDigester</span>();
File file = <span style="color: rgb(255, 0, 0); ">configFile();</span>
try {
InputSource is =
new InputSource("file://" + file.getAbsolutePath());
FileInputStream fis = new FileInputStream(file);
is.setByteStream(fis);
digester.push(this);
digester.parse(is);
fis.close();
} catch (Exception e) {
System.out.println("Catalina.start: " + e);
e.printStackTrace(System.out);
System.exit(1);
}
........................
Thread shutdownHook = new CatalinaShutdownHook();
// Start the new server
if (server instanceof Lifecycle) {
try {
<span style="color: rgb(255, 0, 0); ">server.initialize();
((Lifecycle) server).start();</span>
try {
// Register shutdown hook
Runtime.getRuntime().addShutdownHook(shutdownHook);
} catch (Throwable t) {
// This will fail on JDK 1.2. Ignoring, as Tomcat can run
// fine without the shutdown hook.
}
// Wait for the server to be told to shut down
server.await();
} catch (LifecycleException e) {
System.out.println("Catalina.start: " + e);
补充:软件开发 , Java ,