JavaWeb項目的web.xml加載過程

一、web.xml加載過程

簡單說一下,web.xml的加載過程。當(dāng)我們啟動一個WEB項目容器時,容器包括(JBoss,Tomcat等)。首先會去讀取web.xml配置文件里的配置,當(dāng)這一步驟沒有出錯并且完成之后,項目才能正常的被啟動起來。

啟動WEB項目的時候,容器首先會去讀取web.xml配置文件中的兩個節(jié)點:<listener> </listener>和<context-param> </context-param>如圖:

image

緊接著,容器創(chuàng)建一個ServletContext(application),這個web項目的所有部分都將共享這個上下文。容器以<context-param></context-param>的name作為鍵,value作為值,將其轉(zhuǎn)化為鍵值對,存入ServletContext。

容器創(chuàng)建<listener></listener>中的類實例,根據(jù)配置的class類路徑<listener-class>來創(chuàng)建監(jiān)聽,在監(jiān)聽中會有初始化方法,啟動Web應(yīng)用時,系統(tǒng)調(diào)用Listener的該方法 contextInitialized(ServletContextEvent args),在這個方法中獲得:

  ServletContext application =ServletContextEvent.getServletContext();

  context-param的值= application.getInitParameter("context-param的鍵");

得到這個context-param的值之后,你就可以做一些操作了。

舉例:你可能想在項目啟動之前就打開數(shù)據(jù)庫,那么這里就可以在<context-param>中設(shè)置數(shù)據(jù)庫的連接方式(驅(qū)動、url、user、password),在監(jiān)聽類中初始化數(shù)據(jù)庫的連接。這個監(jiān)聽是自己寫的一個類,除了初始化方法,它還有銷毀方法,用于關(guān)閉應(yīng)用前釋放資源。比如:說數(shù)據(jù)庫連接的關(guān)閉,此時,調(diào)用contextDestroyed(ServletContextEvent args),關(guān)閉Web應(yīng)用時,系統(tǒng)調(diào)用Listener的該方法。

接著,容器會讀取<filter></filter>,根據(jù)指定的類路徑來實例化過濾器。

以上都是在WEB項目還沒有完全啟動起來的時候就已經(jīng)完成了的工作。如果系統(tǒng)中有Servlet,則Servlet是在第一次發(fā)起請求的時候被實例化的,而且一般不會被容器銷毀,它可以服務(wù)于多個用戶的請求。所以,Servlet的初始化都要比上面提到的那幾個要遲??偟膩碚f,web.xml的加載順序是: <context-param>-> <listener> -> <filter> -> <servlet>。其中,如果web.xml中出現(xiàn)了相同的元素,則按照在配置文件中出現(xiàn)的先后順序來加載。

二、web.xml標簽詳解

1.<web-app></web-app>

<web-app></web-app>是部署描述的根元素,該元素含23個子元素。在Servlet2.3中,子元素必須按照DTD文件描述中指定的順序出現(xiàn)。比如:如果部署描述符中的<web-app>元素有<servlet>和<servlet-mapping>兩個子元素,則<servlet>子元素必須出現(xiàn)在<servlet-mapping>子元素之前。在Servlet2.4中,順序并不重要。

2.<display-name></display-name>

<display-name></display-name>定義web應(yīng)用的名稱。如<display-name>trk-order-rest</display-name>

3.<distributable/>

<distributable/>可以使用distributable元素來告訴servlet/JSP容器,Web容器中部署的應(yīng)用程序適合在分布式環(huán)境下運行。

4.<context-param></context-param>

image

<context-param>元素含有一對參數(shù)名和參數(shù)值,用作應(yīng)用的Servlet上下文初始化參數(shù),參數(shù)名在整個Web應(yīng)用中必須是惟一的,在web應(yīng)用的整個生命周期中上下文初始化參數(shù)都存在,任意的Servlet和jsp都可以隨時隨地訪問它。<param-name>子元素包含有參數(shù)名,而<param-value>子元素包含的是參數(shù)值。作為選擇,可用<description>子元素來描述參數(shù)。

配置Spring,必須需要<listener>,而<context-param>可有可無,如果在web.xml中不寫<context-param>配置信息,默認的路徑是/WEB-INF/applicationContext.xml,在WEB-INF目錄下創(chuàng)建的xml文件的名稱必須是applicationContext.xml。如果是要自定義文件名可以在web.xml里加入contextConfigLocation這個context參數(shù):在<param-value>里指定相應(yīng)的xml文件名,如果有多個xml文件,可以寫在一起并以“,”號分隔,比如在business-client工程中,我們采用了自定義配置方式,<context-param>配置如下:

image

配置在同一個容器中的多個web項目,要配置不同的webAppRootKey,web.xml文件中最好定義webAppRootKey參數(shù),如果不定義,將會缺省為“webapp.root”,為防止log4j配置沖突,每個項目配置不同的webAppRootKey。如下:

image

當(dāng)然也不能重復(fù),否則報類似下面的錯誤:

Web app root system property already set to different value: 'webapp.root' = [/home/user/tomcat/webapps/project1/] instead of   [/home/user/tomcat/webapps/project2/] - Choose unique values for the 'webAppRootKey' context-param in your web.xml files!

5.<session-config></session-config>

image

<session-config> 用于設(shè)置容器的session參數(shù),比如:<session-timeout>用于指定http session的失效時間。默認時間設(shè)置(30minutes)。<session-timeout>用來指定默認的會話超時時間間隔,以分鐘為單位。該元素值為整數(shù)。如果 session-timeout元素的值為零或負數(shù),則表示會話將永遠不會超時。

6.<filter></filter>見我的博客,這里不在闡述。(http://www.cnblogs.com/vanl/p/5742501.html)

image

7.<listener></listener>見我的博客,這里不在闡述。(http://www.cnblogs.com/vanl/p/5753722.html)

image

8.<servlet></servlet>

8.1.Servlet介紹

Servlet通常稱為服務(wù)端小程序,是服務(wù)端的程序,用于處理及響應(yīng)客戶的請求。Servlet是一個特殊的Java類,創(chuàng)建Servlet類自動繼承HttpServlet??蛻舳送ǔV挥蠫ET和POST兩種請求方式,Servlet為了響應(yīng)這兩種請求,必須重寫doGet()和doPost()方法。大部分時候,Servlet對于所有的請求響應(yīng)都是完全一樣的,此時只需要重寫service()方法即可響應(yīng)客戶端的所有請求。另外HttpServlet有兩個方法:

init(ServletConfig config):創(chuàng)建Servlet實例時,調(diào)用該方法初始化Servlet資源。

destory():銷毀Servlet實例時,自動調(diào)用該方法回收資源。

通常無需重寫init()和destory()兩個方法,除非需要在初始化Servlet時,完成某些資源初始化的方法,才考慮重寫init()方法。如果重寫了init()方法,應(yīng)該在重寫該方法的第一行調(diào)用super.init(config),該方法將調(diào)用HttpServlet的init()方法。如果需要在銷毀Servlet之前,先完先完成某些資源的回收,比如關(guān)閉數(shù)據(jù)庫鏈接,才需要重寫destory()方法。

8.2.Servlet的生命周期

創(chuàng)建Servlet實例有兩個時機:

客戶端第一次請求某個Servlet時,系統(tǒng)創(chuàng)建該Servlet的實例,大部分Servlet都是這種Servlet;

web應(yīng)用啟動時立即創(chuàng)建Servlet實例,即<load-on-start>1</laod-on-start>(LZ有篇文章詳細說明:http://www.cnblogs.com/vanl/p/5756122.html)

每個Servlet的運行都遵循如下生命周期:

(1)創(chuàng)建Servlet實例。

(2)Web容器調(diào)用Servlet的init()方法,對Servlet進行初始化。

(3)Servlet初始化之后,將一直存在與容器之中,用于響應(yīng)客戶端請求,如果客戶端發(fā)送GET請求,容器調(diào)用Servlet的doGet()方法處理并響應(yīng)請求;如果客戶端發(fā)送POST請求,容器調(diào)用Servlet的doPost()方法處理并響應(yīng)請求?;蛘呓y(tǒng)一使用service()方法處理來響應(yīng)用戶請求。

(4)Web容器決定銷毀Servlet時,先調(diào)用Servlet的destory()方法,通常在關(guān)閉Web應(yīng)用時銷毀Servlet實例。

8.3.Servlet的配置

為了讓Servlet能響應(yīng)用戶請求,還必須將Servlet配置在web應(yīng)用中,配置Servlet需要修改web.xml文件。從Servlet3.0開始,配置Servlet有兩種方式:

(1)在Servlet類中使用基于注解的方式進行配置:@WebServlet

(2)在web.xml文件中進行配置。

image

我們用web.xml文件來配置Servlet,需要配置<servlet>和<servlet-mapping>。<servlet>用來聲明一個Servlet。<icon>、<display-name>和<description>元素的用法和<filter>的用法相同。<init-param>元素與<context-param>元素具有相同的元素描述符,可以使用<init-param>子元素將初始化參數(shù)名和參數(shù)值傳遞給Servlet,訪問Servlet配置參數(shù)通過ServletConfig對象來完成,ServletConfig提供如下方法:

java.lang.String.getInitParameter(java.lang.String name):用于獲取初始化參數(shù)

ServletConfig獲取配置參數(shù)的方法和ServletContext獲取配置參數(shù)的方法完全一樣,只是ServletContex是取得當(dāng)前Servlet的配置參數(shù),而ServletContext是獲取整個web應(yīng)用的配置參數(shù)。

8.4.配置Spring MVC的Servlet

image

配置Spring MVC,指定處理請求的Servlet,有兩種方式:

(1)默認查找MVC配置文件的地址是:/WEB-INF/${servletName}-servlet.xml。

(2)可以通過修改配置文件的位置,需要在配置DispatcherServlet時指定MVC配置文件的位置。

我們在平臺項目兩個工程中分別使用了不同的配置方式,介紹如下:

我們在business-client工程中按照默認方式查找MVC的配置文件,配置文件目錄為: /WEB-INF/business-servlet.xml。工程目錄結(jié)構(gòu)如下所示:

image

我們在public-base-server工程中,通過第2種方式進行配置,把spring-servlet.xml放到src/main/resources/config/spring-servlet.xml,則需要在配置DispatcherServlet時指定<init-param>標簽。具體代碼如下:

image

工程目錄結(jié)構(gòu)如下:

image

其中,classpath是web項目的類路徑,可以理解為classes目錄下面。因為無論這些配置文件放在哪里,編譯之后沒有特殊情況的話都直接在classes下面。在我們的工程里,經(jīng)過驗證,maven工程這兩個

image

路徑經(jīng)過編譯后生成的文件都位于classes目錄下,即這兩個路徑相當(dāng)于類路徑,在下面創(chuàng)建config文件夾(folder),創(chuàng)建自定義的xml配置文件即可。

8.5.classpath與classpath*區(qū)別

同名資源存在時,classpath只從第一個符合條件的classpath中加載資源,而classpath會從所有的classpath中加載符合條件的資源。classpath,需要遍歷所有的classpath,效率肯定比不上classpath,因此在項目設(shè)計的初期就盡量規(guī)劃好資源文件所在的路徑,避免使用classpath*來加載。

8.6.ContextLoaderListener和DispatcherServlet初始化上下文關(guān)系和區(qū)別

image

從上圖可以看出,ContextLoaderListener初始化的上下文加載的Bean是對于整個應(yīng)用程序共享的,一般如:DAO層、Service層Bean;DispatcherServlet初始化的上下文加載的Bean是只對Spring MVC有效的Bean,如:Controller、HandlerMapping、HandlerAdapter等,該初始化上下文只加載Web相關(guān)組件。

注意:用戶可以配置多個DispatcherServlet來分別處理不同的url請求,每個DispatcherServlet上下文都對應(yīng)一個自己的子Spring容器,他們都擁有相同的父Spring容器(業(yè)務(wù)層,持久(dao)bean所在的容器)。

9.<welcome-file-list></welcome-file-list>

image

<welcome-file-list>包含一個子元素<welcome-file>,<welcome-file>用來指定首頁文件名稱。<welcome-file-list>元素可以包含一個或多個<welcome-file>子元素。如果在第一個<welcome-file>元素中沒有找到指定的文件,Web容器就會嘗試顯示第二個,以此類推。

轉(zhuǎn)自:https://blog.csdn.net/qq_22075041/article/details/78692780

最后編輯于
?著作權(quán)歸作者所有,轉(zhuǎn)載或內(nèi)容合作請聯(lián)系作者
【社區(qū)內(nèi)容提示】社區(qū)部分內(nèi)容疑似由AI輔助生成,瀏覽時請結(jié)合常識與多方信息審慎甄別。
平臺聲明:文章內(nèi)容(如有圖片或視頻亦包括在內(nèi))由作者上傳并發(fā)布,文章內(nèi)容僅代表作者本人觀點,簡書系信息發(fā)布平臺,僅提供信息存儲服務(wù)。

友情鏈接更多精彩內(nèi)容