深入探讨Spring与Struts集成方案

转载 2007年09月22日 21:42:00

引言
Spring是一个轻量级(大小和系统开支的角度)的IoC和AOP容器.它力图简化J2EE开发即J2EE without EJB.而且作为帮助企业级开发的核心支柱,Spring为模型层(OR持久层:Hibernate、JDO、iBatis等)服务层(EJB、JNDI、WebService)以及表现层(Struts、JSF、Velocity)都提供了良好的支持和集成方案. 访问Spring官方站
Jakarta-Struts是Apache软件组织提供的一个开源项目.它为Java Web应用提供了基于Model-View-Controller的MVC框架,尤其适用于开发大型可扩展的Web应用.尽管基于Java的MVC框架层出不穷,事实上Spring的MVC模型也提供了驱动应用系统Web层的能力,但Jakarta-Struts仍然是所有这些框架中的佼佼者. 访问Struts官方站
下面,我就将如何整合这两个J2EE领域的经典项目给出两套详尽的集成方案.

进入主题
1.首先我们来看一个Spring-Struts整合应用下的控制器Action类源代码.
public class CourceAction extends Action {
private CourceService courceService;
public ActionForward execute(
ActionMapping mapping,
ActionForm form,
HttpServletRequest request,
HttpServletResponse response) throws Exception {
Set allCources = courceService.getAllCources();
//..........the other statements
request.setAttribute("cources", allCources);
return mapping.findForward("jspView");
} }
分析:CourceService为一个业务实现的接口,此接口声明了一系列的业务处理方法.该方法的实现配置为Spring上下问的一个Bean.由此看来,我们大家都可能会产生一个疑问:Struts action如何取得一个包含在Spring上下文中的Bean呢?为了回答这个问题,Spring提供了两种与Struts集成的方式:(1).从一个知晓Spring上下文的基类派生我们自己的Struts Action类.然后,在派生类中就可以使用super.XX()方法来获得一个对Spring受控Bean的引用.
(2).将请求委托给作为Spring Bean管理的Struts Action来处理.
2.注册Spring插件:为了使Struts Action能够访问由Spring管理的Bean,我们就必须要注册一个知道Spring应用上下文的Struts插件.可以在struts-config.xml中通过如下的方式来完成注册.
<plug-in classname="org.springframework.web.struts.ContextLoadPlugin">
<set-property value="WEB-INF/Yhcip.xml,......" property="contextConfigLocation">
</PLUG-IN>
ContextLoadPlugin()负责装载一个Spring应用上下文.(具体的说:是一个WebApplicationContext).value属性值为要加载的配置Spring受控Bean的xml文件的URI.
3.完成第一种集成方案:实现一个知晓Spring的Action基类.
这种集成方案是从一个公共的能够访问Spring应用上下文的基类中派生所有的Struts Action,但值得庆幸的是:我们不用自己去编写这个知晓Spring应用上下文的基类,因为Spring已经提供了org.springframework.web.struts.ActionSupport:一个org.apache.struts.action.Action的抽象实现.它重载了setServlet()方法以从ContextLoaderPlugin中获取WebapplicationContext.因此,任何时候我们只需要调用super.getBean()方法即可获得一Spring上下文中的一个Bean的引用.
我们再来看一段Action源代码:
public class CourceAction extends ActionSupport {
public ActionForward execute(
ActionMapping mapping,
ActionForm form,
HttpServletRequest request,
HttpServletResponse response) throws Exception {
//取得Spring上下文
ApplicationContext context = super.getWebApplicationContext();
//取得CourceService Bean CourseService courseService = (CourseService) context.getBean("courseService");
Set allCources = courceService.getAllCources(); request.setAttribute("cources", allCources);
//..........the other statements.
return mapping.findForward("jspView");
}}
分析:这个Action类由ActionSupport派生,当CourceAction需要一个Spring受控Bean时:它首先调用基类的getWebApplicationContext()方法以取得一个Spring应用上下文的引用;接着它调用getBean()方法来获取由Spring管理的courceService Bean的一个引用.
小结
至此,我们已经用第一种方案圆满的完成了Spring与Struts的集成工作.这种集成方式的好处在于直观简洁容易上手.除了需要从ActionSupport中派生,以及需要从应用上下文中获取Bean之外,其他都与在非Spring的Struts中编写和配置Action的方法相似.但这种集成方案也有不利的一面.最为显著的是:我们的Action类将直接使用Spring提供的特定类,这样会使我们的Struts Action(即控制层)的代码与Spring紧密耦合在一起.这是我们不情愿看到的.另外,Action类也负责查找由Spring管理的Bean,这违背了反向控制(IoC)的原则.
4.实现第二种集成方案:代理和委托Action.
这种集成方案要求我们编写一个Struts Action,但它只不过是一个包含在Spring应用上下文中的真正Struts Action的一个代理.该代理Action从Struts插件ContextLoaderPlugIn中获取应用上下文,从中查找真正的Struts Action,然后将处理委托给真正的Struts Action.这个方法的幽雅之处在于:只有代理action才会包含Spring特定的处理.真正的Action可以作为org.apache.struts.Action的子类来编写.
下面我们来看一段在之中集成方式下的Struts Action源代码:
public class CourceAction extends Action {
private CourceService courceService;
public ActionForward execute(
ActionMapping mapping,
ActionForm form,
HttpServletRequest request,
HttpServletResponse response) throws Exception {
Set allCources = courceService.getAllCources();
request.setAttribute("cources", allCources);
//..........the other statements.
return mapping.findForward("jspView");
}
/* 注入CourceService */
public void setCourceService(CourceService courceService) {
this.courceService = courceService;
}}
分析:大家可以看到,在这种方式之下,我们的Struts Action类和Spring是低耦合的,它仅仅依赖了Spring提供的反向控制(IoC)机制把CourceService注入到了我们的Action中.到此,大家肯定会有一个疑问:那就是Spring到底是如何提供IoC反向控制的呢?回答这个问题,我们需要完成两个步骤的配置:
(1).在struts-config.xml中注册Struts Action.但要注意的是我们在这里注册的是代理Action.幸运的是,我们不必亲自编写这个类.因为Spring已经通过org.springframework.web.struts.DelegatingActionProxy提供了这个代理的Action.具体的配置方法如下:
<action type="org.springframework.web.struts.DelegatingActionProxy" path="/listCourses">
(2)将真正的Struts Action作为一个Spring Bean并在Spring上下文配置文件中作为一个Bean注册之.并将Action所要引用的courceService注入给它.
<bean class="com.eRedCIP.web.CourceAction" name="/listCourses">
<property name="">
<ref bean="courseService">
</property>
</bean>
注意:name属性的值是非常重要的,它必须和struts-config.xml中的path属性完全一致.这是因为DelegatingActionProxy会使用path属性值在Spring上下文中查找真正的Action.使用DelegatingActionProxy的好处在于我们可以不使用任何Spring特定的类来编写Struts Action.同时,Struts动作能够利用IoC取得和他合作的对象.唯一不足之处就是不太直观,配置相对复杂.为了使action委托显得更为直观一些,我们可对这种集成方案做进一步的改进:使用请求委托.

DelegatingActionProxy同样是org.apache.struts.action.Action的一个子类,它将把调用请求转交给真正的Action实现。下面是DelegatingActionProxy的execute方法代码:
public ActionForward execute(
ActionMapping mapping,
ActionForm form,
HttpServletRequest request,
HttpServletResponse response)
throws Exception {
//获得实际的Action实例,并将请求转交
Action delegateAction = getDelegateAction(mapping);
return delegateAction.execute(mapping, form, request, response);
}
如此一来,Struts 在运行期加载的实际上是DelegatingActionProxy , 而DelegatingActionProxy则实现了针对实际Action的调用代理,Struts最终调用的将是由Spring管理的Action实例
5.使用请求委托.
为了使action委托看上去更为直观一些,Spring提供了DelegatingRequestProcessor,另一种专门用于Spring的请求处理器.需要在struts-config.xml中做如下配置:
<controller processorclass="org.springframework.web.struts.DelegatingRequestProcessor">
这样,DelegatingRequestProcessor将告诉Struts自动将动作请求委托给Spring上下文中的Action来处理.这使得我们可以在struts-config.xml中用struts action的真正类型来声明它们.例如:
<action type="com.eRedCIP.web.CourceAction" path="/listCourses"<
当接受到一个针对/listCourses的请求时,DelegatingRequestProcessor会自动从Spring上下文配置文件中查找一个名为/listCourses的Bean(实为一个Struts Action)类.
<action type="com.eRedCIP.web.CourceAction" path="/listCourses">

结束语
在当今J2EE开发领域,涌现出了一大批优秀的开源项目可供我们选择.让J2EE软件架构师们困惑的问题也由是否要引入开源转变为引入哪些开源以及如何高效整合以做为我们的一个基础开发平台上来.在这篇文章里,我根据自己在J2EE方面的开发经验并结合学习心得向大家提供了两个整合Spring与Struts开源项目的有效集成方案.由于作者水平有限,纰漏之处恳请各路剑客侠女批评指正. 

大型网站系统架构实践(五)深入探讨web应用高可用方案

Haproxy提高web应用的高可用        上一篇文章讲到了haproxy+tomcat的方案,文章地址:大型网站系统架构的演进(四)http层负载均衡之haproxy实践篇(一) ...

深入探讨Box2D中ghost collision问题解决方案

在使用Box2D引擎时,我们必须牢记它只能对物理世界进行近似的仿真。这其中最根本的原因是帧速受限,而且在pixmeter换算以及其它乘除法的约算上,会衍生出大量的边界问题。在box2d官方的FAQ页上...

Struts1.X与Spring集成——第一种方案

spring+struts(第一种方案) 集成原理:在Action中取得BeanFactory,通过BeanFactory取得业务逻辑对象   一,新建一个项目Spring_Struts_01,项目结...

spring与struts2的几种集成方案(部分内容转载网络)

对于spring与struts2的集成有多种方案,在网上找到下面说明还算清楚,所以这里将它直接引用过来,后面将对其原理详加分析  一、需要的JAR文件为:Spring和Struts2框架本身需要的J...

Spring4.2.5+Hibernate4.3.11+Struts1.3.8集成方案一

前面我们已经集成了Spring4.2.5+Hibernate4.3.11这两个框架,现在是时候集成web层框架——Struts1.3.8了。本文是是建立在Spring4.2.5+Hibernate4....

spring与struts1集成方案(二)

上一节介绍了struts单独植入系统的一种使用方式,以及WebApplicationContext在Servlet容器中初始化的原理,一般的Web应用就可以轻松的使用了。          但是,随...

软件测试管理常见问题深入探讨

  • 2015年09月01日 11:30
  • 1.07MB
  • 下载

10053深入探讨

  • 2012年08月30日 10:17
  • 20KB
  • 下载
内容举报
返回顶部
收藏助手
不良信息举报
您举报文章:深入探讨Spring与Struts集成方案
举报原因:
原因补充:

(最多只允许输入30个字)