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

tomcat源码分析三

阅读更多

            这里看下tomcat中责任链模式的使用。首先看下什么是责任链模式,责任链模式是抽象的处理者和具体的处理者组成。而具体处理者都拥有其下家的应用,从而形成处理链。直到有处理者处理,并且可以任意扩展链的长度。从简单点的开始,在阎宏《java与模式》一书中,有一个击鼓传花的例子。对责任链模式有很好的讲解,这里就不啰嗦了。通过书中例子,应该可以理解责任链的处理方式,这里主要看下tomcat中的使用。

        首先我们来看下tomcat的配置文件,在conf/server.xml里面。

这个事原始配置文件:

<Service name="Catalina">
    <Connector port="8080" protocol="HTTP/1.1"     connectionTimeout="20000" redirectPort="8443"/>
   <Connector port="8009" protocol="AJP/1.3" redirectPort="8443"/>
    <Engine name="Catalina" defaultHost="localhost">
         <Realm className="org.apache.catalina.realm.UserDatabaseRealm" resourceName="UserDatabase"/>
           <Host name="localhost" appBase="webapps" unpackWARs="true" autoDeploy="true" xmlValidation="false" xmlNamespaceAware="false">
            </Host>
    </Engine>
</Service>

按照需求更改后的<Engine></Engine>以内的配置文件,其他部分没有变动:

 

<Host name="wap.**.cc" appBase="d:/test/wapPortal" unpackWARs="true" autoDeploy="true" xmlValidation="false" xmlNamespaceAware="false">
   <Context crossContext="true" debug="5" displayName="tawap" docBase="d:/test/wapPortal" path="" reloadable="true">
    <Resource auth="Container" name="jdbc/wapportal" type="javax.sql.DataSource" maxWait="10000" maxIdle="30" maxActive="100" username="root" password="admin" driverClassName="com.mysql.jdbc.Driver" url="jdbc:mysql://localhost:3306/onetouch?useUnicode=true&characterEncoding=UTF-8"/>
<ResourceLink global="jdbc/wapportal" name="jdbc/wapportal" type="javax.sql.DataSource"/>
   </Context>
</Host>
<Host name=www.**.com appBase="d:/test" unpackWARs="true" autoDeploy="true" xmlValidation="false" xmlNamespaceAware="false">
 <Context path="/" reloadable="true" docBase="d:/test"> 
 </Context>
</Host>

 tomcat对这部分的处理,就是采用责任链的模式。接下来看下实现责任链的类关系,如图:

tomcat责任链

那么从tomcat哪部分是配置文件呢?我们看下StandardService代码

public class StandardService implements Lifecycle, Service, MBeanRegistration

 依照责任链模式,显然和UML图中的不属于同一个类别,所以其他的部分不构成责任链。由责任链的定义,我们主要看下其上家和下家的定义。

1.首先StandardEngine类:

//setParent方法(上家),可以看出是没有上家的
public void setParent(Container container) {
        throw new IllegalArgumentException
            (sm.getString("standardEngine.notParent"));

    }
//addChild方法如下(下家),可以看到Host为其下家
public void addChild(Container child) {
        if (!(child instanceof Host))
            throw new IllegalArgumentException
                (sm.getString("standardEngine.notHost"));
        super.addChild(child);
}
//有必要设置默认值
public void setDefaultHost(String host) {

        String oldDefaultHost = this.defaultHost;
        if (host == null) {
            this.defaultHost = null;
        } else {
            this.defaultHost = host.toLowerCase();
        }
        support.firePropertyChange("defaultHost", oldDefaultHost,
                                   this.defaultHost);

    }

 2.依照这个顺序,很明显接下来看下Host了。

  //下家为Context
public void addChild(Container child) {
        if (child instanceof Lifecycle) {
            ((Lifecycle) child).addLifecycleListener(
                    new MemoryLeakTrackingListener());
        }
        if (!(child instanceof Context))
            throw new IllegalArgumentException
                (sm.getString("standardHost.notContext"));
        super.addChild(child);
}

 

3.Context的处理,standContext类中addChild方法,可以从代码中看出下家是Wrapper。

   Wrapper oldJspServlet = null;

        if (!(child instanceof Wrapper)) {
            throw new IllegalArgumentException
                (sm.getString("standardContext.notWrapper"));
        }

        Wrapper wrapper = (Wrapper) child;

 

4.Wrapper对应实现

 

//可以看到这层到了责任链处理的终点了
public void addChild(Container child) {
        throw new IllegalStateException
            (sm.getString("standardWrapper.notChild"));
}
//该类中还限制了其上家
public void setParent(Container container) {

        if ((container != null) &&
            !(container instanceof Context))
            throw new IllegalArgumentException
                (sm.getString("standardWrapper.notContext"));
        if (container instanceof StandardContext) {
            swallowOutput = ((StandardContext)container).getSwallowOutput();
            unloadDelay = ((StandardContext)container).getUnloadDelay();
        }
        super.setParent(container);

    }

 

tomcat启动的时候,是肯定要从配置文件读取数据启动的,那么是怎么来启动这个链的呢?接下来看下这部分的启动,

首先是standardEngine类中的启动了。

  // Standard container startup
        super.start();

 那么看下父类中的启动代码了,即CantainerBasestart()如下:

  Container children[] = findChildren();
        for (int i = 0; i < children.length; i++) {
            if (children[i] instanceof Lifecycle)
                ((Lifecycle) children[i]).start();
        }

 根据上面的代码addChild和这里的 findChildren(),维护了一个链。这样就可以按照配置文件的不同配置,来启动加载了。

         同时,我们可以看到的是责任链的整个部分都实现了观察者的Lifecycle接口,从而它们都是在观察者模式中处于主题对象的角色。观察者对象对其作相应的处理,启动前,启动,启动后,观察者会有不同的处理。在stop()中有关闭的处理,这里看下启动部分start()中观察者处理代码,。

//start中的部分代码
// Notify our interested LifecycleListeners
        lifecycle.fireLifecycleEvent(BEFORE_START_EVENT, null);
        started = true;
        //省略部分代码
       // Notify our interested LifecycleListeners
        lifecycle.fireLifecycleEvent(START_EVENT, null);

        // Start our thread
        threadStart();

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

 

分享到:
评论

相关推荐

    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源码分析1

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

    tomcat源码分析1

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

    tomcat源码依赖包

    3. **Apache Commons**:Apache Commons是Apache软件基金会的一个项目,提供了大量的Java实用工具类,Tomcat源码中可能使用了如Commons Logging、Commons Lang、Commons IO等模块。 4. **Servlet API**:Tomcat作为...

    tomcat8源码

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

Global site tag (gtag.js) - Google Analytics