struts+spring 最优整合

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

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

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


<?xml version="1.0" encoding="ISO-8859-1" ?>

<!DOCTYPE
struts-config PUBLIC
          "-//Apache Software Foundation
  //DTD Struts Configuration 1.1//EN"
          "http://jakarta.apache.org
  /struts/dtds/struts-config_1_1.dtd">

<struts-config>
<form-beans>
    <form-bean name="searchForm" 
      type="org.apache.struts.
  validator.DynaValidatorForm">
               <form-property name="isbn"   
   type="java.lang.String"/>
    </form-bean>
  
  </form-beans>

<global-forwards
type="org.apache.struts.
action.ActionForward">
     <forward   name="welcome"               
path="/welcome.do"/>
     <forward   name="searchEntry"           
path="/searchEntry.do"/>
     <forward   name="searchSubmit"          
path="/searchSubmit.do"/>
</global-forwards>

<action-mappings>
    <action    path="/welcome"
forward="/WEB-INF/pages/welcome.htm"/>
    <action    path="/searchEntry"
forward="/WEB-INF/pages/search.jsp"/>
    <action    path="/searchSubmit" 
             type="org.springframework.
web.struts.DelegatingActionProxy" |(1)
             input="/searchEntry.do"
             validate="true"
             name="searchForm">
             <forward name="success"
path="/WEB-INF/pages/detail.jsp"/>
             <forward name="failure"
path="/WEB-INF/pages/search.jsp"/>
    </action>  

</action-mappings>

<message-resources
parameter="ApplicationResources"/>


<plug-in className="org.apache.struts.
validator.ValidatorPlugIn">
    <set-property 
    property="pathnames" 
    value="/WEB-INF/validator-rules.xml,
/WEB-INF/validation.xml"/>
</plug-in>


<plug-in 
    className="org.springframework.web.
struts.ContextLoaderPlugIn">
    <set-property
property="contextConfigLocation"
value="/WEB-INF/beans.xml"/>
</plug-in>

 
</struts-config>


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

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

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


<?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>

</beans>




动作委托的优点
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 应用程序中的日志记录能力。

你可能感兴趣的:(spring,AOP,bean,struts,配置管理)