`
shenkun_918
  • 浏览: 27579 次
  • 性别: Icon_minigender_1
  • 来自: 深圳
社区版块
存档分类
最新评论

tomcat源码分析二

阅读更多

       在这一篇中,看下观察者模式的应用。首先来看下观察者模式的概念:观察者模式是一种一对多的关系,多个观察者对象同时关注一个主题对象。观察者模式中有主题对象和观察者对象,我们可以把球赛比作一个观察者模型,那么球赛就是主题对象,观众就是观察者对象。以下通过java语言对观察者,java.util.Observable的应用实现,观察者在tomcat源代码中的应用,三个部分来阐述观察者模式。

    一. java语言中的观察者模式

通过java.util.Observable,首先来看下其源代码。

//观察者接口
public interface Observer {
    void update(Observable o, Object arg);
}



//主题对象
public class Observable {
    private boolean changed = false;//状态变量
   //维护观察者对象的集合
   private Vector obs;
    public Observable() {
	obs = new Vector();
    }
   //将观察者加入到集合中
  public synchronized void addObserver(Observer o) {
        if (o == null)
            throw new NullPointerException();
	if (!obs.contains(o)) {
	    obs.addElement(o);
	}
    }
  //从集合中删除观察者
  public synchronized void deleteObserver(Observer o) {
        obs.removeElement(o);
    }
  //通知
  public void notifyObservers(Object arg) {
        Object[] arrLocal;
	synchronized (this) {
	    if (!changed) return;
            arrLocal = obs.toArray();//将结合转化成数组
            clearChanged();
        }

        for (int i = arrLocal.length-1; i>=0; i--)
            ((Observer)arrLocal[i]).update(this, arg);//观察者作出状态改变的操作
    }
   //状态的几个相关方法 
  protected synchronized void setChanged() {
	changed = true;
    }
   protected synchronized void clearChanged() {
	changed = false;
    }
   public synchronized boolean hasChanged() {
	return changed;
    }

 

    二.java.util.Observable的应用实现

     上一部分是java源代码中对于观察者模式的实现,对代码有注释。如果不明白的话,可以结合下面的一个例子来看,就应该很清楚了。个人觉得以下的例子(来自网上)比《设计与模式》一书中的例子更直观些,商品为主题对象,对于商品的价格和名称的改变有相应的观察者。

主题对象

public class Product extends Observable{
	
	private String name;
	
	private float price;

	public String getName() {
		return name;
	}

	public void setName(String name) {
		this.name = name;
		//设置观察点(changed=true )
		setChanged();
                               //观察者作出相应的改变
		notifyObservers(name);
	}

	public float getPrice() {
		return price;
	}

	public void setPrice(float price) {
		this.price = price;
		//设置观察点,同上
		setChanged();
		notifyObservers(price);
	}
}



观察者对象

//商品名称观察者类
public class NameObserver implements Observer{
	
	private String name = "";
	//源代码中对应((Observer)arrLocal[i]).update(this, arg)
	public void update(Observable ob, Object arg) {
		
		if(arg instanceof String){
			name = (String)arg;
			System.out.println("name has been changed to:"+name);
		}
		
	}
}
//价格观察者类
public class PriceObserver implements Observer{
	
	private float price;
	//同上
	public void update(Observable ob, Object arg) {
		if(arg instanceof Float){
			price = (Float)arg;
			System.out.println("name has been changed to:"+price);
		}
		
	}
}

 

 运行看下效果

public static void main(String[] args) {
		Product p1 = new Product();
		NameObserver nameObserver = new NameObserver();
		PriceObserver priceObserver = new PriceObserver();
		p1.addObserver(nameObserver);
		p1.addObserver(priceObserver);
		p1.setName("苹果");
		p1.setPrice(8);
		p1.setName("香蕉");
	}




三. tomcat中观察者的实现

结合源代码的分析以及一个实例,应该对于观察者模式有一定的理解了,接下来看下在tomcat的源代码中的使用。

 tomcat

(1)主题接口LifeCycle,在其中定义了状态变量init,start…等的状态,看下源代码对于该接口的定义。

//增加观察者
public addLifecycleListener(LifecycleListener listener);
//获取所有的观察者
public LifecycleListener[] findLifecycleListeners();
//移除观察者
public void removeLifecycleListener(LifecycleListener listener);
//其他2个方法
public void start() throws LifecycleException;
public void stop() throws LifecycleException;

 

(2)观察者接口  LifecycleListener的定义

//主题变化时候,要执行的方法
public void lifecycleEvent(LifecycleEvent event);  

 

 

(3) 有大量类实现了主题LifeCycle接口,作为取其中的StandardServer来分析,看下是怎么用的。

由于在StandardServer中用到了LifeCycleSupport,所以先分析下该类。

 

public final class LifeCycleSupport{
//构造器
public LifeCycleSupport (Lifecycle lifecycle) {
        super();
        this.lifecycle = lifecycle;
}
//存储观察者的数组,看Lifecycle就会发现。里面有一个findLifecycleListeners获取数组,但是没有定义数组变量。
private LifecycleListener listeners[] = new LifecycleListener[0];
 //将观察者对象放入到数组中,此处定义直接每次增加的时候,定义一个数目加1的数据。是出于性能的考虑,这种方式可以在编程中运用。在tomcat中可以看到大量类似的编程方式有些是用System.arraycopy来处理. 
public void addLifecycleListener(LifecycleListener listener) {
      synchronized (listenersLock) {
          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 removeLifecycleListener(LifecycleListener listener) {
        lifecycle.removeLifecycleListener(listener);
    }
public void fireLifecycleEvent(String type, Object data) {

        if (Lifecycle.INIT_EVENT.equals(type)) {
            state = "INITIALIZED";
        }//此处省略部分else if 语句
        LifecycleEvent event = new LifecycleEvent(lifecycle, type, data);
        LifecycleListener interested[] = listeners;
        for (int i = 0; i < interested.length; i++)
            interested[i].lifecycleEvent(event);//有改变后观察者进行处理
    }
}

 

 

 (4)看了LifeCycleSupport的实现,再看下StandardServer中的实现就很清楚了。该类中lifecycle的方法全部是调用LifeCycleSupport。这里是对观察者之上有进一步的处理。

 

 

public final class StandardServer
implements LifeCycle, Server, MBeanRegistration
//这里看下LifeCycle接口中的几个方法的实现

private LifeCycleSupport lifeCycle = new LifeCycleSupport(this);

public void addLifeCycleListener(LifeCycleListener listener) {
       lifeCycle.addLifeCycleListener(listener);
    }
public LifecycleListener[] findLifecycleListeners() {
        return lifecycle.findLifecycleListeners();
    }
  public void start() throws LifecycleException {

        // Validate and update our current component state
        if (started) {
            log.debug(sm.getString("standardServer.start.started"));
            return;
        }

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

        lifecycle.fireLifecycleEvent(START_EVENT, null);
        started = true;

        // Start our defined Services
        synchronized (services) {
            for (int i = 0; i < services.length; i++) {
                if (services[i] instanceof Lifecycle)
                    ((Lifecycle) services[i]).start();
            }
        }

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

(5)LifecycleEvent这个类,是将数据封装在一个对象中。

org.apache.catalina.mbeans.ServerLifecycleListener中可以看到,对于观察者在不同状态下的实现代码。

文字编译器不好用,莫名奇妙的多了很多空的java代码框。

分享到:
评论

相关推荐

    tomcat 源码分析系列文档

    【标签】"tomcat源码分析"表明整个资料集专注于Tomcat的源代码级探索,适合于开发者或运维人员深入了解服务器的底层实现。 【文件名称列表】中的每个文档都对应一个特定主题: 1. "Tomcat处理HTTP请求源码分析.doc...

    tomcat6源码分析

    《Tomcat6源码分析——深入理解Web服务器的运行机制》 Tomcat6作为Apache软件基金会的Jakarta项目的一部分,是一款广泛使用的Java Servlet容器,它实现了Java Servlet和JavaServer Pages(JSP)规范,为开发和部署...

    tomcat架构的源码分析

    ### Tomcat架构的源码分析 #### 一、Tomcat的架构概述 Tomcat作为一款广泛使用的开源Java Servlet容器,其内部架构设计简洁而高效。本文档将对Tomcat的架构进行详细介绍,并从源码层面深入分析其核心组成部分。...

    「Tomcat源码剖析」.pdf

    Tomcat源码剖析 : 整体架构 层层分析 源码解析 架构分析 (Http服务器功能:Socket通信(TCP/IP)、解析Http报文 Servlet容器功能:有很多Servlet(自带系统级Servlet+自定义Servlet),Servlet处理具体的业务逻辑...

    TOMCAT源码分析(启动框架)

    【TOMCAT源码分析(启动框架)】 Tomcat是一款广泛应用的开源Java Servlet容器,它实现了Java Servlet和JavaServer Pages(JSP)规范,为Web应用程序提供了运行环境。本篇文章将深入探讨Tomcat的系统框架及其启动流程...

    tomcat源码分析图谱

    tomcat的基础脚本分析 tomcat的源码启动分析 tomcat的web应用启动分析 tomcat的socket分析 tomcat的cocket与容器对接时序分析

    tomcat源码

    Apache Tomcat源码分析 Apache Tomcat是一款广泛应用的开源Java Servlet容器,它是Java EE Web应用程序的标准实现。Tomcat源码的深入理解对于Java Web开发者来说是至关重要的,它可以帮助我们了解HTTP服务器的工作...

    Tomcat源码分析

    【标题】"Tomcat源码分析" 在深入探讨Tomcat源码之前,首先需要了解Tomcat是什么。Tomcat是一款开源的、基于Java的Web应用服务器,由Apache软件基金会开发。它实现了Java Servlet和JavaServer Pages(JSP)规范,...

    tomcat 最全源码分析

    对 NIO 模式,请求的流程描述的很详细。值得去仔细的研究。

    tomcat源码分析

    tomcat源码分析,tomcat原理分析,底层机制,一些源代码等等

    Tomcat源码分析1

    《Tomcat源码分析1——服务启动与架构详解》 Tomcat,作为一款广泛应用的开源Java Servlet容器,其内部架构和启动流程对于深入理解和优化Web应用程序至关重要。本文将重点解析Tomcat启动时的关键步骤和核心组件,...

    tomcat源码分析1

    《深入理解Tomcat源码分析1:Connector配置详解》 Tomcat,作为广泛使用的Java Servlet容器,其核心组件之一就是Connector,它负责处理Web服务器与客户端之间的通信。本篇文章将详细探讨Tomcat Connector的种类、...

    tomcat源码依赖包

    2. **Apache Ant**:Ant是一个Java库和命令行工具,用于构建Java项目,它是编译Tomcat源码的必备工具。Ant的jar文件包含了构建脚本执行所需的所有类和方法。 3. **Apache Commons**:Apache Commons是Apache软件...

    tomcat8源码

    Apache Tomcat 8.5.23 源码分析 Apache Tomcat 是一个开源的、免费的Web服务器和Servlet容器,它实现了Java Servlet和JavaServer Pages(JSP)规范,是开发和部署Java Web应用的重要平台。深入理解Tomcat的源码有助...

    tomcat7源码

    源码分析是提升开发者对服务器内部运作机制理解的重要途径,尤其对于Tomcat这样的核心组件,源码的学习能够帮助我们更深入地理解Web应用的部署、运行以及性能优化。 首先,我们要了解Tomcat的架构。Tomcat7基于...

Global site tag (gtag.js) - Google Analytics