来源:http://diecui1202.iteye.com/blog/1037370

Context代表一个Web应用,它运行在某个指定的虚拟主机(Host)上;每个Web应用都是一个WAR文件,或是一个包含WAR解压后的文件的目录;

Connector组件接收到http请求后,通过将请求URI的最长可能前缀与每个Context的path进行匹配,然后选择相应的Web应用来处理这个http请求。之后,Context会根据web application deployment descriptor文件中定义的servlet映射,会选择一个正确的Servlet来处理请求。Servlet映射必须定义在该Web应用目录层次结构中的/WEB-INF/web.xml中。

一、几个重要的概念
1、context frgament file
Context片断文件,即描述Context配置的xml文件;它有三个层级:
a) Engine Scoped:适用于Engine下的所有Web应用程序,位于$CATALINA_BASE/conf/context.xml;
b) Host Scoped:适用于指定的Host组件下的应用程序,位于$CATALINA_BASE/[Engine]/[Host]/context.xml.default;
c) Web Application Scoped:代表一个独立的应用程序,它可以位于$CATALINA_BASE/[Engine]/[Host]/[ContextPath].xml或应用程序中的META-INF/context.xml;

对于应用程序中内嵌的context.xml文件,有两个局限性:
1) 当server.xml文件中的Host节点指定deployXML属性为false时,则会忽略Web应用程序内嵌的context.xml;
2) 内嵌的context.xml不能指定context path;
2、appBase、docBase&context path
a) appBase:Host组件中需要部署的应用的目录,如webapps;也可以指定绝对路径,将Web应用程序放在tomcat之外;
b) docBase:应用程序资源所有的路径;应用程序的资源包括HTML、CSS、JS、jar、class文件等,其中静态资源直接放在该docBase或其子目录下,jar文件放在WEB-INF/lib目录下,class文件则放在WEB-INF/classes目录下;
c) context path:唯一代表一个应用;

二、如何配置Context?
配置context有多种方式,如下:
1、将应用文件夹或war文件直接copy到tomcat的webapps目录下,这样tomcat启动的时候会将webapps目录下的文件夹或war文件的内容当成应用部署。这种方式最简单且无须书写任何配置文件。
2、在tomcat的server.xml配置文件中的Host节点下增加Context子节点,如:

  1. <Context path="/test" docBase="D:\private\tomcat\test.war" />
<Context path="/test" docBase="D:\private\tomcat\test.war" />

其中,path即context path;docBase指向应用所在的文件夹或war文件,可以是绝对路径,也可以是相对路径(相对该Context所在的Host的appBase属性值);
3、在tomcat的conf/[Engine]/[Host]目录下新建xml文件,文件名为context path,内容如下:

  1. <Context docBase="D:\private\tomcat\test.war"
  2. privileged="true" antiResourceLocking="false" antiJARLocking="false">
  • <!-- Link to the user database we will get roles from -->
  • <ResourceLink name="users" global="UserDatabase"
  • type="org.apache.catalina.UserDatabase"/>
  • </Context>
<Context docBase="D:\private\tomcat\test.war"
privileged="true" antiResourceLocking="false" antiJARLocking="false">
<!-- Link to the user database we will get roles from -->
<ResourceLink name="users" global="UserDatabase"
type="org.apache.catalina.UserDatabase"/>
</Context>

其中,docBase与第二种方式中的含义一样;

当Host的autoDeploy属性值为true时,以上三种配置Context的方式中,只有第1、3两种方式配置署的应用不需要重启tomcat即可完成部署;第二种方式需要重启tomcat;另外,第1种方式不能指定特定的context path;

三、启动Context
在《Tomcat Host组件》这篇文档中提到,应用的部署是由HostConfig完成的;Host组件在初始化过程中会扫描三种不同类型的应用:context.xml描述文件、war包、文件夹;对于直接通过修改server.xml文件来配置的应用(上一节中的第2种场景),则是在启动tomcat解析server.xml文件时根据Context子节点来构造相应的应用;

不管是哪种方式配置Context(context.xml描述文件、war包、文件夹、配置server.xml的Context节点),最终都是构造出一个StandardContext实例,并将其作为子容器添加到Host组件中;与Host组件类似,在构造StandardContext实例时,会为每个StandardContext对象构造一个ContextConfig实例,该ContextConfig实例实现了LifecycleListener接口,它会监听StandardContext实例的各个生命周期事件,并针对不同的事件做出不同的响应;

当StandardContext实例以子容器被添加到Host组件中时,会触发StandardContext实例的start()方法,至此Context工作由此展开:
1、Context初始化和启动
Context初始化时,主要会触发init事件,并通过ContextConfig来完成初始化工作;
Context启动时主要完成如下事情:
a) 触发before_start事件来处理文件锁的问题(见下一小节before_start事件);
b) 根据docBase是war包还是文件夹,初始化应用程序资源的访问对象;
c) 初始化context特定的classloader:WebappLoader;
d) 计算work directory并初始化ServletContext:tomcat会为每个Context生成一个work directory,位于$CATALINA_BASE/work/[Engine]/[Host]目录下,work directory目录名根据context path而来(将“/”转换为“_”);work directory目录用于存放由jsp生成的servlet的class文件;
e) 启动内嵌组件,如Loader等;
f) 触发start事件来解析web应用描述符文件:如Servlet配置、Filter配置、Listener配置、session-timeout、welcome-file以及servlet参数等;
g) 启动Listerer;
h) 根据backgroundProcessorDelay决定是否需要开启后台线程:该后台线程可以用于管理session超时、监听类的变化来决定是否需要重启Context;当Context的reloadable属性为true时,如果应用程序的资源发生变化时,会通过backgroundProcess()来完成应用的重启;
i) 根据Servlet配置的loadOnStartup参数及大小顺序决定是否需要初始化Servlet及其初始化顺序;
2、ContextConfig事件处理
a) init事件
ContextConfig在处理init事件时,主要工作是:
1) 实例化了两个Digester类,分别为webDigester和contextDigester;webDigester用于解析web.xml配置文件,contextDigester用于解析前面提到的三个层级的context fragment file;在解析context fragment file时,主要的工作是解析内嵌元素,如Listener, Loader, Manager, Parameter, Resources, Valve以及WatchedResource,并将它们设置到该Context对应的属性上;;
2) 调整docBase属性值(即应用程序资源所在的位置):

  • 在配置Context时如果没有指定docBase,则根据context path计算得出(“/”会替换成“#”,空会替换成ROOT),并转化为绝对路径;
  • 根据Host中配置的unpackWARs属性,决定是否将配置在tomcat之外的war包解压到appBase下,并以context path为目录名(“/”会替换成“#”);此时docBase指向解压后的文件夹;如果的unpackWARs为false,则不会自动解压,此时docBase不变;

用流程图来表述如下:

b) before_start事件
在该过程中,主要是针对反文件锁做了一定的处理;在windows下,当ClassLoader加载类时,会打开相应的jar包,此时该jar包会被锁定,是不能被删除的;在tomcat中,当Context的antiResourceLocking设置为true时,如果删掉应用程序的war包时,对应的文件夹也会被删除,这是怎么做到的呢?
很简单,把应用程序的资源拷贝到一个临时的目录,然后将docBase指向该临时目录,这样锁定的都是副本;
c) start事件
当start事件发生时,ContextConfig会针对该Context完成如下工作:
1) 解析应用程序描述符:
   a) $CATALINA_BASE/conf/web.xml:作用于所有的Web应用程序;
   b) $CATALINA_BASE/conf/[Engine]/[Host]]/web.xml.default:作用于指定Host下的所有Web应用程序;
   c) WEB-INF/web.xml:仅作用于当前Web应用程序;
2) 新版本中增加了对Listener、Filter、Servlet注解的支持;
3) 对web.xml里设置的一些roles进行一些简单的校验,,然后全部放到context持有的字符串数组securityRoles中;(这块没有仔细研究过,熟悉的同学可以解释一下);
4) 根据web.xml里配置的login-config等权限安全访问来确定是否为本context配置一个用于确定访问权限的Valve;如果需要,则通过addValve添加到pipeline中;
d) destroy事件
在Context需要reload时,会触发destory事件,此时则会将该Context的work directory目录删除;
e) stop事件
此时会清除所有与Context相关的配置,如子容器、从web.xml读取的配置信息(如Listener、Filter、Servlet等);

四、Context对请求的处理
Context在初始化时,会创建StandardContextValve的实例并加入pipeline中;Host组件在接收到请求后,会调用以下方法将请求转交给Context来处理:

  1. context.getPipeline().getFirst().invoke(request, response);
context.getPipeline().getFirst().invoke(request, response);

也就是会调用StandardContextValve的invoke方法,其具体流程如下:
1、先检查所请求的资源是否是保护资源,如果是,则直接返回客户端“资源不存在”(404);
2、如果应用在reload,则sleep 1s;此处是通过忙等待实现;同时用新的WebappLoader替换当前的ClassLoader;
3、如果找不到该请求对应的Wrapper(Servlet),则同样返回404;
4、触发ServletRequestListener的requestInitialized()方法;
5、将请求交由wrapper进行处理;

  1. wrapper.getPipeline().getFirst().invoke(request, response);
wrapper.getPipeline().getFirst().invoke(request, response);

6、wrapper处理完后,再触发发ServletRequestListener的requestDestroyed()方法;

Tomcat Context 组件介绍(转载)的更多相关文章

  1. Tomcat负载均衡、调优核心应用进阶学习笔记(一):tomcat文件目录、页面、架构组件详解、tomcat运行方式、组件介绍、tomcat管理

    文章目录 tomcat文件目录 bin conf lib logs temp webapps work 页面 架构组件详解 tomcat运行方式 组件介绍 tomcat管理 tomcat文件目录 ➜ ...

  2. Tomcat 组件介绍

    用了好长时间tomcat,但是其实自己只是反复听了这个名字,对Tomcat并不了解 1.Tomcat组件 Catalina Coyote Jasper Cluster 2.组件介绍 Tomcat Co ...

  3. NET平台开源项目速览(6)FluentValidation验证组件介绍与入门(转载)

    原文地址:http://www.cnblogs.com/asxinyu/p/dotnet_Opensource_project_FluentValidation_1.html 阅读目录 1.基本介绍 ...

  4. 深入理解NIO(一)—— NIO的简单使用及其三大组件介绍

    深入理解NIO(一)—— NIO的简单使用及其三大组件介绍 深入理解NIO系列分为四个部分 第一个部分也就是本节为NIO的简单使用(我很少写这种新手教程,所以如果你是复习还好,应该不难理解这篇,但如果 ...

  5. 免费开源的DotNet任务调度组件Quartz.NET(.NET组件介绍之五)

    很多的软件项目中都会使用到定时任务.定时轮询数据库同步,定时邮件通知等功能..NET Framework具有“内置”定时器功能,通过System.Timers.Timer类.在使用Timer类需要面对 ...

  6. Android四大基本组件介绍与生命周期

    Android四大基本组件介绍与生命周期 Android四大基本组件分别是Activity,Service服务,Content Provider内容提供者,BroadcastReceiver广播接收器 ...

  7. Android应用的基本组件介绍和签名Android应用程序

    一.Android应用的基本组件介绍  Activity和View :Activity只能通过setContentView(View)来显示指定的组件.View组件是所有UI控件.容器控件的基类,Vi ...

  8. Android官方架构组件介绍之LifeCycle

    Google 2017 I/O开发者大会于近日召开,在开发者大会上谷歌除了发布了Android O等一些新产品之外,也对Android代码的架构做出了一个官方的回应. Google 2017 I/O开 ...

  9. Tomcat基本组件、其功能和处理请求的过程

      一.Tomcat是一个基于组件的服务器,它的构成组件都是可配置的,其中最外层的组件是Catalina Servlet容器,其他的组件按照一定的格式要求配置在这个顶层容器中 Tomcat的各个组件是 ...

随机推荐

  1. win install pip

    在windows下,我们使用python时,常常因为找不到需要的pthon模块,导致一些脚本不能正常执行,这时候可以安装pip工具,使用它来管理安装python所需要的模块: pip install ...

  2. Java 学习(2):java 基础概念

    Java作为一种面向对象语言.支持以下基本概念: 多态 继承 封装 抽象 类 对象 实例 方法 重载 基础语法: 一个Java程序可以认为是一系列对象的集合,而这些对象通过调用彼此的方法来协同工作.以 ...

  3. 2-sat 问题 【例题 Flags(2-sat+线段树优化建图)】

    序: 模拟赛考了一道 2-sat 问题.之前从来没听过…… 考完才发现其实这个东东只要一个小小的 tarjan 求强连通分量就搞定了. 这个方法真是巧妙啊,拿来讲讲. What is it? [・_・ ...

  4. 【BZOJ3524】Couriers(主席树)

    题意:给一个长度为n的序列a.1≤a[i]≤n.m组询问,每次询问一个区间[l,r],是否存在一个数在[l,r]中出现的次数大于(r-l+1)/2.如果存在,输出这个数,否则输出0. n,m≤5000 ...

  5. net1:DateTime,Application与Session,

    原文发布时间为:2008-07-29 -- 来源于本人的百度文章 [由搬家工具导入] using System;using System.Data;using System.Configuration ...

  6. webRTC windows demo1(转)

    // setup video engine char cCameraName[MAX_CAMERA_NAME_LENGTH]; memset(cCameraName, , MAX_CAMERA_NAM ...

  7. 关于unity3d插件的自动打包

    开发中,迩可能会遇到在xcode里添加一些需要调用原生api的方法,可能是game center,可能是内购之类的,但是这些插件实在太多了,所以迩大可不必自己写这些插件,问题在于,国内的一些插件,像9 ...

  8. LeetCode OJ——Longest Valid Parentheses

    http://oj.leetcode.com/problems/longest-valid-parentheses/ 最大括号匹配长度,括号是可以嵌套的 #include <string> ...

  9. 一个页面多个ng-app注意事项

    1.一个页面会自动加载第一个ng-app 2.如果想启动其它ng-app,需要通过下列代码的红色部分来启动,此时一共启动了2个ng-app 3.特别注意:代码红色部分一定要放在最后,比如,不能放在蓝色 ...

  10. codevs——2181 田忌赛马

    2181 田忌赛马  时间限制: 1 s  空间限制: 32000 KB  题目等级 : 钻石 Diamond 题解       题目描述 Description 中国古代的历史故事“田忌赛马”是为大 ...