web.xml加載過程(步驟):
1.啓動WEB項目的時候,容器(如:Tomcat)會去讀它的配置文件web.xml.讀兩個節點:
<listener></listener> 和 <context-param></context-param>
2.緊接着,容器建立一個ServletContext(上下文),這個WEB項目全部部分都將共享這個上下文.
3.容器將<context-param></context-param>轉化爲鍵值對,並交給ServletContext.
4.容器建立<listener></listener>中的類實例,即建立監聽.
5.在監聽中會有contextInitialized(ServletContextEvent args)初始化方法,在這個方法中得到:
ServletContext = ServletContextEvent.getServletContext();
context-param的值 = ServletContext.getInitParameter("context-param的鍵");
6.獲得這個context-param的值以後,你就能夠作一些操做了.注意,這個時候你的WEB項目尚未徹底啓動完成.這個動做會比 所 有的Servlet都要早.
換句話說,這個時候,你對<context-param>中的鍵值作的操做,將在你的WEB項目徹底啓動以前被執行.
7.舉例.你可能想在項目啓動以前就打開數據庫.
那麼這裏就能夠在<context-param>中設置數據庫的鏈接方式,在監聽類中初始化數據庫的鏈接.
8.這個監聽是本身寫的一個類,除了初始化方法,它還有銷燬方法.用於關閉應用前釋放資源.好比說數據庫鏈接的關閉.
web.xml節點加載順序:
能夠確定的是,節點的加載順序與它們在 web.xml 文件中的前後順序無關。即不會由於 filter 寫在 listener 的前面而會先加載 filter。最終得出的結論是:listener -> filter -> servlet
同時還存在着這樣一種配置節點:context-param,它用於向 ServletContext 提供鍵值對,即應用程序上下文信息。咱們的 listener, filter 等在初始化時會用到這些上下文中的信息,那麼 context-param 配置節是否是應該寫在 listener 配置節前呢?實際上 context-param 配置節可寫在任意位置,所以真正的加載順序爲:
context-param -> listener -> filter -> servlet
對於某類配置節而言,與它們出現的順序是有關的。以 filter 爲例,web.xml 中固然能夠定義多個 filter,與 filter 相關的一個配置節是 filter-mapping,這裏必定要注意,對於擁有相同 filter-name 的 filter 和 filter-mapping 配置節而言,filter-mapping 必須出如今 filter 以後,不然當解析到 filter-mapping 時,它所對應的 filter-name 還未定義。web 容器啓動時初始化每一個 filter 時,是按照 filter 配置節出現的順序來初始化的,當請求資源匹配多個 filter-mapping 時,filter 攔截資源是按照 filter-mapping 配置節出現的順序來依次調用 doFilter() 方法的。
servlet 同 filter 相似,此處再也不贅述。
【加載Spring】
好比filter 須要用到 bean ,但加載順序是: 先加載filter 後加載spring,則filter中初始化操做中的bean爲null;
因此,若是過濾器中要使用到 bean,能夠將spring 的加載 改爲 Listener的方式 :
<listener>
<listener-class>
org.springframework.web.context.ContextLoaderListener
</listener-class>
</listener>
最終結論:
web.xml 的加載順序是:[context-param -> listener -> filter -> servlet -> spring] ,而同類型節點之間的實際程序調用的時候的順序是根據對應的 mapping 的順序進行調用的。