http://dev2dev.bea.com.cn/blog/chaocai/200712/spring_osgi_04_719.html
http://dev2dev.bea.com.cn/bbs/ext/dev2devperson/
蔡超
http://dev2dev.bea.com.cn/blog/chaocai/200710/architecture_24_536.html
http://dev2dev.bea.com.cn/blog/chaocai/200711/06_623.html
多层结构是J2EE应用开发的基本模式,很多开发者都会按照多层结构来组织自己的应用(通常分为Facade,Application Service,DAO等层),但是他们往往会选择在不同层上去控制事务和Hibernate Session的边界,可千万不要小看这样的选择它会大大影响程序的可维护性和可复用性。
其实在Facade层来控制事务的边界通常都是最佳选择。我们知道Facade层的粗粒度接口是直接为用户请求提供相应服务的,在典型的J2EE环境中通常使用Session Bean来实现Facade层,并且使用CMT。这时如果有的开发人员在其他层次控制了事务如DAO,由于这些层次通常不会采用EJB实现,所以所使用的事务为容器提供的用户管理事务,根据EJB的事务规范CMT是无法把事务上下文传递到用户管理事务的边界中的,由于J2EE并不支持事务的嵌套,所以当来自Facade的CMT事务遇见DAO的事务时,内部事务将被挂起,这样整个事务的情况,就会和设想的业务逻辑产生很大的差异。
并且有时不同业务逻辑的实现会复用DAO提供多个方法,所以很难控制事务的边界,导致这些方法难以被复用。
对于Hibernate Session,由于存在懒加载的问题,所以开发人员常会预见这样的异常LazyInitializationException。避免这个问题就要求在关闭session前要装载好要使用的对象关系域。而这种逻辑通常只与界面显示内容相关,如果把session的边界控制放置在DAO或者Application Service中就会使业务逻辑的实现要和界面显示逻辑混合在一起,我们必须在这些方法中加载那些界面显示需要的对象关系域。而界面显示是经常变化的,并且业务逻辑会被多个不同的界面所复用,如果这样Application Service,DAO中方法的复用性就会大大降低。
把这些工作放在离表现层最近的Facade中便可以避免这些问题。
注意在其他层次中我们不需要控制session的边界,我们通常采用getCurrentSession()来获得当前事务中的session,记住这个方法必须在事务上下文存在的情况下才可以调用,并且在事务被提交的时候Hibernate会在自动关闭session,所以我们不要显示的关闭session.
你是否已经被像JBPM,XFLow等那样的复杂编程和配置搞头昏脑胀;被他们所依赖的大量jar和容器搞得不知所措。
如果这样就试试笔者开发的这个简单工作流引擎吧,配置和编程都很简单,也不依赖任何容器。支持spring的版本。
下载地址:
http://www.blogjava.net/Files/chaocai/swf-beta-1[1].3-bin.zip
内附用户手册
(SWF开发设计:蔡超,北京天融信,
chaocai2001@yahoo.com.cn)
简介
SWF是一种嵌入式的工作流引擎,它不需要任何应用服务器的支持。SWF使用十分简单,但却可以满足多数流程驱动应用的需求。并且支持和主流j2ee框架整合(spring).
本文介绍如何基于SWF开发流程驱动的应用。
你是否已经被像JBPM,XFLow等那样的复杂编程和配置搞头昏脑胀;被他们所依赖的大量jar和容器搞得不知所措。
如果这样就试试笔者开发的这个简单工作流引擎吧,配置和编程都很简单,也不依赖任何容器。马上会推出支持spring的版本。
下载地址:
http://www.blogjava.net/Files/chaocai/swf-beta-1-bin.zip
内附用户手册
(SWF开发设计:蔡超,北京天融信,
chaocai2001@yahoo.com.cn)
简介
SWF是一种嵌入式的工作流引擎,它不需要任何应用服务器的支持。SWF使用十分简单,但却可以满足多数流程驱动应用的需求。
本文介绍如何基于SWF开发流程驱动的应用。
问题
随着轻量级持久化框架的流行(如:Hibernate,JDO,JPA),领域对象取代了传统的DTO直接作为值对象,而在这种架构应用的开发过程中,开发人员常会预见这样的异常LazyInitializationException。上述问题是由于Hibernate对于领域对象的关系域对象采取了懒加载策略所导致的(即在关系域被访问时才真正加载创建这些相关对象,Hibernate提供的懒加载策略在很多时候都可以让我的程序获得更高的效率);由于领域对象在脱管的状态下被作为值对象传回显示层,而显示层如果访问了采用懒加载策略加载的关系域,便会导致LazyInitializationException异常。
为了避免这个问题,我们常常会在Façade层的业务方法中加入与特定显示要求相绑定的返回对象初始化过程(即装载那些被懒加载了的关系域对象)。Façade通常是我们用于控制事务边界和完成返回的领域对象脱钩的地方。
1 表现层是易变的这样就会导致连锁反应,大量的代码需要维护,完全违背了面向对象设计的原则,增加了程序的维护成本。
2 并且Façade可能用于支持多种不同的表现层,很难让一个方法满足不同的要求。
OSIV(Open Session in View)结构是一种解决上述问题的方法,这种结构之所以能解决上述问题关键就在于OSIV在表现层中控制Session的打开和关闭,控制事务边界。OSIV虽然简化了应用程序的结构,也避免了LazyInitializationException问题,但是也有很多不足:1.增加了表示层的负责度,2.在响应返回表示层前必须提交事务。3.由于减少了封装层次,表现层直接操作领域对象使得包括性能方面的各种优化更为困难。
解决方案
思考既然表示层知道要显示的信息,即领域对象应该加载哪些相关联的对象。那么我们何不把这个任务交给Façade的调用者(表现层)来完成呢?
不同的表示层可能会有不同的显示策略,利用策略模式(GoF)我们让表示层来注入所需的关系域加载策略实现。
下面便是这个想法的实现:
示例中的领域模型:
图表 1示例中领域对象模型
示例中相关的组件
图表 2示例相关组件
LazyObjectLoader:懒对象加载者接口,其定义如下
来对象加载策略接口
package org.ccsoft;
publicinterface LazyObjectLoader {
publicvoid loadLazyObjects(Object obj);
}
该接口定义了不同懒对象加载策略实现者要实现的方法,在loadLazyObjects方法中实现对领域对象obj相关的关系域对象进行加载的策略。
OrderItemLoader一种加载策略的实现,用于加载Order对象的关系域对象OrderItem对象
package org.ccsoft;
import java.io.Serializable;
publicclass OrderItem implements Serializable {
private String detail;
public String getDetail() {
returndetail;
}
publicvoid setDetail(String detail) {
this.detail = detail;
}
}
OrderMgrFacadeImp: Façade的实现,可以使POJO也可以使Session Bean
package org.ccsoft;
publicclass OrderMgrFacadeImp implements OrderMgrFacade {
private OrderDAO orderDAO;
public OrderDAO getOrderDAO() {
returnorderDAO;
}
publicvoid setOrderDAO(OrderDAO orderDAO) {
this.orderDAO = orderDAO;
}
public Order getOrder(int orderId, LazyObjectLoader loader) {
Order order=orderDAO.getOrder(orderId);
loader.loadLazyObjects(order);
return order;
}
}
在getOrder方法中我们要求调用者提供了懒对象装载策略的实例用于装载那些调用者要用到的关系域对象。注意该示例是通过spring实现的,利用spring AOP完成事务管理,事务的边界在Façade中方法上,当方法执行结束,事务业务将结束,并且Hibernate会自动关闭session,我们看到getOrder方法中在事务结束前调用了懒对象装载策略,从而按照调用者的要求装载了调用者所需的关系域对象。
该模式的优点
1 将领域对象的处理逻辑与显示层的显示逻辑完全分离,提高了代码的可维护性和可扩展性
该模式的不足
1 要求显示层的开发者,了解懒加载的情况
2 增加了代码的复杂性
________________________________________________________________________
蔡 超
SCEA , SCBCD , MCSD
IBM Certified Specialist RUP
IBM Certified Solution Designer OOA&D UML v2
北京天融信软件架构师
SUN,Microsoft培训中心特邀高端教师
常年提供架构咨询服务
chaocai2001@yahoo.com.cn , 010-82776427