了解tomcat的人可能知道tomcat是由一个个的组件组成的,有些组件可以包含子组件,比如容器中可能包含loader、manager等组件。不了解tomcat结构的可以看下本系列的第三节。tomcat用catalina类来表示整个tomcat,在Catalina中负责初始化和启动这些组件。我们不需要去依次处理每个组件的启动,tomcat中父组件负责启动和停止它下面所有的子组件,因此我们只需要启动最顶层的组件即可,再启动过程中可能会伴随着一些初始化的动作,这些功能全部依靠tomcat中的Lifecycle接口实现。本节着重了解下tomcat中的生命周期管理。
Catalina类中关于组件初始化和启动的代码:
// Start the new server if (server instanceof Lifecycle) { try { server.initialize(); ((Lifecycle) server).start(); 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); } } }StandardServer类表示最顶级的组件,初始化的过程可以用下面这张流程图表示:
首先是所有的组件完成初始化的动作,StandardServer这些组件全部都实现了Lifecycle接口。
package org.apache.catalina; /** * Common interface for component life cycle methods. Catalina components * may, but are not required to, implement this interface (as well as the * appropriate interface(s) for the functionality they support) in order to * provide a consistent mechanism to start and stop the component. * * @author Craig R. McClanahan * @version $Revision: 1.6 $ $Date: 2002/06/09 02:10:50 $ */ /** *Lifecycle中定义了六种事件,前三种是启动的时候可能被触发的,后三种是停止的时候可能被触发的 * */ 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); //统一的start方法 public void start() throws LifecycleException; public void stop() throws LifecycleException; }代码来到启动StandardServer,主要逻辑如下:
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 //触发一个start前的事件 lifecycle.fireLifecycleEvent(BEFORE_START_EVENT, null); //触发一个start事件 lifecycle.fireLifecycleEvent(START_EVENT, null); //修改启动状态 started = true; // Start our defined Services synchronized (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); }tomcat为了方便对lifelistener的管理封装了一个LifecycleSupport类,每个实现Lifecycle接口的组件内容都会持有这个类,通过这个类在初始化的过程中将合适的监听器注册上,然后当事件被触发的时候,由LifecycleSupport类通知所有的监听器,该类代码如下:
package org.apache.catalina.util; import org.apache.catalina.Lifecycle; import org.apache.catalina.LifecycleEvent; import org.apache.catalina.LifecycleListener; /** * Support class to assist in firing LifecycleEvent notifications to * registered LifecycleListeners. * * @author Craig R. McClanahan * @version $Id: LifecycleSupport.java,v 1.3 2001/11/09 19:40:54 remm Exp $ */ public final class LifecycleSupport { public LifecycleSupport(Lifecycle lifecycle) { super(); this.lifecycle = lifecycle; } /** * 持有触发对应事件的事件源 */ private Lifecycle lifecycle = null; //对该事件源感兴趣的监听器 private LifecycleListener listeners[] = new LifecycleListener[0]; //新增监听器 public void addLifecycleListener(LifecycleListener listener) { //为了性能,tomcat中几乎没用jdk原生的集合,全部是基于数组的操作。 synchronized (listeners) { LifecycleListener results[] = new LifecycleListener[listeners.length + 1]; for (int i = 0; i < listeners.length; i++) results[i] = listeners[i]; results[listeners.length] = listener; listeners = results; } } public LifecycleListener[] findLifecycleListeners() { return listeners; } //触发一个事件 public void fireLifecycleEvent(String type, Object data) { //LifecycleEvent继承自jdk的EventObject,持有事件源的引用 LifecycleEvent event = new LifecycleEvent(lifecycle, type, data); LifecycleListener interested[] = null; //首先克隆出监听器的副本,防止在通知的时候,有新的监听器加入 synchronized (listeners) { interested = (LifecycleListener[]) listeners.clone(); } //通知对应的监听器 for (int i = 0; i < interested.length; i++) interested[i].lifecycleEvent(event); } //移除监听器 public void removeLifecycleListener(LifecycleListener listener) { synchronized (listeners) { int n = -1; for (int i = 0; i < listeners.length; i++) { if (listeners[i] == listener) { n = i; break; } } if (n < 0) return; LifecycleListener results[] = new LifecycleListener[listeners.length - 1]; int j = 0; for (int i = 0; i < listeners.length; i++) { if (i != n) results[j++] = listeners[i]; } listeners = results; } } }
package org.apache.catalina; public interface LifecycleListener { //所有的生命周期监听器都实现该接口,以便在事件发生的时候处理事件 public void lifecycleEvent(LifecycleEvent event); }tomcat就是靠着这样一层层的事件触发和调用完成对tomcat中所有组件生命周期控制的。
原文地址:http://blog.csdn.net/tangyongzhe/article/details/45128145