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. selenium学习总结

    selenium主要用来做web自动化,分1.0和2.0两个版本,1.0包括selenium IDE.selenium Grid.selenium Remote Control,2.0在1.0的基础上 ...

  2. 网页弹出[Object HTMLDivElement],怎么取值?

    使用innerHTML方法,可以得到文本值

  3. 你们知道SEO每天都在做什么吗?

    医院也有做SEO的,专门负责医院网站优化工作,那么医院的SEO每天都做什么呢?偶然见到一篇文章,转载来分享给大家.感觉写的很实在. 大凡做seo工作的人都知道seo工作者每天都要做大量的外链,像有些个 ...

  4. 深入理解PHP7之zval

    PHP7已经发布, 如承诺, 我也要开始这个系列的文章的编写, 今天我想先和大家聊聊zval的变化. 在讲zval变化的之前我们先来看看zval在PHP5下面是什么样子 PHP5zval回顾在PHP5 ...

  5. yarn 无法下载node-sass

    指定node-sass的下载源 yarn config set sass-binary-site http://npm.taobao.org/mirrors/node-sass

  6. PHP脚本执行效率性能检测之WebGrind的使用

    webgrind这个性能检测是需要xdebug来配合,因为webgrind 进行性能检测分析就是通过xdebug生成的日志文件进行编译分析的 那么这就需要们配置好xdebug,这个一般的php 版本都 ...

  7. 学习Pytbon第十七篇,面向对象编程

    面向对象技术简介 类(Class): 用来描述具有相同的属性和方法的对象的集合.它定义了该集合中每个对象所共有的属性和方法.对象是类的实例. 类变量:类变量在整个实例化的对象中是公用的.类变量定义在类 ...

  8. 493. Reverse Pairs

    // see more at https://www.youtube.com/watch?v=j68OXAMlTM4 // https://leetcode.com/problems/reverse- ...

  9. ABAP自定义截取字符串长度函数

    SAP 中strlen()只能计算字符串的个数,不能计算含有中文字符串的长度,如字符串“SAP大波霸”,strlen('SAP大波霸') = 6,其实真实长度为3+3*2 = 9.我们可以通过cl_a ...

  10. Android 内嵌 HTML5 并进行交互

    Android与HTML5的交互主要是两个部分, 与HTML5的交互以及与JavaScript的交互, 与HTML5的交互可以通过注册onclick事件转化为与JavaScript的交互 Androi ...