一、 实现容器的接口是Container接口,Tomcat中共有四种类型的容器:

1、Engine:表示整个Catalina Servlet引擎;

2、Host:表示含有一个或者多个Context容器的虚拟主机,通常一个Engine下含有一个Host;

3、Context:表示一个web应用程序;

4、Wrapper :表示一个独立的Servlet;

二、Container接口的UML图:

三、Container接口:

1、容器管理相关:addChild, removeChild, findChild等等;

Container是有层级关系的,Engine下有一个或者多个Host ,一个Host下有一个或者多个Context,一个Context下有一个或者多个Wrapper;这些都可以通过容器管理相关方法来管理,Wrapper是最底层的容器,无法再包含自容器了;

2、支持的其他一些组件:Loader, Logger, Manager, Cluster,Realm, ParentClassLoader, DirContext, Mapper等,支持这些的方法更像是一个实体类,提供了对应的Get和 Set方法;

3、Container接口提供了一个最重要的方法invoke,Container接口示例会传递给Connector连接器,连接器处理用户请求并解析生成Request和Response对象后,会调用Container容器的invoke方法;

四、Container.Invoke的调用流程:

1、这里的Container接口实现使用的是Context,Connect.invoke方法调用就传递给Context.invoke;

2、Context.invoke传递给pipeline.invoke,然后pipeline.invoke方法会借助ValveContext来循环调用Valves数组中的Valve,Valves数组调用完成后就会调用BasicValve(这种循环调用是用过InvokeNext方法实现的),不管是Valves数组还是BasicValve都是valve接口的实现;

3、Valve的Invoke方法会调用Context.map方法,map方法中先根据request请求字符串调用findMapper方法返回对应协议的mapper,然后调用对应mapper.map方法;

4、Mapper的map方法实现首先从Context中根据request请求字符串查找到对应的Wrapper(也即对应的servlet实例),然后由对应的Wrapper去处理用户请求;

请求转到每个Servlet对应的Wrapper后,其调用流程如下:

每个Container的实现都含有一个PipeLine对象,于是Container的invoke实现就传递给PipeLine的invoke方法,pipeLine对象含有一个BasicValve和Valves列表,PipeLine会首先循环调用valves列表中的valve,最后再调用Basic Valve;在Basic Valve的invoke方法中传递进了Request和Response对象,然后调用对应Servlet;

在BasicValve.invoke方法中,首先会根据servletClass生成servlet实例并初始化,然后调用其service方法来完成servlet方法的调用;

五、UML 图:

1、Wrapper接口的实现类StandardWrapper继承自ContainerBase类,也就是实现了Container接口,StandardWrapper类是Container接口的最小实现单位。StandardWrapper类继承了ContainwrBase类的两个重要方法invoke和map,Connector的invoke方法会调用此处的invoke,map方法会根据请求URL(Request对象)查找映射器,然后由映射器将请求传给对应的子容器处理;

2、StandardWrapper类的allocate调用LoadServlet加载Servlet,unload会卸载servlet,也即调用servlet.Destroy方法;同时StandardWrapper作为Container接口的实现,也包含了pipeLine接口的实现类StandardPipeLine;

3、PipeLine包含了多个Valve和一个BasicValve,StandardWrapperValve作为BasicValve,其invoke方法调用时首先加载servlet并调用,然后根据配置文件中给该servlet配置的过滤器链创建ApplicationFilterChain,最后调用过滤器链中的过滤器;

4、FilterDef对应了一个配置文件中配置的一个过滤器,包含了filterName, DisplayName, Description, parameters, SmallIcon等信息,ApplicationFilterConfig对应了一个过滤器,他能根据filterClass加载出对应的过滤器Filter并初始化。ApplicationFilterChain根据filterMaps数组中的配置加载出过滤器链表;

5、Mapper定义了映射器接口,StandardContextMapper、StandardEngineMapper、StandardHostMapper类实现了Mapper(Wrapper是最小的Container单位,对应一个具体的servlet,因此其不需要映射器实现类),map方法实现了根据Request查找到对应处理这个请求的子容器对象;

6、Context对应一个web应用;

其中管理子容器的变量是一个hash表:

在addChild方式时,会将child.getName作为Key,child对象作为value存入hash表:

servletMappings变量存储了servletName和请求路径的映射关系,也是一个hash表:

其中的数据存储是以servletName和请求路径为映射关系存储的:

这样方便根据请求地址能很快查找到servletName,然后根据servletName能很快查找到对应的Wrapper(Context的map方法就是这样实现的);

tomcat源码阅读之容器(Container)的更多相关文章

  1. Tomcat源码阅读(二)初始化

    近来,我开始阅读tomcat的源码,感觉还挺清晰易懂:为了方便理解,我参考了网上的一些文章,把tomcat的组成归纳一下:整个tomcat的组成如下图所示: Tomcat在接收到用户请求时,将会通过以 ...

  2. tomcat源码阅读之过滤器

    一.Servlet过滤器: 1.介绍: Servlet过滤器本身并不生成请求和响应对象,它只提供过滤作用. Servlet过滤器能够在Servlet被调用之前检查Request对象,修改Request ...

  3. tomcat源码阅读

    1      工具准备 需要SVN.Maven.JDK.Eclipse.Eclipse M2插件 2      下载源码及发布包 源码在这里:http://svn.apache.org/repos/a ...

  4. tomcat源码阅读之SingleThreadModel

    一.接口简介: 实现了SingleThreadModel接口的servlet类只能保证在同一时刻,只有一个线程执行该servlet实例的service方法,在tomcat实现中会创建多个servlet ...

  5. tomcat源码阅读之载入器(Loader)

    一.Java类的载入器: 双亲委派模型: 1.JVM提供了三种类型的类加载器:引导类载入器(bootstrap class loader).扩展类载入器(extension class loader) ...

  6. tomcat源码阅读之StandardHost和StandardEngine

    StandardHost及UML类图: 1.StandardHost类是Host接口的默认实现:其继承自ContainerBase类,说明他也是一个容器类,既然是容器类,那肯定也有管道对象PipeLi ...

  7. Tomcat源码分析之—容器整体结构

    Tomcat有多个容器组成,而Container也就是容器与Connecter连接器是Tomcat最核心的两个模块,Connecter连接器接收客户端的请求,并根据客户端的请求传递给Container ...

  8. tomcat源码解读(2)–容器责任链模式的实现

    责任链模式:责任链模式可以用在这样的场景,当一个request过来的时候,需要对这个request做一系列的加工,使用责任链模式可以使每个加工组件化,减少耦合.也可以使用在当一个request过来的时 ...

  9. tomcat源码阅读之集群

    一. 配置: 在tomcat目录下的conf/Server.xml配置文件中增加如下配置: <!-- Cluster(集群,族) 节点,如果你要配置tomcat集群,则需要使用此节点. clas ...

随机推荐

  1. mappingDirectoryLocations

    aaarticlea/png;base64,iVBORw0KGgoAAAANSUhEUgAAA+kAAAG8CAIAAAAtg3NFAAAgAElEQVR4nO3dO28bTYLv/z4v4MTnPR

  2. JVM笔记(一) Java内存区域

    Java 内存区域 总概 java虚拟机在执行java程序的过程中,会把它管理的内存划分为几个不同的数据区域.每当运行一个java程序时,就会启动一个虚拟机. 具体的区域如图所示: 同时,方法区 与 ...

  3. C# 值类型与引用类型 (上)

    1. 主要内容 类型的基本概念 值类型深入 引用类型深入 值类型与引用类型的比较及应用 2. 基本概念 C#中,变量是值还是引用仅取决于其数据类型. C#的基本数据类型都以平台无关的方式来定义,C#的 ...

  4. iis 7 asp.net ajax post 请求字节过大报错问题解决办法

    遇到一个ajax post 提交新闻资讯类的文章,报 {"Message":"There was an error processing the request.&quo ...

  5. dnspod 动态域名的使用。openwrt使用dnspod动态域名解析。

    这里主要说的是linux shell下的使用. 先看接口说明: 接口地址: https://dnsapi.cn/Record.Ddns HTTP请求方式: POST 请求参数: 公共参数 domain ...

  6. flask(十)使用alembic,进行数据库结构管理,升级,加表,加项

    1.安装扩展,在虚拟环境中安装 alembic,不懂可以去看pycharm的系列文章. 2.初始化, 使用 Alembic 前需要通过 alembic init 命令创建一个 alembic 项目,该 ...

  7. struts1的parameter

    1.配置文件    parameter="method" 2.请求路径      http://localhost:8081/purchaseDeclareAction.do?me ...

  8. Python3 文件操作(十六)

    一 文件操作 1.介绍 计算机系统分为:计算机硬件,操作系统,应用程序三部分. 我们用python或其他语言编写的应用程序若想要把数据永久保存下来,必须要保存于硬盘中,这就涉及到应用程序要操作硬件,众 ...

  9. 高版本的jdk编译过的项目移到低版本的JDK的eclipse中出错的问题

    由于2台电脑安装的jdk版本不一样,导致从一台电脑移动项目到另一台电脑上时,运行出现了错误,错误信息如下: 主要是原先项目运行的JDK版本为1.8, 而要移过去的电脑的jdk是1.7的,首先已经把bu ...

  10. memcache原理及环境搭建、测试

    一.原理       Memcache是一个高性能的分布式的内存对象缓存系统,通过在内存里维护一个统一的巨大的hash表,它能够用来存储各种格式的数据,包括图像.视频.文件以及数据库检索的结果等.简单 ...