论坛首页 Java企业应用论坛

再读Tomcat5.5下的‘观察者模式’

浏览 9691 次
精华帖 (5) :: 良好帖 (4) :: 新手帖 (1) :: 隐藏帖 (1)
作者 正文
   发表时间:2011-04-05   最后修改:2011-05-09
最近我正在根据《How Tomcat Works》这本书的讲解,阅读Tomcat 7的源码
但这本书的源码讲解基于Tomcat 4
讲到第5章:关于Tomcat4的生命周期的时候
我就看不大明白Tomcat 7的源码,于是我从Apache Tomcat网站又下载了Tomcat 5.5的源码
进一步了解这一章,这一章讲的就是Tomcat的生命周期Lifecycle,其中最主要的就是利用了
设计模式中相当经典的模式:观察者模式。

现在推荐一下相关文章和相关类图,学习设计模式而不去看类图或是看不懂,那是相当大的一个阻碍。
1.
标题:《设计模式之:解剖观察者模式》
网址:http://www.iteye.com/topic/102068
内容:从最基础的方面剖析了'观察者模式'
发表时间:2007-07-17(相当的早,我还没出道就发布了...)
类图:



2.
标题:《Tomcat源码---容器生命周期管理(Lifecycle)一》
网址:http://wuquanyin1011.iteye.com/blog/628993
内容:从源码上讲到了‘观察者模式’的运用,这也就是我文章题目只能写再读了,人家都分析过了...
发表时间:2010-03-31
类图:



3.
标题:《Tomcat 系统架构与设计模式,第 2 部分: 设计模式分析》
网址:http://www.ibm.com/developerworks/cn/java/j-lo-tomcat2/
内容:讲解了Tomcat中几个最重要的模式,但这是第2部分的内容,大家也要看一下第1部分的内容
发表时间:2010-05-27
类图:




如果是新接触观察者模式或是还没深入理解观察者模式的朋友一定要看推荐的第一篇文章。这样下面的东西就好理解。

以下都是Tomcat5.5的相关源码,而在Tomcat 7中又增添了新的接口和类来管理生命周期。
这里我把Tomcat构建观察者模式来处理Tomcat生命周期的所有相关类和接口都抽了出来
删除了不必要的类和代码,因为我们只是为了要探究下观察者模式。

其中有以下类和接口:(上面的相关类图对帮助理解这6个类和接口之间的依赖关系是非常有帮助的,所以我先贴出了类图)
Lifecycle.java:抽象被观察者
StandardServer.java :具体被观察者(这个类是Tomcat5.5下实现的众多具体被观察者中的一个)
LifecycleListener.java : 抽象观察者
ServerLifecycleListener.java : 具体观察者(这个类是Tomcat5.5下实现的众多具体观察者中的一个)
这里还要提下:在Tomcat 7中,具体被观察者和具体观察者中的功能都被抽出来统一管理
LifecycleSupport.java :具体被观察者的代理类,为了把所有具体被观察者的共同操作统一管理(在推荐第2篇文章中那哥们说这里用了‘适配器模式’)
LifecycleEvent.java :事件类

下面根据顺序放出各个类的具体实现代码

Lifecycle.java:抽象被观察者


package demo.tomcat5.lifecycle;
//抽象被观察者
public interface Lifecycle {
	
   //抽象被观察者中定义的各种事件
    public static final String INIT_EVENT = "init";
    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 static final String DESTROY_EVENT = "destroy";
    public static final String PERIODIC_EVENT = "periodic";
    
    //添加一个观察者去观察被观察者
    public void addLifecycleListener(LifecycleListener listener);
    
    //列出一个被观察者上的所有观察者
    public LifecycleListener[] findLifecycleListeners();
    
    //删除一个被观察者上的指定观察者
    public void removeLifecycleListener(LifecycleListener listener);

    public void start();
    public void stop();
}


StandardServer.java :具体被观察者
package demo.tomcat5.lifecycle;
//具体被观察者
public final class StandardServer implements Lifecycle {
	
	//把当前具体被观察者交给被观察者支持类,由它来代理实现添加、删除、查找观测者的操作
	//具体观察者只要启动业务,然后在启动业务后根据业务事件的状态来激活观察者做相应操作
	private LifecycleSupport lifecycle = new LifecycleSupport(this);
	
	public void addLifecycleListener(LifecycleListener listener) {

		lifecycle.addLifecycleListener(listener);
	}

	public LifecycleListener[] findLifecycleListeners() {
		
		return lifecycle.findLifecycleListeners();
	}

	public void removeLifecycleListener(LifecycleListener listener) {
		
		lifecycle.removeLifecycleListener(listener);
	}

	public void start() {

        lifecycle.fireLifecycleEvent(BEFORE_START_EVENT, "Server 启动前我们干什么呢?也许我们要初始化一些配置信息");
        
        lifecycle.fireLifecycleEvent(START_EVENT, "Server 启动中我们干什么呢?也许我们要添加Service到Server中");
        
        lifecycle.fireLifecycleEvent(AFTER_START_EVENT, "Server 启动后我们干什么呢?不知道了");
	}

	public void stop() {
		
        lifecycle.fireLifecycleEvent(BEFORE_STOP_EVENT, "... Server 停止前");

        lifecycle.fireLifecycleEvent(STOP_EVENT, "... Server 停止中");
      
        lifecycle.fireLifecycleEvent(AFTER_STOP_EVENT, "... Server 停止后");
	}

}


LifecycleListener.java : 抽象观察者
package demo.tomcat5.lifecycle;
//抽象观察者
public interface LifecycleListener {
	public void lifecycleEvent(LifecycleEvent event);
}


ServerLifecycleListener.java : 具体观察者
package demo.tomcat5.lifecycle;

//具体观察者类
public class ServerLifecycleListener implements LifecycleListener {

	public void lifecycleEvent(LifecycleEvent event) {

		if (Lifecycle.BEFORE_START_EVENT.equals(event.getType())) {

			System.out.println(event.getData().toString());

		} else if (Lifecycle.START_EVENT.equals(event.getType())) {

			System.out.println(event.getData().toString());

		} else if (Lifecycle.AFTER_START_EVENT.equals(event.getType())) {

			System.out.println(event.getData().toString());

		} else if (Lifecycle.BEFORE_STOP_EVENT.equals(event.getType())) {
			
			System.out.println(event.getData().toString());
			
		} else if (Lifecycle.STOP_EVENT.equals(event.getType())) {
			
			System.out.println(event.getData().toString());
			
		} else if (Lifecycle.AFTER_STOP_EVENT.equals(event.getType())) {
			
			System.out.println(event.getData().toString());
			
		}
	}

}



LifecycleSupport.java :具体被观察者的代理类
package demo.tomcat5.lifecycle;
//具体被观察者代理类
public final class LifecycleSupport {

	private Lifecycle lifecycle = null;
	
	public LifecycleSupport(Lifecycle lifecycle) {
		super();
		this.lifecycle = lifecycle;
	}
	//定义一个观察者数组,就是为了维护在这个具体被观察者上的所有观察者。
	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) {
			//这里是我唯一不解的地方,为什么要用副本。
			//当然这只是tomcat5.5的实现,在tomcat7中这个步骤被删除了
			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;
		}

	}
}



LifecycleEvent.java :事件类
package demo.tomcat5.lifecycle;

import java.util.EventObject;
//事件类
public final class LifecycleEvent extends EventObject {

	private static final long serialVersionUID = 1L;

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

	}
}



最后我在提供‘推荐第一篇文章’和‘本文’的源代码供同学们学习
  • 大小: 8.6 KB
  • 大小: 4 KB
  • 大小: 13.4 KB
   发表时间:2011-04-05  
写的满辛苦,自己支持自己
0 请登录后投票
   发表时间:2011-04-05  
楼主写了这么多,下的功夫很深了。很想跟楼主交个朋友。。。
0 请登录后投票
   发表时间:2011-04-05  
quxiaoyong 写道
楼主写了这么多,下的功夫很深了。很想跟楼主交个朋友。。。

不容易有人关注了
0 请登录后投票
   发表时间:2011-04-05  
kanny87929 写道
quxiaoyong 写道
楼主写了这么多,下的功夫很深了。很想跟楼主交个朋友。。。

不容易有人关注了


客气!!原创文章都是值得鼓励的嘛。。有些人只看帖子从不贡献,才要不得。
0 请登录后投票
   发表时间:2011-04-06  
我觉得这章的内容非常的重要,所以很有必要一遍再一遍的讲
0 请登录后投票
   发表时间:2011-04-06  
我也正打算看这本书。
0 请登录后投票
   发表时间:2011-04-06  
这本书 我看到一半 没有坚持下去
0 请登录后投票
   发表时间:2011-04-06  
...是不是因为你看不懂才坚持不下去
0 请登录后投票
   发表时间:2011-04-06  
我是看了一半,那英文....有些就懂了,有些就不懂,还有些就模糊的...
0 请登录后投票
论坛首页 Java企业应用版

跳转论坛:
Global site tag (gtag.js) - Google Analytics