• how tomcat works 六 生命周期


    我认为这一章叫tomcat中的观察者模式,比較好!
    首先,不要看本章,请查看一下关于观察者模式的资料比較好。

    推荐下面知识点
    基础篇
    设计模式之禅----观察者模式
    大家能够找到pdf阅读一下
    另外本人的博客中也有一篇<<谈谈观察者模式 >> 非常久之前写的,是阅读上书观察者模式时做的笔记,写的实在不敢恭维,假设找不到书,倒是能够看看鄙人的博客。


    http://www.cnblogs.com/wangjq/archive/2012/07/12/2587966.html
    上面的这个博客,让详细的观察者和被观察者耦合,大家能够看看。
    进阶篇
    http://blog.csdn.net/lovelion/article/details/7720232

    看了上面的一个pdf两个博客,我就觉得大家理解了观察者模式,如今咱们開始说tomcat;
    第六章的题目叫做生命周期,说的内容就是怎样在上级容器启动或者关闭的时候,能够自己主动启动或关闭它的组件。
    事实上更准确的说是,在上级容器启动的时候怎样通知别的容器(由于要实现父容器启动,子组件也启动,非常easy,循环获得全部子组件,调用start方法就可以)

    几个类和接口

    Lifecycle接口

    我们既然说到生命周期,说到事件,那总得有个接口来表示这些事件吧
    package org.apache.catalina;
    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;
    }


    一共六个事件类型開始,结束等等。以下的几个方法见名知意不再赘述。

    LifeEvent类

    package org.apache.catalina;
    
    import java.util.EventObject;
    
    public final class LifecycleEvent extends EventObject {
    
        private Object data = null;
        private Lifecycle lifecycle = null;
        private String type = null;
    
        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;
        }
    
        public Object getData() {
            return (this.data);
        }
    
        public Lifecycle getLifecycle() {
            return (this.lifecycle);
        }
    
        public String getType() {
            return (this.type);
        }<pre name="code" class="java">
    

    }
    
    

    这个Event非常easy,就是哪个实现了Lifecycle接口的对象在某个时间发生了某件事。

    LifecycleListener接口

    <pre name="code" class="java">package org.apache.catalina;
    import java.util.EventObject;
    public interface LifecycleListener {
        public void lifecycleEvent(LifecycleEvent event);
    }

    
    

    这就相当于上面几篇博客中的Observiser接口,lifecycleEvent就是update方法,不同的是前面几篇博客中,实现LifecycleListener接口的对象就是监听的实体,这里不是*************

    LifecycleSupport类

    一个对象,能够给自己添加多个监听器,这个多个监听器能够组成一个数组或其它类似的结构中,这个功能就由LifecycleSupport类来实现。
    package org.apache.catalina.util;
    
    
    import org.apache.catalina.Lifecycle;
    import org.apache.catalina.LifecycleEvent;
    import org.apache.catalina.LifecycleListener;
    
    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) {
    
          ..省略代码
        }
    }


    我们看看那个fireLifecycleEvent(String type, Object data),它就是上面几篇博客中Subjet中的notify方法,依次调用每一个listener的lifeEvent()方法(就是上面说的update方法)。
    ok,我们看应用程序

    应用程序

    xml图例如以下:





    看看SimpleContext与LifecycleSuppot,它们是使用的关系,SimpleContext中有一个LifecycleSuppot,
    代码例如以下
    protected LifecycleSupport lifecycle = new LifecycleSupport(this);
    事实上每个实现了Lifecycle接口的组件,都能够有一个LifecycleSupport。
    另外,另一个布尔型变量started,来知识容器是否已经启动。
    如今我们看看SimpleContext中实现Lifecycle接口中的方法。
    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();
        }


    本节的启动程序与上一节没有什么差别,除了
     
             LifecycleListener listener = new SimpleContextLifecycleListener();
            ((Lifecycle) context).addLifecycleListener(listener);
    context的addLifecycleListener方法,就是把监听器(就是上面说的李斯)放到context中的LifecycleSuppour的数组中去!
    我们再看看SimpleContextLifecycleListener

    public class SimpleContextLifecycleListener implements LifecycleListener {
    
      @SuppressWarnings("unused")
    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.");
        }
      }
    }
    不用解释了吧。
    事实上在本节程序里,我们仅仅是给SimpleContext加了一个监听器,换句话说,SimpleWrapper中的start方法中尽管也有lifecycle.fireLifecycleEvent(START_EVENT, null)方法,可是LifecycelSupport中的数组中并没有监听器,也就没有什么通知的了。


    最后我们执行起来看看
    HttpConnector Opening server socket on all host IP addresses
    HttpConnector[8080] Starting background thread
    SimpleContextLifecycleListener's event before_start
    Starting SimpleLoader
    Starting Wrapper Modern
    Starting Wrapper Primitive
    SimpleContextLifecycleListener's event start
    Starting context.
    SimpleContextLifecycleListener's event after_start
    Wrapper,Loader的start方法仅仅是在屏幕中打印出信息,并没有再次触发什么事件。


    一点感觉
    总感觉这一章怪怪的,要说是启动子容器,直接循环取得子容器,然后调用start方法就可以;观察者模式在本节的作用就是打印出
    SimpleContextLifecycleListener's event before_start
    SimpleContextLifecycleListener's event start
    SimpleContextLifecycleListener's event after_start
    这三句话而已,似乎没有什么大的作用。
    后来我细致想想观察者模式,它就是一个通知的作用,通知全部关注自己的对象,仅仅有那观察者知道自己观察的对象有了状态变化之后干什么,就不是观察者模式考虑的是事了,观察者模式仅仅管通知!
    在本节,观察者仅仅是打印出一句话,所以显得比較简单而已,当然要想复杂改LifecycleListener类的lifecycleEvent方法就可以。




  • 相关阅读:
    JadConfig 注解驱动的java 配置管理包
    coroot 开源微服务架构监控以及问题解决工具
    observIQ 开源的OpenTelemetry collector 实现
    graylog MessageOutput 简单说明
    graylog 的schema
    【职场】辞职的时间节点有讲究,你知道吗?
    【精选】面试官:聊下常见设计模式有哪些?
    今日头条架构千字分析,这一篇就够了
    【收藏分享】2022年PHP中高级面试题(三)
    四种策略确保 RabbitMQ 消息发送可靠性
  • 原文地址:https://www.cnblogs.com/lxjshuju/p/6911635.html
Copyright © 2020-2023  润新知