詳解web.xml中元素的加載順序

1、背景

  最近在項目中遇到了啓動時出現加載service註解注入失敗的問題,後來通過不懈努力發現了是由於web.xml配置文件中的元素加載順序致使的,那麼就抽空研究瞭如下tomcat在啓動時web.xml文件中元素的加載順序,如今和你們分享。web

2、問題剖析和研究結果

  遇到這種問題的時候,通常看源碼是最直接和最權威的獲取答案的方式,根據tomcat架構設計Context的實現類是StandardContext,全稱org.apache.catalina.core.StandardContext。看到其實現Lifecycle接口,咱們在StandardContext中找到startInternal方法,下面給出我把暫時無用的代碼去掉後的註釋版源碼:apache

image.png

那咱們接着概括和整理一下代碼:tomcat

  1.首先初始化context-param節點架構

  2.接着配置和調用listeners 並開始監聽app

  3.而後配置和調用filters filters開始起做用ide

  4.最後加載和初始化配置在load on startup的servletsspa

即元素加載順序爲:架構設計

context-param --> listeners --> filters --> servlets

注意:設計

  1.該加載順序並不會受元素在web.xml文件中的位置的影響。orm

  2.但對於某類配置節而言,與它們出現的順序是有關的。以 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() 方法的。

接着讓咱們來回憶一下web項目的啓動順序

  1.web容器讀取web.xml配置文件,並首先讀取<context-param>和<listener>兩個結點。

  2.容器建立一個ServletContext(servlet上下文),該web項目的全部部分都將共享這個上下文。

  3.容器將<context-param>轉換爲鍵值對,並交給servletContext。

  4.容器按照load on startup中的啓動順序建立<listener>中的類實例,建立監聽器。

關於load on startup

  • load-on-startup 元素在web應用啓動的時候指定了servlet被加載的順序,它的值必須是一個整數。

  • 若是它的值是一個負整數或是這個元素不存在,那麼容器會在該servlet被調用的時候,加載這個servlet 。

  • 若是值是正整數或零,容器在配置的時候就加載並初始化這個servlet,容器必須保證值小的先被加載。若是值相等,容器能夠自動選擇先加載誰。

  • 正數的值越小,啓動該servlet的優先級越高。

3、總結

  經過研究源碼咱們明白了web.xml中各個元素的加載順序,再遇到這種問題,咱們就能夠很快的定位出問題所在了。由此也發現和體會到了研究源碼是一種很好的習慣也是解決問題不可缺乏的方式。

相關文章
相關標籤/搜索