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>
首先介紹一下啟動一個專案的整體流程:
- 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相關元件。