Host和Engine容器

Context容器的父容器通常是Host容器。 
Engine容器表示Catalina的整个servlet引擎。如果使用Engine容器,那么它总是处于容器层级的最顶层。默认情况下,Tomcat会使用Engine容器,并且有一个Host容器作为子容器。

Host接口继承Container接口

public interface Host extends Container {
...
}

StandardHost类继承ContainerBase并且实现Host接口,与StandardContext和StandardWrapper类相似,StandardHost类会在构造方法会设置一个基础阀门添加到管道中。

public StandardHost() {
super();
pipeline.setBasic(new StandardHostValve());
}

StandardHostValve类也和StandardContext,StandardWrapper相似,实现了一个invoke方法,基于具体的请求路径,选择合适的子容器处理请求,如果没有匹配的,则返回Http error。

public final void invoke(Request request, Response response)
throws IOException, ServletException { // Select the Context to be used for this Request
Context context = request.getContext();
if (context == null) {
response.sendError
(HttpServletResponse.SC_INTERNAL_SERVER_ERROR,
sm.getString("standardHost.noContext"));
return;
} // Bind the context CL to the current thread
if( context.getLoader() != null ) {
// Not started - it should check for availability first
// This should eventually move to Engine, it's generic.
if (Globals.IS_SECURITY_ENABLED) {
PrivilegedAction<Void> pa = new PrivilegedSetTccl(
context.getLoader().getClassLoader());
AccessController.doPrivileged(pa);
} else {
Thread.currentThread().setContextClassLoader
(context.getLoader().getClassLoader());
}
}
if (request.isAsyncSupported()) {
request.setAsyncSupported(context.getPipeline().isAsyncSupported());
} boolean asyncAtStart = request.isAsync();
boolean asyncDispatching = request.isAsyncDispatching();
if (asyncAtStart || context.fireRequestInitEvent(request)) { // Ask this Context to process this request. Requests that are in
// async mode and are not being dispatched to this resource must be
// in error and have been routed here to check for application
// defined error pages.
try {
if (!asyncAtStart || asyncDispatching) {
context.getPipeline().getFirst().invoke(request, response);
} else {
// Make sure this request/response is here because an error
// report is required.
if (!response.isErrorReportRequired()) {
throw new IllegalStateException(sm.getString("standardHost.asyncStateError"));
}
}
} catch (Throwable t) {
ExceptionUtils.handleThrowable(t);
// If a new error occurred while trying to report a previous
// error simply log the new error and allow the original error
// to be reported.
if (response.isErrorReportRequired()) {
container.getLogger().error("Exception Processing " +
request.getRequestURI(), t);
} else {
request.setAttribute(RequestDispatcher.ERROR_EXCEPTION, t);
throwable(request, response, t);
}
} // Now that the request/response pair is back under container
// control lift the suspension so that the error handling can
// complete and/or the container can flush any remaining data
response.setSuspended(false); Throwable t = (Throwable) request.getAttribute(RequestDispatcher.ERROR_EXCEPTION); // Protect against NPEs if the context was destroyed during a
// long running request.
if (!context.getState().isAvailable()) {
return;
} // Look for (and render if found) an application level error page
if (response.isErrorReportRequired()) {
if (t != null) {
throwable(request, response, t);
} else {
status(request, response);
}
} if (!request.isAsync() && (!asyncAtStart || !response.isErrorReportRequired())) {
context.fireRequestDestroyEvent(request);
}
} // Access a session (if present) to update last accessed time, based on a
// strict interpretation of the specification
if (ACCESS_SESSION) {
request.getSession(false);
} // Restore the context classloader
if (Globals.IS_SECURITY_ENABLED) {
PrivilegedAction<Void> pa = new PrivilegedSetTccl(
StandardHostValve.class.getClassLoader());
AccessController.doPrivileged(pa);
} else {
Thread.currentThread().setContextClassLoader
(StandardHostValve.class.getClassLoader());
}
}

ContextConfig类 
主要加载一些配置属性 
web.xml的加载

/**
* Identify the application web.xml to be used and obtain an input source
* for it.
*/
protected InputSource getContextWebXmlSource() {
InputStream stream = null;
InputSource source = null;
URL url = null; String altDDName = null; // Open the application web.xml file, if it exists
ServletContext servletContext = context.getServletContext();
if (servletContext != null) {
altDDName = (String)servletContext.getAttribute(
Globals.ALT_DD_ATTR);
if (altDDName != null) {
try {
stream = new FileInputStream(altDDName);
url = new File(altDDName).toURI().toURL();
} catch (FileNotFoundException e) {
log.error(sm.getString("contextConfig.altDDNotFound",
altDDName));
} catch (MalformedURLException e) {
log.error(sm.getString("contextConfig.applicationUrl"));
}
}
else {
stream = servletContext.getResourceAsStream
(Constants.ApplicationWebXml);
try {
url = servletContext.getResource(
Constants.ApplicationWebXml);
} catch (MalformedURLException e) {
log.error(sm.getString("contextConfig.applicationUrl"));
}
}
}
if (stream == null || url == null) {
if (log.isDebugEnabled()) {
log.debug(sm.getString("contextConfig.applicationMissing") + " " + context);
}
} else {
source = new InputSource(url.toExternalForm());
source.setByteStream(stream);
}
return source;
}
//常量类
public final class Constants{
...
public static final String ApplicationWebXml = "/WEB-INF/web.xml";
...
}

Tomcat学习笔记(十二)的更多相关文章

  1. python3.4学习笔记(十二) python正则表达式的使用,使用pyspider匹配输出带.html结尾的URL

    python3.4学习笔记(十二) python正则表达式的使用,使用pyspider匹配输出带.html结尾的URL实战例子:使用pyspider匹配输出带.html结尾的URL:@config(a ...

  2. Go语言学习笔记十二: 范围(Range)

    Go语言学习笔记十二: 范围(Range) rang这个关键字主要用来遍历数组,切片,通道或Map.在数组和切片中返回索引值,在Map中返回key. 这个特别像python的方式.不过写法上比较怪异使 ...

  3. java jvm学习笔记十二(访问控制器的栈校验机制)

    欢迎装载请说明出处:http://blog.csdn.net/yfqnihao 本节源码:http://download.csdn.net/detail/yfqnihao/4863854 这一节,我们 ...

  4. (C/C++学习笔记) 十二. 指针

    十二. 指针 ● 基本概念 位系统下为4字节(8位十六进制数),在64位系统下为8字节(16位十六进制数) 进制表示的, 内存地址不占用内存空间 指针本身是一种数据类型, 它可以指向int, char ...

  5. Python学习笔记(十二)—Python3中pip包管理工具的安装【转】

    本文转载自:https://blog.csdn.net/sinat_14849739/article/details/79101529 版权声明:本文为博主原创文章,未经博主允许不得转载. https ...

  6. ROS学习笔记十二:使用gazebo在ROS中仿真

    想要在ROS系统中对我们的机器人进行仿真,需要使用gazebo. gazebo是一种适用于复杂室内多机器人和室外环境的仿真环境.它能够在三维环境中对多个机器人.传感器及物体进行仿真,产生实际传感器反馈 ...

  7. JavaScript权威设计--命名空间,函数,闭包(简要学习笔记十二)

    1.作为命名空间的函数 有时候我们需要声明很多变量.这样的变量会污染全局变量并且可能与别人声明的变量产生冲突. 这时.解决办法是将代码放入一个函数中,然后调用这个函数.这样全局变量就变成了 局部变量. ...

  8. MySQL学习笔记十二:数据备份与恢复

    数据备份 1.物理备份与逻辑备份 物理备份 物理备份就是将数据库的数据文件,配置文件,日志文件等复制一份到其他路径上,这种备份速度一般较快,因为只有I/O操作.进行物理备份时,一般都需要关闭mysql ...

  9. Java基础学习笔记十二 类、抽象类、接口作为方法参数和返回值以及常用API

    不同修饰符使用细节 常用来修饰类.方法.变量的修饰符 public 权限修饰符,公共访问, 类,方法,成员变量 protected 权限修饰符,受保护访问, 方法,成员变量 默认什么也不写 也是一种权 ...

随机推荐

  1. PHP 基础知识总结

    PHP 代表 PHP: Hypertext Preprocessor PHP 文件可包含文本.HTML.JavaScript代码和 PHP 代码 PHP 代码在服务器上执行,结果以纯 HTML 形式返 ...

  2. rootfls(根操作系统)

    rootfs根文件系统,linux下的任何目录都是rootfs的一个路径 Files 文件 Directory   目录 FHS(文件层级标准)规定了linux发行标准,也就是一些固定的文件存储 文件 ...

  3. P1582倒水 位运算

    题目描述 一天,CC买了N个容量可以认为是无限大的瓶子,开始时每个瓶子里有1升水.接着~~CC发现瓶子实在太多了,于是他决定保留不超过K个瓶子.每次他选择两个当前含水量相同的瓶子,把一个瓶子的水全部倒 ...

  4. 通过aop添加日志管理

    1.使用spring 的 aop 技术切到自定义注解上,所以先创建一个自定义注解类 import java.lang.annotation.*; @Target(ElementType.METHOD) ...

  5. easyui js拼接html,class属性失效的问题

    问题:要在前一个按钮之后添加相同的样式的按钮,通过$("#cj").html(str); 这样的形式添加,却不能添加上样式 <div id="btn" c ...

  6. Web安全1&沙箱隔离

    1.web安全 Web安全的本质是信任问题 •由于信任,正常处理用户恶意的输入导致问题的产生 •非预期的输入(就是不是程序员预期的客户的输入) 安全是木桶原理,短的那块板决定的木桶世纪能装多少水,同样 ...

  7. Java的接口和抽象类深入理解

    对于面向对象编程来说,抽象是它的一大特征之一.在Java中,可以通过两种形式来体现OOP的抽象:接口和抽象类.这两者确实有很多相似的地方,看了一整天别人怎么说,大致总结如下: 一.抽象类 在了解抽象类 ...

  8. Server Message Block

    Question: Server Message Block文件共享存储虚拟机的优势是什么? Answer:微软在Windows Server 2012和Hyper-V 3.0中引进了SMB文件共享存 ...

  9. MySQL 5.7.18 压缩包版配置记录

    1.解压到一个目录(建议根目录),比如:D:\mysql2.在系统Path中添加 D:\mysql\bin3.这个版本不带my-default.ini,需要自己写,放在D:\mysql\my.ini, ...

  10. 《Cracking the Coding Interview》——第2章:链表——题目7

    2014-03-18 02:57 题目:检查链表是否是回文的,即是否中心对称. 解法:我的做法是将链表从中间对半拆成两条,然后把后半条反转,再与前半条对比.对比完了再将后半条反转了拼回去.这样不涉及额 ...