基于struts+spring+ibatis的轻量级J2EE开发.docx
- 文档编号:7163031
- 上传时间:2023-01-21
- 格式:DOCX
- 页数:17
- 大小:85.22KB
基于struts+spring+ibatis的轻量级J2EE开发.docx
《基于struts+spring+ibatis的轻量级J2EE开发.docx》由会员分享,可在线阅读,更多相关《基于struts+spring+ibatis的轻量级J2EE开发.docx(17页珍藏版)》请在冰豆网上搜索。
基于struts+spring+ibatis的轻量级J2EE开发
基于struts+spring+ibatis的轻量级J2EE开发
JpetStore4.0是ibatis的最新示例程序,基于StrutsMVC框架(注:
非传统Struts开发模式),以ibatis作为持久化层。
该示例程序设计优雅,层次清晰,可以学习以及作为一个高效率的编程模型参考。
本文是在其基础上,采用Spring对其中间层(业务层)进行改造。
使开发量进一步减少,同时又拥有了Spring的一些好处…
1.前言
JpetStore4.0是ibatis的最新示例程序。
ibatis是开源的持久层产品,包含SQLMaps2.0和DataAccessObjects2.0框架。
JpetStore示例程序很好的展示了如何利用ibatis来开发一个典型的J2EEweb应用程序。
JpetStore有如下特点:
∙ibatis数据层
∙POJO业务层
∙POJO领域类
∙StrutsMVC
∙JSP表示层
以下是本文用到的关键技术介绍,本文假设您已经对Struts,SpringFramewok,ibatis有一定的了解,如果不是,请首先查阅附录中的参考资料。
∙Struts是目前JavaWebMVC框架中不争的王者。
经过长达五年的发展,Struts已经逐渐成长为一个稳定、成熟的框架,并且占有了MVC框架中最大的市场份额。
但是Struts某些技术特性上已经落后于新兴的MVC框架。
面对SpringMVC、Webwork2这些设计更精密,扩展性更强的框架,Struts受到了前所未有的挑战。
但站在产品开发的角度而言,Struts仍然是最稳妥的选择。
本文的原型例子JpetStore4.0就是基于Struts开发的,但是不拘泥于Struts的传统固定用法,例如只用了一个自定义Action类,并且在formbean类的定义上也是开创性的,令人耳目一新,稍后将具体剖析一下。
∙SpringFramework实际上是ExpertOne-on-OneJ2EEDesignandDevelopment一书中所阐述的设计思想的具体实现。
SpringFramework的功能非常多。
包含AOP、ORM、DAO、Context、Web、MVC等几个部分组成。
Web、MVC暂不用考虑,JpetStore4.0用的是更成熟的Struts和JSP;DAO由于目前Hibernate、JDO、ibatis的流行,也不考虑,JpetStore4.0用的就是ibatis。
因此最需要用的是AOP、ORM、Context。
Context中,最重要的是Beanfactory,它能将接口与实现分开,非常强大。
目前AOP应用最成熟的还是在事务管理上。
∙ibatis是一个功能强大实用的SQLMap工具,不同于其他ORM工具(如hibernate),它是将SQL语句映射成Java对象,而对于ORM工具,它的SQL语句是根据映射定义生成的。
ibatis以SQL开发的工作量和数据库移植性上的让步,为系统设计提供了更大的自由空间。
有ibatis代码生成的工具,可以根据DDL自动生成ibatis代码,能减少很多工作量。
2.JpetStore简述
2.1.背景
最初是Sun公司的J2EEpetstore,其最主要目的是用于学习J2EE,但是其缺点也很明显,就是过度设计了。
接着Oracle用J2EEpetstore来比较各应用服务器的性能。
微软推出了基于.Net平台的Petshop,用于竞争J2EEpetstore。
而JpetStore则是经过改良的基于struts的轻便框架J2EEweb应用程序,相比来说,JpetStore设计和架构更优良,各层定义清晰,使用了很多最佳实践和模式,避免了很多"反模式",如使用存储过程,在java代码中嵌入SQL语句,把HTML存储在数据库中等等。
最新版本是JpetStore4.0。
2.2.JpetStore开发运行环境的建立
1、开发环境
∙JavaSDK1.4.2
∙ApacheTomcat4.1.31
∙Eclipse-SDK-3.0.1-win32
∙HSQLDB1.7.2
2、Eclipse插件
∙EMFSDK2.0.1:
Eclipse建模框架,lomboz插件需要,可以使用runtime版本。
∙lomboz3.0:
J2EE插件,用来在Eclipse中开发J2EE应用程序
∙SpringIDE1.0.3:
SpringBean配置管理插件
∙xmlbuddy_2.0.10:
编辑XML,用免费版功能即可
∙tomcatPluginV3:
tomcat管理插件
∙PropertiesEditor:
编辑java的属性文件,并可以预览以及自动存盘为Unicode格式。
免去了手工或者ANT调用native2ascii的麻烦。
3、示例源程序
∙ibatis示例程序JpetStore4.0
∙改造后的源程序(+spring)(源码链接)
2.3.架构
图1JpetStore架构图
图1是JPetStore架构图,更详细的内容请参见JPetStore的白皮书。
参照这个架构图,让我们稍微剖析一下源代码,得出JpetStore4.0的具体实现图(见图2),思路一下子就豁然开朗了。
前言中提到的非传统的struts开发模式,关键就在strutsAction类和formbean类上。
strutsAction类只有一个:
BeanAction。
没错,确实是一个!
与传统的struts编程方式很不同。
再仔细研究BeanAction类,发现它其实是一个通用类,利用反射原理,根据URL来决定调用formbean的哪个方法。
BeanAction大大简化了struts的编程模式,降低了对struts的依赖(与struts以及WEB容器有关的几个类都放在com.ibatis.struts包下,其它的类都可以直接复用)。
利用这种模式,我们会很容易的把它移植到新的框架如JSF,spring。
这样重心就转移到formbean上了,它已经不是普通意义上的formbean了。
查看源代码,可以看到它不仅仅有数据和校验/重置方法,而且已经具有了行为,从这个意义上来说,它更像一个BO(BusinessObject)。
这就是前文讲到的,BeanAction类利用反射原理,根据URL来决定调用formbean的哪个方法(行为)。
formbean的这些方法的签名很简单,例如:
publicStringmyActionMethod(){
//..work
return"success";
}
方法的返回值直接就是字符串,对应的是forward的名称,而不再是ActionForward对象,创建ActionForward对象的任务已经由BeanAction类代劳了。
另外,程序还提供了ActionContext工具类,该工具类封装了request、response、formparameters、requestattributes、sessionattributes和applicationattributes中的数据存取操作,简单而线程安全,formbean类使用该工具类可以进一步从表现层框架解耦。
在这里需要特别指出的是,BeanAction类是对struts扩展的一个有益尝试,虽然提供了非常好的应用开发模式,但是它还非常新,一直在发展中。
图2JpetStore4.0具体实现
2.4.代码剖析
下面就让我们开始进一步分析JpetStore4.0的源代码,为下面的改造铺路。
∙BeanAction.java是唯一一个Strutsaction类,位于com.ibatis.struts包下。
正如上文所言,它是一个通用的控制类,利用反射机制,把控制转移到formbean的某个方法来处理。
详细处理过程参考其源代码,简单明晰。
∙Formbean类位于com.ibatis.jpetstore.presentation包下,命名规则为***Bean。
Formbean类全部继承于BaseBean类,而BaseBean类实际继承于ActionForm,因此,Formbean类就是Struts的ActionForm,Formbean类的属性数据就由struts框架自动填充。
而实际上,JpetStore4.0扩展了struts中ActionForm的应用:
Formbean类还具有行为,更像一个BO,其行为(方法)由BeanAction根据配置(struts-config.xml)的URL来调用。
虽然如此,我们还是把Formbean类定位于表现层。
Struts-config.xml的配置里有3种映射方式,来告诉BeanAction把控制转到哪个formbean对象的哪个方法来处理。
以这个请求连接为例http:
//localhost/jpetstore4/shop/viewOrder.do
1.URLPattern
name="orderBean"scope="session" validate="false"> 此种方式表示,控制将被转发到"orderBean"这个formbean对象的"viewOrder"方法(行为)来处理。 方法名取"path"参数的以"/"分隔的最后一部分。 2.MethodParameter name="orderBean"parameter="viewOrder"scope="session" validate="false"> 此种方式表示,控制将被转发到"orderBean"这个formbean对象的"viewOrder"方法(行为)来处理。 配置中的"parameter"参数表示formbean类上的方法。 "parameter"参数优先于"path"参数。 3.NoMethodcall name="orderBean"parameter="*"scope="session" validate="false"> 此种方式表示,formbean上没有任何方法被调用。 如果存在"name"属性,则struts把表单参数等数据填充到formbean对象后,把控制转发到"success"。 否则,如果name为空,则直接转发控制到"success"。 这就相当于struts内置的org.apache.struts.actions.ForwardAction的功能 parameter="/order/ViewOrder.jsp"scope="session"validate="false"> ∙Service类位于com.ibatis.jpetstore.service包下,属于业务层。 这些类封装了业务以及相应的事务控制。 Service类由formbean类来调用。 ∙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类则继承ibatisDAO框架中的SqlMapDaoTemplate类。 ibatis的配置文件存放在com.ibatis.jpetstore.persistence.sqlmapdao.sql目录下。 这些类和配置文件位于数据层 ∙Domain类位于com.ibatis.jpetstore.domain包下,是普通的javabean。 在这里用作数据传输对象(DTO),贯穿视图层、业务层和数据层,用于在不同层之间传输数据。 剩下的部分就比较简单了,请看具体的源代码,非常清晰。 2.5.需要改造的地方 JpetStore4.0的关键就在strutsAction类和formbean类上,这也是其精华之一(虽然该实现方式是试验性,待扩充和验证),在此次改造中我们要保留下来,即控制层一点不变,表现层获取相应业务类的方式变了(要加载spring环境),其它保持不变。 要特别关注的改动是业务层和持久层,幸运的是JpetStore4.0设计非常好,需要改动的地方非常少,而且由模式可循,如下: 1.业务层和数据层用SpringBeanFactory机制管理。 2.业务层的事务由spring的aop通过声明来完成。 3.表现层(formbean)获取业务类的方法改由自定义工厂类来实现(加载spring环境)。 3.JPetStore的改造 3.1.改造后的架构 其中红色部分是要增加的部分,蓝色部分是要修改的部分。 下面就让我们逐一剖析。 3.2.SpringContext的加载 为了在Struts中加载SpringContext,一般会在struts-config.xml的最后添加如下部分: value="/WEB-INF/applicationContext.xml"/> Spring在设计时就充分考虑到了与Struts的协同工作,通过内置的StrutsPlug-in在两者之间提供了良好的结合点。 但是,因为在这里我们一点也不改动JPetStore的控制层(这是JpetStore4.0的精华之一),所以本文不准备采用此方式来加载ApplicationContext。 我们利用的是springframework的BeanFactory机制,采用自定义的工具类(bean工厂类)来加载spring的配置文件,从中可以看出Spring有多灵活,它提供了各种不同的方式来使用其不同的部分/层次,您只需要用你想用的,不需要的部分可以不用。 具体的来说,就是在com.ibatis.spring包下创建CustomBeanFactory类,spring的配置文件applicationContext.xml也放在这个目录下。 以下就是该类的全部代码,很简单: publicfinalclassCustomBeanFactory{ staticXmlBeanFactoryfactory=null; static{ Resourceis=new InputStreamResource(CustomBeanFactory.class.getResourceAsStream("applicationContext.xml")); factory=newXmlBeanFactory(is); } publicstaticObjectgetBean(StringbeanName){ returnfactory.getBean(beanName); } } 实际上就是封装了Spring的XMLBeanFactory而已,并且Spring的配置文件只需要加载一次,以后就可以直接用CustomBeanFactory.getBean("someBean")来获得需要的对象了(例如someBean),而不需要知道具体的类。 CustomBeanFactory类用于{耦合1}的解耦。 CustomBeanFactory类在本文中只用于表现层的formbean对象获得service类的对象,因为我们没有把formbean对象配置在applicationContext.xml中。 但是,为什么不把表现层的formbean类也配置起来呢,这样就用不着这CustomBeanFactory个类了,Spring会帮助我们创建需要的一切? 问题的答案就在于formbean类是struts的ActionForm类! 如果大家熟悉struts,就会知道ActionForm类是struts自动创建的: 在一次请求中,struts判断,如果ActionForm实例不存在,就创建一个ActionForm对象,把客户提交的表单数据保存到ActionForm对象中。 因此formbean类的对象就不能由spring来创建,但是service类以及数据层的DAO类可以,所以只有他们在spring中配置。 所以,很自然的,我们就创建了CustomBeanFactory类,在表现层来衔接struts和spring。 就这么简单,实现了另一种方式的{耦合一}的解耦。 3.3.表现层 上面分析到,struts和spring是在表现层衔接起来的,那么表现层就要做稍微的更改,即所需要的service类的对象创建上。 以表现层的AccountBean类为例: 原来的源代码如下 privatestaticfinalAccountServiceaccountService=AccountService.getInstance(); privatestaticfinalCatalogServicecatalogService=CatalogService.getInstance(); 改造后的源代码如下 privatestaticfinalAccountServiceaccountService=(AccountService)CustomBeanFactory.getBean("AccountService"); privatestaticfinalCatalogServicecatalogService=(CatalogService)CustomBeanFactory.getBean("CatalogService"); 其他的几个presentation类以同样方式改造。 这样,表现层就完成了。 关于表现层的其它部分如JSP等一概不动。 也许您会说,没有看出什么特别之处的好处啊? 你还是额外实现了一个工厂类。 别着急,帷幕刚刚开启,spring是在表现层引入,但您发没发现: ∙presentation类仅仅面向service类的接口编程,具体"AccountService"是哪个实现类,presentation类不知道,是在spring的配置文件里配置。 (本例中,为了最大限度的保持原来的代码不作变化,没有抽象出接口)。 Spring鼓励面向接口编程,因为是如此的方便和自然,当然您也可以不这么做。 ∙CustomBeanFactory这个工厂类为什么会如此简单,因为其直接使用了Spring的BeanFactory。 Spring从其核心而言,是一个DI容器,其设计哲学是提供一种无侵入式的高扩展性的框架。 为了实现这个目标,Spring大量引入了Java的Reflection机制,通过动态调用的方式避免硬编码方式的约束,并在此基础上建立了其核心组件BeanFactory,以此作为其依赖注入机制的实现基础。 org.springframework.beans包中包括了这些核心组件的实现类,核心中的核心为BeanWrapper和BeanFactory类。 3.4.持久层 在讨论业务层之前,我们先看一下持久层,如下图所示: 在上文中,我们把iface包下的DAO接口归为业务层,在这里不需要做修改。 ibatis的sql配置文件也不需要改。 要改的是DAO实现类,并在spring的配置文件中配置起来。 1、修改基类 所有的DAO实现类都继承于BaseSqlMapDao类。 修改BaseSqlMapDao类如下: publicclassBaseSqlMapDaoextendsSqlMapClientDaoSupport{ protectedstaticfinalintPAGE_SIZE=4; protectedSqlMapClientTemplatesmcTemplate=this.getSqlMapClientTemplate(); publicBaseSqlMapDao(){ } } 使BaseSqlMapDao类改为继承于Spring提供的SqlMapClientDaoSupport类,并定义了一个保护属性smcTemplate,其类型为SqlMapClientTemplate。 关于SqlMapClientTemplate类的详细说明请参照附录中的"Spring中文参考手册" 2、修改DAO实现类 所有的DAO实现类还是继承于BaseSqlMapDao类,实现相应的DAO接口,但其相应的DAO操作委托SqlMapClientTemplate来执行,以AccountSqlMapDao类为例,部分代码如下: publicListgetUsernameList(){ returnsmcTemplate.queryForList("getUsernameList",null); } publicAccountgetAccount(Stringusername,Stringpassword){ Accountaccount=newAccount(); account.setUsername(username); account.setPassword(password); return(Account)smcTemplate.queryForObject("getAccountByUsernameAndPassword",account); }
- 配套讲稿:
如PPT文件的首页显示word图标,表示该PPT已包含配套word讲稿。双击word图标可打开word文档。
- 特殊限制:
部分文档作品中含有的国旗、国徽等图片,仅作为作品整体效果示例展示,禁止商用。设计者仅对作品中独创性部分享有著作权。
- 关 键 词:
- 基于 struts spring ibatis 轻量级 J2EE 开发