码迷,mamicode.com
首页 > 其他好文 > 详细

How Tomcat Works 6

时间:2015-04-19 14:43:45      阅读:148      评论:0      收藏:0      [点我收藏+]

标签:tomcat   server   components   

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


How Tomcat Works 6

标签:tomcat   server   components   

原文地址:http://blog.csdn.net/tangyongzhe/article/details/45128145

(0)
(0)
   
举报
评论 一句话评论(0
登录后才能评论!
© 2014 mamicode.com 版权所有  联系我们:gaon5@hotmail.com
迷上了代码!