基于J2EE轻量级架构的多层应用的研究 (转载自http://www.blogjava.net/caoqingsong/archive/2006/06/16/53158.html)

 

1    J2EE 多层应用分析

1.1          J2EE 层次结构

J2EE 的三层结构在业界是指表示层 (Presentation) ,业务逻辑层 (Business logic) 以及基础架构层 (Infrastructure) 。这样的划分当然是经典的,但是在实际项目中,往往会对三层体系结构做一些扩展来满足项目的需要。一个最常用的扩展就是将三层体系扩展为五层体系,即表示层 (Presentation) 、控制 / 中介层 (Controller/Mediator) 、领域层 (Domain) 、 数据持久层 (Data Persistence) 和数据源层 (Data Source) 。它其实是在三层架构中增加了两个中间层。控制 / 中介层位于表示层和领域层之间,数据持久层位于领域层和基础架构层之间。而轻量级架构 Struts + Spring + Ibatis 可以实现J2EE多层结构,Struts 用于表示层、控制层,Spring 用于业务处理层,而Ibatis 用于数据持久层。

1.2          Struts 框架

Struts 是一个基于Sun J2EE平台的MVC框架,主要是采用ServletJSP技术来实现的。是开发Web应用程序的开放源码的FrameworkStrutsServletJSP、自定义标签和信息资源(message resources)整合到一个统一的框架中,开发人员利用其进行开发时不用再自己编码实现全套MVC模式,极大的节省了时间,Struts包括如下的主要功能:

  包含一个controller servlet,能将用户的请求发送到相应的Action对象。

  JSP 自由tag库,并且在controller servlet中提供关联支持,帮助开发员创建交互式表单应用。

  提供了一系列实用对象:XML处理、通过Java reflection APIs自动处理JavaBeans属性、国际化的提示和消息

1.3          Spring 框架

Spring 是一个目前非常活跃的开源项目;它是一个基于IoCInversion of Control)和AOPAspect-Oriented Programming)的,轻量级的,多层j2ee系统的框架,但它不强迫你必须在每一层中必须使用Spring,它模块化的很好,允许你根据自己的需要选择使用它的某一个模块;它实现了很优雅的MVC ,对不同的数据访问技术提供了统一的接口,采用IoC使得可以很容易的实现bean的装配,提供了简洁的AOP并据此实现Transcation Managment,等等 [ 1 ]

Spring 虽然提供了MVC Web框架的解决方案,但是也能与其他的web框架相结合使用,如strutsWebworkJFS等。Spring也可以与其他持久层结构相结合,如:jdbcHibernateIbatis等,能够使用AOP的技术提供事务处理等功能  

1.4          数据关系映射 Ibatis

Ibatis 提供了ORM机制,对业务逻辑实现人员而言,面对的是纯粹的Java对象, 这一层与通过Hibernate 实现ORM 而言基本一致,而对于具体的数据操作,Hibernate 会自动生成SQL 语句,而Ibatis 则要求开发者编写具体的SQL 语句。相对Hibernate全自动”ORM机制而言,Ibatis SQL开发的工作量和数据库移植性上的让步,为系统设计提供了更大的自由空间。作为全自动”ORM 实现的一种有益补充,Ibatis 的出现显得别具意义 [ 2 ]

 

2    J2EE 轻量级架构

2.1          架构

 

               
                                                                                             
                                                                                                 图1  框架示意图

2.2          View

在视图层主要使用Struts结构的技术。

TagLib

jsp的前端页面中使用Struts提供的标签完成页面数据逻辑的组织与显示。如(htmlbeanlogic等)

国际化的消息处理功能

jsp页面中不出现特定语言的字符串描述,将这些统一的字符串信息统一的提取到文件中,通过StrutsBean标签提取。便于整个系统的语言变更与组织。

界面组合功能Tiles

页面中将使用Struts的技术,统一组织页面的结构,便于系统改版、维护。

2.3          Control

控制层中依然使用Struts结构。此层将接受、处理View发送的请求,在对信息初步的验证、处理后,将把此请求委派给后端的业务处理层去处理。等待业务处理完成之后,将把处理结果传递给View层进行表现。

2.4          业务处理层

在该层中使用Service模式,提供给Control层必要的处理方法。

在接收到Control层的业务处理请求后,按照业务规范、算法对数据进行处理。将处理结果返回给Control层。

2.5          数据访问层

本层属于低级的数据处理层,将完成具体的数据处理工作,如数据的增加,更新,查询,删除等。

本层使用DAOData Access Object)的设计模式 [ 3 ] ,屏蔽多数据库对上层应用的影响,并使用IbatisORMapping技术,降低数据操作的复杂程度。

3    数据持久层解决方案

3.1             数据持久层

将数据持久单独作为 J2EE 体系一个层提出来,表面上是因为数据持久性是企业实际开发中比较棘手的一个方面,数据持久层设计的成功与否往往对项目起着至关重要的影响,单独将其提出来以便在开发中能够避免它的设计草率。究其最深刻的内因,则是在对象范例和关系范例这两大领域之间“阻抗不匹配”。对象范例基于软件工程的一些原理,例如耦合、聚合和封装,而关系范例则基于数学原理,特别是集合论的原理。两种不同的理论基础导致各自有不同的优缺点。而且,对象范例侧重于从包含数据和行为的对象中构建应用程序,而关系范例则主要针对数据的存储。当为访问而寻找一种合适的方法时,“阻抗不匹配”就成了主要矛盾:使用对象范例,通过它们的关系来访问对象,而使用关系范例,则通过复制数据来连接表中的行。这种基本的差异导致两种范例的结合并不理想,于是有人提出对象数据库以希望解决这个问题。但是,关系数据库技术已经发展得相当成熟,占据了数据库市场 90 %以上的份额,对象数据库的普及尚需时日。数据持久层就是要在对象-关系数据库之间提供一个成功的企业级别的映射解决方案,尽最大可能弥补这两种范例之间的差异。

3.2             J2EE 体系解决方案

3.2.1      EJB

CMP ( 容器管理持久 ) 实体 Bean ,提供健壮的数据持久性。 Bean 容器处理大部分的数据完整性、资源管理和并发性功能,从而使开发人员关注业务逻辑和数据处理,而不是这些低级细节。使用 Bean 管理的持久性 (Bean Managed Persistence BMP) 实体 Bean 时,开发人员编写持久性代码而容器确定何时执行该代码。使用容器管理的持久性   ( Container Managed Persistence CMP) 实体 Bean 时,容器生成持久性代码并管理持久性逻辑 [ 4 ]

3.2.2      JDO

Java 数据对象 (JDO) 是一个存储 Java 对象的规范 [ 5 ] 。它已经被 JCP 组织定义成 JSR12 规范。规范的两个主要目的是提供数据处理和访问机制的 API 以及允许规范的实现作为应用服务器的一部分。 Java 数据对象是最新的持久性规范。 JDO 提供了面向对象的持久数据存储。开发人员使用 POJO( 无格式普通 Java 对象, Plain Ordinary Java Object) 来装入和存储持久数据。

3.2.3      ORM

ORM 具有自我存储到关系数据库的能力,对对象的改变能够直接得以存储,而不考虑数据库存取代码。这样,把全部精力集中到对对象和类进行编程,解决业务问题。在整个系统中除了这一个层次,没有一句数据库存取代码。其中, Hibernate Ibatis 作为 ORM 中最好的开源工具,受到数量众多的程序员的拥护。

4    基于轻量级架构的应用案例分析

某大型水利信息系统需要使用 J2EE 平台以满足分布式处理、事务管理和安全的要求, 使整个软件呈现分层的体系结构,支持多种数据库的扩展,支持多语言界面的调整,支持页面整体布局的可扩展性调整。封装业务逻辑,使得在外部条件变化时,将影响尽可能的降低,即采用了基于J2EE的轻量级架构。图2是信息系统的体系结构,图3是系统包结构

 

                                   2  体系结构图

 

 

3  系统包结构

 

3中箭头表示软件包之间的依赖关系。独立的包会被SpringstrutsIbatis框架结构间接的与其他软件包关联。

4.1             系统剖析

4.1.1      包结构描述

com.water.query.dao :该包内的类将引入Ibatis的重要组件,使系统能够感知功能操作的接口与接口实现类的关系,这些信息是Ibatis自动映射的前提条件之一。

com.water.query.dao.sqlmapdao :该包是数据访问的核心,使用Spring结构的数据层功能引进对Ibatis的支持

com.water.query.dao.iface :该包规定了所有业务的访问接口,只有在此包的接口中定义的方法才会被用户使用。是本系同中所有原子数据操作的定义点。

Ibatis :该包是由Ibatis数据存储层结构定义。由支持机构提供支持。

com.water.query.dao.sqlmapdao.sql :该包定义了所有操作的SQLSequence Query Language)语句,以及SQL语句与具体值对象的映射关系。

com.water.query.form :该包定义了本系统中用于数据传输的类。这些类实例是Web界面层与业务逻辑实现层之间的桥梁,起着传输数据的功能。

com.water.query.service : 该包是本系统引入Spring结构的入口点。通过该入口,系统中其他成员可以通过IoC(依赖倒转)功能访问具体业务的Service对象。

com.water.query.condition :该包内定义了一系列简单JavaBean,这些JavaBean将携带SQL需要的参数穿行于软件的Control层与Model层之间。

com.water.log :该包中定义了本系统使用的log组件。

com.water.query.domain.baseinfo :该包定义了所有基本信息查询模块将要使用的数据传输类。

 

4.1.2      控制层

在视图层和控制层中采用了Struts框架,在传统的Struts用法中,我们一般都有几个Action Bean和相应的form bean ,但在此设计中并不拘泥于Struts的传统固定用法,这里只用了一个自定义Action类,并且在form bean类的定义上也是创新的。

非传统的Struts开发模式,关键就在Struts Action类和form bean类上。Struts Action类只有一个:BeanAction,这与传统的struts编程方式很不同。BeanAction类是一个通用类,利用反射原理 [ 6 ] ,根据URL来决定调用form bean的哪个方法。BeanAction大大简化了struts的编程模式,降低了对struts的依赖。利用这种模式,我们会很容易的把它移植到新的框架如JSFSpring

这样重心就转移到form bean上了,它已经不是普通意义上的form bean了。它不仅仅有数据和校验/重置方法,而且已经具有了行为,从这个意义上来说,它更像一个BO(Business Object)Struts-config.xml的配置里有3种映射方式,来告诉BeanAction把控制转到哪个form bean对象的哪个方法来处理。form bean的这些方法的签名很简单,例如:

				
						public String myActionMethod(){
				
		
				
						
								  
								                   
								 //..work
				
		
				
						
								                   
								  return "success";
				
		

 }

方法的返回值直接就是字符串,对应的是forward的名称,而不再是ActionForward对象,创建ActionForward对象的任务已经由BeanAction类代劳了。

 

4.1.3      业务层

利用Spring Framework BeanFactory机制,采用自定义的工具类(bean工厂类)来加载spring的配置文件,从中可以看出Spring有多灵活,它提供了各种不同的方式来使用其不同的部分/层次,您只需要用你想用的,不需要的部分可以不用。

具体的来说,创建CustomBeanFactory类,Spring的配置文件applicationContext.xml。以下就是该类的全部代码,很简单:

public final class CustomBeanFactory {

static XmlBeanFactory factory = null;

static {

     Resource is = new

InputStreamResource( CustomBeanFactory.class.

getResourceAsStream("applicationContext.xml"));

     factory = new XmlBeanFactory(is);             

}

public static Object getBean(String beanName){

     return factory.getBean(beanName);

}

}

实际上就是封装了Spring XMLBeanFactory而已,并且Spring的配置文件只需要加载一次,以后就可以直接用CustomBeanFactory.getBean("someBean")来获得需要的对象了(例如someBean),而不需要知道具体的类。CustomBeanFactory类用于{耦合1}的解耦。CustomBeanFactory类用于表现层的form bean对象获得service类的对象。

4.1.4      数据持久层的配置

4.1.4.1       Spring 配置文件

Spring 在设计时就充分考虑到了与Struts的协同工作,并且对Ibatis 有很好的支持,在此轻量级架构中,不需要对Ibatis单独进行配置,只需对 Spring 进行配置就以足够。以下就是Spring的配置文件 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>net.sourceforge.jtds.jdbc.Driver</value>

</property>

<property name="url"><value>jdbc:jtds:sqlserver://127.0.0.1:1433/Sample</value>

</property>

<property name="username"><value>test</value></property>

<property name="password"><value>changeit</value></property>

</bean>

<bean id="sqlMapClient"class="org.springframework.orm.ibatis.SqlMapClientFactoryBean">

<property name="configLocation"><value>SqlMapConfig.xml</value></property>

</bean>

<bean id="transactionManager"

class="org.springframework.jdbc.datasource.DataSourceTransactionManager">

<property name="dataSource"><ref local="dataSource"/></property>

</bean>

<bean id="userDAO" class="net.xiaxin.dao.UserDAO">

<property name="dataSource"><ref local="dataSource" /></property>

<property name="sqlMapClient"><ref local="sqlMapClient" /></property>

</bean>

</beans>

可以看到:

1 sqlMapClient 节点

sqlMapClient 节点实际上配置了一个 sqlMapClient 的创建工厂类。

configLocation 属性配置了 ibatis 映射文件的名称。

2 transactionManager 节点

transactionManager 采用了 Spring 中的 DataSourceTransactionManager

3 userDAO 节点

对应的, UserDAO 需要配置两个属性, sqlMapClient DataSource

sqlMapClient 将从指定的 DataSource 中获取数据库连接。

4.1.4.2       Ibatis 映射文件

sqlMapConfig.xml:

<sqlMapConfig>

<sqlMap resource="net/xiaxin/dao/entity/user.xml"/>

</sqlMapConfig>

user.xml 为:

<sqlMap namespace="User">

<typeAlias alias="user" type="net.xiaxin.dao.entity.User" />

<insert id="insertUser" parameterClass="user">

INSERT INTO users ( username, password) VALUES ( #username#,

#password# )

</insert>

</sqlMap>

UserDAO.java

public class UserDAO extends SqlMapClientDaoSupport implements

IUserDAO {

public void insertUser(User user) {

getSqlMapClientTemplate().update("insertUser", user);

}

}

SqlMapClientDaoSupport Spring 中面向 ibatis 的辅助类,它负责调度 DataSource

SqlMapClientTemplate 完成 ibatis 操作,而 DAO 则通过对此类进行扩展获得上述功能。上面配置文件中针对 UserDAO 的属性设置部分,其中的属性也是继承自于这个基类。 SqlMapClientTemplate 对传统 SqlMapClient 调用模式进行了封装,简化了上层访问代码。

5    总结

从软件层次结构的角度来说,软件的框架要具有较高的伸缩性和可扩展性,本文所讨论的J2EE轻量级架构,由于它采用了Struts框架,因而它的模块化设计得到了很好的应用,层次非常清晰,具有很好的可复用度,但是,同时,此架构存在可伸缩性问题, 架构 中明显存在可伸缩性问题的设计是 Action 。控制器 ActionServlet 对每个 Action 类只创建一个实例 , 所有对该 Action 类的请求都用这个实例进行处理 , 因此 , 它是无状态的、多线程共享的。这意味着 Action 实例的数量是一个常数 , 不能随工作量增加而增加。此外, 反射的利用是对架构扩展的一个有益尝试,虽然提供了非常好的应用开发模式,但是它还非常新,一直在发展中。数据持久层中,Ibatis的应用给人一种耳目一新的感觉,但它也存在着一些不足之处,例如相对于Hibernate Ibatis不能直接生成sql语句,需要人工编写。

轻量级架构结合StrutsSpringIbatis ,充分发挥了三者的优点, 基于轻量级框架的 J2EE 架构开发简洁、结构清晰,有很好的可扩展性和可维护性,非常适于面向对象的设计与开发。



posted on 2006-06-16 11:20 nbt 阅读(831) 评论(1)  编辑  收藏 所属分类: Java2EE

评论

# re: 基于J2EE轻量级架构的多层应用的研究 (转载自http://www.blogjava.net/caoqingsong/archive/2006/06/16/53158.html)[未登录] 2007-04-24 16:26 Alex

would you please upload some programme in detail for application?
thanks  回复  更多评论   


只有注册用户登录后才能发表评论。


网站导航:
 
<2006年6月>
28293031123
45678910
11121314151617
18192021222324
2526272829301
2345678

导航

统计

常用链接

留言簿(3)

随笔分类

随笔档案

文章分类

文章档案

相册

收藏夹

Java技术网站

友情链接

国内一些开源网站

最新随笔

搜索

积分与排名

最新评论

阅读排行榜

评论排行榜