首页 | 新闻 | 新品 | 文库 | 方案 | 视频 | 下载 | 商城 | 开发板 | 数据中心 | 座谈新版 | 培训 | 工具 | 博客 | 论坛 | 百科 | GEC | 活动 | 主题月 | 电子展
返回列表 回复 发帖

基于 struts+spring+ibatis 的轻量级 J2EE 开发(1)

基于 struts+spring+ibatis 的轻量级 J2EE 开发(1)

JpetStore 4.0 是 ibatis 的最新示例程序,基于 Struts MVC 框架(注:非传统 Struts 开发模式),以 ibatis 作为持久化层。该示例程序设计优雅,层次清晰,可以学习以及作为一个高效率的编程模型参考。本文是在其基础上,采用 Spring 对其中间层(业务层)进行改造。使开发量进一步减少,同时又拥有了 Spring 的一些好处…
1.         前言JpetStore 4.0 是 ibatis 的最新示例程序。ibatis 是开源的持久层产品,包含 SQL Maps 2.0 和 Data Access Objects 2.0 框架。JpetStore 示例程序很好的展示了如何利用 ibatis 来开发一个典型的 J2EE web 应用程序。JpetStore 有如下特点:
  • ibatis 数据层
  • POJO 业务层
  • POJO 领域类
  • Struts MVC
  • JSP 表示层
以下是本文用到的关键技术介绍,本文假设您已经对 Struts,SpringFramewok,ibatis 有一定的了解,如果不是,请首先查阅附录中的参考资料。
  • Struts 是目前 Java Web MVC 框架中不争的王者。经过长达五年的发展,Struts 已经逐渐成长为一个稳定、成熟的框架,并且占有了 MVC 框架中最大的市场份额。但是 Struts 某些技术特性上已经落后于新兴的 MVC 框架。面对 Spring MVC、Webwork2 这些设计更精密,扩展性更强的框架,Struts 受到了前所未有的挑战。但站在产品开发的角度而言,Struts 仍然是最稳妥的选择。本文的原型例子 JpetStore 4.0 就是基于 Struts 开发的,但是不拘泥于 Struts 的传统固定用法,例如只用了一个自定义 Action 类,并且在 form bean 类的定义上也是开创性的,令人耳目一新,稍后将具体剖析一下。
  • Spring Framework 实际上是 Expert One-on-One J2EE Design and Development 一书中所阐述的设计思想的具体实现。Spring Framework 的功能非常多。包含 AOP、ORM、DAO、Context、Web、MVC 等几个部分组成。Web、MVC 暂不用考虑,JpetStore 4.0 用的是更成熟的 Struts 和 JSP;DAO 由于目前 Hibernate、JDO、ibatis 的流行,也不考虑,JpetStore 4.0 用的就是 ibatis。因此最需要用的是 AOP、ORM、Context。Context 中,最重要的是 Beanfactory,它能将接口与实现分开,非常强大。目前 AOP 应用最成熟的还是在事务管理上。
  • ibatis 是一个功能强大实用的 SQL Map 工具,不同于其他 ORM 工具(如 hibernate),它是将 SQL 语句映射成 Java 对象,而对于 ORM 工具,它的 SQL 语句是根据映射定义生成的。ibatis 以 SQL 开发的工作量和数据库移植性上的让步,为系统设计提供了更大的自由空间。有 ibatis 代码生成的工具,可以根据 DDL 自动生成 ibatis 代码,能减少很多工作量。
2.          JpetStore 简述2.1.         背景最初是 Sun 公司的 J2EE petstore,其最主要目的是用于学习 J2EE,但是其缺点也很明显,就是过度设计了。接着 Oracle 用 J2EE petstore 来比较各应用服务器的性能。微软推出了基于 .Net 平台的 Pet shop,用于竞争 J2EE petstore。而 JpetStore 则是经过改良的基于 struts 的轻便框架 J2EE web 应用程序,相比来说,JpetStore 设计和架构更优良,各层定义清晰,使用了很多最佳实践和模式,避免了很多"反模式",如使用存储过程,在 java 代码中嵌入 SQL 语句,把 HTML 存储在数据库中等等。最新版本是 JpetStore 4.0。
2.2.          JpetStore 开发运行环境的建立1、开发环境
  • Java SDK 1.4.2
  • Apache Tomcat 4.1.31
  • Eclipse-SDK-3.0.1-win32
  • HSQLDB 1.7.2
2、Eclipse 插件
  • EMF SDK 2.0.1:Eclipse 建模框架,lomboz 插件需要,可以使用 runtime 版本。
  • lomboz 3.0:J2EE 插件,用来在 Eclipse 中开发 J2EE 应用程序
  • Spring IDE 1.0.3:Spring Bean 配置管理插件
  • xmlbuddy_2.0.10:编辑 XML,用免费版功能即可
  • tomcatPluginV3:tomcat 管理插件
  • Properties Editor:编辑 java 的属性文件 , 并可以预览以及自动存盘为 Unicode 格式。免去了手工或者 ANT 调用 native2ascii 的麻烦。
3、示例源程序
2.3.         架构图 1 JpetStore 架构图图 1 是 JPetStore 架构图,更详细的内容请参见 JPetStore 的白皮书。参照这个架构图,让我们稍微剖析一下源代码,得出 JpetStore 4.0 的具体实现图(见图 2),思路一下子就豁然开朗了。前言中提到的非传统的 struts 开发模式,关键就在 struts Action 类和 form bean 类上。
struts Action 类只有一个:BeanAction。没错,确实是一个!与传统的 struts 编程方式很不同。再仔细研究 BeanAction 类,发现它其实是一个通用类,利用反射原理,根据 URL 来决定调用 formbean 的哪个方法。BeanAction 大大简化了 struts 的编程模式,降低了对 struts 的依赖(与 struts 以及 WEB 容器有关的几个类都放在 com.ibatis.struts 包下,其它的类都可以直接复用)。利用这种模式,我们会很容易的把它移植到新的框架如 JSF,spring。
这样重心就转移到 form bean 上了,它已经不是普通意义上的 form bean 了。查看源代码,可以看到它不仅仅有数据和校验 / 重置方法,而且已经具有了行为,从这个意义上来说,它更像一个 BO(Business Object)。这就是前文讲到的,BeanAction 类利用反射原理,根据 URL 来决定调用 form bean 的哪个方法(行为)。form bean 的这些方法的签名很简单,例如:
1
2
3
4
public String myActionMethod() {
  //..work
  return "success";
}




方法的返回值直接就是字符串,对应的是 forward 的名称,而不再是 ActionForward 对象,创建 ActionForward 对象的任务已经由 BeanAction 类代劳了。
另外,程序还提供了 ActionContext 工具类,该工具类封装了 request 、response、form parameters、request attributes、session attributes 和 application attributes 中的数据存取操作,简单而线程安全,form bean 类使用该工具类可以进一步从表现层框架解耦。
在这里需要特别指出的是,BeanAction 类是对 struts 扩展的一个有益尝试,虽然提供了非常好的应用开发模式,但是它还非常新,一直在发展中。
图 2 JpetStore 4.0 具体实现2.4.         代码剖析下面就让我们开始进一步分析 JpetStore4.0 的源代码,为下面的改造铺路。
  • BeanAction.java 是唯一一个 Struts action 类,位于 com.ibatis.struts 包下。正如上文所言,它是一个通用的控制类,利用反射机制,把控制转移到 form bean 的某个方法来处理。详细处理过程参考其源代码,简单明晰。
  • Form bean 类位于 com.ibatis.jpetstore.presentation 包下,命名规则为 ***Bean。Form bean 类全部继承于 BaseBean 类,而 BaseBean 类实际继承于 ActionForm,因此,Form bean 类就是 Struts 的 ActionForm,Form bean 类的属性数据就由 struts 框架自动填充。而实际上,JpetStore4.0 扩展了 struts 中 ActionForm 的应用: Form bean 类还具有行为,更像一个 BO, 其行为(方法)由 BeanAction 根据配置(struts-config.xml)的 URL 来调用。虽然如此,我们还是把 Form bean 类定位于表现层。
    Struts-config.xml 的配置里有 3 种映射方式,来告诉 BeanAction 把控制转到哪个 form bean 对象的哪个方法来处理。
    以这个请求连接为例 http://localhost/jpetstore4/shop/viewOrder.do
    1.          URL Pattern
    1
    2
    3
    4
    5
      <action path="/shop/viewOrder" type="com.ibatis.struts.BeanAction"
      name="orderBean" scope="session"
      validate="false">
      <forward name="success" path="/order/ViewOrder.jsp"/>
    </action>




    此种方式表示,控制将被转发到"orderBean"这个 form bean 对象 的"viewOrder"方法(行为)来处理。方法名取"path"参数的以"/"分隔的最后一部分。
    2.          Method Parameter
    1
    2
    3
    4
    5
      <action path="/shop/viewOrder" type="com.ibatis.struts.BeanAction"
      name="orderBean" parameter="viewOrder" scope="session"
      validate="false">
      <forward name="success" path="/order/ViewOrder.jsp"/>
    </action>




    此种方式表示,控制将被转发到"orderBean"这个 form bean 对象的"viewOrder"方法(行为)来处理。配置中的"parameter"参数表示 form bean 类上的方法。"parameter"参数优先于"path"参数。
    3.          No Method call
    1
    2
    3
    4
    5
      <action path="/shop/viewOrder" type="com.ibatis.struts.BeanAction"
      name="orderBean" parameter="*" scope="session"
      validate="false">
      <forward name="success" path="/order/ViewOrder.jsp"/>
    </action>




    此种方式表示,form bean 上没有任何方法被调用。如果存在"name"属性,则 struts 把表单参数等数据填充到 form bean 对象后,把控制转发到"success"。否则,如果 name 为空,则直接转发控制到"success"。
    这就相当于 struts 内置的 org.apache.struts.actions.ForwardAction 的功能
    1
    2
    3
    <action path="/shop/viewOrder" type="org.apache.struts.actions.ForwardAction"
       parameter="/order/ViewOrder.jsp " scope="session" validate="false">
    </action>




  • Service 类位于 com.ibatis.jpetstore.service 包下,属于业务层。这些类封装了业务以及相应的事务控制。Service 类由 form bean 类来调用。
  • com.ibatis.jpetstore.persistence.iface 包下的类是 DAO 接口,属于业务层,其屏蔽了底层的数据库操作,供具体的 Service 类来调用。DaoConfig 类是工具类(DAO 工厂类),Service 类通过 DaoConfig 类来获得相应的 DAO 接口,而不用关心底层的具体数据库操作,实现了如图 2 中 { 耦合 2} 的解耦。
  • com.ibatis.jpetstore.persistence.sqlmapdao 包下的类是对应 DAO 接口的具体实现,在 JpetStore4.0 中采用了 ibatis 来实现 ORM。这些实现类继承 BaseSqlMapDao 类,而 BaseSqlMapDao 类则继承 ibatis DAO 框架中的 SqlMapDaoTemplate 类。ibatis 的配置文件存放在 com.ibatis.jpetstore.persistence.sqlmapdao.sql 目录下。这些类和配置文件位于数据层
  • Domain 类位于 com.ibatis.jpetstore.domain 包下,是普通的 javabean。在这里用作数据传输对象(DTO),贯穿视图层、业务层和数据层,用于在不同层之间传输数据。
剩下的部分就比较简单了,请看具体的源代码,非常清晰。
2.5.         需要改造的地方JpetStore4.0 的关键就在 struts Action 类和 form bean 类上,这也是其精华之一(虽然该实现方式是试验性,待扩充和验证),在此次改造中我们要保留下来,即控制层一点不变,表现层获取相应业务类的方式变了(要加载 spring 环境),其它保持不变。要特别关注的改动是业务层和持久层,幸运的是 JpetStore4.0 设计非常好,需要改动的地方非常少,而且由模式可循,如下:
1.         业务层和数据层用 Spring BeanFactory 机制管理。
2.         业务层的事务由 spring 的 aop 通过声明来完成。
3.         表现层(form bean)获取业务类的方法改由自定义工厂类来实现(加载 spring 环境)。
返回列表