一、 实现容器的接口是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. USART相关问题

    最近发现一个FT232+stm32的USB转串口问题,不能理解,记录下来. PC和STM32通讯,USB-B连接,连接方式如下所示: 上图为USB口引出USB_N/USB_P/USB_EN三个PIN脚 ...

  2. MySQL 5.6比较重要的参数,以及5.5到5.6默认值有过变化的参数

    新参数说明和设置,这里说下5.6比较重要的参数,以及5.5到5.6默认值有过变化的参数. MySQL Server参数: 1,optimizer_switch:优化器选项. Variable_name ...

  3. Java——线程定时器

    body, table{font-family: 微软雅黑; font-size: 10pt} table{border-collapse: collapse; border: solid gray; ...

  4. hdu 1003 Max Sum (动态规划)

    转载于acm之家http://www.acmerblog.com/hdu-1003-Max-Sum-1258.html Max Sum Time Limit: 2000/1000 MS (Java/O ...

  5. Quartz表结构说明

    一.表信息解析: 1.1. qrtz_blob_triggers : 以Blob 类型存储的触发器. 1.2. qrtz_calendars:存放日历信息, quartz可配置一个日历来指定一个时间范 ...

  6. Beta 冲刺(6/7)

    前言 队名:拖鞋旅游队 组长博客:https://www.cnblogs.com/Sulumer/p/10129063.html 作业博客:https://edu.cnblogs.com/campus ...

  7. 2019.1.22 zigbee test

    1传输测试 频谱仪设置: sigfox 模块串口设置: 自动选择对应型号 Test step: PS:发送TX指令 AT$cw=波特率,通道,uint 这里有个问题--不应该只发送一次 ------- ...

  8. python打包成.exe

    pyuic5 mainwindow.ui -o test.py pip install pyinstaller pyinstaller -F -w ***.py https://blog.csdn.n ...

  9. ARM 平台下的 SSHD 配置

    sshd_config 文件中 允许 root 用户登录 PermitRootLogin yes 配置为内部的 sftp Subsystem sftp internal-sftp key 配置 ssh ...

  10. m函数与m文件的命名

    问题 创建函数test_image,按照定义方式进行调用,一直出现下图所示的错误, 调试的过程中一直提示输入参数太多,可是test_image这个函数的输入个数和调用这个函数的输入输出数目是一致的,然 ...