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


原文:https://blog.csdn.net/qq_35571554/article/details/82385838
本篇主要在基於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>
首先介紹一下啟動一個項目的整體流程:
 tomcat啟動一個WEB項目的時候,WEB容器會去讀取它的配置文件web.xml,讀取<listener>和<context-param>兩個結點。
   緊接着,容器創建一個ServletContext(servlet上下文,全局的),這個web項目的所有部分都將共享這個上下文。可以把ServletContext看成是一個Web應用的服務器端組件的共享內存,在ServletContext中可以存放共享數據。ServletContext對象是真正的一個全局對象,凡是web容器中的Servlet都可以訪問
 容器將<context-param>轉換為鍵值對,並交給servletContext。
  容器創建<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主要用作職責調度工作,本身主要用於控制流程,主要職責如下:
文件上傳解析,如果請求類型是multipart將通過MultipartResolver進行文件上傳解析;
 通過HandlerMapping,將請求映射到處理器(返回一個HandlerExecutionChain,它包括一個處理器、多個HandlerInterceptor攔截器);
 通過HandlerAdapter支持多種類型的處理器(HandlerExecutionChain中的處理器);
 通過ViewResolver解析邏輯視圖名到具體視圖實現;
 本地化解析;
 渲染具體的視圖等;
 如果執行過程中遇到異常將交給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實例有兩個時機:
客戶端第一次請求某個Servlet時,系統創建該Servlet的實例,大部分Servlet都是這種Servlet;
 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配置嗎?
如果只有 Spring mvc 的一個 Servlet,listener 可以不用。
  但是如果用了Shiro 等,Shiro 用到的 Spring 的配置必須在 listener 里加載。
  一般 Dao, Service 的 Spring 配置都會在 listener 里加載,因為可能會在多個 Servlet 里用到,因為父子 Context 的可見性問題,防止重復加載所以在 listener 里加載。
4、web.xml中spring的核心ContextLoaderListener初始化的上下文和springmvc的核心DispatcherServlet初始化的上下文關系
     
     ContextLoaderListener初始化的上下文加載的Bean是對於整個應用程序共享的   :一般如DAO層、Service層Bean;
      DispatcherServlet初始化的上下文加載的Bean是只對Spring Web MVC有效的Bean,如Controller,該初始化上下文應該只加載Web相關組件。



免責聲明!

本站轉載的文章為個人學習借鑒使用,本站對版權不負任何法律責任。如果侵犯了您的隱私權益,請聯系本站郵箱yoyou2525@163.com刪除。



 
粵ICP備18138465號   © 2018-2025 CODEPRJ.COM