在tomcat4中,StandardContext.java是最大的一个类,有117k。废话不说,开始分析吧。

其实要分析StandardContext,也就主要分析两个方法,一个start,一个invoke。

两个变量

这里首先咱们得说两个boolean型的变量available,configured。

先说available,它表示了StandardContext是否可用,初始值为false。若StandardContext启动成功,其值就变为true;另外各种原因都会导致StandardContext启动失败,这个时候available就是false。

configured,表明configured是否正确配置。与available不同的是,对configured这个参数我们采用了观察者模式。

public class SimpleContextConfig implements LifecycleListener {

  public void lifecycleEvent(LifecycleEvent event) {
    if (Lifecycle.START_EVENT.equals(event.getType())) {
      Context context = (Context) event.getLifecycle();
      context.setConfigured(true);
    }
  }
}

在StandardContext配置完成后调用

lifecycle.fireLifecycleEvent(START_EVENT, null);



不过为什么configured使用了观察者模式,而available没有用呢?

start方法

1 lifecycle.fireLifecycleEvent(BEFORE_START_EVENT, null); 触发BEFORE_START_EVENT事件

2 设置available与configured的值为false;

        setAvailable(false);
        setConfigured(false);

3 配置资源  (这部分我也不是太懂)

4 配置载入器  setLoader(new WebappLoader(getParentClassLoader()));

5 配置Session  setManager(new StandardManager());

6 初始化字符集映射器  getCharsetMapper(); 这里面的详细代码我也没有研究过

7 启动load,loger,mapper

        ((Lifecycle) loader).start();
                ((Lifecycle) logger).start();
        ((Lifecycle) mappers[i]).start();

8 启动子容器

                Container children[] = findChildren();
                for (int i = 0; i < children.length; i++) {
                    if (children[i] instanceof Lifecycle)
                        ((Lifecycle) children[i]).start();
                }

9 启动管道

                if (pipeline instanceof Lifecycle)
                    ((Lifecycle) pipeline).start();

10 触发START_EVENT,注意呀 观察者模式,SimpleContextConfig, configured会被设置为true

                // Notify our interested LifecycleListeners
                // 会调用SimpleContextConfig的lifecycleEvent
                lifecycle.fireLifecycleEvent(START_EVENT, null);

11 启动session

                //session部分
                if ((manager != null) && (manager instanceof Lifecycle))
                    ((Lifecycle) manager).start();

12 (书上说)检查confired的值,postWelcomeFiles会载入需要提前载入的子容器,StandardContext的子容器能有什么?StandardWrapper呗。

    if (!getConfigured())
            ok = false;
        if (ok) {
            postWelcomeFiles();
        }

问题是加载需要提前载入的子容器是

 loadOnStartup(findChildren());这行代码干的事呀。至于postWelcomeFiles倒像是设定什么属性。

 如果confired为false就调用stop();

    if (ok) {
            setAvailable(true);
        } else {
            try {
                stop();
            } catch (Throwable t) {
                log(sm.getString("standardContext.startCleanup"), t);
            }
            setAvailable(false);
        }

stop里面具体的代码就不说了。

 13 触发AFTER_START_EVENT事件 lifecycle.fireLifecycleEvent(AFTER_START_EVENT, null);

invoke方法

StandardContext的invoke方法会在两种情况下被调用。至于有哪两种自己想。

首先会检查程序是否正在重载:

        while (getPaused()) {        //getPaused如果返回true 就说明正在重载
            try {
                Thread.sleep(1000);
            } catch (InterruptedException e) {
                ;
            }
        }

然后调用父类,也就是ContainerBase的invoke

super.invoke(request, response);

在 Tomcat5 中,StandardContext 并没有提供 invoke 方法的实现,因此它会执行 ContainerBase 的 invoke 方法。检查应用程序加载的任务在StandardContextValve 类的 invoke 方法中完成。

StandardContextMapper类

上面到StandardContextValve类的invoke 方法,接着就是调用管道的invoke,然后基础阀的invoke(基础阀是哪个类,什么时候注入的,还记的吗)

基础阀干的事情就是获得Wrapper

        Context context = (Context) getContainer();
        wrapper = (Wrapper) context.map(request, true);

接着在ContainerBase的map中先获得相应协议(http还是https)的映射器,再用映射器的map方法根据request的uri获得Wrapper。

根据uri获得Wrapper就是应用一系列的匹配规则获得Wrapper。

你可能会问,上下文容器时如何获得 Servlet 映射的?看Bootstrap。



现在就有几个问题了,生产映射器哪家强?映射器从哪里来?

来,听本座给你一一道来..

在StandardContext的start方法中

调用了

addDefaultMapper(this.mapperClass); //private String mapperClass = "org.apache.catalina.core.StandardContextMapper";

StandardContext会调用父类的addDefaultMapper。这里面,默认的协议是http

            Class<?> clazz = Class.forName(mapperClass);
            Mapper mapper = (Mapper) clazz.newInstance();
            mapper.setProtocol("http");
            addMapper(mapper);

在addMapper中

        mapper.setContainer((Container) this);  

可见映射器与容器是双向关联的。(并且只能与Context级别的容器关联)

为什么?单向关联不行么?

(某个协议下的)映射器根据uri返回相应的Wrapper,如何映射器"不知道"Context容器,它怎么查找众多的子容器?用for循环么?

所有的子容器是存放在ContainerBase中的

protected HashMap<String, Container> children = new HashMap<String, Container>();





这一节就先到这里,下面我们在说tomcat4对重载的支持和在Tomcat5中的backgroundProcess方法。

How tomcat works 读书笔记十二 StandardContext 上的更多相关文章

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

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

  2. How tomcat works 读书笔记十五 Digester库 下

    在这一节里我们说说ContextConfig这个类. 这个类在很早的时候我们就已经使用了(之前那个叫SimpleContextConfig),但是在之前它干的事情都很简单,就是吧context里的co ...

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

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

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

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

  5. How Tomcat Works 读书笔记 八 载入器 上

    Java的类载入器 详细资料见 http://blog.csdn.net/dlf123321/article/details/39957175 http://blog.csdn.net/dlf1233 ...

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

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

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

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

  8. 《深入理解Java虚拟机》读书笔记十二

    第十二章  Java内存模型与线程 1.硬件效率与一致性 由于计算机的存储设备与处理器的运算速度有几个数量级的差距,所以现代计算机系统都不得不加入一层读写速度尽可能接近处理器运算速度的高速缓存(Cac ...

  9. 《深入剖析Tomcat》读书笔记(二)

    三.容器Container Container 是容器的父接口,所有子容器都必须实现这个接口.Container 容器的设计用的是典型的责任链的设计模式,它有四个子容器组件构成,分别是:Engine. ...

随机推荐

  1. ListView嵌套GridView

    首先,我们通过两个实例来了解下本篇文章所讲的重点,看下图: 微博: 陌陌: 大家应该对这两款软件并不陌生,接下来,我将列举下本文将要实现的几个点: 1.ListView嵌套GridView,互不冲突, ...

  2. 【移动开发】 Android隐藏输入法软键盘的一些说明

    刚刚在写一个仿微信的Android聊天软件,在编写的过程中,发现一个严重的BUG---当用户点击输入框用软键盘输入文本的时候点击了"返回好友列表"的按钮,返回到好友列表时软键盘无法 ...

  3. Dynamics CRM2016 Supported versions of Internet Explorer and Microsoft Edge

    在CRM2016发布在即之时,让咱们看下新版的CRM对IE及Edge的支持 这次和以往不同,官方给出的不只是IE几以上支持,IE几以下不支持,而是有一个对应的系统列表,具体看下表. 当然你也可以说我I ...

  4. Dynamics CRM2013/2015 检索实体属性的两种方式

    昨天有朋友问起如何查询一个字段属性是否存在于某个实体中,一般这个问题我们会采取最直观的查询方式即MetadataBrowser,该工具是一个zip解决方案包在SDK中的如下目录内"\SDK\ ...

  5. Android JavascriptBridge 详解(二)

    原文出自:http://blog.csdn.net/sk719887916/article/details/47189607 Android开发目前现状来说,开发者大部分时间花在UI的屏幕适配上,使用 ...

  6. Servlet之Request对象

    下面的方法可用在 Servlet 程序中读取 HTTP 头.这些方法通过HttpServletRequest 对象可用. 1    Cookie[] getCookies() 返回一个数组,包含客户端 ...

  7. 04springMVC结构,mvc模式,spring-mvc流程,spring-mvc的第一个例子,三种handlerMapping,几种控制器,springmvc基于注解的开发,文件上传,拦截器,s

     1. Spring-mvc介绍 1.1市面上流行的框架 Struts2(比较多) Springmvc(比较多而且属于上升的趋势) Struts1(即将被淘汰) 其他 1.2  spring-mv ...

  8. 最简单的基于FFmpeg的视频编码器-更新版(YUV编码为HEVC(H.265))

    ===================================================== 最简单的基于FFmpeg的视频编码器文章列表: 最简单的基于FFMPEG的视频编码器(YUV ...

  9. Axure如何建立共享项目、如何编辑共享项目、如何获取共享项目

    如果小伙伴是一名编程工作者,我们不可以避免的会和Axure这块软件握手,但是但一个项目需要协同操作的时候,就需要用到项目共享的功能.类似我们的svn,想起机房合作的时候,每天早上来到427的我们,打开 ...

  10. SimpleDateFormat用法大全及易错分析

    SimpleDateFormat 使用java语言处理日期相关操作,就不可避免的会使用到SimpleDateFormat.当然了,目前我们采用较多的是Calendar类,通过对之求相关的属性值即可得到 ...