Tomcat源码分析(七)--单一启动/关闭机制(生命周期)(一)

2014-11-24 08:41:38 · 作者: · 浏览: 0

在前面的大部分文章都是讲连接器和容器的,以后的内容会偏向写一些Tomcat的其他组件以及一些细节的东西。
Tomcat有很多组件,要一个一个启动组件难免有点麻烦。由于Tomcat的包含关系是Catalina->Server->Service->容器/连接器/日志器等,于是可通过父组件负责启动/关闭它的子组件,这样只要启动Catalina,其他的都自动启动了。这种单一启动和关闭的机制是通过实现Lifecycle接口来实现的。下面是Lifecycle接口的定义:
[java]
public interface Lifecycle {
public static final String START_EVENT = "start"; //生命周期的六个事件类型!
public static final String BEFORE_START_EVENT = "before_start";
public static final String AFTER_START_EVENT = "after_start";
public static final String STOP_EVENT = "stop";
public static final String BEFORE_STOP_EVENT = "before_stop";
public static final String AFTER_STOP_EVENT = "after_stop";

public void addLifecycleListener(LifecycleListener listener);//在此组件中添加一个监听器
public LifecycleListener[] findLifecycleListeners();
public void removeLifecycleListener(LifecycleListener listener);
public void start() throws LifecycleException;//组件启动方法
public void stop() throws LifecycleException;
}

当组件实现了Lifecycle接口,父组件启动的时候,即调用start方法时,只要在父组件的start方法中也调用子组件的start方法即可(只有实现统一的接口Lifecycle才能实现统一调用,如以下调用方式:(Lifecycle)子组件.start()),下面一步一步来看源代码,首先在Catalina启动start,部分代码如下:
[java]
// Start the new server
if (server instanceof Lifecycle) {
try {
server.initialize();
((Lifecycle) server).start();//启动server
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);
e.printStackTrace(System.out);
if (e.getThrowable() != null) {

System.out.println("----- Root Cause -----");
e.getThrowable().printStackTrace(System.out);
}
}
}
关键看((Lifecycle) server).start();这样便在启动Catalina的时候启动了Server,再看StandardServer的start方法:
[java]
public void start() throws LifecycleException {

// Validate and update our current component state
if (started)
throw new LifecycleException
(sm.getString("standardServer.start.started"));
// Notify our interested LifecycleListeners
//发送这个事件
lifecycle.fireLifecycleEvent(BEFORE_START_EVENT, null);//发送生命周期事件。

lifecycle.fireLifecycleEvent(START_EVENT, null);
started = true;

// Start our defined Services
synchronized (services) { //由这里也可以看出一个server可以有多个services
for (int i = 0; i < services.length; i++) {
if (services[i] instanceof Lifecycle)
((Lifecycle) services[i]).start();
}
}

// Notify our interested LifecycleListeners
lifecycle.fireLifecycleEvent(AFTER_START_EVENT, null);

}
主要做了两件事,1:发送生命周期事件给监听者;2:启动子组件services(至于server怎么关联上services请看前面的几篇文章,以后都不再题怎么关联上的了)。
这里先岔开一下,说一下监听器,lifecycle是一个工具类LifecycleSupport的实例,每一个组件都有这样一个工具类,这个工具类的作用就是帮助管理该组件上的监听器,包括添加监听器和群发事件给监听器,看LifecycleSupport类的一些关键代码:
[j