我觉得这一章叫tomcat中的观察者模式,比较好!

首先,不要看本章,请查看一下关于观察者模式的资料比较好。



推荐以下知识点

基础篇

设计模式之禅----观察者模式

大家可以找到pdf阅读一下

另外本人的博客中也有一篇<<谈谈观察者模式 >> 很久之前写的,是阅读上书观察者模式时做的笔记,写的实在不敢恭维,如果找不到书,倒是可以看看鄙人的博客。

http://www.cnblogs.com/wangjq/archive/2012/07/12/2587966.html

上面的这个博客,让具体的观察者和被观察者耦合,大家可以看看。

进阶篇

http://blog.csdn.net/lovelion/article/details/7720232



看了上面的一个pdf两个博客,我就认为大家理解了观察者模式,现在咱们开始说tomcat;

第六章的题目叫做生命周期,说的内容就是如何在上级容器启动或者关闭的时候,可以自动启动或关闭它的组件。

其实更准确的说是,在上级容器启动的时候如何通知别的容器(因为要实现父容器启动,子组件也启动,很简单,循环获得所有子组件,调用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很简单,就是哪个实现了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方法即可。

how tomcat works 六 生命周期的更多相关文章

  1. Tomcat 8(九)解读Tomcat组件的生命周期(Lifecycle)

    Tomcat 8(七)解读Bootstrap介绍过.运行startup.bat.将引发Tomcat一连串组件的启动.事实上这一连串启动是通过组件的生命周期(Lifecycle)实现的 今天来看看Lif ...

  2. LitElement(六)生命周期

    1.概述 基于LitElement的组件通过响应观察到的属性更改而异步更新. 属性更改是分批进行的,如果在请求更新后,更新开始之前,发生更多属性更改,则所有更改都将捕获在同一次更新中. 在较高级别上, ...

  3. How Tomcat works — 六、tomcat处理请求

    tomcat已经启动完成了,那么是怎么处理请求的呢?怎么到了我们所写的servlet的呢? 目录 Http11ConnectionHandler Http11Processor CoyoteAdapt ...

  4. How tomcat works(深入剖析tomcat)生命周期Lifecycle

    How Tomcat Works (6)生命周期Lifecycle 总体概述 这一章讲的是tomcat的组件之一,LifeCycle组件,通过这个组件可以统一管理其他组件,可以达到统一启动/关闭组件的 ...

  5. 【微信小程序开发•系列文章六】生命周期和路由

    这篇文章理论的知识比较多一些,都是个人观点,描述有失妥当的地方希望读者指出. [微信小程序开发•系列文章一]入门 [微信小程序开发•系列文章二]视图层 [微信小程序开发•系列文章三]数据层 [微信小程 ...

  6. 【转】Tomcat组件生命周期管理

    Tomcat组件生命周期管理 Tomcat中Server,Service,Connector,Engine,Host,Context,它们都实现了org.apache.catalina.Lifecyc ...

  7. Servlet第六篇【Session介绍、API、生命周期、应用】

    什么是Session Session 是另一种记录浏览器状态的机制.不同的是Cookie保存在浏览器中,Session保存在服务器中.用户使用浏览器访问服务器的时候,服务器把用户的信息以某种的形式记录 ...

  8. Tomcat 源码分析(一)——启动与生命周期组件

    写在前面的话:读Tomcat源码也有段时间了,大领悟谈不上.一些小心得记录下来,供大家参考相护学习. 一.启动流程 Tomcat启动首先需要熟悉的是它的启动流程.和初学者第一天开始写Hello Wor ...

  9. Servlet第六篇【Session介绍、API、生命周期、应用、与Cookie区别】

    什么是Session Session 是另一种记录浏览器状态的机制.不同的是Cookie保存在浏览器中,Session保存在服务器中.用户使用浏览器访问服务器的时候,服务器把用户的信息以某种的形式记录 ...

随机推荐

  1. 将meteor部署到自己的服务器(deploy meteor to your own server)

    安装指定版本的node # 所有版本在:https://nodejs.org/download/release/# current dir:/rootwget -c https://nodejs.or ...

  2. 27 自定义View 和案例

    有时安卓提供的View不满足我们的需求时可以创建一个类继承View或其子类重写方法 如 package com.qf.sxy.day28_customview.view; import android ...

  3. [线程]Thead 中传参数RuntimeError: thread.__init__() not called

    在写一个多线程类的时候调用报错 RuntimeError: thread.__init__() not called class NotifyTread(threading.Thread): def ...

  4. [error]error while loading shared libraries: libpcre.so.1 解决

    nginx 安装好之后,启动的时候报错 [root@localhost nginx-1.6.2]# /usr/local/nginx/sbin/nginx  /usr/local/nginx/sbin ...

  5. SQLite Where 子句(http://www.w3cschool.cc/sqlite/sqlite-where-clause.html)

    SQLite Where 子句 SQLite的 WHERE 子句用于指定从一个表或多个表中获取数据的条件. 如果满足给定的条件,即为真(true)时,则从表中返回特定的值.您可以使用 WHERE 子句 ...

  6. Oracle 执行计划(Explain Plan) 说明

    如果要分析某条SQL的性能问题,通常我们要先看SQL的执行计划,看看SQL的每一步执行是否存在问题. 如果一条SQL平时执行的好好的,却有一天突然性能很差,如果排除了系统资源和阻塞的原因,那么基本可以 ...

  7. java.util.ServiceLoader使用

    近期在项目中需要实现能在配置文件中定义多个统一接口类型的类,可以在程序中获取到所有配置的类,刚开始打算配置到properties中,然后去程序读取,感觉这种方式不太灵活,于是,研究研究java中有没有 ...

  8. Oracle 总账年终结算流程

     1.Oracle 总账应用中年终结算流程包含在开启/关闭期间程序里.当用户开启新一年的第一个期间,开启/关闭期间程序中的"gloire" 流程会完成传送所有收入及支出(损益表 ...

  9. Collections类解析

    最常用的排序: 需要实现Comparable接口 1.什么是Comparable接口 此接口强行对实现它的每个类的对象进行整体排序.此排序被称为该类的自然排序 ,类的 compareTo 方法被称为它 ...

  10. UE4实现描边效果

    描边效果属于常见常用的功能,现VR项目中,也需要射线选中一个物体,使物体高亮. 于是在网上找了部分资料,同时也感谢群里的一位大神的提点,总算将描边的功能实现了,这里也写一个简单的示例步骤. 1.我并不 ...