当前位置: 首页 > 图文教程 > Java技术 > Web框架 > Struts in Spring

Web框架
struts2(三)
struts2(四)
struts2(五)
struts2(六)
Spring中注入概念的简单介绍
深入探讨struts的ActionMessages消息机制(转)
DWR 的 Converter 实现原理简单分析及应用
详解Spring中bean的作用域
AJAX实现级联下拉框
Spring AOP面向方面编程原理:AOP概念
Spring结合Hibernate声明式事务配置
Struts 概述
Ajax 入门简介
Struts配置文件详解
Struts in Spring
Struts 开发的最佳实践
Struts核心标签
开发框架:利用STRUTS实现国际化支持
Struts自定义标签的过程
Struts 框架的基本概念及实现MVC模式的原理

Web框架 中的 Struts in Spring


出处:互联网   整理: 软晨网(RuanChen.com)   发布: 2009-08-14   浏览: 78 ::
收藏到网摘: n/a

勿庸置疑,Struts是目前Java Web MVC框架中不争的王者。经过长达五年的发展,Struts
已经逐渐成长为一个稳定、成熟的框架,并且占有了MVC框架中最大的市场份额。
长达五年的设计延续性,自然导致其在某些技术特性上已经落后于新兴的MVC框架。
面对Spring MVC、Webwork2 这些设计更精密,扩展性更强的框架,Struts受到了前所未有
的挑战。
不过,纵然目前讨伐之声日起,甚至包括Spring Framework的作者Rod Johnson对Struts
的评价也不甚高。但站在产品开发的角度而言,Struts仍然是最稳妥的选择。
何谓“最稳妥”?并非完全意味着技术上的稳定性,而是指社会劳动力供给。感兴趣的
读者可以去51job、chinahr 这些人力资源网站上搜索一下Java Web 程序员应聘简历。几乎
所有Java Web 开发人员都在简历上注明“精通Struts”,且不论真正精通的能有多少,但就
凭Struts这非凡的上镜率,其普及度也可见一斑。
这也就意味着,即使公司发生惨绝人寰的人事大变动,产品经理也不必过于惊惶失措,
茫茫人海中,有大批的Struts们以供选择,只需好好考虑好新员工的业务培训如何开展即可,
而对于技术延续性,则不必太过于担心。
这也就是Struts 带来的战略性优势(对于公司而言,这一点往往是关键所在),其他
MVC框架目前还无法在这点上与之并驾齐驱。
考虑到目前市面上已经有了众多的Struts书籍8。这里也就不再针对Struts的技术细节再
加赘述,下面主要针对Struts-Spring组合应用进行探讨。

首先,Struts与Spring如何整合?

为了在Struts中加载Spring Context,在struts-config.xml中增加如下部分:

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

Spring在设计时就充分考虑到了与Struts的协同工作,通过内置的Struts Plug-in在两者
之间提供了良好的结合点,这与WS组合不同,WS组合需要嵌入来自第三方的类库。
通过plug-in我们实现了Spring Context的加载,不过仅仅加载Context并没有什么实际
意义,我们还需要修改配置,将Struts Action交给Spring容器进行管理:
下面的struts-config.xml 中包含了用户登录示例的相关配置:

<struts-config>
<form-beans>
<form-bean name="loginForm" type="net.xiaxin.bean.LoginForm" />
</form-beans>
<action-mappings>
<action path="/login"
type="org.springframework.web.struts.DelegatingActionProxy"
name="loginForm">
<forward name="success" path="/main.jsp" />
<forward name="failure" path="/login.jsp" />
</action>
<!-- Struts Action Setting
<action path="/login" type="net.xiaxin.action.LoginAction"
name="loginForm">
<forward name="success" path="/main.jsp" />
<forward name="failure" path="/login.jsp" />
</action>
-->
</action-mappings>
<plug-in
className="org.springframework.web.struts.ContextLoaderPlugIn"><set-property property="contextConfigLocation"
value="/WEB-INF/applicationContext.xml" />
</plug-in>
</struts-config>
可以看到,其中配置了一个form bean “LoginForm”,在这点上,配置与传统Struts配置
并没有什么不同。
而在action配置上,则出现了一些变化,上面的action-mapping配置中包含了loginForm
的两种配置形式,第一种是面向SS组合改造后的形式,第二种(作为注释)是与之对应的
传统Struts配置方式。
不难看出,我们试图在action-mapping 中增加一个名为loginForm 的Action,传统方式
中,直接将类名作为action节点的type属性,Struts将根据type中的类名加载对应的Action
实例。
而在面向SS组合的配置方式中,我们用Spring提供的DelegatingActionProxy 作为Action
的type属性。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实例。
SS 组合的玄机也正在与此,通过这样的方式,Spring 获得了对Action 实例的管理权,
它将对Action进行调度,并为Struts提供所需的Action实例。既然Action已经由Spring全
权接管,那么我们就可以将此Action看作是Spring中的一个Bean,它可享受Spring提供的
所有服务(依赖注入、实例管理、事务管理等)。
与之对应,Spring Context配置如下:
applicationContext.xml:
<?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="dataSource"
class="org.apache.commons.dbcp.BasicDataSource"
destroy-method="close">
<property name="driverClassName">
<value>org.gjt.mm.mysql.Driver</value>
</property>
<property name="url">
<value>jdbc:mysql://localhost/sample</value>
</property>
<property name="username">
<value>sysadmin</value>
</property>
<property name="password">
<value>security</value>
</property>
</bean>
<bean id="sessionFactory"
class="org.springframework.orm.hibernate.LocalSessionFactoryBean"
>
<property name="dataSource">
<ref local="dataSource" />
</property>
<property name="mappingResources">
<list>
<value>net\xiaxin\db\entity\User.hbm.xml</value>
</list>
</property>
<property name="hibernateProperties">
<props>
<prop key="hibernate.dialect">
net.sf.hibernate.dialect.MySQLDialect
</prop>
<prop key="hibernate.show_sql">true</prop>
</props>
</property></bean>
<bean id="transactionManager"
class="org.springframework.orm.hibernate.HibernateTransactionMana
ger">
<property name="sessionFactory">
<ref local="sessionFactory" />
</property>
</bean>
<bean id="userDAO" class="net.xiaxin.db.dao.UserDAOImp">
<property name="sessionFactory">
<ref local="sessionFactory" />
</property>
</bean>
<bean id="userDAOProxy"
class="org.springframework.transaction.interceptor.TransactionPro
xyFactoryBean">
<property name="transactionManager">
<ref bean="transactionManager" />
</property>
<property name="target">
<ref local="userDAO" />
</property>
<property name="transactionAttributes">
<props>
<prop key="insert*">PROPAGATION_REQUIRED</prop>
<prop key="get*">PROPAGATION_REQUIRED,readOnly</prop>
<prop key="is*">PROPAGATION_REQUIRED,readOnly</prop>
</props>
</property>
</bean>
<bean name="/login" class="net.xiaxin.action.LoginAction"
singleton="false">
<property name="userDAO">
<ref bean="userDAOProxy" />
</property>
</bean></beans>

最后一个Bean的配置是关键,这个名为"/login"的Bean与Struts中的
<action path="/login" ……>
……
</action>
节点相对应。
这样,Spring Bean Name与Struts Action Path相关联,当Struts加载对应的Action时,
DelegatingActionProxy就根据传入的path属性,在Spring Context寻找对应的bean,并将其
实例返回给Struts(参见Spring 中org.springframework.web.struts.DelegatingActionUtils.
determineActionBeanName 方法的实现代码,DelegatingActionProxy将调用此方法获得Struts
Action对应的Bean name)。
与此同时,还可以看到,"/login" bean 中包含了一个userDAO 引用,Spring 在运行
期将根据配置为其提供userDAO 实例,以及围绕userDAO 的事务管理服务。这样一来,对
于Struts 开发而言,我们既可以延续Struts 的开发流程,也可以享受Spring 提供的事务管
理服务。
而bean 的另外一个属性singleton="false",指明了Action 的实例获取方式为每次
重新创建。这也解决了Struts中令人诟病的线程安全问题(Struts中,由一个Action实例处
理所有的请求,这就导致了类公用资源在并发请求中的线程同步问题。)
至此,SS组合已经将Struts MVC以及Spring中的Bean管理、事务管理融为一体。如
果算上userDAO 中的Hibernate 部分,我们就获得了一个全面、成熟、高效、自顶而下的
Web 开发框架。