在这一节里我们说说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库 下的更多相关文章

  1. How tomcat works 读书笔记十五 Digester库 上

    Digester库 在前面的几个章节里,我们对tomcat里各个组件的配置完全是使用写硬编码的形式完成的. 如 Context context = new StandardContext(); Loa ...

  2. How tomcat works 读书笔记十四 服务器组件和服务组件

    之前的项目还是有些问题的,例如 1 只能有一个连接器,只能处理http请求,无法添加另外一个连接器用来处理https. 2 对容器的关闭只能是粗暴的关闭Bootstrap. 服务器组件 org.apa ...

  3. How tomcat works 读书笔记十二 StandardContext 下

    对重载的支持 tomcat里容器对重载功能的支持是依靠Load的(在目前就是WebLoader).当在绑定载入器的容器时 public void setContainer(Container cont ...

  4. How tomcat works 读书笔记十二 StandardContext 上

    在tomcat4中,StandardContext.java是最大的一个类,有117k.废话不说,开始分析吧. 其实要分析StandardContext,也就主要分析两个方法,一个start,一个in ...

  5. how tomcat works 读书笔记(二)----------一个简单的servlet容器

    app1 (建议读者在看本章之前,先看how tomcat works 读书笔记(一)----------一个简单的web服务器 http://blog.csdn.net/dlf123321/arti ...

  6. how tomcat works 读书笔记四 tomcat的默认连接器

    事实上在第三章,就已经有了连接器的样子了,只是那仅仅是一个学习工具,在这一章我们会開始分析tomcat4里面的默认连接器. 连接器 Tomcat连接器必须满足下面几个要求 1 实现org.apache ...

  7. how tomcat works读书笔记 七 日志记录器

    大家可以松一口气了,这个组件比较简单,这一节和前面几节想比,也简单的多. Logger接口 Tomcat中的日志记录器都必须实现org.apache.catalina.Logger接口. packag ...

  8. How Tomcat Works读书笔记三-------连接器

    几个概念 HttpServlet,Servlet Servlet是一个接口,定义了一种网络服务,我们所有的servlet都要实现它(或它的子类) HttpServlet是一个抽象类,它针对的就是htt ...

  9. How tomcat works 读书笔记十七 启动tomcat 上

    一路跋山涉水,这是最后一章了. 关于tomcat的启动,有两个类,一个是Catalina类,一个是Bootstrap类. 理论上,两个类可以和到一起,但是为了支持多种运行模式,又把他们分开了. 为了让 ...

随机推荐

  1. FFmpeg的HEVC解码器源代码简单分析:CTU解码(CTU Decode)部分-PU

    ===================================================== HEVC源代码分析文章列表: [解码 -libavcodec HEVC 解码器] FFmpe ...

  2. Nginx的负载均衡 - 加权轮询 (Weighted Round Robin) 上篇

    Nginx版本:1.9.1 我的博客:http://blog.csdn.net/zhangskd 算法介绍 来看一个简单的Nginx负载均衡配置. http { upstream cluster { ...

  3. maven的UnsupportedClassVersionError

    问题描述 我安装了maven3.3.3,配置好了M2_HOME和path环境变量之后,执行mvn -v报错:java.lang.UnsupportedClassVersionError: -. : U ...

  4. 如何将Provisioning Profile安装到开发的Mac系统上

    大熊猫猪·侯佩原创或翻译作品.欢迎转载,转载请注明出处. 如果觉得写的不好请多提意见,如果觉得不错请多多支持点赞.谢谢! hopy ;) 免责申明:本博客提供的所有翻译文章原稿均来自互联网,仅供学习交 ...

  5. Android的ToggleButton和Switch以及AnalogColok和DigitalColok的用法-android学习之旅(二十)

    ToggleButton 和Switch简介 ToggleButton 和Switch都是继承了Button,所以他们的属性设置和Button差不多. 分别支持的属性 ToggleButton 的属性 ...

  6. jsp中文乱码 Servlet中文乱码 utf-8

    JSP+Servlet项目中,项目统一使用utf-8编码.配置过滤器过滤所以请求并设置utf-8编码,jsp页面也都设置utf-8,但是还有一点很容易忽视的就是tomcat也要设置utf-8,默认情况 ...

  7. ROS(indigo)使用Qt Creator Plug in即ros_qtc_plugin

    更为详细版本请参考: http://blog.csdn.net/zhangrelay/article/details/52214411 结合看更为具体. 首先,先上原版参考: 1 http://wik ...

  8. iOS中 本地通知/本地通知详解 韩俊强的博客

    布局如下:(重点讲本地通知) iOS开发者交流QQ群: 446310206 每日更新关注:http://weibo.com/hanjunqiang  新浪微博 Notification是智能手机应用编 ...

  9. android 网络通信框架volly

    1. 什么是Volley 在这之前,我们在程序中需要和网络通信的时候,大体使用的东西莫过于AsyncTaskLoader,HttpURLConnection,AsyncTask,HTTPClient( ...

  10. 1033. To Fill or Not to Fill (25) -贪心算法

    题目如下: With highways available, driving a car from Hangzhou to any other city is easy. But since the ...