0
点赞
收藏
分享

微信扫一扫

how tomcat works 六 生命周期


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

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

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


看了上面的一个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图如下:

how tomcat works 六 生命周期_观察者模式





看看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中的数组中并没有监听器,也就没有什么通知的了。


最后我们运行起来看看


Wrapper,Loader的start方法只是在屏幕中打印出信息,并没有再次触发什么事件。

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


一点感觉


总感觉这一章怪怪的,要说是启动子容器,直接循环取得子容器,然后调用start方法即可;观察者模式在本节的作用就是打印出

SimpleContextLifecycleListener's event before_start

SimpleContextLifecycleListener's event start

SimpleContextLifecycleListener's event after_start


这三句话而已,似乎没有什么大的作用。


后来我仔细想想观察者模式,它就是一个通知的作用,通知所有关注自己的对象,只有那观察者知道自己观察的对象有了状态变化之后干什么,就不是观察者模式考虑的是事了,观察者模式只管通知!


在本节,观察者只是打印出一句话,所以显得比较简单而已,当然要想复杂改LifecycleListener类的lifecycleEvent方法即可。



举报

相关推荐

0 条评论