`

Struts+Spring整合3

阅读更多

struts与<nobr>spring</nobr>三种整合方法_3

分类:默认栏目

窍门 3. 将动作管理委托给 Spring

     一个更好的解决方法是将 Strut 动作管理委托给 Spring。您可以通过在 struts-config 动作映射中注册一个代理来实现。代理负责在 Spring 环境中查找 Struts 动作。由于动作在 Spring 的控制之下,所以它可以填充动作的 JavaBean 属性,并为应用诸如 Spring 的 AOP 拦截器之类的特性带来了可能。

清单 5 中的 Action 类与清单 4 中的相同。但是 struts-config 有一些不同:


清单 5. Spring 整合的委托方法

xml 代码
  1. <?xml version="1.0" encoding="ISO-8859-1" ?>  
  2. <!DOCTYPE struts-config PUBLIC   
  3.             "-//Apache Software Foundation//DTD Struts Configuration 1.1//EN"   
  4.             "http://jakarta.apache.org/struts/dtds/struts-config_1_1.dtd">  
  5. <struts-config>  
  6.  <form-beans>  
  7.       <form-bean name="searchForm"    
  8.         type="org.apache.struts.validator.DynaValidatorForm">  
  9.                  <form-property name="isbn"      type="java.lang.String"/>  
  10.       </form-bean>  
  11.     </form-beans>  
  12.  <global-forwards type="org.apache.struts.action.ActionForward">  
  13.        <forward     name="welcome"                  path="/welcome.do"/>  
  14.        <forward     name="searchEntry"              path="/searchEntry.do"/>  
  15.        <forward     name="searchSubmit"             path="/searchSubmit.do"/>  
  16.  </global-forwards>  
  17.  <action-mappings>  
  18.       <action      path="/welcome" forward="/WEB-INF/pages/welcome.htm"/>  
  19.       <action      path="/searchEntry" forward="/WEB-INF/pages/search.jsp"/>  
  20.       <action      path="/searchSubmit"    
  21.                type="org.springframework.web.struts.DelegatingActionProxy" |(1)   
  22.                input="/searchEntry.do"  
  23.                validate="true"  
  24.                name="searchForm">  
  25.                <forward name="success" path="/WEB-INF/pages/detail.jsp"/>  
  26.                <forward name="failure" path="/WEB-INF/pages/search.jsp"/>  
  27.       </action>       
  28.  </action-mappings>  
  29.  <message-resources parameter="ApplicationResources"/>  
  30.  <plug-in className="org.apache.struts.validator.ValidatorPlugIn">  
  31.       <set-property    
  32.       property="pathnames"    
  33.       value="/WEB-INF/validator-rules.xml,/WEB-INF/validation.xml"/>  
  34.  </plug-in>  
  35.  <plug-in    
  36.       className="org.springframework.web.struts.ContextLoaderPlugIn">  
  37.       <set-property property="contextConfigLocation" value="/WEB-INF/beans.xml"/>  
  38.  </plug-in>  
  39. </struts-config>  


 

      清单 5 是一个典型的 struts-config.xml 文件,只有一个小小的差别。它注册 Spring 代理类的名称,而不是声明动作的类名,如(1)处所示。DelegatingActionProxy 类使用动作映射名称查找 Spring 环境中的动作。这就是我们使用 ContextLoaderPlugIn 声明的环境。

      将一个 Struts 动作注册为一个 Spring bean 是非常直观的,如清单 6 所示。我利用动作映射使用 <bean> 标记的名称属性(在这个例子中是 "/searchSubmit")简单地创建了一个 bean。这个动作的 JavaBean 属性像任何 Spring bean 一样被填充:


清单 6. 在 Spring 环境中注册一个 Struts 动作

xml 代码
  1.   
  2. <?xml version="1.0" encoding="UTF-8"?>  
  3. <!DOCTYPE beans PUBLIC "-//SPRING//DTD BEAN//EN"    
  4.  "http://www.springframework.org/dtd/spring-beans.dtd">  
  5. <beans>  
  6.     <bean id="bookService" class="ca.nexcel.books.business.BookServiceImpl"/>  
  7.     <bean name="/searchSubmit"        
  8.           class="ca.nexcel.books.actions.SearchSubmit">  
  9.        <property name="bookService">  
  10.           <ref bean="bookService"/>  
  11.        </property>  
  12.     </bean>  
  13. </beans>  
  14.   
  15.     


动作委托的优点

     动作委托解决方法是这三种方法中最好的。Struts 动作不了解 Spring,不对代码作任何改变就可用于非 Spring 应用程序中。RequestProcessor 的改变不会影响它,并且它可以利用 Spring AOP 特性的优点。

      动作委托的优点不止如此。一旦让 Spring 控制您的 Struts 动作,您就可以使用 Spring 给动作补充更强的活力。例如,没有 Spring 的话,所有的 Struts 动作都必须是线程安全的。如果您设置 <bean> 标记的 singleton 属性为“false”,那么不管用何种方法,您的应用程序都将在每一个请求上有一个新生成的动作对象。您可能不需要这种特性,但是把它放在您的工具箱中也很好。您也可以利用 Spring 的生命周期方法。例如,当实例化 Struts 动作时,<bean> 标记的 init-method 属性被用于运行一个方法。类似地,在从容器中删除 bean 之前,destroy-method 属性执行一个方法。这些方法是管理昂贵对象的好办法,它们以一种与 Servlet 生命周期相同的方式进行管理。

拦截 Struts

     前面提到过,通过将 Struts 动作委托给 Spring 框架而整合 Struts 和 Spring 的一个主要的优点是:您可以将 Spring 的 AOP 拦截器应用于您的 Struts 动作。通过将 Spring 拦截器应用于 Struts 动作,您可以用最小的代价处理横切关注点。

     虽然 Spring 提供很多内置拦截器,但是我将向您展示如何创建自己的拦截器并把它应用于一个 Struts 动作。为了使用拦截器,您需要做三件事:

  1. 创建拦截器。
  2. 注册拦截器。
  3. 声明在何处拦截代码。

     这看起来非常简单的几句话却非常强大。例如,在清单 7 中,我为 Struts 动作创建了一个日志记录拦截器。 这个拦截器在每个方法调用之前打印一句话:


清单 7. 一个简单的日志记录拦截器


package ca.nexcel.books.interceptors;
import org.springframework.aop.MethodBeforeAdvice;
import java.lang.reflect.Method;
public class LoggingInterceptor implements MethodBeforeAdvice {
    public void before(Method method, Object[] objects, Object o) throws Throwable {
         System.out.println("logging before!");
     }
}
      

     这个拦截器非常简单。before() 方法在拦截点中每个方法之前运行。在本例中,它打印出一句话,其实它可以做您想做的任何事。下一步就是在 Spring 配置文件中注册这个拦截器,如清单 8 所示:


清单 8. 在 Spring 配置文件中注册拦截器

xml 代码
  1. <?xml version="1.0" encoding="UTF-8"?>  
  2. <!DOCTYPE beans PUBLIC "-//SPRING//DTD BEAN//EN"    
  3.    "http://www.springframework.org/dtd/spring-beans.dtd">  
  4. <beans>  
  5.    <bean id="bookService" class="ca.nexcel.books.business.BookServiceImpl"/>  
  6.    <bean name="/searchSubmit"    
  7.          class="ca.nexcel.books.actions.SearchSubmit">  
  8.       <property name="bookService">  
  9.          <ref bean="bookService"/>  
  10.       </property>  
  11.    </bean>  
  12.    <!--   Interceptors -->    
  13.    <bean name="logger"        
  14.      class="ca.nexcel.books.interceptors.LoggingInterceptor"/> |(1)   
  15.    <!-- AutoProxies -->  
  16.    <bean name="loggingAutoProxy"    
  17.          class="org.springframework.aop.framework.autoproxy.   
  18.            BeanNameAutoProxyCreator"> |(2)   
  19.      <property name="beanNames">  
  20.            <value>/searchSubmit</valuesgt; |(3)   
  21.      </property>  
  22.      <property name="interceptorNames">  
  23.          <list>  
  24.            <value>logger</value> |(4)   
  25.          </list>  
  26.      </property>  
  27.     </bean>  
  28. </beans>  
  29.         


您可能已经注意到了,清单 8 扩展了 清单 6 中所示的应用程序以包含一个拦截器。具体细节如下:

  • 在 (1) 处,我注册了这个拦截器。
  • 在 (2) 处,我创建了一个 bean 名称自动代理,它描述如何应用拦截器。还有其他的方法定义拦截点,但是这种方法常见而简便。
  • 在 (3) 处,我将 Struts 动作注册为将被拦截的 bean。如果您想要拦截其他的 Struts 动作,则只需要在 "beanNames" 下面创建附加的 <value> 标记。
  • 在 (4) 处,当拦截发生时,我执行了在 (1) 处创建的拦截器 bean 的名称。这里列出的所有拦截器都应用于“beanNames”。

     就是这样。就像这个例子所展示的,将您的 Struts 动作置于 Spring 框架的控制之下,为处理您的 Struts 应用程序提供了一系列全新的选择。在本例中,使用动作委托可以轻松地利用 Spring 拦截器提高 Struts 应用程序中的日志记录能力。

结束语

     在本文中,您已经学习了将 Struts 动作整合到 Spring 框架中的三种窍门。使用 Spring 的 ActionSupport 来整合 Struts(第一种窍门中就是这样做的)简单而快捷,但是会将 Struts 动作与 Spring 框架耦合在一起。如果您需要将应用程序移植到一个不同的框架,则需要重写代码。第二种解决方法通过委托 RequestProcessor 巧妙地解开代码的耦合,但是它的可扩展性不强,并且当 Struts 的 RequestProcessor 变成一系列命令时,这种方法就持续不了很长时间。第三种方法是这三种方法中最好的:将 Struts 动作委托给 Spring 框架可以使代码解耦,从而使您可以在您的 Struts 应用程序中利用 Spring 的特性(比如日志记录拦截器)。

三种 Struts-Spring 整合窍门中的每一种都被实现成一个完整可用的应用程序

你可以通过这个链接引用该篇文章:http://pearlkeeper.bokee.com/tb.b?diaryId=15898825

分享到:
评论
3 楼 sahero167 2008-07-02  
请问,第三种方法,把Struts 动作委托给 Spring 后,可以干些什么呢?
2 楼 binfei 2008-06-27  
文章很好,可惜不是你的,请转载标注一下!!!
1 楼 sniperyj 2008-03-12  
看了你的文章收获很是巨大,明白了Sping整合Struts的3种方法.理解了这3种方法的优缺点!!受益良多~~谢谢.

相关推荐

Global site tag (gtag.js) - Google Analytics