posts - 64,  comments - 9,  trackbacks - 0
           如果需要使用第三方MVC框架,則不能在web.xml文件中配置ApplicationContext的啟動。但是,ApplicationContext是Spring的容器,負責管理所有的組件,從業務邏輯層組件,到持久層組件,都必須運行在Spring容器中。因此,必須在Web應用啟動時,創建Spring的ApplicationContext實例。事實上,Spring ApplictionContext作為IoC容器,總應該優先加載。
          不管采用怎樣的方法,Spring容器都應該在應用啟動時,自動加載。為了讓Spring容器能自動加載,通常有兩個做法:
          1.讓MVC框架負責創建ApplicationContext實例,MVC框架加載時自動創建Spring容器。Struts就是采用這種機制與Spring整合。
          2.采用load-on-startup Servlet實現。
          根據Servlet2.3標準,所有的ServletContextListener都會比Servlet優先加載——即使是load-on-startup Servlet。ApplicationContext實例是Spring容器,負責管理應用中所有的組件,包括業務邏輯層組件和持久層組件。因此,應該盡可能早的創建Spring容器。
          為此,應該優先采用listener創建ApplicationContext。只是,ServletContextListener是從Servlet 2.3才出現的規范。如果使用了不支持Servlet2.3以上的Web服務器,則只能放棄ServletContextListener,采用load-on-startup Servlet策略。
          Spring管理的組件相當多,如果將所有的組件部署在同一個配置文件里。不僅會降低配置文件的可讀性,增大修改配置文件時引入錯誤的可能性,也不符合軟件工程“分而治之”的規則。通常推薦服務層對象,業務邏輯對象,DAO對象都存在于互不相同的Context中,而表現層對象如Spring MVC控制器,則被配置在表現層Context中。甚至將某個特定模塊的組件部署在單獨的Context中。
          實際的應用中,Spring的配置文件通常不只一個,而是按功能被分成多個。好在,所有負責加載Spring容器的工具都可同時加載多個配置文件。

          一. 采用ContextLoaderListener創建ApplicationContext
          使用ContextLoaderListener創建ApplicationContext必須服務器支持listener,下面這些服務器都是支持Listener的,如果使用這些服務器,則可以使用ContextLoaderListener創建ApplicationContext實例:
          1.Apache Tomcat 4.x+ 。
          2.etty 4.x+ 。
          3.Resin 2.1.8+ 。
          4.Orion 2.0.2+ 。
          5.BEA WebLogic 8.1 SP3。
          Spring提供ServletContextListener的一個實現類ContextLoaderListener,該類可以作為listener使用,它會在創建時候自動查找WEB-INF/下的applicationContext.xml文件,因此,如果只有一個配置文件,并且文件名為applicationContext.xml,只需在web.xml文件中增加如下一段即可:
          <listener>
              <listener-class>org.springframework.web.context.ContextLoaderListener</listener-class>
          </listener>
          如果有多個配置文件需要載入,則考慮使用<context-param>元素來確定配置文件的文件名。ContextLoaderListener加載時,會查找名為contextConfigLocation的參數。因此,配置context-param時參數名字應該是contextConfigLocation。
          帶多個配置文件的web.xml文件如下:
          <!--  XML文件的文件頭-->
          <?xml version="1.0" encoding="ISO-8859-1"?>
          <!--  web.xml文件的DTD等信息-->
          <!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>
           <!--  確定多個配置文件-->
          在web.xml文件中加載Spring容器,這是最常見的做法。Spring自己的MVC框架就是采用這種策略。
          關于讓MVC框架負責創建ApplicationContext實例的情況比較多,因為每個MVC框架的啟動機制有區別,因此加載ApplicationContext的方式也各有不同。
          對于在web.xml配置文件中配置ApplicationContext的自動創建有兩種策略:
          1.利用ServletContextListener實現。
          <context-param>
            <!--  參數名為contextConfigLocation -->
            <param-name>contextConfigLocation</param-name>
            <!--  多個配置文件之間以,隔開 -->
            <param-value>/WEB-INF/daoContext.xml,/WEB-INF/applicationContext.xml</param-value>
           </context-param>
           <!--  采用listener創建ApplicationContext實例-->
              <listener>
                  <listener-class>org.springframework.web.context.ContextLoaderListener</listener-class>
              </listener>
          </web-app>
          如果沒有contextConfigLocation制定配置文件,Spring自動查找applicationContext.xml配置文件。
          如果有contextConfigLocation,則利用該參數確定的配置文件,該參數指定的一個字符串,Spring的ContextLoaderListener負責將該字符串分解成多個配置文件,逗號“,”、空格“ ”、分號“;”都可作為字符串的分割符。
          如果既然沒有applicationContext.xml文件,也沒有使用contextConfigLocation參數確定配置文件,或者contextConfigLocation確定的配置文件不存在,都將導致:Spring無法加載配置文件,無法正常創建ApplicationContext實例。
          Spring根據bean定義創建 WebApplicationContext對象,并將其保存在Web應用的ServletContext中。大部分情況下,應用中的bean無需感受到ApplicationContext的存在,只要利用ApplicationContext的IoC即可。
          如果需要在應用中獲取ApplicationContext實例,可以通過如下方法獲?。?br /> WebApplicationContext ctx =
          WebApplicationContextUtils.getWebApplicationContext(servletContext);
          下面是采用Servlet獲取ApplicationContext的完整源代碼:
          public class SpringTestServlet extends HttpServlet
          {
           //Servlet的響應方法。
           public void service(HttpServletRequest request, HttpServletResponse response)
            throws ServletException,java.io.IOException
           {z
            //獲取Servlet的ServletContext對象
            ServletContext sc = getServletContext();
            //使用WebApplicationContextUtils類獲得ApplicationContext
            WebApplicationContext ctx = WebApplicationContextUtils.getWebApplicationContext(sc);
            //獲取Servlet的頁面輸出流
            PrintWriter out = response.getWriter();
            //將ApplicationContext對象輸出
            out.println(ctx);
           }
          }
          程序里手動獲取ApplicationContext對象,然后直接輸出到Servlet的響應。結果看到,ApplicationContext加載了web.xml文件中指定的兩個配置文件。

          二. 采用load-on-startup Servlet創建ApplicationContext
          如果容器不支持Listener,則只能使用load-on-startup Servlet創建ApplicationContext實例,下面的容器都不支持Listener:
          1.BEA WebLogic up to 8.1 SP2。
          2.IBM WebSphere 5.x 。
          3.Oracle OC4J 9.0.3。
          Spring提供了一個特殊的Servlet類:ContextLoaderServlet。該Servlet在啟動時,會自動查找WEB-INF/下的applicationContext.xml文件。
          當然,為了讓ContextLoaderServlet隨應用啟動而啟動,應將此Servlet配置成load-on-startup的Servlet,load-on-startup的值小一點比較合適,因為要保證ApplicationContext優先創建。如果只有一個配置文件,并且文件名為:applicationContext.xml。在web.xml文件中增加如下一段即可:
          <servlet>
           <servlet-name>context</servlet-name>
           <servlet-class>org.springframework.web.context.ContextLoaderServlet</servlet-class>
           <load-on-startup>1</load-on-startup>
          </servlet>
          該Servlet用于提供“后臺”服務,作為容器管理應用中的其他bean,不需要響應客戶請求,因此無需配置servlet-mapping。
          如果有多個配置文件,一樣使用<context-param>元素來確定多個配置文件。事實上,不管是ContextLoaderServlet,還是ContextLoaderListener,都依賴于ContextLoader創建ApplicationContext實例。在ContextLoader代碼的第240行,有如下代碼:
          String configLocation = servletContext.getInitParameter(CONFIG_LOCATION_PARAM);
          if (configLocation != null) {
           wac.setConfigLocations(StringUtils.tokenizeToStringArray(configLocation,
           ConfigurableWebApplicationContext.CONFIG_LOCATION_DELIMITERS));
          }
          其中CONFIG_LOCATION_PARAM是該類的常量,其值為contextConfigLocation。可看出:ContextLoader首先檢查servletContext中是否有contextConfigLocation的參數,如果有該參數,則加載該參數指定的配置文件。帶多個配置文件的web.xml文件如下:
          <!--  XML文件的文件頭-->
          <?xml version="1.0" encoding="ISO-8859-1"?>
          <!--  web.xml文件的DTD等信息-->
          <!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>
           <!--  確定多個配置文件-->
           <context-param>
            <!--  參數名為contextConfigLocation -->
            <param-name>contextConfigLocation</param-name>
            <!--  多個配置文件之間以,隔開 -->
            <param-value>/WEB-INF/daoContext.xml,/WEB-INF/applicationContext.xml</param-value>
           </context-param>
           <!--  采用load-on-startup Servlet創建ApplicationContext實例-->
          <servlet>
            <servlet-name>context</servlet-name>
            <servlet-class>org.springframework.web.context.ContextLoaderServlet</servlet-class>
            <!--  下面值小一點比較合適,會優先加載-->
            <load-on-startup>1</load-on-startup>
          </servlet>
          </web-app>
          測試所用的Servlet與前面所用的沒有區別。ContextLoaderServlet與ContextLoaderListener底層都依賴于ContextLoader。因此,二者的效果幾乎沒有區別。之間區別不是它們本身引起的,而是由于Servlet2.3的規范:listener比servlet優先加載。因此,采用ContextLoaderListener創建ApplicationContext的時機更早。
          當然,也可以通過ServletContext的getAttribute方法獲取ApplicationContext,使用WebApplicationContextUtils類更便捷,因為無需記住ServletContext屬性名。即使ServletContext的WebApplicationContext.ROOT_WEB_APPLICATION_CONTEXT_ATTRIBUTE屬性沒有對應對象,WebApplicationContextUtils的getWebApplicationContext()方法將會返回空,而不會引起異常。
          獲得了WebApplicationContext實例的引用后,可以通過bean的名字訪問容器中的bean實例。大部分時候,無需通過這種方式訪問容器中的bean。將表現層的控制器bean置入容器的管理中,客戶端請求直接轉發給容器中的bean,然后由容器管理bean之間的依賴,因此,無需手動獲取ApplicationContext引用。當然,每個框架都會有自己特定的整合策略。

          posted on 2009-10-15 11:21 super_nini 閱讀(362) 評論(0)  編輯  收藏

          只有注冊用戶登錄后才能發表評論。


          網站導航:
           
          <2009年10月>
          27282930123
          45678910
          11121314151617
          18192021222324
          25262728293031
          1234567

          常用鏈接

          留言簿

          隨筆檔案

          文章檔案

          相冊

          搜索

          •  

          最新評論

          閱讀排行榜

          評論排行榜

          主站蜘蛛池模板: 嫩江县| 遂平县| 牡丹江市| 香港 | 沧州市| 桃源县| 宿州市| 安泽县| 苗栗市| 雅安市| 太保市| 南投市| 明星| 石家庄市| 缙云县| 多伦县| 沧州市| 金塔县| 迁安市| 通州区| 温宿县| 永寿县| 潼关县| 利辛县| 敖汉旗| 赤水市| 丹巴县| 界首市| 隆尧县| 柘城县| 乌鲁木齐市| 灯塔市| 安岳县| 海淀区| 夹江县| 大化| 灌云县| 汶川县| 布尔津县| 扶余县| 五莲县|