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; }
從上面的組件和方法能夠看出,容器所需完成的功能或者說是所具有的功能有:
說好的堅持,老是斷斷續續