zoukankan      html  css  js  c++  java
  • How Tomcat Works(九)

    本文接下来描述servlet容器是怎样管理其相关组件的生命周期的,首先本人描述一下事件监听模式,也可以称为观察者模式,该模式分为以下角色

    即抽象主题角色 具体主题角色 抽象观察者角色及具体观察者角色,通常在主题角色里面维持一个观察者角色的聚集,并定义了对观察者角色的添加和删除方法;在主题角色事件发生时,通过迭代向这些观察者角色发布事件。

    在tomcat容器中,管理其相关组件的生命周期即是基于事件监听模式实现的,相关接口和类为org.apache.catalina.Lifecycle接口、org.apache.catalina.LifecycleListener接口、org.apache.catalina.LifecycleEvent类

    org.apache.catalina.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);
        
        public void start() throws LifecycleException;
       
        public void stop() throws LifecycleException;
    
    }

    上面的六个静态字符串代表六种类型的事件,接着的三个方法addLifecycleListener()、 findLifecycleListeners()、removeLifecycleListener()为与事件监听器相关的,最后的两个方法start()和stop()为启动与关闭操作,组件必须提供这两种方法的实现,供其父组件调用。

    org.apache.catalina.LifecycleEvent类用于传递事件及携带事件数据

    public final class LifecycleEvent
        extends EventObject {
       
        public LifecycleEvent(Lifecycle lifecycle, String type) {
            this(lifecycle, type, null);
        }
       
        public LifecycleEvent(Lifecycle lifecycle, String type, Object data) {
    
            super(lifecycle);
            this.lifecycle = lifecycle;
            this.type = type;
            this.data = data;
        }
       
        private Object data = null;
       
        private Lifecycle lifecycle = null;
       
        private String type = null;
       
        public Object getData() {
            return (this.data);
        }
        
        public Lifecycle getLifecycle() {
            return (this.lifecycle);
        }
       
        public String getType() {
            return (this.type);
        }
    }

    org.apache.catalina.LifecycleListener为监听器接口

    public interface LifecycleListener {
    
    
        /**
         * Acknowledge the occurrence of the specified event.
         *
         * @param event LifecycleEvent that has occurred
         */
        public void lifecycleEvent(LifecycleEvent event);
    
    
    }

    通常实现了Lifecycle接口并且对某个事件注册了监听器的组件必须提供 Lifecycle接口中三个与监听器相关方法(分别为addLifecycleListener()、 findLifecycleListeners()、removeLifecycleListener())的实现,然后该组件需要将所有注册的监听器存储到数组、ArrayList或者其他类似的对象中;tomcat容器提供了一个工具类org.apache.catalina.util.LifecycleSupport来帮助组件管理监听器,并触发相应的生命周期事件。

    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) {
    
          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 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;
            }
        }
    }

    下面我们来看Context容器(SimpleContext实例)是怎么实现生命周期管理及触发监听器事件的,关键代码如下

    public class SimpleContext implements Context, Pipeline, Lifecycle {
    
    protected LifecycleSupport lifecycle = new LifecycleSupport(this);
    
    // implementation of the Lifecycle interface's methods
      public void addLifecycleListener(LifecycleListener listener) {
        lifecycle.addLifecycleListener(listener);
      }
    
      public LifecycleListener[] findLifecycleListeners() {
        return null;
      }
    
      public void removeLifecycleListener(LifecycleListener listener) {
        lifecycle.removeLifecycleListener(listener);
      }
    
      public synchronized void start() throws LifecycleException {
        if (started)
          throw new LifecycleException("SimpleContext has already started");
    
        // Notify our interested LifecycleListeners
        lifecycle.fireLifecycleEvent(BEFORE_START_EVENT, null);
        started = true;
        try {
          // Start our subordinate components, if any
          if ((loader != null) && (loader instanceof Lifecycle))
            ((Lifecycle) loader).start();
    
          // Start our child containers, if any
          Container children[] = findChildren();
          for (int i = 0; i < children.length; i++) {
            if (children[i] instanceof Lifecycle)
              ((Lifecycle) children[i]).start();
          }
    
          // Start the Valves in our pipeline (including the basic),
          // if any
          if (pipeline instanceof Lifecycle)
            ((Lifecycle) pipeline).start();
          // Notify our interested LifecycleListeners
          lifecycle.fireLifecycleEvent(START_EVENT, null);
        }
        catch (Exception e) {
          e.printStackTrace();
        }
    
        // Notify our interested LifecycleListeners
        lifecycle.fireLifecycleEvent(AFTER_START_EVENT, null);
      }
    
      public void stop() throws LifecycleException {
        if (!started)
          throw new LifecycleException("SimpleContext has not been started");
        // Notify our interested LifecycleListeners
        lifecycle.fireLifecycleEvent(BEFORE_STOP_EVENT, null);
        lifecycle.fireLifecycleEvent(STOP_EVENT, null);
        started = false;
        try {
          // Stop the Valves in our pipeline (including the basic), if any
          if (pipeline instanceof Lifecycle) {
            ((Lifecycle) pipeline).stop();
          }
    
          // Stop our child containers, if any
          Container children[] = findChildren();
          for (int i = 0; i < children.length; i++) {
            if (children[i] instanceof Lifecycle)
              ((Lifecycle) children[i]).stop();
          }
          if ((loader != null) && (loader instanceof Lifecycle)) {
            ((Lifecycle) loader).stop();
          }
        }
        catch (Exception e) {
          e.printStackTrace();
        }
        // Notify our interested LifecycleListeners
        lifecycle.fireLifecycleEvent(AFTER_STOP_EVENT, null);
      }
    }

    Context容器实例持有对LifecycleSupport lifecycle = new LifecycleSupport(this)的引用,与事件监听器相关方法均为操作该实例的相应方法

    在其与生命周期相关方法start()和stop()方法里面,分别调用相关组件的生命周期方法,并采用LifecycleSupport lifecycle引用发布事件

    一个简单的监听器实现如下:

    public class SimpleContextLifecycleListener implements LifecycleListener {
    
      public void lifecycleEvent(LifecycleEvent event) {
        Lifecycle lifecycle = event.getLifecycle();
        System.out.println("SimpleContextLifecycleListener's event " +
          event.getType().toString());
        if (Lifecycle.START_EVENT.equals(event.getType())) {
          System.out.println("Starting context.");
        }
        else if (Lifecycle.STOP_EVENT.equals(event.getType())) {
          System.out.println("Stopping context.");
        }
      }
    }

    子容器wrapper实例(SimpleWrapper),同样实现了Lifecycle接口,其相关实现与Context容器类似

    public class SimpleWrapper implements Wrapper, Pipeline, Lifecycle {
    
    protected LifecycleSupport lifecycle = new LifecycleSupport(this);
    
    // implementation of the Lifecycle interface's methods
      public void addLifecycleListener(LifecycleListener listener) {
      }
    
      public LifecycleListener[] findLifecycleListeners() {
        return null;
      }
    
      public void removeLifecycleListener(LifecycleListener listener) {
      }
    
      public synchronized void start() throws LifecycleException {
        System.out.println("Starting Wrapper " + name);
        if (started)
          throw new LifecycleException("Wrapper already started");
    
        // Notify our interested LifecycleListeners
        lifecycle.fireLifecycleEvent(BEFORE_START_EVENT, null);
        started = true;
    
        // Start our subordinate components, if any
        if ((loader != null) && (loader instanceof Lifecycle))
          ((Lifecycle) loader).start();
    
        // Start the Valves in our pipeline (including the basic), if any
        if (pipeline instanceof Lifecycle)
          ((Lifecycle) pipeline).start();
    
        // Notify our interested LifecycleListeners
        lifecycle.fireLifecycleEvent(START_EVENT, null);
        // Notify our interested LifecycleListeners
        lifecycle.fireLifecycleEvent(AFTER_START_EVENT, null);
      }
    
      public void stop() throws LifecycleException {
        System.out.println("Stopping wrapper " + name);
        // Shut down our servlet instance (if it has been initialized)
        try {
          instance.destroy();
        }
        catch (Throwable t) {
        }
        instance = null;
        if (!started)
          throw new LifecycleException("Wrapper " + name + " not started");
        // Notify our interested LifecycleListeners
        lifecycle.fireLifecycleEvent(BEFORE_STOP_EVENT, null);
    
        // Notify our interested LifecycleListeners
        lifecycle.fireLifecycleEvent(STOP_EVENT, null);
        started = false;
    
        // Stop the Valves in our pipeline (including the basic), if any
        if (pipeline instanceof Lifecycle) {
          ((Lifecycle) pipeline).stop();
        }
    
        // Stop our subordinate components, if any
        if ((loader != null) && (loader instanceof Lifecycle)) {
          ((Lifecycle) loader).stop();
        }
    
        // Notify our interested LifecycleListeners
        lifecycle.fireLifecycleEvent(AFTER_STOP_EVENT, null);
      }
    }

    其他相关组件的相关实现不再赘述

    --------------------------------------------------------------------------- 

    本系列How Tomcat Works系本人原创 

    转载请注明出处 博客园 刺猬的温驯 

    本人邮箱: chenying998179#163.com (#改为@

    本文链接http://www.cnblogs.com/chenying99/p/3235736.html

  • 相关阅读:
    Android 中的code sign
    iOS 中的Certificate,Provisioning Profile 的一些注意 (不断完善中)
    xcode 和 android studio中在Mac系统下的自动对齐快捷键
    iOS block 声明时和定义时的不同格式
    iOS 和 Android 中的后台运行问题
    Android 阅读Tasks and Back Stack文章后的重点摘抄
    Android 中PendingIntent---附带解决AlarmManager重复加入问题
    Android 中获得notification的发出时间
    iOS 关于Layer的疑问
    iOS的 context 和Android 中的 canvas
  • 原文地址:https://www.cnblogs.com/chenying99/p/3235736.html
Copyright © 2011-2022 走看看