1. 程式人生 > >Spring之ContextLoaderListener的作用

Spring之ContextLoaderListener的作用

原文連結:http://blog.csdn.net/c5153000/article/details/6234207

[java] view plaincopyprint?
  1. Spring org.springframework.web.context.ContextLoaderListener  
  2. public class ContextLoaderListener   
  3. extends Object   
  4. implements ServletContextListener   
作用:在啟動Web容器時,自動裝配Spring applicationContext.xml的配置資訊。

因為它實現了

ServletContextListener這個介面,在web.xml配置這個監聽器,啟動容器時,就會預設執行它實現的方法。在ContextLoaderListener中關聯了ContextLoader這個類,所以整個載入配置過程由ContextLoader來完成。

看看ContextLoader的API說明

第一段說明ContextLoader可以由 ContextLoaderListenerContextLoaderServlet生成。如果檢視ContextLoaderServletAPI,可以看到它也關聯了ContextLoader這個類而且它繼承了HttpServlet

第二段,ContextLoader

建立的是 XmlWebApplicationContext這樣一個類,它實現的介面是WebApplicationContext->ConfigurableWebApplicationContext->ApplicationContext->

BeanFactory這樣一來spring中的所有bean都由這個類來建立

第三段,講如何部署applicationContextxml檔案,如果在web.xml中不寫任何引數配置資訊,預設的路徑是"/WEB-INF/applicationContext.xml,在WEB-INF目錄下建立的xml檔案的名稱必須是applicationContext.xml

。如果是要自定義檔名可以在web.xml里加入contextConfigLocation這個context引數:

<context-param>
<param-name>contextConfigLocation</param-name>
<param-value>
/WEB-INF/classes/applicationContext-*.xml
</param-value>
</context-param>

<param-value> </param-value>裡指定相應的xml檔名,如果有多個xml檔案,可以寫在一起並一“,”號分隔。上面的applicationContext-*.xml採用萬用字元,比如這那個目錄下有applicationContext-ibatis-base.xmlapplicationContext-action.xmlapplicationContext-ibatis-dao.xml等檔案,都會一同被載入。

-----------------------------------------------------------------------------------------

例子,在web.xml檔案中加入下面程式碼

[xhtml] view plaincopyprint?
  1. <listener>  
  2.   <listener-class>org.springframework.web.context.ContextLoaderListener</listener-class>  
  3. </listener>  

如果applicationContext.xml檔案沒有在/WEB-INF/下,或檔名不一致,或存在多個Spring配置檔案,在web.xml檔案中根據下面程式碼修改

[xhtml] view plaincopyprint?
  1. <context-param>  
  2.   <param-name>contextConfigLocation</param-name>  
  3.   <param-value>classpath*:applicationContext-*.xml,/WEB-INF/applicationContext.xml,/WEB-INF/classes/applicationContext-*.xml  
  4. lt;/param-value>  
  5.  </context-param>  

----------------------------------------------------------------------------------------------------------------------------------------------

spring在web中的啟動是由ContextLoaderListener開始的。ContextLoaderListener實現了ServlContextListener介面,並繼承了ContextLoader類。

Java程式碼 [java] view plaincopyprint?
  1. public class ContextLoaderListener extends ContextLoader implements ServletContextListener    
  2. public class ContextLoaderListener extends ContextLoader implements ServletContextListener  



筆記如下:

1.ServletContextListener 介面有兩個方法:contextInitialized,contextDestroyed。
在伺服器載入web應用的時候,這個Listener將被呼叫。
spring在contextInitialized中進行spring容器的初始化。

  1. [java] view plaincopyprint?
    1. <textarea cols="50" rows="15" name="code" class="c-sharp">this.contextLoader.initWebApplicationContext(event.getServletContext());  
    2. </textarea><span style="color: #800000;"> </span>  



2.ContextLoader的initWebApplicationContext方法:

首先判斷web應用中是否有spring容器被載入過,如下

Java程式碼
  1. [java] view plaincopyprint?
    1. <textarea cols="50" rows="15" name="code" class="java">if (servletContext.getAttribute(WebApplicationContext.ROOT_WEB_APPLICATION_CONTEXT_ATTRIBUTE) != null)  
    2. </textarea><span style="color: #800000;"> </span>  



如果有被載入過,將丟擲異常。提示是否放置了多個ContextLoaderListener。

3.建立WebApplicationContext前,將先處理父上下文(對於ERA工程而言有用可能)。
普通的web專案,是沒有父上下文的。

ApplicationContext parent = loadParentContext(servletContext);

下面這句是建立WebApplicationContext的主過程。

Java程式碼 [c-sharp] view plaincopyprint?
  1. this.context = createWebApplicationContext(servletContext, parent);  



建立完的context置於servletContext中,這樣Spring容器的宿主就是ServletContext(application Scope)。

Java程式碼 [c-sharp] view plaincopyprint?
  1. servletContext.setAttribute(WebApplicationContext.ROOT_WEB_APPLICATION_CONTEXT_ATTRIBUTE, this.context);   



4.createWebApplicationContext方法:
首先進行ApplicationContext Class的診斷:如果指定了ContextClass但沒有實現ConfigurableWebApplicationContext的,將丟擲異常。
預設將根據ContextLoader.properties中指定class的例項
即:org.springframework.web.context.support.XmlWebApplicationContext

之後根據Servlet的版本2.4之前及2.5的不同,獲取web的DisplayName。
設定ConfigurableWebApplicationContext的id。

最後程式碼進入實質性的處理

Java程式碼 [java] view plaincopyprint?
  1. wac.setParent(parent);     
  2.  wac.setServletContext(sc);     
  3. //獲取configLocation的配置     
  4.  wac.setConfigLocation(sc.getInitParameter(CONFIG_LOCATION_PARAM));     
  5.  customizeContext(sc, wac);// 用於自定義ContextClass時,擴充自定義Context     
  6.  wac.refresh();// 完成context構造過程。