How tomcat works 读书笔记十五 Digester库 下
在这一节里我们说说ContextConfig这个类。
这个类在很早的时候我们就已经使用了(之前那个叫SimpleContextConfig),但是在之前它干的事情都很简单,就是吧context里的configured变量置为true。在这里我们看看完整版的ContextConfig都干了什么。
在tomcat的实际部署中,StandContext类的实际监听器是org.apache.catalina.startup.ContextConfig的实例。
ContextConfig完成加载验证器阀,许可阀到StandContext的管道阀中。但最重要的就是应用上一节的Digester库,解析两个xml文件。一个是整个tomcat的配置文件,web.xml,在conf目录下。另一个是单个web应用的xml文件,在WEB-INF目录下。
在这里我主要说说如何让系统根据我们在某个web应用下的web.xml里面指定的那样,自动创建StandWrapper。
LifecycleListener listener = new ContextConfig();
((Lifecycle) context).addLifecycleListener(listener);
首先得在StandContext里注入ContextConfig这个监听器。
在StandContext的启动与关闭中,会触发以下的事件:
START_ENENT
STOP_ENENT
ContextConfig.java
public void lifecycleEvent(LifecycleEvent event) {
...
// Process the event that has occurred
if (event.getType().equals(Lifecycle.START_EVENT))
start();
else if (event.getType().equals(Lifecycle.STOP_EVENT))
stop();
}
我们看看ContextConfig的start方法。
private synchronized void start() {
...
// Process the default and application web.xml files
defaultConfig(); //解析conf/xml.xml
applicationConfig(); //解析WEB-INF/web.xml
...
}
我们先不管整个tomcat的xml就看单个项目的:
private void applicationConfig() {
...
// Process the application web.xml file
synchronized (webDigester) {
//public static final String ApplicationWebXml = "/WEB-INF/web.xml";
URL url =servletContext.getResource(Constants.ApplicationWebXml);
InputSource is = new InputSource(url.toExternalForm());
is.setByteStream(stream);
webDigester.setDebug(getDebug());
if (context instanceof StandardContext) {
((StandardContext) context).setReplaceWelcomeFiles(true);
}
webDigester.clear();
webDigester.push(context);//此时的栈里面就有context了
webDigester.parse(is); //开始解析
}
...
}
现在的问题是,那webDigester是怎么来的?
在ContextConfig中有下面的一个类变量。
private static Digester webDigester = createWebDigester();
我们看看createWebDigester
private static Digester createWebDigester() {
...
Digester webDigester = new Digester();
...
webDigester.addRuleSet(new WebRuleSet()); //addRuleSet 对这个不清楚的看上一节
return (webDigester);
}
现在我们就要去看WebRuleSet类了,还记得主要看哪个方法吗?
WebRuleSet.java
public void addRuleInstances(Digester digester) {
....
digester.addRule(prefix + "web-app/servlet",new WrapperCreateRule(digester));
...
digester.addCallMethod(prefix + "web-app/servlet/servlet-class",
"setServletClass", 0);
digester.addCallMethod(prefix + "web-app/servlet/servlet-name",
"setName", 0);
digester.addCallMethod(prefix + "web-app/servlet-mapping",
"addServletMapping", 2);
//setServletClass这个方法最后在哪里调用的? 请大家自己想一想
}
final class WrapperCreateRule extends Rule {
public void begin(Attributes attributes) throws Exception {
Context context =(Context) digester.peek(digester.getCount() - 1);
Wrapper wrapper = context.createWrapper();
digester.push(wrapper);
if (digester.getDebug() > 0)
digester.log("new " + wrapper.getClass().getName());
}
}
大家看出流程了吗?
首先加入一个规则
digester.addRule(prefix + "web-app/servlet",new WrapperCreateRule(digester));
碰到web-app/servlet就调用begin方法,产生了一个wrapper。
web-app/servlet/servlet-name 碰到这个后,调用wrapper的那个方法就ok。
How tomcat works 读书笔记十五 Digester库 下的更多相关文章
- How tomcat works 读书笔记十五 Digester库 上
Digester库 在前面的几个章节里,我们对tomcat里各个组件的配置完全是使用写硬编码的形式完成的. 如 Context context = new StandardContext(); Loa ...
- How tomcat works 读书笔记十四 服务器组件和服务组件
之前的项目还是有些问题的,例如 1 只能有一个连接器,只能处理http请求,无法添加另外一个连接器用来处理https. 2 对容器的关闭只能是粗暴的关闭Bootstrap. 服务器组件 org.apa ...
- How tomcat works 读书笔记十二 StandardContext 下
对重载的支持 tomcat里容器对重载功能的支持是依靠Load的(在目前就是WebLoader).当在绑定载入器的容器时 public void setContainer(Container cont ...
- How tomcat works 读书笔记十二 StandardContext 上
在tomcat4中,StandardContext.java是最大的一个类,有117k.废话不说,开始分析吧. 其实要分析StandardContext,也就主要分析两个方法,一个start,一个in ...
- how tomcat works 读书笔记(二)----------一个简单的servlet容器
app1 (建议读者在看本章之前,先看how tomcat works 读书笔记(一)----------一个简单的web服务器 http://blog.csdn.net/dlf123321/arti ...
- how tomcat works 读书笔记四 tomcat的默认连接器
事实上在第三章,就已经有了连接器的样子了,只是那仅仅是一个学习工具,在这一章我们会開始分析tomcat4里面的默认连接器. 连接器 Tomcat连接器必须满足下面几个要求 1 实现org.apache ...
- how tomcat works读书笔记 七 日志记录器
大家可以松一口气了,这个组件比较简单,这一节和前面几节想比,也简单的多. Logger接口 Tomcat中的日志记录器都必须实现org.apache.catalina.Logger接口. packag ...
- How Tomcat Works读书笔记三-------连接器
几个概念 HttpServlet,Servlet Servlet是一个接口,定义了一种网络服务,我们所有的servlet都要实现它(或它的子类) HttpServlet是一个抽象类,它针对的就是htt ...
- How tomcat works 读书笔记十七 启动tomcat 上
一路跋山涉水,这是最后一章了. 关于tomcat的启动,有两个类,一个是Catalina类,一个是Bootstrap类. 理论上,两个类可以和到一起,但是为了支持多种运行模式,又把他们分开了. 为了让 ...
随机推荐
- 开发人员需要熟知的常用Linux命令Version、Kernel查看
当我们需要在Linux系统中安装一些软件而去下载安装文件时,一般都需要确认到底下载哪个版本的安装包,这就需要我们知道自己的Linux系统到底是什么版本.什么内核,常见的版本.内核查看命令或者文件有如下 ...
- Struts 2之Servlet API
Struts 2对Servlet API进行了封装,是业务层更加独立,如果需要调用Request.Response等Servlet API有两种途径 利用ServletActinContext的静态方 ...
- 1091. Acute Stroke (30)
题目如下: One important factor to identify acute stroke (急性脑卒中) is the volume of the stroke core. Given ...
- SYBASE的select into与insert into使用和区别
对于表的部分或全部字段的复制,Sybase数据库提供了两种方式:select into和insert into. select into: 语法:select value1, value2, val ...
- linux2.6内核链表
一. 链表数据结构简介 链表是一种常用的组织有序数据的数据结构,它通过指针将一系列数据节点连接成一条数据链,是线性表的一种重要实现方式.相对于数组,链表具有更好的动态性,建立链 ...
- Linux系统编程---守护进程
守护进程是什么?就是在后台运行的进程. 那么如何创建守护进程呢? 1. 创建孤儿进程 2. setsid() 创建进程会话 3. 重定向标准输入, 标准输出 4. chdir, 改当当前进程的工作目录 ...
- Android游戏开发之SurfaceView的使用-android学习之旅(五)
SurfaceView和View的区别 View是在ui主线程中,直接响应用户的操作,以及任务的分发,但是任务比较复杂会出现阻塞. SurfaceView则不会出现这种问题,以为它直接从内存等取得图像 ...
- 【一天一道Leetcode】#203.Remove Linked List Elements
一天一道LeetCode 本系列文章已全部上传至我的github,地址:ZeeCoder's Github 欢迎大家关注我的新浪微博,我的新浪微博 我的个人博客已创建,欢迎大家持续关注! 一天一道le ...
- iOS中 Realm的学习与使用 韩俊强的博客
每日更新关注:http://weibo.com/hanjunqiang 新浪微博! 有问题或技术交流可以咨询!欢迎加入! 这篇直接搬了一份官方文档过来看的 由于之前没用markdown搞的乱七八糟的 ...
- Mysql大量插入数据时SQL语句的优化
1) 对于Myisam类型的表,可以通过以下方式快速的导入大量的数据. ALTER TABLE tblname DISABLE KEYS; loading the data ALT ...