How Tomcat Works 6

来源:互联网 发布:免费洗车软件2016 编辑:程序博客网 时间:2024/06/05 03:12

了解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中所有组件生命周期控制的。


0 0
原创粉丝点击