1. 程式人生 > >ssm框架中,專案啟動過程以及web.xml配置詳解

ssm框架中,專案啟動過程以及web.xml配置詳解

本篇主要在基於SSM的框架,深入講解web.xml的配置

web.xml

       每個javaEE專案中都會有,web.xml檔案是用來初始化配置資訊:比如Welcome頁面、servlet、servlet-mapping、filter、listener、啟動載入級別等。

     web.xml配置檔案內容如下:

 <!DOCTYPE web-app PUBLIC
 "-//Sun Microsystems, Inc.//DTD Web Application 2.3//EN"
 "http://java.sun.com/dtd/web-app_2_3.dtd" >
 
<web-app>
  <display-name>Archetype Created Web Application</display-name>
 
  <!--welcome pages-->
  <welcome-file-list>
    <welcome-file>index.jsp</welcome-file>
  </welcome-file-list>
 
  <!--applicationContext.xml是全域性的,應用於多個serverlet,配合listener一起使用-->
  <!-- 如果是監聽多個檔案,可用‘,’隔開 -->
 
  <context-param>
    <description>配置Spring配置檔案路徑</description>
    <param-name>contextConfigLocation</param-name>
 
    <param-value>classpath:spring/applicationContext.xml</param-value>
  </context-param>
 
  <!-- 定義SPRING監聽器,載入spring -->
  <listener>
    <listener-class>
      org.springframework.web.context.request.RequestContextListener
    </listener-class>
  </listener>
 
  <listener>
    <listener-class>org.springframework.web.context.ContextLoaderListener</listener-class>
  </listener>
 
  <!--log4j配置檔案載入-->
  <context-param>
    <param-name>log4jConfigLocation</param-name>
    <param-value>classpath:log4j.properties</param-value>
  </context-param>
  <!--啟動一個watchdog執行緒每1800秒掃描一下log4j配置檔案的變化-->
  <context-param>
    <param-name>log4jRefreshInterval</param-name>
    <param-value>1800000</param-value>
  </context-param>
  <context-param>
    <param-name/>
    <param-value/>
  </context-param>
 
  <!-- 配置Spring字元編碼過濾器 -->
  <filter>
    <filter-name>encodingFilter</filter-name>
    <filter-class>org.springframework.web.filter.CharacterEncodingFilter</filter-class>
    <init-param>
      <param-name>encoding</param-name>
      <param-value>UTF-8</param-value>
    </init-param>
    <init-param>
      <param-name>forceEncoding</param-name>
      <param-value>true</param-value>
    </init-param>
  </filter>
  <filter-mapping>
    <filter-name>encodingFilter</filter-name>
    <url-pattern>/*</url-pattern>
  </filter-mapping>
 
  <!-- Spring MVC 核心控制器 DispatcherServlet 配置開始 -->
  <!--配置springmvc DispatcherServlet-->
  <servlet>
    <servlet-name>springMVC</servlet-name>
    <servlet-class>org.springframework.web.servlet.DispatcherServlet</servlet-class>
    <init-param>
      <!--Sources標註的資料夾下需要新建一個spring資料夾-->
      <param-name>contextConfigLocation</param-name>
      <!-- 如果是監聽多個檔案,可用‘,’隔開 -->
      <param-value>classpath:spring/spring-mvc.xml</param-value>
    </init-param>
    <load-on-startup>1</load-on-startup>
    <async-supported>true</async-supported>
  </servlet>
 
  <!-- 攔截設定 -->
  <servlet-mapping>
    <servlet-name>springMVC</servlet-name>
    <!-- 此處可以可以配置成*.do,對應struts的字尾習慣 -->
    <url-pattern>/</url-pattern>
  </servlet-mapping>
  <!-- Spring MVC 核心配置結束 -->
 
  <!-- 啟用Tomcat的defaultServlet來處理靜態檔案 -->
  <servlet-mapping>
    <servlet-name>default</servlet-name>
    <url-pattern>/static/*</url-pattern>
  </servlet-mapping>
 
  <!-- session 時間 -->
  <session-config>
    <session-timeout>30</session-timeout>
  </session-config>
 
</web-app>

首先介紹一下啟動一個專案的整體流程:

  1.  tomcat啟動一個WEB專案的時候,WEB容器會去讀取它的配置檔案web.xml,讀取<listener>和<context-param>兩個結點。
  2.   緊接著,容器建立一個ServletContext(servlet上下文,全域性的),這個web專案的所有部分都將共享這個上下文。可以把ServletContext看成是一個Web應用的伺服器端元件的共享記憶體,在ServletContext中可以存放共享資料。ServletContext物件是真正的一個全域性物件,凡是web容器中的Servlet都可以訪問
  3. 容器將<context-param>轉換為鍵值對,並交給servletContext。
  4.  容器建立<listener>中的類例項,建立監聽器。 

       以上步驟,都是基於web.xml的配置檔案進行操作的,現在簡單說一下,web.xml檔案主要的工作包括兩部分:1、web.xml啟動spring容器;2、DispathcheServlet的宣告;3、其餘工作是session過期,字串編碼等

       web.xml中標籤的載入順序:<context-param>  >  <listener> (spring的相關工作)  >  filter >servlet(springmvc的相關工作)

A、web.xml啟動spring容器的載入過程:

        讀取web.xml中兩個節點,<context-param>  >  <listener>,建立ServletContext物件,listener中ContextLoaderListener監聽器的作用就是啟動Web容器時,監聽servletContext物件的變化,獲取servletContext物件的<context-param>,來自動裝配ApplicationContext的配置資訊。

     1) 當我們啟動一個WEB專案容器時,容器包括(JBoss,Tomcat等)。首先會去讀取web.xml配置檔案裡的配置,當這一步驟沒有出錯並且完成之後,專案才能正常的被啟動起來。

     2) 啟動WEB專案的時候:

       容器首先會去讀取web.xml配置檔案中的兩個節點:

               第一個節點:<context-param> </context-param> ,<context-param>是web應用的資源配置,是wen應用的上下文引數,如資料庫連線方式,spring的配置檔案路徑(application.xml)等,這些鍵值對都會加入到servletContext物件。

               第二個節點:<listener> </listener>,<listener>可以獲取當前該web應用物件,即servletContext物件,獲取context-param值,進而獲取資源,在web應用啟動前操作)  ,listener中ContextLoaderListener監聽器的作用就是啟動Web容器時,監聽servletContext物件的變化,獲取servletContext物件的<context-param>,來自動裝配ApplicationContext的配置資訊。因為它實現了ServletContextListener這個介面,在web.xml配置這個監聽器,啟動容器時,就會預設執行它實現的方法。

<context-param>元素含有一對引數名和引數值,用作應用的Servlet上下文初始化引數,引數名在整個Web應用中必須是惟一的,在web應用的整個生命週期中上下文初始化引數都存在,任意的Servlet和jsp都可以隨時隨地訪問它。<context-param>用於向 ServletContext 提供鍵值對。

       監聽器<Listener>,它是實現了javax.servlet.ServletContextListener 介面的伺服器端程式,它也是隨web應用的啟動而啟動,只初始化一次,隨web應用的停止而銷燬。主要作用是: listener中ContextLoaderListener監聽器的作用就是啟動Web容器時,監聽servletContext物件的變化,獲取servletContext物件的<context-param>,來自動裝配ApplicationContext的配置資訊。

     3)緊接著,容器建立一個ServletContext(application),這個web專案的所有部分都將共享這個上下文。容器以<context-param></context-param>的name作為鍵,value作為值,將其轉化為鍵值對,存入ServletContext。ServletContext即代表當前web應用。

     4)容器建立<listener></listener>中的類例項,即建立監聽.,listener中ContextLoaderListener監聽器的作用就是啟動Web容器時,監聽servletContext物件的變化,獲取servletContext物件的<context-param>,來自動裝配ApplicationContext的配置資訊。

     5) 監聽器中通過contextInitialized(ServletContextEvent args)初始化方法,來獲得ServletContext 物件以及context-param值。

                  ServletContext = ServletContextEvent.getServletContext();

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

        6)  拿到這個context-param的值之後,可以在WEB專案還沒有完全啟動時,進行一些初始化工作,但是最主要的還是自動裝配ApplicationContext的配置資訊。

        7)   .舉例.你可能想在專案啟動之前就開啟資料庫.
           那麼這裡就可以在<context-param>中設定資料庫的連線方式,在監聽類中初始化資料庫的連線.。這個監聽是自己寫的一個類,除了初始化方法,它還有銷燬方法.用於關閉應用前釋放資源.比如說資料庫連線的關閉.

B、DispathcheServlet的宣告(主要是servlet標籤的配置,,主要配置springmvc)

         DispatcherServlet是前端控制器設計模式的實現,提供Spring Web MVC的集中訪問點(也就是把前端請求分發到目標controller),而且與Spring IoC容器無縫整合,從而可以獲得Spring的所有好處。

    DispatcherServlet主要用作職責排程工作,本身主要用於控制流程,主要職責如下:

  1. 檔案上傳解析,如果請求型別是multipart將通過MultipartResolver進行檔案上傳解析;
  2. 通過HandlerMapping,將請求對映到處理器(返回一個HandlerExecutionChain,它包括一個處理器、多個HandlerInterceptor攔截器);
  3. 通過HandlerAdapter支援多種型別的處理器(HandlerExecutionChain中的處理器);
  4. 通過ViewResolver解析邏輯檢視名到具體檢視實現;
  5. 本地化解析;
  6. 渲染具體的檢視等;
  7. 如果執行過程中遇到異常將交給HandlerExceptionResolver來解析。

從以上我們可以看出DispatcherServlet主要負責流程的控制(而且在流程中的每個關鍵點都是很容易擴充套件的)。

     web.xml中spring的核心ContextLoaderListener初始化的上下文和springmvc的核心DispatcherServlet初始化的上下文關係:

從圖中可以看出:

      ContextLoaderListener初始化的上下文載入的Bean是對於整個應用程式共享的,不管是使用什麼表現層技術,一般如DAO層、Service層Bean;

     DispatcherServlet初始化的上下文載入的Bean是隻對Spring Web MVC有效的Bean,如Controller、HandlerMapping、HandlerAdapter等等,該初始化上下文應該只加載Web相關元件。

小結:

   1、javaEE專案啟動過程:首先載入Spring上下文環境配置檔案,然後載入SpringMVC配置檔案。

   Spring配置載入過程:

         tomcat伺服器啟動一個WEB專案的時候,WEB容器會去讀取它的配置檔案web.xml,然後會讀取它的listener和context-param節點,然後緊接著會建立一個ServletContext(servlet上下文,全域性的),這個web專案的所有部分都將共享這個上下文,容器將<context-param>轉換為鍵值對,並交給servletContext,<listener>可以獲取當前該web應用物件,即servletContext物件,獲取context-param值,進而獲取資源,在web應用啟動前操作)  ,listener中ContextLoaderListener監聽器的作用就是啟動Web容器時,監聽servletContext物件的變化,獲取servletContext物件的<context-param>,來自動裝配ApplicationContext的配置資訊。這樣spring的載入過程就完成了。

   SpringMVC配置載入過程:

                  springMVC其實和spring是一樣的,但是它不用在程式開始時訪問。springMVC的載入過程是通過Servlet節點 。

      Servlet介紹:

        Servlet通常稱為服務端小程式,是服務端的程式,用於處理及響應客戶的請求。Servlet是一個特殊的Java類,建立Servlet類自動繼承HttpServlet。客戶端通常只有GET和POST兩種請求方式,Servlet為了響應這兩種請求,必須重寫doGet()和doPost()方法。大部分時候,Servlet對於所有的請求響應都是完全一樣的,此時只需要重寫service()方法即可響應客戶端的所有請求。

       建立Servlet例項有兩個時機:

  1. 客戶端第一次請求某個Servlet時,系統建立該Servlet的例項,大部分Servlet都是這種Servlet;
  2. web應用啟動時立即建立Servlet例項,即<load-on-start>1</laod-on-start>

 2、監聽器如何進行專案的初始化

         監聽器中通過contextInitialized(ServletContextEvent args)初始化方法,來獲得ServletContext 物件以及context-param值。

                              ServletContext = ServletContextEvent.getServletContext();

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

       拿到這個context-param的值之後,可以在WEB專案還沒有完全啟動時,進行一些初始化工作,但是最主要的還是自動裝配ApplicationContext的配置資訊。

3、spring和springMVC整合後,可以取消掉web.xml中spring的listener配置嗎?

  1. 如果只有 Spring mvc 的一個 Servlet,listener 可以不用。
  2.  但是如果用了Shiro 等,Shiro 用到的 Spring 的配置必須在 listener 里加載。
  3.  一般 Dao, Service 的 Spring 配置都會在 listener 里加載,因為可能會在多個 Servlet 裡用到,因為父子 Context 的可見性問題,防止重複載入所以在 listener 里加載。

4、web.xml中spring的核心ContextLoaderListener初始化的上下文和springmvc的核心DispatcherServlet初始化的上下文關係

      

  1.      ContextLoaderListener初始化的上下文載入的Bean是對於整個應用程式共享的   :一般如DAO層、Service層Bean;
  2. DispatcherServlet初始化的上下文載入的Bean是隻對Spring Web MVC有效的Bean,如Controller,該初始化上下文應該只加載Web相關元件。