Tapestry+Spring+Hibernate整合工作小结

转载 2004年07月05日 21:44:00

Tapestry+Spring+Hibernate整合工作小结<?xml:namespace prefix = o ns = "urn:schemas-microsoft-com:office:office" />

 

Cyberwing

bnusunny@yahoo.com

 

 

FrankSoo是我的项目经理。前段时间公司决定作个新的J2EE二次开发平台,以替换公司原有的开发平台。公司让FrankSoo和我组成平台开发项目组,FrankSoo担任项目经理。现在这个平台整合开发阶段已经结束,进入项目应用阶段。下面是我们的整合工作小结,介绍一下我们在工作中遇到的问题,以及我们选择的解决方案.

 

 

1、架构的选择

 

首先,我们都同意以我们现有的能力,没有足够的时间和资源自行开发一套完整的平台的。在已有的众多开源项目中选择若干优秀的项目进行整合,才可能按时完成项目,达到项目目的。

 

但是在平台项目开始前,我们对平台的技术架构有各自的构想。FrankSoo原来的构想是Struts+Spring+Hibernate,而我的构想是Tapestry+Hibernate

 

不过FrankSoo非常open,在我向他演示了Tapestry的经典范例workbench,介绍了Tapestry基于组件的编程方式之后,他同意选用Tapestry作为实现Web展现层的框架。我想FrankSoo以前的Struts开发经验(painful)也是他做出这个决定的因素之一。

 

FrankSoo gave me a nice introduction of Spring Framework. Wow, what an amazing framework! IOC, Declarative Transaction Support, Hibernate Session Management, Hibernate DAO Support… These features are just what we need for a middle tire container.

 

至于Hibernate,这个最成功的开源ORM项目,我们都投了它一票^_^

 

最后我们确定平台的技术架构是Tapestry+Spring+Hibernate.

 

2、架构整合

 

最初的平台架构借鉴了一篇介绍如何集成TapestrySpring的文章[1]中提到的架构:

 

 o_Libra_old.GIF

<?xml:namespace prefix = v ns = "urn:schemas-microsoft-com:vml" />

 

Web层的Tapestry负责数据输入输出, 响应用户事件,及输入校验的工作, 通过访问预先加载的WebApplicationContext(Spring提供, 包含着所有Service bean)获得Service层的Service Bean, 把业务操作都委托给它们.

 

Service层的bean则负责use case逻辑, domain相关的逻辑委托给domain model中的bean去实现. Service通过DAO完成对domain model的持久化工作. Service负责数据库事务和Hibernate Session的管理(通过Spring的声明式事务管理和与之集成的Hibernate Session管理). Service层的另一项重要工作是权限和访问控制。

 

Domain model负责表示问题域的数据和domain logic. DAO使用Hibernate持久化数据以及查询.

 

这样的架构优点很明显, 层次清晰, 各层的职责也明确, 便于分层设计与开发, 结合mockspringIOC, unit test也是非常容易的. 而且后台(Service, domain model and DAO)的代码不依赖于Web容器或是EJB容器的API, 移植性非常好, 同样的代码可以在Web app中使用也可在普通的Java app中使用, 只需更换UI.

 

按照这个整合的构架,我们实现一个简单的实例,实现了列表分页查询和显示,数据增删改,基于Hibernate Criteria Query提供了一个比较通用的查询机制。利用MiddlegenVelocity我们可以从已经建好的数据库表结构自动生成Hibernate映射文件,实体类和DAO,减少了很大工作量。我们还对这个小例子进行了压力测试(测试时的数据量为10万条记录),确定平台不存在性能问题。

 

通过这个实例我们把整个架构基本走通一遍,并总结了使用这套架构开发时适用的开发流程和需要做的工作。

 

3、困扰我们的问题

 

在实现例子和现在的项目应用过程中,我们发现了若干头疼的问题,有的解决了,有的还没有。

 

问题1:要不要使用DTO

 

在上面的架构中我们并没有明确ServiceWeb层间的数据传输是如何进行的。我们讨论好久要不要使用DTO,最后的结论是不用。

 

使用DTO有两个主要的理由:1、减少Web层和Service层间的方法调用,通过一个方法调用就将Web需要的数据都传给Web2、隔离domain modelWeb层。

 

第一个理由在我们的架构下是不成立的。因为我们的架构是集中式的,WebService是在同一个JVM中,它们之间的方法调用是没有EJB远程访问的巨大消耗的。

 

第二个理由还是需要考虑的。如果允许把domain model中的对象传给Web层,那么修改domain model,就会影响到Web层。如果使用DTO,那么domain model实现上的变化就不会影响到Web。但是大量的变化不是domain model实现上的变化,而是domain model接口的变化,比如一个domain model的对象上添加了一个属性,而这个属性需要用户修改,那么这时候必须修改Web层,不管是不是用了DTO。而且使用DTO,就需要维护着一大堆对象,或是它们的生成器,这是非常无聊、且容易出错的工作。

 

基于这些考虑,我们没有使用DTO,而是选择把domain model直接传到Web层。下面是修改后的架构图(呵呵,修改了别人的图[2])。

 o_Libra.GIF

问题2Entity like domain model or rich domain model?

 

因为我们使用Middlegen自动生成Hibernate映射文件,Entity类和DAO类,所以我们遇到了一个问题:我们的domain model还要不要包含domain logic?如果包含业务方法,那么和自动生成工具如何结合?

 

我们讨论后认为一个rich domain model还是非常有必要的,可以减少Service中的重复代码,提高复用性。

 

如何同自动生成结合?使用 标签,生成抽象基类,我们继承这些自动生成的基类,添加业务方法。

 

问题3Model driven or Data driven?

 

采用Model driven还是Data driven的方式大家有过热烈的讨论。我们主要是受到Rod Johnson3]的影响,采用了Data driven的方式。先作数据库设计,生成库表,然后用Middlegen反向生成Hibernate映射文件和EntityDAO。但是我们在进入项目应用之后发现这种方法有两个问题:

 

a)  数据库设计仅说明了系统要管理的静态数据,我们还是得作面向对象分析,以反映系统的动态行为。特别是当系统的业务不仅仅是简单的CRUD操作时,这个问题更严重。

b)  数据库设计为了优化性能,可能会把好几个应该是单独实体的数据放入一个实体中。这样如果直接报这种极粗粒度实体映射成Entity类,那简直是不可接受的。面向对象的分析设计模型得到的类都是相当细粒度的。这种情况还得作面向对象的分析,明确到底这个粗粒度的大表应该映射成那几个细粒度的对象。

 

或许我们应该试试Model driven,用AndroMDA生成domain modelHibernate DAOHibernate mapping,数据库表,简单的Service和前台的Tapestry页面。

 

问题4Hibernate Session生命周期如何管理?

 

对于Hibernate Session的生命周期我们采用的是Session-per-Transaction模式,未采用Open Session in View模式。 虽然Hibernate team认为这种方法没什么不好,而且AtlassianconfluenceFreeRoller都使用了Open Session In View这种模式,但是我们对它可能产生的影响还没有很好的把握,所以暂时弃置不用。 如果Web层要访问lazy load的数据, 需要先调用Service的业务方法, 以获得数据.

 

问题5Use case logic domain logic 如何区分?

 

Service负责use case logicdomain model负责domain logic。这样的划分看起来很好,实现起来就很麻烦。怎么划分什么是use case logic,什么是domain logicTBD.

 

 

问题6Service粒度如何确定?

 

这个问题真是很烦,原先考虑使用usecase controller的方式,每个usecase对应一个Service,但是发现这样复用性太低,而且好多地方必须复用相同的功能:(

 

另一种方法是用package level service,每个package作个service,这样倒是可以重用,但是感觉太死了,不好。

 

现在也没有什么很好的办法,只好在详细设计时根据具体情况确定需要多少个Service了。TBD.

 

问题7:权限如何设定?如何检查?

 

权限设定也是个头疼的问题。我们本想是按照use case设定权限,每个用例一个权限。在角色设定的时候直接处理的都是业务意义非常明确的权限。但是在权限验证过程中发现了问题:如果在Service的方法中验证权限,而且这个方法在用例中用到(复用Service),那么这个Service的方法就需要检查多个权限,如果每个Service方法对应一个权限, 那么权限又太细了, 不像use case权限那样代表一个完整的业务. 真的是很麻烦阿!TBD.

 

 

 

Ok, 这些就是我们这段工作的结果。希望能给大家一些启发,也希望能得到大家的帮助,帮我们出出主意,谢谢大家。

 

 

 

 

 

Reference:

[1] Integrating Tapestry and Spring Framework. 原来Spring网站上有单独的文章,现在合入Spring Reference中了,见Spring Reference, chapter 12, section 7.

[2] Wiring Your Web Application with Open Source Java, Mark Eagle, 2004/04/07, O’Reilly OnJava.com, http://www.onjava.com/pub/a/onjava/2004/04/07/wiringwebapps.html.

[3] Expert one-on-one J2EE Design and Development, Rod Johnson, 2003, Wrox Press

Tapestry+Spring+Hibernate整合工作小结[转]

Tapestry+Spring+Hibernate整合工作小结[转]下面是我发在Spring中文论坛上的文字, 但是没有得到回应, 希望在这里能得到帮助. 谢谢大家 -----------------...
  • eako
  • eako
  • 2004年12月27日 18:12
  • 1523

近一个月的工作学习总结

清明节3天的假期
  • acm365
  • acm365
  • 2014年04月07日 18:18
  • 2076

兰州铁路局融雪项目工作小结1

计划中今天应该完成新区站融雪设备的安装的,而且应该已经把iOS开发blog更新到swift2.0基础的第一部分的。但是由于一些原因,导致融雪设备安装缓慢,搁置了这两项计划,幸好刚刚已经补充了一篇iOS...
  • nextway
  • nextway
  • 2015年09月14日 00:59
  • 273

对于数据工作的一些总结

近几天由于升级了系统,系统的中文输入法ibus-pinyin一直用不了,安装了一个Sougou的云输入法Chrome插件,又可以输入中文了。科技的进步给我么生活带来的便利确实是令人惊讶的,所以做人当怀...
  • cnweike
  • cnweike
  • 2011年09月30日 12:30
  • 3415

第二周工作学习总结

第二周工作学习总结
  • Dorthyn
  • Dorthyn
  • 2017年05月01日 21:34
  • 230

工作半年后总结与感想

说好写文章不矫情的……坚决不矫情,用理性与客观的态度与分析,更确切是说剖析自己。让自己认识到错误,并能有所改进。to be a  better man     在某xx公司也工作将近半年的时间了。我到...
  • lindapao
  • lindapao
  • 2014年12月22日 00:17
  • 485

入职两月半的工作业务总结

这阵子工作上全用上了ReactNative,边学边写一个月,基本熟悉品类或服务发布等业务的写法。可以分为几个部分: 一、搭建调试接口 写代码之前,得先考虑要写的页面从什么地方跳转进来,那么首先要建...
  • fjienigui
  • fjienigui
  • 2015年12月22日 16:31
  • 453

2018年1月25日的工作总结

PS自设旅游类APP一级分类的UI页面
  • Z1575248622
  • Z1575248622
  • 2018年01月25日 14:11
  • 41

【工作笔记】从零开始学ExtJs6(三)—— 首页搭建

首页搭建就是需要3层,上面板(项目名称和工具栏等),做面板(树形菜单),中间面板(变换的内容)分成三层的代码(很简单)关键代码如下extend: 'Ext.container.Viewport', l...
  • qq_20597479
  • qq_20597479
  • 2017年03月03日 13:32
  • 704

工作两年小结----勿忘初心不负梦想

前言:转眼又是一年,2016年7月3号是自己正式参加工作两年,入职一家新公司工作两个月的日子。每年到这个时间点,总是想要写点儿什么总结一下。前半年除了学习提高专业技能外,主要读了几本书《余罪》,沉默的...
  • yisuowushinian
  • yisuowushinian
  • 2016年08月01日 00:21
  • 5951
内容举报
返回顶部
收藏助手
不良信息举报
您举报文章:Tapestry+Spring+Hibernate整合工作小结
举报原因:
原因补充:

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