对重载的支持

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

    public void setContainer(Container container) {
              ...
        // Register with the new Container (if any)
        if ((this.container != null) && (this.container instanceof Context)) {
            setReloadable( ((Context) this.container).getReloadable() );
            ((Context) this.container).addPropertyChangeListener(this);
        }
    }

可见载入器的reloadable与它所绑定的容器的reloadable是一致的。

我们再看看载入器的setReloadable

 public void setReloadable(boolean reloadable) {

        // Process this property change
        boolean oldReloadable = this.reloadable;
        this.reloadable = reloadable;
      ....
        if (!started)
            return;
        if (!oldReloadable && this.reloadable)  //
            threadStart();
        else if (oldReloadable && !this.reloadable)
            threadStop();
    }

之前在第八章的时候,我们就知道congext容器reloadable的默认值是false,而且载入器的reloadable也是false。

因而默认情况下,载入器的run方法不会运作。那载入器的start没有启动run方法么?

public void start() throws LifecycleException {
               .....
        // Start our background thread if we are reloadable
        if (reloadable) {
            log(sm.getString("webappLoader.reloading"));
            try {
                threadStart();
            } catch (IllegalStateException e) {
                throw new LifecycleException(e);
            }
        }
    }

而载入器的run方法干什么?就是用

        while (!threadDone) {
            // Wait for our check interval
            threadSleep();

            if (!started)
                break;

            try {
                // Perform our modification check
                if (!classLoader.modified())     //WebappClassLoader的modified是根据时间判定所监
                    continue;                    //控的class是否改变
            } catch (Exception e) {              //一旦改变了 返回true 就 notifyContext
                log(sm.getString("webappLoader.failModifiedCheck"), e);
                continue;
            }

            // Handle a need for reloading
            notifyContext();
            break;
        }

notifyContext()会启用WebappContextNotifier,后者调用容器的reload方法。

不过上面说了这么多,前提条件是载入器的reloadable得是true....

backgroundProcess 方法

在tomcat5中(上面说的那些是基于tomcat4的),关于时间戳的检查交给了backgroundProcess。

现在有个问题,4里好好的,为什么到5里就改了呢?

改是有原因的嘛。

想想之前,session因为要检查过期时间得启用一个线程,关于重载得检查时间戳,还得启用一个线程...

因而,在tomcat5中,所以的后台处理程序共用一个线程。具体怎么办呢?听老夫给你细细道来。

后面的所有代码来自tomcat7.0.55

在tomcat中,ContainerBase里面有

    protected void threadStart() {

        if (thread != null)
            return;
        if (backgroundProcessorDelay <= 0)
            return;
        threadDone = false;
        String threadName = "ContainerBackgroundProcessor[" + toString() + "]";
        thread = new Thread(new ContainerBackgroundProcessor(), threadName);
        thread.setDaemon(true);
        thread.start();
    }

重启了一个线程,不用说关键问题就是ContainerBackgroundProcessor。而它是ContainerBase的一个内部类。

ContainerBackgroundProcessor在run方法里会周期性的调用processChildren方法。
 protected void processChildren(Container container, ClassLoader cl) {
       ...
                container.backgroundProcess();
           ...
            Container[] children = container.findChildren();
            for (int i = 0; i < children.length; i++) {
                if (children[i].getBackgroundProcessorDelay() <= 0) {
                    processChildren(children[i], cl);
                }
            }
}

processChildren会先调用自己的backgroundProcess,然后让自己的子孙们也走一遍自己的流程。

   public void backgroundProcess() {

        if (!getState().isAvailable())
            return;

        if (loader != null) {
            try {
                loader.backgroundProcess();     //载入器的后台程序
            } catch (Exception e) {
                log.warn(sm.getString("containerBase.backgroundProcess.loader", loader), e);
            }
        }
        if (manager != null) {
            try {
                manager.backgroundProcess();    //session的后台程序
            } catch (Exception e) {
                log.warn(sm.getString("containerBase.backgroundProcess.manager", manager), e);
            }
        }
}

那具体的载入器的backgroundProcess怎么写呢?如下

WebappLoader.java
 public void backgroundProcess() {
        if (reloadable && modified()) {
            try {
                Thread.currentThread().setContextClassLoader
                    (WebappLoader.class.getClassLoader());
                if (container instanceof StandardContext) {
                    ((StandardContext) container).reload();
                }
            } finally {
                if (container.getLoader() != null) {
                    Thread.currentThread().setContextClassLoader
                        (container.getLoader().getClassLoader());
                }
            }
        } else {
            closeJARs(false);
        }
    }

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

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

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

  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 读书笔记 八 载入器下

    载入类 我们看看之前的文章,这一节就从SimpleWrapper的loadServlet讲起. SimpleWrapper.java如下(省略了try catch及其他部分代码) public Ser ...

  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. SELinux策略语言--客体类别和许可

    1. 简介 SELinux策略语言主要描述policy.conf的相关语法,其相关部分如下图所示: 2. 客体类别 定义内核支持的客体类别和许可的策略语言指令,并对SELinux系统中内核客体类别标准 ...

  2. 【Unity Shader实战】卡通风格的Shader(二)

    写在前面 本系列其他文章: 卡通风格的Shader(一) 好久没写博客了,一定是因为课程作业比较多,一定不是因为我懒,恩恩. 三个月以前,在一篇讲卡通风格的Shader的最后,我们说到在Surface ...

  3. 怎样在Ubuntu 14.04中搭建gitolite git服务器

     1.   首先这里我们安装openssh-serveropenssh-client,如果你用的是VPS之类的一般都默认安装好了,不过运行一个这个命令不会有错的,如果有安装就会提示已安装. sud ...

  4. springMVC源码分析--国际化实现Session和Cookie(二)

    上一篇博客springMVC源码分析--国际化LocaleResolver(一)中我们介绍了springMVC提供的国际化的解决方案,接下来我们根据springMVC提供的解决方案来简单的实现一个多语 ...

  5. mqtt推送介绍

    方案1.使用GCM服务(Google Cloud Messaging) 简介:Google推出的云消息服务,即第二代的C2DM. 优点:Google提供的服务.原生.简单,无需实现和部署服务端. 缺点 ...

  6. Qt应用程序中设置字体

    Qt应用程序中设置字体 应用程序中经常需要设置字体,例如office软件或者是其他的编辑器软件等等.这里主要涉及到如下几个概念:字体,字号以及风格(例如:粗体,斜体,下划线等等).Qt里面也有对应的类 ...

  7. Java-IO之BufferedWriter(字符缓冲输出流)

    BufferedWriter是字符缓冲输出流,继承于Writer,作用是为其他字符输出流添加一些缓冲功能. BufferedWriter主要的函数列表: BufferedWriter(Writer o ...

  8. Android开发技巧——ViewPager衍生出来的2个类

    1.不能左右滑动的ViewPager /* * Date: 14-7-28 * Project: Access-Control-V2 */ package cn.irains.access.v2.co ...

  9. Linux Debugging(六): 动态库注入、ltrace、strace、Valgrind

    实际上,Linux的调试方法非常多,针对不同的问题,不同的场景,不同的应用,都有不同的方法.很难去概括.本篇文章主要涉及本专栏还没有涵盖,但是的确有很重要的方法.本文主要包括动态库注入调试:使用ltr ...

  10. Chapter 2 User Authentication, Authorization, and Security(4):限制SA帐号的管理权限

    原文出处:http://blog.csdn.net/dba_huangzj/article/details/38817915,专题目录:http://blog.csdn.net/dba_huangzj ...