How tomcat works 读书笔记十二 StandardContext 下
对重载的支持
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 下的更多相关文章
- How tomcat works 读书笔记十二 StandardContext 上
在tomcat4中,StandardContext.java是最大的一个类,有117k.废话不说,开始分析吧. 其实要分析StandardContext,也就主要分析两个方法,一个start,一个in ...
- How tomcat works 读书笔记十五 Digester库 下
在这一节里我们说说ContextConfig这个类. 这个类在很早的时候我们就已经使用了(之前那个叫SimpleContextConfig),但是在之前它干的事情都很简单,就是吧context里的co ...
- How tomcat works 读书笔记十五 Digester库 上
Digester库 在前面的几个章节里,我们对tomcat里各个组件的配置完全是使用写硬编码的形式完成的. 如 Context context = new StandardContext(); Loa ...
- How tomcat works 读书笔记十四 服务器组件和服务组件
之前的项目还是有些问题的,例如 1 只能有一个连接器,只能处理http请求,无法添加另外一个连接器用来处理https. 2 对容器的关闭只能是粗暴的关闭Bootstrap. 服务器组件 org.apa ...
- how tomcat works 读书笔记 八 载入器下
载入类 我们看看之前的文章,这一节就从SimpleWrapper的loadServlet讲起. SimpleWrapper.java如下(省略了try catch及其他部分代码) public Ser ...
- how tomcat works 读书笔记(二)----------一个简单的servlet容器
app1 (建议读者在看本章之前,先看how tomcat works 读书笔记(一)----------一个简单的web服务器 http://blog.csdn.net/dlf123321/arti ...
- how tomcat works 读书笔记四 tomcat的默认连接器
事实上在第三章,就已经有了连接器的样子了,只是那仅仅是一个学习工具,在这一章我们会開始分析tomcat4里面的默认连接器. 连接器 Tomcat连接器必须满足下面几个要求 1 实现org.apache ...
- 《深入理解Java虚拟机》读书笔记十二
第十二章 Java内存模型与线程 1.硬件效率与一致性 由于计算机的存储设备与处理器的运算速度有几个数量级的差距,所以现代计算机系统都不得不加入一层读写速度尽可能接近处理器运算速度的高速缓存(Cac ...
- 《深入剖析Tomcat》读书笔记(二)
三.容器Container Container 是容器的父接口,所有子容器都必须实现这个接口.Container 容器的设计用的是典型的责任链的设计模式,它有四个子容器组件构成,分别是:Engine. ...
随机推荐
- Java之继承深刻理解
1.关于私有成员变量 无论父类中的成员变量是私有的.共有的.还是其它类型的,子类都会拥有父类中的这些成员变量.但是父类中的私有成员变量,无法在子类中直接访问,必须通过从父类中继承得到的protecte ...
- 学习TensorFlow,TensorBoard可视化网络结构和参数
在学习深度网络框架的过程中,我们发现一个问题,就是如何输出各层网络参数,用于更好地理解,调试和优化网络?针对这个问题,TensorFlow开发了一个特别有用的可视化工具包:TensorBoard,既可 ...
- 剑指Offer——分治算法
剑指Offer--分治算法 基本概念 在计算机科学中,分治法是一种很重要的算法.字面上的解释是"分而治之",就是把一个复杂的问题分成两个或更多的相同或相似的子问题,再把子问题分成更 ...
- 最简单的基于librtmp的示例:发布H.264(H.264通过RTMP发布)
===================================================== 最简单的基于libRTMP的示例系列文章列表: 最简单的基于librtmp的示例:接收(RT ...
- 一个简单的安卓+Servlet图片上传例子
例子比较 简单,服务端为Java Web Servlet,doPost方法中接收图片并保存,然后将保存的图片名返回给客户端,关键代码: @SuppressWarnings("deprecat ...
- C++中const加强
demo // C语言中的const是一个冒牌货 int main() { // 好像a是一个常量 const int a = 10; int *p = NULL; p = (int *)&a ...
- linux中的网络通信指令
1.write write命令通信是一对一的通信,即两个人之间的通信,如上图. 效果图 用法:write <用户名> 2.wall wall指令可将信息发送给每位同意接收公众信息的终端机用 ...
- JqGrid 显示表格
JqGrid 是前台的表格显示库,使用起来相当方便. 这里分享下本人使用过程中遇到的问题及解决方案 ** 一.rowNum属性 ** 1.如果不设置,默认显示数是20,也就是说超过20以后的数据.不再 ...
- xml的今生今世
跟随小编学习的脚步,今天小编来简单总结一下xml的今生今世,xml百度百科对她这样诠释到:可扩展标记语言 (ExtensibleMarkup Language, XML),用于标记电子文件使其具有结构 ...
- UNIX环境高级编程——非阻塞设置
非阻塞I/O使我们可以调用open.read和write这样的I/O操作,并使这些操作不会永远阻塞.如果这种操作不能完成, 则调用立即出错返回,表示该操作如继续执行将阻塞. 对于一个给定的描述符有两种 ...