一、 web.xml加載過程(步驟):
- 啟動web項目,容器(如Tomcat、Apache)會去讀取它的配置文件web.xml 中的兩個節點,context-param和listener。
- 緊接着,容器將創建一個ServletContext(又稱為:Servlet上下文),應用范圍內即整個WEB項目都能使用這個Servlet上下文。
- 容器將< context-param >轉化為鍵值對,並交給ServletContext。
- 容器創建< listener >中的類實例,即創建監聽。(備注:listener定義的類可以是自定義的類但必須需要繼承ServletContextListener)。
- 在監聽中會有contextInitialized(ServletContextEvent args)初始化方法,在這個方法中獲得:ServletContext = ServletContextEvent.getServletContext(); context-param的值 = ServletContext.getInitParameter(“context-param的鍵”); 在這個類中還必須有一個contextDestroyed(ServletContextEvent event) 銷毀方法。用於關閉應用前釋放資源,比如說數據庫連接的關閉。
- 得到這個context-param的值之后,你就可以做一些操作了。注意,這個時候你的WEB項目還沒有完全啟動完成。這個動作會比所有的Servlet都要早。換句話說,這個時候,你對 < context-param > 中的鍵值做的操作,將在你的WEB項目完全啟動之前被執行。
- 舉例.你可能想在項目啟動之前就打開數據庫。那么這里就可以在< context-param >中設置數據庫的連接方式,在監聽類中初始化數據庫的連接。
補充知識:ServletContext,是一個全局的儲存信息的空間,服務器開始,其就存在,服務器關閉,其才釋放。request,一個用戶可有多個;session,一個用戶一個;而servletContext,所有用戶共用一個。所以,為了節省空間,提高效率,ServletContext中,要放必須的、重要的、所有用戶需要共享的線程又是安全的一些信息。例如,一個購物網站,用戶要訪問商品的詳細信息,如果放在session域,每個用戶都要訪問一遍數據庫,這樣效率太低;而放在ServletContext中,服務器一啟動,就訪問數據庫將商品信息放入數據庫,這樣所有用戶只需要通過上下文就能訪問到商品的信息。
二、web.xml節點加載順序:
- web.xml節點的加載順序與它們在web.xml中位置的先后無關,即不會因為< filter >寫在< context-param >前面就先加載< filter >。
- 上文也提到到了,< context-param >用於對ServletContext提供鍵值對,即應用程序的上下文信息。而listener、servlet等節點在初始化的過程中會使用到這些上下文信息,所以最后我們得出web.xml節點的加載順序應該為:context-param->listener->filter->servlet。
- 對於某類配置節點而言,位置的先后是有要求的。以servlet舉例,與servlet相關的配置節點是servlet-mapping,對於擁有相同配置節servlet-name的servlet和servlet-mapping來說,servlet-mapping必須在servlet后定義,否則當解析到servlet-mapping時,它的servlet-name還沒有定義。web 容器啟動時初始化每個 servlet時,是按照 servlet配置節出現的順序來初始化的。
- 最終結論: web.xml 的加載順序是:[context-param -> listener -> filter -> servlet -> spring] ,而同類型節點之間的實際程序調用的時候的順序是根據對應的 mapping 的順序進行調用的。