spring加載及和struts的結合

 web應用中spring提供了幾種加載方式:
1.在web.xml中配置:
<context-param>
    <param-name>contextConfigLocation</param-name>
    <param-value>/WEB-INF/applicationContext.xml</param-value>
</context-param>
<servlet>
    <servlet-name>context</servlet-name>
    <servlet-class>org.springframework.web.context.ContextLoaderServlet</servlet-class>
    <load-on-startup>1</load-on-startup>
</servlet>
2.在web.xml中配置:
<context-param>
    <param-name>contextConfigLocation</param-name>
    <param-value>/WEB-INF/applicationContext.xml</param-value>
</context-param>

<listener>
    <listener-class>org.springframework.web.context.ContextLoaderListener</listener-class>
</listener>

1和2兩種方式,實質是一樣的,因爲在他們各自的初始化方法中,調用的是一樣的創建spring容器的方法
這是1中的:
public void init() throws ServletException {
       contextLoader = createContextLoader();
       contextLoader.initWebApplicationContext(getServletContext());
      }
這是2中的:
public void contextInitialized(ServletContextEvent event) {
       contextLoader = createContextLoader();
       contextLoader.initWebApplicationContext(event.getServletContext());
      }
所以這兩種加載spring容器的方法本質上一樣,spring容器初始化完後,就放到servletContext中。
其key值爲:WebApplicationContext.ROOT_WEB_APPLICATION_CONTEXT_ATTRIBUTE
我們如果要使用WebApplicationContext則需要從ServletContext取出,Spring提供了一個WebApplicationContextUtils類,可以方便的取出

WebApplicationContext,只要把ServletContext傳入就可以了。
獲得applicationContext 方法:
ServletContext context = getServletContext();

WebApplicationContext applicationContext  = WebApplicationContextUtils
     .getWebApplicationContext(context);
  
 DataSource dataSource=(DataSource)applicationContext.getBean("dataSource");
這個方便的類是針對以上面的方式創建的spring容器而用的。


3.在struts.xml中配置加載spring的插件:
<plug-in className="org.springframework.web.struts.ContextLoaderPlugIn">
  <set-property property="contextConfigLocation" value="/WEB-INF/applicationContext.xml,/WEB-INF/action-servlet.xml" />
</plug-in>
這種方法初始化的spring容器,也放在servletContext中,
其key值爲:
ContextLoaderPlugIn.SERVLET_CONTEXT_PREFIX+ModuleConfig.getPrefix()(具體請查看源代碼)。


4.在web.xml中配置:
<servlet>
        <servlet-name>dispatcherServlet</servlet-name>
        <servlet-class>org.springframework.web.servlet.DispatcherServlet</servlet-class>
        <init-param>
            <param-name>contextConfigLocation</param-name>
            <param-value>/WEB-INF/applicationContext</param-value>
        </init-param>
    </servlet>

獲得applicationContext 方法:
ServletContext context = getServletContext();
 
  XmlWebApplicationContext applicationContext = (XmlWebApplicationContext) context.getAttribute

("org.springframework.web.servlet.FrameworkServlet.CONTEXT.dispatcherServlet");


  DataSource dataSource=(DataSource)applicationContext.getBean("dataSource");

************************************************************************************
spring和struts的結合方式。
兩者的結合可以有以下三種方式:
1.使用 Spring 的 ActionSupport 類整合 Structs
2.使用 Spring 的 DelegatingRequestProcessor 覆蓋 Struts 的 RequestProcessor
3.將 Struts Action 管理委託給 Spring 框架


第1種方式用我們自己的Action繼承ActionSupport。這種方式只是方便了我們在action中獲得spring容器對象,在ActionSupport中提供了getWebApplicationContext()方法。獲得了spring容器後,就可以享用spring容器中的bean了。


第2種方式和第3種方式,都是把Struts Action 管理委託給 Spring 框架 ,只是委託方式不一樣。
第2種方式使用 Spring 的 DelegatingRequestProcessor 覆蓋 Struts 的 RequestProcessor。而DelegatingRequestProcessor 所做的工作,也就是,獲得spring容器,獲得被spring容器管理的真正action。

第3種方式在struts.xml中的action配置中配置:
 <action    path="/searchSubmit"  type="org.springframework.web.struts.DelegatingActionProxy"> ...
而這個代理action:DelegatingActionProxy所做的工作也是,獲得spring容器,獲得被spring容器管理的真正action。

這3種結合方式,都需要獲得spring容器,而上面也說到,spring容器的創建也有三種方式(本質上是三種,目前爲止我知道的)。
三種創建spring容器的方式,都在他們創建完spring容器後,將spring容器,放到servletContext對象中,但key值不一樣。這也就決定了獲得spring容器的方法是不同的。

 

在這三種spring和struts的結合方式中都通過以下方式獲得spring容器:
DelegatingActionUtils.findRequiredWebApplicationContext(ActionServlet actionServlet, ModuleConfig moduleConfig)
而這種方法會先去尋找以struts插件形式,創建的spring容器。也就是以上面spring加載方式3中的key值到servletContext中找。
如果找不到,再調用WebApplicationContextUtils.getWebApplicationContext(ServletContext context)方法獲得spring容器。

由WebApplicationContextUtils類獲得的spring容器和由DelegatingActionUtils類獲得的spring容器是不同的。這兩種獲得方法是針對不同的spring容器創建方法的。前者對應的創建方法是上面spring創建方法的第1,2兩種。後者對應的創建方法是上面spring創建方法的第3種。


結論:spring和struts的三種結合方式中,會先去尋找以struts插件形式,創建的spring容器。所以我們在struts中配置spring的加載插件,可以滿足這三種結合方式。在找不到以struts插件形式,創建的spring容器後,會去找以ContextLoaderListener或ContextLoaderServlet創建的spring容器,所以,不管以那種方式創建的spring容器都能滿足spring和struts的三種結合方式。(第4種創建spring容器方式除外)。

這只是自己的分析,還沒實踐,需要研究。

 

發佈了38 篇原創文章 · 獲贊 11 · 訪問量 8萬+
發表評論
所有評論
還沒有人評論,想成為第一個評論的人麼? 請在上方評論欄輸入並且點擊發布.
相關文章