《How tomcat works》读书笔记_生命周期_应用

应用程序

这章的程序是依据上一章建立的,在其中加入了生命周期的支持。下面是这个程序的类图。
这里写图片描述

SimpleContext

本章中的SimpleContext类与上一章中的相似,除了实现Lifecycle接口以外。

在这个类中除了声明一个LifecycleSupport类的变量以外,它还声明了一个started的布尔值变量,用来记录Context容器是否已经被启动。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();
        }

        // Notify our interested LifecycleListeners
        lifecycle.fireLifecycleEvent(AFTER_START_EVENT, null);
    }

从上面SimpleContext类的start方法中可以看到,它启动了它所有的子容器,以及和它关联的其它组件,如Loader,Pipeline等。使用这种机制,如果你要启动容器中所有的组件,那么你只需要启动容器内最高层的组件就可以了(在这里是SimpleContext)。若是要停止这些组件,也只需要调用最高层组件的stop方法就可以了。

start方法的执行过程

  1. 检查这个组件是否已经被启动,如果已经启动那么抛出一个LifecycleException.异常
  2. 然后派发了一个BEFORE_START_EVENT事件。这样所有在SimpleContext中注册的监听器中对这个事件感兴趣的都会被通知到。
  3. 将布尔值started设置成true,表示容器已经被启动
  4. 然后启用所有组件以及它的子容器,有两个实现了Lifecycle接口的组件SimpleLoader和SimplePipeline。SimpleContext有两个Wrapper类型的子容器,同样也实现了Lifecycle接口。
  5. 在所有组件和了容器的start方法都完成后,会派发两个事件START_EVENT和AFTER_START_EVENT

stop方法的执行过程

  1. 首先,检查容器是否被启动,如果没有启动直接抛出一个LifecycleException.异常
  2. 然后,派发两个事件BEFORE_STOP_EVENT和STOP_EVENT,将布尔值started设置成true
  3. 接下来,停止所有与容器相关的组件以及它所有的子容器
  4. 最后,派发一个AFTER_STOP_EVENT事件

SimpleContextLifecycleListener

SimpleContextLifecycleListener类是一个SimpleContext实例的监听器。代码如下:

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.");
        }
    }
}

接口中lifecycleEvent方法的实现比较简单,它只是在控制台打印出派发出事件的类型。

SimpleLoader

同上一章不同的是,这个类实现了Lifecycle接口。接口中的方法在SimpleLoader中的实现只是简单的打印字符串到控制台。
重要的是,通过实现Lifecycle接口,SimpleLoader实例就可以通过与它关联的容器来启动了。
SimpleLoader中对接口Lifecycle中方法的实现如下:

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 SimpleLoader");
}
public void stop() throws LifecycleException {
}

SimplePipeline

实现了Lifecycle接口,继承自Lifecycle接口的方法全部置空,没有任何处理。

SimpleWrapper

同样实现了Lifecycle接口,那么它就可以被其父容器启动了。接口中的方法在SimpleWrapper类中只实现了两个:start和stop。

这里的start方法同SimpleContext类中的start方法很相似,它启动所有与Wrapper容器关联的组件,并派发BEFORE_START_EVENT, START_EVENT, 和 AFTER_START_EVENT事件。

但是SimpleWrapper中的stop方法与Context容器的stop方法处理起来有些不同。

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

它首先会请求servlet的destroy方法;然后检查Wrapper是否被启动,如果没有抛出LifecycleException异常,重置started布尔值;接下来停止与Wrapper关联的Loader和Pipeline等组件(在当前SimpleWrapper中并没有关联Loader组件);最后,派发一个AFTER_STOP_EVENT事件。

运行程序

运行Bootstrap类的main方法,控制台会打印如下信息:

HttpConnector Opening server socket on all host IP addresses
HttpConnector[8080] Starting background thread
SimpleContextLifecycleListener's event before_start
Starting SimpleLoader
Starting Wrapper Primitive
Starting Wrapper Modern
SimpleContextLifecycleListener's event start
Starting context.
SimpleContextLifecycleListener's event after_start

停止Bootstrap时,控制台打印如下:

SimpleContextLifecycleListener's event before_stop
SimpleContextLifecycleListener's event stop
Stopping context.
Stopping wrapper Primitive
Stopping wrapper Modern
SimpleContextLifecycleListener's event after_stop

前两条的HttpConnector类中open方法打印到控制台的信息。
因为只有SimpleContext类注册了监听器SimpleContextLifecycleListener。所以以SimpleContextLifecycleListener’s开头的信息都是由SimpleContext监听器打印的,另外当SimpleContext派发状态START_EVENT时,监听器会打印“Starting context.”,派发状态为STOP_EVENT时,监听器打印”Stopping context.”。其它信息均是由各组件或是子容器的start方法或是stop方法打印的。

  • 0
    点赞
  • 0
    收藏
    觉得还不错? 一键收藏
  • 0
    评论
评论
添加红包

请填写红包祝福语或标题

红包个数最小为10个

红包金额最低5元

当前余额3.43前往充值 >
需支付:10.00
成就一亿技术人!
领取后你会自动成为博主和红包主的粉丝 规则
hope_wisdom
发出的红包
实付
使用余额支付
点击重新获取
扫码支付
钱包余额 0

抵扣说明:

1.余额是钱包充值的虚拟货币,按照1:1的比例进行支付金额的抵扣。
2.余额无法直接购买下载,可以购买VIP、付费专栏及课程。

余额充值