SpringMVC載入WebApplicationContext源碼分析

來源:互聯網
上載者:User

標籤:gpl   hand   變數   自訂   mvc   apt   imp   bean   基於   

        Spring架構提供了構建Web應用程式的全功能MVC模組,叫Spring MVC,通過Spring Core+Spring MVC即可搭建一套穩定的Java Web項目。本文通過Spring MVC源碼分析介紹它的核心實現原理。

        Tomcat伺服器啟動入口檔案是web.xml,通過在其中配置相關的Listener和Servlet即可載入Spring MVC所需資料。基於Spring MVC最簡單的配置如下。

 

  1. <!-- 載入Spring設定檔 -->  
  2. <context-param>  
  3.     <param-name>contextConfigLocation</param-name>  
  4.     <param-value>  
  5.     classpath:spring-context*.xml  
  6.     </param-value>  
  7. </context-param>  
  8. <listener>  
  9.     <listener-class>org.springframework.web.context.ContextLoaderListener</listener-class>  
  10. </listener>  
  11.   
  12. <!-- 載入spring mvc -->  
  13. <servlet>  
  14.     <servlet-name>spring3mvc</servlet-name>  
  15.     <servlet-class>org.springframework.web.servlet.DispatcherServlet</servlet-class>  
  16.     <init-param>  
  17.         <param-name>contextConfigLocation</param-name>  
  18.         <param-value>  
  19.         classpath:spring-mvc*.xml  
  20.         </param-value>  
  21.     </init-param>  
  22.     <load-on-startup>1</load-on-startup>  
  23. </servlet>  
  24.   
  25. <servlet-mapping>  
  26.     <servlet-name>spring3mvc</servlet-name>  
  27.     <url-pattern>/</url-pattern>  
  28. </servlet-mapping>  

 

  • 建立容器

         ContextLoaderListener基於Web上下文層級的監聽器在啟動伺服器時就建立ApplicationContext並且將配置的Spring Bean載入到XML中。

        DispatcherServlet是一個請求分發控制器,所有匹配的URL都會通過該Servlet分發執行,在建立Servlet對象時會初始化Spring MVC相關配置。

        在web.xml中,我們看到基於ContextLoaderListener和DispatcherServlet都可以配置spring相關的XML,值得說明的是這兩種方式載入spring的ApplicationContext內容物件不是合并儲存的,具體可參考http://blog.csdn.net/madun/article/details/8988860。所以個人建議,基於mvc相關的spring配置由DispatcherServlet載入,而其餘的JavaBean都交給ContextLoaderListener載入。

 

一、ContextLoaderListener

        ContextLoaderListener是一個實現了ServletContextListener介面的監聽器,在啟動項目時會觸發contextInitialized方法(該方法主要完成ApplicationContext對象的建立),在關閉項目時會觸發contextDestroyed方法(該方法會執行ApplicationContext清理操作)。

Java代碼 
  1. public class ContextLoaderListener extends ContextLoader implements ServletContextListener  

 

          ConextLoaderListener載入Spring內容相關的過程可以用表示,黃色區塊是核心代碼。



簡單介紹一下的運行流程:

①啟動項目時觸發contextInitialized方法,該方法就做一件事:通過父類contextLoader的initWebApplicationContext方法建立Spring內容物件。

②initWebApplicationContext方法做了三件事:建立WebApplicationContext;載入對應的Spring檔案建立裡面的Bean執行個體;將WebApplicationContext放入ServletContext(就是Java Web的全域變數)中。

③createWebApplicationContext建立內容物件,支援使用者自訂的內容物件,但必須繼承自ConfigurableWebApplicationContext,而Spring MVC預設使用ConfigurableWebApplicationContext作為ApplicationContext(它僅僅是一個介面)的實現。

④configureAndRefreshWebApplicationContext方法用於封裝ApplicationContext資料並且初始化所有相關Bean對象。它會從web.xml中讀取名為contextConfigLocation的配置,這就是spring xml資料來源設定,然後放到ApplicationContext中,最後調用傳說中的refresh方法執行所有Java對象的建立。

⑤完成ApplicationContext建立之後就是將其放入ServletContext中,注意它儲存的key值常量。

Java代碼  
  1. servletContext.setAttribute(WebApplicationContext.ROOT_WEB_APPLICATION_CONTEXT_ATTRIBUTE, this.context);  
  2. //常量  
  3. public static final String ROOT_WEB_APPLICATION_CONTEXT_ATTRIBUTE = WebApplicationContext.class.getName() + ".ROOT";  

 

註:要擷取 ContextLoader層級的IOC容器物件可以這樣寫:

  1. WebApplicationContext rootContext = WebApplicationContextUtils.getWebApplicationContext(getServletContext());  

 

 

 二、DispatcherServlet

DispatcherServlet是前端控制器設計模式的實現,提供Spring Web MVC的集中訪問點,而且負責職責的指派,而且與Spring IoC容器無縫整合,從而可以獲得Spring的所有好處。

 

要瞭解DispatcherServlet是如何載入容器,需要先瞭解它的繼承關係,如所示:


 

如果在web.xml中設定了Servlet的<load-on-startup>1</load-on-startup>,則表示隨項目啟動,而我們知道Servelt建立時會首先調用init方法,所以繼承了HttpServlet的HttpServletBean就是關鍵入口了。那麼整個代碼運行流程如所示。


 

①HttpServletBean.init方法中執行initServletBean方法進行初始化操作,當然該方法在HttpServletBean是空方法,所以需要子類重寫。

②FrameworkServlet.initServletBean子類不負眾望,重寫了initServletBean方法,該方法最核心的操作就是調用initWebApplicationContext()執行內容Bean初始化。

③FrameworkServlet.initWebApplicationContext方法首先擷取自己的雙親上下文(也就是ContextLoaderListener初始化成功的WebApplicationContext);然後建立或者擷取當前Servelet的WebApplicationContext。

④無論是自己建立還是擷取現有的WebApplicationContext,最終都會讓Servelt層級的WebApplicationContext執行configureAndRefreshWebApplicationContext()方法進行上下文容器初始化。

 

通過以上幾步即可建立一個完整的IOC容器,而完成容器建立之後,DispatcherServlet還做了一件事:初始化Servelt控制器必備對象,這個是在initWebApplicationContext()方法中通過調用onRefresh(wac)方法實現的。而onRefresh也被重寫過,如果要瞭解怎麼初始化Servlet控制器必備對象可以查看DispatcherServlet的onRefresh方法瞭解。

Java代碼  
    1. /** 
    2.  * This implementation calls {@link #initStrategies}. 
    3.  */  
    4. @Override  
    5. protected void onRefresh(ApplicationContext context) {  
    6.     initStrategies(context);  
    7. }  
    8.   
    9. /** 
    10.  * Initialize the strategy objects that this servlet uses. 
    11.  * <p>May be overridden in subclasses in order to initialize further strategy objects. 
    12.  */  
    13. protected void initStrategies(ApplicationContext context) {  
    14.     initMultipartResolver(context);  
    15.     initLocaleResolver(context);  
    16.     initThemeResolver(context);  
    17.     initHandlerMappings(context);  
    18.     initHandlerAdapters(context);  
    19.     initHandlerExceptionResolvers(context);  
    20.     initRequestToViewNameTranslator(context);  
    21.     initViewResolvers(context);  
    22.     initFlashMapManager(context);  
    23. }  

SpringMVC載入WebApplicationContext源碼分析

相關文章

聯繫我們

該頁面正文內容均來源於網絡整理,並不代表阿里雲官方的觀點,該頁面所提到的產品和服務也與阿里云無關,如果該頁面內容對您造成了困擾,歡迎寫郵件給我們,收到郵件我們將在5個工作日內處理。

如果您發現本社區中有涉嫌抄襲的內容,歡迎發送郵件至: info-contact@alibabacloud.com 進行舉報並提供相關證據,工作人員會在 5 個工作天內聯絡您,一經查實,本站將立刻刪除涉嫌侵權內容。

A Free Trial That Lets You Build Big!

Start building with 50+ products and up to 12 months usage for Elastic Compute Service

  • Sales Support

    1 on 1 presale consultation

  • After-Sales Support

    24/7 Technical Support 6 Free Tickets per Quarter Faster Response

  • Alibaba Cloud offers highly flexible support services tailored to meet your exact needs.