Tomcat之Servlet容器Container。

Container是容器的父接口,所有子容器都必须实现这个接口,Container容器的设计用的是典型的责任链的设计模式,他由4个子容器组件构成,分别实Engine、Host、Context和Wrapper,这4个组件不是平行的,而是父子关系,Engine包含Host,Host包含Context,Context包含Wrapper。通常一个Servlet class对应一个Wrapper,如果有多个Servlet,则可以定义多个Wrapper;如果有多个Wrapper,则要定义一个更高的Container,如Context,Context通常对应如下的配置:

<Context path="/library/" docBase="D:\projects\library\deploy\target\library.war" reloadable="true" />

容器的整体设计

Context还可以定义在父容器Host中,Host不是必须的,但是要运行war程序,就必须要用Host,因为在war中必有web.xml文件,这个文件的解析就需要Host。如果要有多个Host就要定义一个top容器Engine。而Engine没有父容器了,一个Engine代表一个完整的Servlet引擎。

当Connector接受一个连接请求时,会将请求交给Container,Container是如何处理这个请求的?这4个组件是怎么分工的?怎么把请求传给特定的子容器的?又是如何将最终的请求交给Servlet处理的?下图是这个过程的时序图。

这里看到了Value,是不是很熟悉?没错,Value的设计在其他框架中也有用到,同样Pipeline的原理基本上也是相似的。他是一个管道,Engine和Host都会执行这个Pipeline,你可以在这个管道上增加任意的Value,Tomcat会挨个执行这些Value,而且4个组件都会有自己的一套Value集合。你怎么才能定义自己的Value呢?在server.xml文件中可以添加,如给Engine和Host增加一个Value,代码如下:

<Engine defaultHost="localhost" name="Catalina">
    <Value className="org.apache.catalina.values.RequestDumperValue" />
    ......
    <Host appBase="webapps" autoDeploy="true" name="localhost" unpackWARs="true" xmlNamespaceAware="false" xmlValidation="false">
        <Value className="org.apache.catalina.values.FastCommonAccessLogValue" directory="logs" prefix="localhost_access_log." suffix=".txt" pattern="common" resolveHosts="false" />
        ......
    </Host>
</Engine>

StandardEngineValue、StandardHostValue是Engine和Host默认的Value,最后一个Value负责将请求传给他们的子容器,以继续往下执行。

前面是Engine和Host容器的请求过程,下面看Context和Wrapper容器是如何处理请求的。下图是处理请求的时序图。

从Tomcat 5 开始,子容器的路由放在了request中,在request中保存了当前请求正在处理的Host、Context和Wrapper。

Engine容器

Engine容器比较简单,他定义了一些基本的关联关系。

他的标准实现类是StandardEngine,注意Engine没有父容器,如果调用setParent方法将会报错。添加的子容器也只能是Host类型的。

他的初始化方法也就是初始化和他相关联的组件,以及一些事件的监听。

Host容器

Host是Engine的子容器,一个Host在Engine中代表一个虚拟主机,这个虚拟主机的作用就是运行多个应用,他负责安装和展开这些应用,并且标识这个应用以便能够区分他们。他的子容器通常是Context,他除了关联子容器外,还保存一个主机应有的信息。

除了所有容器都继承的ContainerBase外,StandardHost还实现了Deployer接口。

Deployer接口的实现是StandardHostDeployer,这个类实现了最主要的几个方法,Host可以调用这些方法完成应用的部署等。

Context容器

Context代表Servlet的Context,他具备了Servelt运行的基本环境,理论上只要有Context就能运行Servlet了。简单地Tomcat可以没有Engine和Host。

Context最重要的功能就是管理他里面的Servlet实例,Servlet实例在Context中是以Wrapper出现的。还有一点就是Context如何才能找到正确的Servlet来执行他呢?Tomcat 5以前是通过一个Mapper类来管理的,在Tomcat 5 以后这个功能被移到了Request中,在前面的时序图中就可以发现获取子容器都是通过Request来分配的。

Context准备Servlet的运行环境是从Start方法开始的。他的主要作用是设置各种资源属性和管理组件,还有一个非常重要的作用就是启动子容器和Pipeline。

我们知道Context的配置文件中有个reloadable属性,如下面的配置:

<Context path="/library/" docBase="D:\projects\library\deploy\target\library.war" reloadable="true" />

当这个reloadable设为true时,war被修改后Tomcat会自动重新加载这个应用。如何做到这点呢?这个功能是在StandardContext的backgroundProcess方法中实现的。

他会调用reload方法,而reload方法会先调用stop方法,然后再调用Start方法,完成Context的一次重新加载。可以看出,执行reload方法的条件是reloadable为true和应用被修改,那么这个backgroundProcess方法是怎么被调用的呢?

这个方法是在ContainerBase类中定义的内部类ContainerBackgroundProcessor中被周期调用的,这个类运行在一个后台线程中。他会周期的执行run方法,他的run方法会周期的调用所有容器的backgroundProcess方法,因为所有容器都会继承ContainerBase类,所以所有容器都能够在backgroundProcess方法中定义周期执行的事件。

Wrapper容器

Wrapper代表一个Servlet,他负责管理一个Servlet,包括Servlet的装载、初始化、执行及资源回收。Wrapper是最底层的容器,他没有子容器了,所以调用他的addChild将会报错。

Wrapper的实现类是StandardWrapper,StandardWrapper还实现了拥有一个Servlet初始化信息的ServletConfig,由此看出StandardWrapper将直接和Servlet的各种信息打交道。

LoadServlet是一个非常重要的方法,他基本上描述了对Servlet的操作,装载了Servlet后就会调用Servlet的init方法,同时会传一个StandardWrapperFacade对象给Servlet,这个对象包装了StandardWrapper.

Servlet可以获得信息都在StandardWrapperFacade里封装,这些信息又是在StandardWrapper对象中拿到的,所以Servlet可以通过ServletConfig拿到有限的容器的信息。

当Servlet被初始化完成后,就等着StandardWrapperValue去调用他的Servlice方法了,调用Service方法之前要调用Servlet所有的filter。

  • 2
    点赞
  • 6
    收藏
    觉得还不错? 一键收藏
  • 0
    评论
说明:10分虽然有点高 但东西值 重点是 我也只想搞点分数下东西 谢谢支持 目录 I 简介 1 概览 1 适合读者 1 servlet容器是如何工作的 1 catalina结构图 1 tomcat的版本4和版本5 2 章节简介 2 第1章 一个简单的Web服务器 3 1.1 The Hypertext Transfer Protocol (HTTP) 3 1.2 HTTP Request 3 1.3 HTTP Response 4 1.4 Socket类 4 1.5 ServerSocket类 5 1.6 应用举例 5 第2章 一个简单的servlet容器 7 2.1 简述 7 2.2 javax.servlet.Servlet接口 7 2.3 Application 1 7 2.3.1 HttpServer1类 8 2.3.2 Request类 8 2.3.3 Response类 9 2.3.4 StaticResourceProcessor类 9 2.3.5 ServletProcessor1类 9 2.4 Application 2 9 第3章 连接器(Connector) 11 3.1 概述 11 3.2 StringManager类 11 3.3 Application 12 3.3.1 启动 13 3.3.2 connector 13 3.3.3 创建HttpRequest对象 13 3.3.3.1 SocketInputStream类 14 3.3.3.2 解析请求行(request line) 14 3.3.3.3 解析请求头(request header) 14 3.3.3.4 解析cookie 15 3.3.3.5 获取参数 16 3.3.3.6 创建HttpResponse对象 16 3.3.3.7 静态资源处理器和servlet处理器 17 第4章 tomcat的默认连接器 18 4.1 简介 18 4.2 HTTP1.1的新特性 18 4.2.1 持久化连接 18 4.2.2 编码 18 4.2.3 状态码100的使用 19 4.3 Connector接口 19 4.4 HttpConnector类 20 4.4.1 创建ServerSocket 20 4.4.2 维护HttpProcessor对象池 20 4.4.3 提供Http请求服务 21 4.5 HttpProcessor类 21 4.6 request对象 24 4.7 response对象 24 4.8 处理request对象 25 4.8.1 解析连接 28 4.8.2 解析request 28 4.8.3 解析请求头 28 4.9 简单的container程序 30 第5章 container 31 5.1 Container接口 31 5.2 流水线(pipeline)任务 32 5.2.1 Pipeline 34 5.2.2 Valve接口 35 5.2.3 ValveContext接口 35 5.2.4 Contained接口 36 5.3 Wrapper应用程序 36 5.4 Context接口 36 5.5 Wrapper程序实例 36 5.5.1 ex05.pyrmont.core.SimpleLoader 37 5.5.2 ex05.pyrmont.core.SimplePipeline 37 5.5.3 ex05.pyrmont.core.SimpleWrapper 38 5.5.4 ex05.pyrmont.core.SimpleWrapperValve 38 5.5.5 ex05.pyrmont.valves.ClientIPLoggerValve 39 5.5.6 ex05.pyrmont.valves.HeaderLoggerValve 39 5.5.7 ex05.pyrmont.startup.Bootstrap1 39 5.6 Context程序实例 39 5.6.1 ex05.pyrmont.core.SimpleContextValve 40 5.6.2 ex05.pyrmont.core.SimpleContextMapper 41 5.6.3 ex05.pyrmont.core.SimpleContext 42 5.6.4 ex05.pyrmont.startup.Bootstrap2 42 第6章 生命周期(Lifecycle) 43 6.1 概述 43 6.2 Lifecycle接口 43 6.3 LifecycleEvent类 44 6.4 LifecycleListener接口 44 6.5 LifecycleSupport类 44 6.6 应用程序 45 6.6.1 ex06.pyrmont.core.SimpleContext 45 6.6.2 ex06.pyrmont.core.SimpleContextLifecycleListener 45 6.6.3 ex06.pyrmont.core.SimpleLoader 46 6.6.4 ex06.pyrmont.core.SimplePipeline 46 6.6.5 ex06.pyrmont.core.SimpleWrapper 46 第7章 Logger 47 7.1 概述 47 7.2 Logger 47 7.3 Tomcat's Loggers 47 7.3.1 LoggerBase类 48 7.3.2 SystemOutLogger类 48 7.3.3 SystemErrLogger类 48 7.3.4 FileLogger类 49 7.3.4.1 open方法 50 7.3.4.2 close方法 50 7.3.4.3 log方法 51 7.4 应用程序 51 第8章 Loader 52 8.1 概述 52 8.2 java本身的loader 52 8.3 Loader接口 53 8.4 Reloader接口 54 8.5 WebappLoader类 54 8.5.1 创建类载入器 55 8.5.2 设置repository 55 8.5.3 设置类路径 56 8.5.4 设置访问权限 56 8.5.5 开启新线程执行类的重新载入 56 8.6 WebappClassLoader类 57 8.6.1 类缓存 58 8.6.2 载入类 59 8.6.3 应用程序 59 第9章 session管理 62 9.1 概述 62 9.2 Sessions 62 9.2.1 Session接口 62 9.2.2 StandardSession类 63 9.2.3 StandardSessionFacade类 65 9.3 Manager 65 9.3.1 Manager接口 66 9.3.2 ManagerBase类 66 9.3.3 StandardManager类 67 9.3.4 PersistentManagerBase类 68 9.3.4.1 swap out(换出) 69 9.3.4.2 back up(备份) 69 9.3.5 PersistentManager类 70 9.3.6 DistributedManager类 70 9.4 Stores 71 9.4.1 StoreBase类 72 9.4.2 FileStore类 73 9.4.3 JDBCStore类 73 9.5 应用程序 73 9.5.1 Bootstrap类 73 9.5.2 SimpleWrapperValve类 74 第10章 安全性 76 10.1 概述 76 10.2 Realm(领域) 76 10.3 GenericPrincipal 77 10.4 LoginConfig 78 10.5 Authenticator 78 10.6 安装Authenticator 79 10.7 应用程序 79 10.7.1 ex10.pyrmont.core.SimpleContextConfig类 80 10.7.2 ex10.pyrmont.realm.SimpleRealm类 80 10.7.3 ex10.pyrmont.realm.SimpleUserDatabaseRealm 81 10.7.4 ex10.pyrmont.startup.Bootstrap1类 81 10.7.5 ex10.pyrmont.startup.Bootstrap2类 81 第11章 StandardWrapper 82 11.1 方法调用序列 82 11.2 SingleThreadModel 83 11.3 StandardWrapper 83 11.3.1 生成servlet 84 11.3.2 载入servlet 86 11.3.3 ServletConfig对象 90 11.3.3.1 getServletContext方法 90 11.3.3.2 getServletName方法 91 11.3.3.3 getInitParameter方法 91 11.3.3.4 getInitParameterNames方法 92 11.3.4 container的父子关系 92 11.4 StandardWrapperFacade类 93 11.5 StandardWrapperValve类 94 11.6 FilterDef类 95 11.7 ApplicationFilterConfig类 96 11.8 ApplicationFilterChain类 96 11.9 应用程序 97 第12章 StandardContext类 98 12.1 概述 98 12.2 StandardContext的配置 98 12.2.1 StandardContext类的构造函数 98 12.2.2 启动StandardContext 99 12.2.3 invoke方法 99 12.3 StandardContextMapper类 100 12.4 对重载的支持 104 12.5 backgroundProcess方法 105 第13章 Host和Engine 107 13.1 概述 107 13.2 Host接口 107 13.3 StandardHost类 107 13.4 StandardHostMapper类 109 13.5 StandardHostValve类 110 13.6 为什么必须要有一个host 111 13.7 应用程序1 111 13.8 Engine接口 112 13.9 StandardEngine类 112 13.10 StandardEngineValve类 112 13.11 应用程序2 113 第14章 Server与Service 114 14.1 概述 114 14.2 server 114 14.3 StandardServer 114 14.3.1 initialize方法 114 14.3.2 start方法 115 14.3.3 stop方法 115 14.3.4 await方法 116 14.4 Service接口 116 14.5 StandardService类 116 14.5.1 connector和container 117 14.5.2 与生命周期有关的方法 118 14.6 应用程序 120 14.6.1 Bootstrap类 120 14.6.2 Stopper类 121 第15章 Digester 122 15.1 概述 122 15.2 Digester 122 15.2.1 Digester类 123 15.2.1.1 创建对象 123 15.2.1.2 设置属性 124 15.2.1.3 调用方法 124 15.2.1.4 创建对象之间的关系 124 15.2.1.5 验证xml文档 125 15.2.2 Digester示例1 125 15.2.3 Digester示例2 125 15.2.4 Rule类 126 15.2.5 Digester示例3:使用UsingSet 127 15.3 ContextConfig 127 15.3.1 defaultConfig方法 129 15.3.2 applicationConfig方法 129 15.3.3 创建digester 130 15.4 应用程序 130 第16章 Shutdown Hook 131 16.1 概述 131 16.2 tomcat中的shutdown hook 131 第17章 启动tomcat 133 17.1 概述 133 17.2 Catalina类 133 17.2.1 start方法 134 17.2.2 stop方法 135 17.2.3 启动Digester 135 17.2.4 关闭Digester 135 17.3 Bootstrap类 136 第18章 部署器 137 18.1 概述 137 18.2 部署一个web应用 137 18.2.1 部署一个描述符 140 18.2.2 部署一个war 141 18.2.3 部署一个目录 142 18.2.4 动态部署 143 18.3 Deploy接口 145 18.4 StandardHostDeployer类 145 18.4.1 安装一个描述符文件 146 18.4.2 安装一个war文件或目录 147 18.4.3 启动context 148 18.4.4 停止一个context 149 第19章 Manager Servlet 150 19.1 概述 150 19.2 使用Manager应用 150 19.3 ContainerServlet接口 151 19.4 初始化ManagerServlet 152 19.5 列出已经部署的web应用 153 19.6 启动web应用 154 19.7 关闭web应用 155 第20章 基于JMX的管理 156 20.1 jmx简介 156 20.2 jmx api 157 20.2.1 MBeanServer 157 20.2.2 ObjectName 157 20.3 Standard MBeans 158 20.4 Model MBeans 159 20.4.1 MBeanInfo与ModelMBeanInfo 160 20.4.2 ModelMBean实例 161 20.5 Commons Modeler 161 20.5.1 MBean描述符 162 20.5.1.1 mbean 162 20.5.1.2 attribute 163 20.5.1.3 operation 163 20.5.1.4 parameter 163 20.5.2 mbean标签实例 164 20.5.3 自己编写一个model MBean 164 20.5.4 注册 164 20.5.5 ManagedBean 165 20.5.6 BaseModelMBean 165 20.5.7 使用Modeler API 165 20.6 Catalian中的MBean 165 20.6.1 ClassNameMBean 165 20.6.2 StandardServerMBean 166 20.6.3 MBeanFactory 167 20.6.4 MBeanUtil 167 20.7 创建Catalian的MBean 168 20.8 应用程序 172

“相关推荐”对你有帮助么?

  • 非常没帮助
  • 没帮助
  • 一般
  • 有帮助
  • 非常有帮助
提交
评论
添加红包

请填写红包祝福语或标题

红包个数最小为10个

红包金额最低5元

当前余额3.43前往充值 >
需支付:10.00
成就一亿技术人!
领取后你会自动成为博主和红包主的粉丝 规则
hope_wisdom
发出的红包
实付
使用余额支付
点击重新获取
扫码支付
钱包余额 0

抵扣说明:

1.余额是钱包充值的虚拟货币,按照1:1的比例进行支付金额的抵扣。
2.余额无法直接购买下载,可以购买VIP、付费专栏及课程。

余额充值