技术开发 频道

使用 Spring 更好地处理 Struts 动作


动作委托的优点

  动作委托解决方法是这三种方法中最好的。Struts动作不了解Spring,不对代码作任何改变就可用于非Spring应用程序中。RequestProcessor的改变不会影响它,并且它可以利用 Spring AOP 特性的优点。动作委托的优点不止如此。一旦让 Spring 控制您的 Struts 动作,您就可以使用 Spring 给动作补充更强的活力。例如,没有 Spring 的话,所有的 Struts 动作都必须是线程安全的。
 
  如果您设置 标记的 singleton 属性为false,那么不管用何种方法,您的应用程序都将在每一个请求上有一个新生成的动作对象。
 
  您可能不需要这种特性,但是把它放在您的工具箱中也很好。您也可以利用 Spring 的生命周期方法。例如,当实例化 Struts 动作时, 标记的 init-method 属性被用于运行一个方法。
 
  类似地,在从容器中删除 bean 之前,destroy-method 属性执行一个方法。这些方法是管理昂贵对象的好办法,它们以一种与 Servlet 生命周期相同的方式进行管理。
 
拦截 Struts
 
  前面提到过,通过将 Struts 动作委托给 Spring 框架而整合 Struts 和 Spring 的一个主要的优点是:您可以将 Spring 的 AOP 拦截器应用于您的 Struts 动作。通过将 Spring 拦截器应用于 Struts 动作,您可以用最小的代价处理横切关注点。
 
  虽然 Spring 提供很多内置拦截器,但是我将向您展示如何创建自己的拦截器并把它应用于一个 Struts 动作。为了使用拦截器,您需要做三件事:
 
·创建拦截器。
·注册拦截器。
·声明在何处拦截代码。
 
  这看起来非常简单的几句话却非常强大。例如,在清单 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 version="1.0" encoding="UTF-8"?>
<!DOCTYPE beans PUBLIC "-/
/SPRING//DTD BEAN//EN" 
"http://www.springframework.
org/dtd/spring-beans.dtd">
 
<beans>
 <bean id="bookService" class="ca.nexcel.books.business.BookServiceImpl"/>
 
 <bean name="/searchSubmit" 
        class="ca.nexcel.books.actions.SearchSubmit">
     <property name="bookService">
        <ref bean="bookService"/>
     </property>
 </bean>
 
 <!-- Interceptors --> 
 <bean name="logger"    
    class="ca.nexcel.books.interceptors.
     LoggingInterceptor"/> |(1)
 
 <!-- AutoProxies -->
 <bean name="loggingAutoProxy" 
        class="org.springframework.aop.
         framework.autoproxy.
          BeanNameAutoProxyCreator"> |(2)
    <property name="beanNames">
          <value>/searchSubmit</valuesgt; |(3)
    </property>
    <property name="interceptorNames">
        <list>
          <value>logger</value> |(4)
        </list>
    </property>
   </bean>
 
</beans>
 
  您可能已经注意到了,清单8扩展了清单6中所示的应用程序以包含一个拦截器。具体细节如下:在(1)处,我注册了这个拦截器。(2)处,我创建了一个bean名称自动代理,它描述如何应用拦截器。还有其他的方法定义拦截点,但是这种方法常见而简便。
 
  在 (3) 处,我将 Struts 动作注册为将被拦截的 bean。如果您想要拦截其他的 Struts 动作,则只需要在 "beanNames" 下面创建附加的 标记。在 (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 整合窍门中的每一种都被实现成一个完整可用的应用程序。
0
相关文章