2013-09-21java
容器是tomcat的基础,tomcat经过容器来管理和维护tomcat组件,最外层的容器是Server,最内层的容器是Wrapper,容器提供了一些基础的功能,例如添加父容器,子容器,共享数据,数据隔离等。web
Container
Container是tomcat中的容器接口,定义了容器所具备的方法和tomcat中容器的规范。容器接口提供了操做容器的方法,例如设置父容器和添加子容器,查找容器,添加监听容器事件的监听器,是invoke(Request, Response)处理HTTP协议请求的方法。apache
ContainerBase
ContainerBase是Container接口的基本实现,是个抽象类,在类中提供了Container大多数方法的实现,把一些容器公共实现抽象到ContainerBase实现。ContainerBase的功能是:实现了Container接口的大多数方法,把子类所须要实现的共同方法在基类中实现,避免在子类中重复编码,子类经过继承ContainerBase类来完成。数组
LifecycleSupport
ContainerBase抽象类中的属性,Lifecycle接口实现类,功能是负责管理注册在容器上面的LifecycleEvent监听类,监听容器的生命周期变动,集中管理监听器。tomcat
listeners
ContainerBase的属性,容器监听器数组,用户监听容器自己事件,监听的是ContainerEvent事件,与LifecycleEvent不一样。安全
Loader
ContainerBase的属性,tomcat本身封装的类加载器,针对webapp安全的类加载,管理webapp的类加载,在java的类加载器体系中,不一样类加载器加载的类实例是不能同时访问的。session
Manager
ContainerBase的属性,Manager是用来管理在容器上面的Session池,负责Session的生命周期,从生成到销毁,Manager是一个管理Session池的一个方法集合接口。app
cluster : Cluster
ContainerBase的属性,跟集群有关。webapp
pipeline : Pipeline
ContainerBase的属性,很重要,是Valve链,功能是负责管理Valve,也是请求信息传递链,最终目的是ServletWrapper中。pipeline 决定Valve的顺序,控制请求信息,是容器间传递请求信息的桥梁。this
support : PropertyChangeSupport
ContainerBase的属性,容器属性更新监听器集中管理,跟LifecycleSupport功能同样。
backgroundProcess()
Container接口方法,Container定义该方法的目的是启用一个后台进程来处理一些逻辑,好比从新加载配置,判断Session失效等。
ContainerBackgroundProcessor
ContainerBase基本容器的内部类,实现了Runnable接口,具体做用是做为一个后台程序定时触发backgroundProcess()后台处理方法。
/** * Private thread class to invoke the backgroundProcess method of this * container and its children after a fixed delay. */ protected class ContainerBackgroundProcessor implements Runnable { public void run() { while (!threadDone) { try { Thread.sleep(backgroundProcessorDelay * 1000L);//睡眠 } catch (InterruptedException e) { ; } if (!threadDone) { //取类加载器,确保容器和子容器在同一个类加载器中 Container parent = (Container) getMappingObject(); ClassLoader cl = Thread.currentThread() .getContextClassLoader(); if (parent.getLoader() != null) { cl = parent.getLoader().getClassLoader(); } processChildren(parent, cl);//调用容器的backgroundProcess()方法 } } } /** * 处理子容器 * @param container * @param cl */ protected void processChildren(Container container, ClassLoader cl) { try { if (container.getLoader() != null) { Thread.currentThread().setContextClassLoader( container.getLoader().getClassLoader()); } container.backgroundProcess();//调用后台处理方法 } catch (Throwable t) { log.error("Exception invoking periodic operation: ", t); } finally { Thread.currentThread().setContextClassLoader(cl); } Container[] children = container.findChildren(); for (int i = 0; i < children.length; i++) { if (children[i].getBackgroundProcessorDelay() <= 0) { processChildren(children[i], cl);//处理子容器 } } } }
init()
负责容器的初始化工做,主要有一下几步,
/** * Init method, part of the MBean lifecycle. If the container was added via * JMX, it'll register itself with the parent, using the ObjectName * conventions to locate the parent. * * If the container was added directly and it doesn't have an ObjectName, * it'll create a name and register itself with the JMX console. On * destroy(), the object will unregister. * * @throws Exception */ public void init() throws Exception { if (this.getParent() == null) { // "Life" update ObjectName parentName = getParentName(); // log.info("Register " + parentName ); if (parentName != null && mserver.isRegistered(parentName)) { mserver.invoke(parentName, "addChild", new Object[] { this }, new String[] { "org.apache.catalina.Container" }); } } initialized = true; }
start()
负责容器的启动工做,主要有如下几步,主要启动添加在容器上面的组件。
/** * Prepare for active use of the public methods of this Component. * 预启动的公有方法 * @exception LifecycleException * if this component detects a fatal error that prevents it * from being started */ public synchronized void start() throws LifecycleException { // Validate and update our current component state if (started) { if (log.isInfoEnabled()) log.info(sm .getString("containerBase.alreadyStarted", logName())); return; } // Notify our interested LifecycleListeners //开始启动事件监听 lifecycle.fireLifecycleEvent(BEFORE_START_EVENT, null); started = true; // Start our subordinate components, if any if ((loader != null) && (loader instanceof Lifecycle)) ((Lifecycle) loader).start();//加载器启动 logger = null; getLogger(); if ((logger != null) && (logger instanceof Lifecycle)) ((Lifecycle) logger).start(); if ((manager != null) && (manager instanceof Lifecycle)) ((Lifecycle) manager).start();//管理器启动 if ((cluster != null) && (cluster instanceof Lifecycle)) ((Lifecycle) cluster).start();//集群从节点启动 if ((realm != null) && (realm instanceof Lifecycle)) ((Lifecycle) realm).start(); if ((resources != null) && (resources instanceof Lifecycle)) ((Lifecycle) resources).start();//资源启动 // Start our child containers, if any Container children[] = findChildren(); for (int i = 0; i < children.length; i++) { if (children[i] instanceof Lifecycle) ((Lifecycle) children[i]).start();//启动子容器 } // Start the Valves in our pipeline (including the basic), if any if (pipeline instanceof Lifecycle) ((Lifecycle) pipeline).start();//监听pipe功能 // Notify our interested LifecycleListeners //正在启动事件通知 lifecycle.fireLifecycleEvent(START_EVENT, null); // Start our thread threadStart();//启动线程 // Notify our interested LifecycleListeners //完成启动事件通知 lifecycle.fireLifecycleEvent(AFTER_START_EVENT, null); }
stop()
负责中止容器,所作的工做就是按照start()方法中组件启动的顺序逆序中止组件。
/** * Gracefully shut down active use of the public methods of this Component. * 优雅关闭容器的公有方法 * @exception LifecycleException * if this component detects a fatal error that needs to be * reported */ public synchronized void stop() throws LifecycleException { // Validate and update our current component state if (!started) { if (log.isInfoEnabled()) log.info(sm.getString("containerBase.notStarted", logName())); return; } // Notify our interested LifecycleListeners //准备中止容器事件通知 lifecycle.fireLifecycleEvent(BEFORE_STOP_EVENT, null); // Stop our thread threadStop();//中止线程 // Notify our interested LifecycleListeners //中止容器事件通知 lifecycle.fireLifecycleEvent(STOP_EVENT, null); started = false; // Stop the Valves in our pipeline (including the basic), if any if (pipeline instanceof Lifecycle) { ((Lifecycle) pipeline).stop();//pipe中止 } // Stop our child containers, if any Container children[] = findChildren(); for (int i = 0; i < children.length; i++) { if (children[i] instanceof Lifecycle) ((Lifecycle) children[i]).stop();//子容器中止 } // Remove children - so next start can work children = findChildren(); for (int i = 0; i < children.length; i++) { removeChild(children[i]);//移除子容器 } // Stop our subordinate components, if any if ((resources != null) && (resources instanceof Lifecycle)) { ((Lifecycle) resources).stop();//资源中止 } if ((realm != null) && (realm instanceof Lifecycle)) { ((Lifecycle) realm).stop(); } if ((cluster != null) && (cluster instanceof Lifecycle)) { ((Lifecycle) cluster).stop();//集群子节点中止 } if ((manager != null) && (manager instanceof Lifecycle)) { ((Lifecycle) manager).stop();//管理器中止 } if ((logger != null) && (logger instanceof Lifecycle)) { ((Lifecycle) logger).stop(); } if ((loader != null) && (loader instanceof Lifecycle)) { ((Lifecycle) loader).stop(); } // Notify our interested LifecycleListeners //完成中止容器事件通知 lifecycle.fireLifecycleEvent(AFTER_STOP_EVENT, null); }
destroy()
负责销毁容器,主要工做是注销MBeanServer,移除父容器引用,移除容器
/** * 中止容器 * @throws Exception */ public void destroy() throws Exception { if (started) { stop(); } initialized = false; // unregister this component if (oname != null) { try { if (controller == oname) { Registry.getRegistry(null, null).unregisterComponent(oname); if (log.isDebugEnabled()) log.debug("unregistering " + oname); } } catch (Throwable t) { log.error("Error unregistering ", t); } } if (parent != null) { parent.removeChild(this); } // Stop our child containers, if any Container children[] = findChildren(); for (int i = 0; i < children.length; i++) { removeChild(children[i]); } }
threadStart()
负责启动容器的后台任务程序。
/** * Start the background thread that will periodically check for session * timeouts. * 启动后台线程并按期检查session失效 */ 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(); }
threadStop()
负责中止后台进程运行。
/** * Stop the background thread that is periodically checking for session * timeouts. * 中止线程 */ protected void threadStop() { if (thread == null) return; threadDone = true; thread.interrupt();//打断方式中止 try { thread.join(); } catch (InterruptedException e) { ; } thread = null; }
从上面的组件和方法能够看出,容器所需完成的功能或者说是所具有的功能有:
说好的坚持,老是断断续续