标签:tomcat standardcontext standardcontextvalve servlet 读书笔记
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是一致的。
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。
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方法。
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 下
标签:tomcat standardcontext standardcontextvalve servlet 读书笔记
原文地址:http://blog.csdn.net/dlf123321/article/details/41443439