`
kanny87929
  • 浏览: 17580 次
  • 性别: Icon_minigender_1
  • 来自: 上海
社区版块
存档分类
最新评论

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

阅读更多
最近我正在根据《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
分享到:
评论
24 楼 kanny87929 2011-04-08  
tianlovv 写道
讲的不错,也计划着要看tomcat源码了,LZ这么一讲让我对研究tomcat源码兴趣大增,哈哈!关于为什么clone数组那,我想到有两点
1  保证了数组的不变性,其它线程对数组操作与这个副本无关
2  缩小同步代码块。因为可以把执行业务操作也放在同步块中,这样不需要clone了,但通常业务操作是比较占用时间的,这样会影响性能
问一下tomcat7中是用什么容器装载元素的



应该说,tomcat 7是用什么数据结构来存储元素的更专业...
tomcat 7中就是直接操作数组,把复制出副本这个操作给删除了。
23 楼 tianlovv 2011-04-08  
讲的不错,也计划着要看tomcat源码了,LZ这么一讲让我对研究tomcat源码兴趣大增,哈哈!关于为什么clone数组那,我想到有两点
1  保证了数组的不变性,其它线程对数组操作与这个副本无关
2  缩小同步代码块。因为可以把执行业务操作也放在同步块中,这样不需要clone了,但通常业务操作是比较占用时间的,这样会影响性能
问一下tomcat7中是用什么容器装载元素的
22 楼 kanny87929 2011-04-07  
wujianjun0410 写道
好文章,学习了  

谢支持,不要光看头像,头像是我老婆
21 楼 wujianjun0410 2011-04-07  
好文章,学习了  
20 楼 liuxuejin 2011-04-07  
正在看,希望lz多点出tomcat的文章!
19 楼 kanny87929 2011-04-07  
没有太多的建议就是看
how tomcat works
这书学,当然一定要有基础
对java的模式有个大概理解

那么看的时候就轻松很多

以后看到有用的东西会陆续发上来
18 楼 sebatinsky 2011-04-06  
呵呵,先学习一下。。。
17 楼 esanone 2011-04-06  
catalia设计的很组件化,完全可以对感兴趣的组件进行学习。
16 楼 whao189 2011-04-06  
想去看看 tomcat 这个本书, 楼主给点捷径!
15 楼 amwiacel 2011-04-06  
kanny87929 写道
amwiacel 写道
我是看了一半,那英文....有些就懂了,有些就不懂,还有些就模糊的...

我看的中文

哪有中文版,可以告诉吗?
14 楼 houyanhuasong 2011-04-06  
过完年的时候,公司事情不多,不忙,看了一点。。。希望能多点讲解的给我们指指路
13 楼 kanny87929 2011-04-06  
風一樣的男子 写道
kanny87929 写道
amwiacel 写道
我是看了一半,那英文....有些就懂了,有些就不懂,还有些就模糊的...

我看的中文


中文的不全吧?
看到7/8 没再往下看
时间分配问题


这个不清楚,不过看的明白,能深入理解就好
12 楼 風一樣的男子 2011-04-06  
kanny87929 写道
amwiacel 写道
我是看了一半,那英文....有些就懂了,有些就不懂,还有些就模糊的...

我看的中文


中文的不全吧?
看到7/8 没再往下看
时间分配问题
11 楼 kanny87929 2011-04-06  
amwiacel 写道
我是看了一半,那英文....有些就懂了,有些就不懂,还有些就模糊的...

我看的中文
10 楼 tracyhuyan 2011-04-06  
正在看第二章...
9 楼 amwiacel 2011-04-06  
我是看了一半,那英文....有些就懂了,有些就不懂,还有些就模糊的...
8 楼 kanny87929 2011-04-06  
...是不是因为你看不懂才坚持不下去
7 楼 jakehuu 2011-04-06  
这本书 我看到一半 没有坚持下去
6 楼 longxiaoyan 2011-04-06  
我也正打算看这本书。
5 楼 kanny87929 2011-04-06  
我觉得这章的内容非常的重要,所以很有必要一遍再一遍的讲

相关推荐

    tomcat5.5 免安装版+配置教程

    `jdk1.5和tomcat5.5免安装的环境配置.txt`文件很可能是详细记录了配置过程的文字说明,包括JDK和Tomcat的安装、环境变量设置、防火墙端口开放等细节。建议按照这个文件的指示操作,确保每一步都正确无误。 需要注意...

    tomcat5/tomcat5.5安装包

    【标题】"Tomcat5/tomcat5.5安装包" 涵盖了两个不同版本的Apache Tomcat服务器,即Tomcat 5.0和Tomcat 5.5。Tomcat是一个开源的、免费的应用服务器,主要用于部署和运行Java Servlets和JavaServer Pages(JSP)。它...

    tomcat5.5官方版

    《深入理解Tomcat5.5官方版》 Tomcat,作为一个开源且免费的Java Servlet容器,是Apache软件基金会Jakarta项目的重要组成部分。Tomcat5.5版本是其历史上的一个重要里程碑,它为开发者提供了稳定、高效的Java应用...

    Tomcat5.5中文版

    《Tomcat 5.5 中文版:程序设计与应用详解》 Apache Tomcat是一款开源、免费的Java Servlet容器,广泛应用于Web应用程序的部署和运行。Tomcat 5.5是其历史上的一个重要版本,提供了许多增强的功能和优化,使得它在...

    tomcat5.5集群完整版

    【标题】"Tomcat5.5集群完整版"所涉及的知识点主要集中在如何构建和管理一个基于Tomcat5.5的服务器集群。Tomcat作为Apache软件基金会的一个开源项目,是Java Servlet和JavaServer Pages(JSP)技术的开源Web应用...

    tomcat5.5 admin配置

    Tomcat 5.5是Apache软件基金会的Jakarta项目中的一个开源Java Servlet容器,它实现了Java Servlet和JavaServer Pages(JSP)规范。在Tomcat 5.5中,admin页面是一个内置的管理应用程序,允许用户监控和管理Tomcat...

    TOMCAT5.5下载

    **TOMCAT5.5 下载与安装指南** Apache Tomcat 是一款开源的、免费的 Java Servlet 容器,主要用于实现JavaServer Pages (JSP) 和 Java Servlets 的运行环境。Tomcat 5.5 版本是其历史上的一个重要里程碑,它在2006...

    tomcat5.5安装版

    这个"tomcat5.5安装版"包含了所有必要的组件来搭建一个完整的Tomcat服务器环境。以下是关于Tomcat 5.5的一些关键知识点: 1. **Java Servlet和JSP**: - Java Servlet是一种Java编程接口,允许开发者创建动态web...

    tomcat5.5以及tomcatplugin(附详细配置)

    【标题】"Tomcat5.5以及TomcatPlugin(附详细配置)"主要涵盖了两个核心主题:Tomcat 5.5版本的应用服务器以及Tomcat Plugin在Eclipse集成开发环境中的使用,特别是与Lomboz插件的配合。这些知识点对于Java Web开发者...

    tomcat5.5 解压版

    Tomcat 5.5 是一个历史悠久的开源Java应用服务器,主要用作Servlet和JSP容器。这个解压版意味着你无需进行编译或安装过程,只需下载并解压缩到你的计算机上,就可以直接运行,非常方便。以下是关于Tomcat 5.5的一些...

    将tomcat5.5 admin部署到 Tomcat7.0上

    4. **复制admin应用**:从Tomcat 5.5的`webapps`目录下找到`admin`应用,这通常是一个名为`admin.war`的文件。将其复制到Tomcat 7.0的`webapps`目录下。 5. **修改context配置**:Tomcat 7.0对上下文(Context)...

    Apache Tomcat 5.5 安装版

    Apache Tomcat 5.5 安装版

    tomcat5.5中文手册tomcat5.5中文手册tomcat5.5中文手册tomcat5.5中文手册

    tomcat5.5中文手册tomcat5.5中文手册tomcat5.5中文手册tomcat5.5中文手册tomcat5.5中文手册tomcat5.5中文手册tomcat5.5中文手册tomcat5.5中文手册tomcat5.5中文手册tomcat5.5中文手册tomcat5.5中文手册tomcat5.5中文...

    jdk5.5+tomcat5.5 环境配置

    jdk5.5+tomcat5.5 环境配置 jdk5.5+tomcat5.5 环境配置是 Java 开发中常用的服务器配置,下面将详细介绍其配置过程。 一、下载和安装 jdk 和 tomcat 首先,需要下载最新的 jdk 和 tomcat 软件包。目前,最新的 ...

    tomcat5.5和tomcat6.0解压版

    在`conf`目录下,用户可以配置Tomcat的各种设置,如服务器端口、连接器参数、用户权限等。同时,`logs`目录会记录服务器运行时的日志信息,帮助排查问题。 总结来说,这个解压版包含的Tomcat 5.5和6.0版本为用户...

    tomcat5.5.exe

    tomcat5 安装包,适合图方便的人,呵呵

    Tomcat5.5_admin在Linux下跌安装文件

    在Linux环境下部署Tomcat5.5_admin可以帮助用户管理他们的Web应用程序。 首先,让我们详细了解一下如何在Linux系统上安装Apache Tomcat 5.5。安装过程通常包括以下几个步骤: 1. **下载Tomcat**:从Apache官方仓库...

    绿色免安装 tomcat 5.5

    【绿色免安装 Tomcat 5.5】是一个精简版的Tomcat服务器,它不需要复杂的安装过程,只需解压即可运行。Tomcat是Apache软件基金会的Jakarta项目下的一个核心项目,是一个开源的、免费的Web应用服务器,主要用于处理...

    Tomcat5.5配置SSL

    在IT行业中,Tomcat是一...总结一下,配置Tomcat 5.5的SSL涉及到生成和导入证书、修改Tomcat配置文件以及在Web应用层设置安全约束。通过这些步骤,你可以确保Web应用程序通过HTTPS提供服务,从而提高数据传输的安全性。

    Tomcat5.5中文技术手册(真正的)

    《Tomcat5.5中文技术手册》是一份详尽的指南,专为使用Apache Tomcat 5.5版本的开发者和管理员提供。这份手册以中文呈现,方便了中文读者理解和应用Tomcat的相关知识。HTML版的形式使得查阅和学习更加便捷,无需安装...

Global site tag (gtag.js) - Google Analytics