讀Tomcat原始碼確定載入web.xml中節點元素的順序
阿新 • • 發佈:2019-01-22
有時候面試時會被問tomcat啟動時web.xml中節點(類似listener,filter等)被載入的順序,死記硬背那多沒品,正好手裡有tomcat7的原始碼,找了點時間翻了翻。
讓我們先來喵一眼tomcat的架構,大致瞭解下tomcat啟動的順序,那我們目前關心的僅僅是web.xml中的載入順序,按照架構來講肯定是在Context中,架構如下圖:
那我們就來到Context中尋找線索,按照tomcat架構設計Context的實現類是StandardContext,全稱org.apache.catalina.core.StandardContext
看到其實現Lifecycle介面,我們在StandardContext中笑而不語的找到startInternal方法,看看我把暫時無語的程式碼去掉後的註釋版
/** * Start this component and implement the requirements * of {@link org.apache.catalina.util.LifecycleBase#startInternal()}. * * @exception LifecycleException if this component detects a fatal error * that prevents this component from being used */ @Override protectedsynchronized void startInternal() throwsLifecycleException { //設定webappLoader 程式碼省略 // Standard container startup 程式碼省略 try{ // Set up the context init params 初始化context-param節點資料 mergeParameters(); // Configure and call application event listeners //配置和呼叫listeners 也就是說開始監聽 if(ok) { if(!listenerStart()) { log.error("Error listenerStart"); ok = false; } } // Configure and call application filters //配置和呼叫filters filters開始起作用 if(ok) { if(!filterStart()) { log.error("Error filterStart"); ok = false; } } // Load and initialize all "load on startup" servlets //載入和初始化配置在load on startup的servlets if(ok) { loadOnStartup(findChildren()); } // Start ContainerBackgroundProcessor thread super.threadStart(); }finally{ // Unbinding thread unbindThread(oldCCL); } }
所以程式碼就是最好的文件就是這樣,我們歸納一下程式碼
1:首先是context-param節點
2:接著配置和呼叫listeners 並開始監聽
3:然後配置和呼叫filters filters開始起作用
4:最後載入和初始化配置在load on startup的servlets
另外贈送一枚彩蛋,也就是load on startup中的啟動順序是按照配置引數從小到大載入例項化的(小於0的忽略),
原始碼中是用一個TreeMap,其中鍵為Integer,那麼就是按照配置引數預設從小到大排列啟動。