读书人

轻量流程发动机接口设计

发布时间: 2012-06-26 10:04:13 作者: rapoo

轻量流程引擎接口设计

接上文,业务应用和流程引擎之间以及流程引擎和业务服务组件之间通过良好定义的接口进行交互。

业务应用和流程引擎之间的接口称为北向接口,流程引擎和业务组件之间的接口称为南向接口,流程引擎的其他接口如管理接口在此忽略。

?

1.北向接口

北向接口主要是事件引擎提供的面向业务应用的接口(我们的事件引擎是一个简单的事件引擎,用来接收事件、派发和管理事件。业务复杂后可采用复杂事件处理CEP),主要是事件通道(EventChannel)和业务事件。

?

事件通道是事件引擎提供的接口,用来接收业务应用的业务事件,业务应用通过事件通道交付业务事件。

?

业务事件分为同步事件和异步事件。业务应用交付同步事件时需要等待业务服务组件处理完毕后才返回,异步事件只要交付到事件引擎就立即返回,不必等待事件处理完毕。异步事件处理完后将事件处理结果通知流程引擎。

?

1.1业务事件类层次


轻量流程发动机接口设计

?

BusinessEvent类

该类采用范型定义如下:

//ResultDto为事件处理器(EventHandler)方法的返回值类型,BusinessDataDto为业务数据类

public abstract class BusinessEvent <ResultDto,BusinessDataDto> {??
??? private String processName;? //流程名称
??? private Integer? businessKey;? //业务key,对我们的应用来讲,就是交易id(tradeId),为了BusinessEvent通用性,其类型也可范型化。
??? private String eventType; //事件类型id
??? private BusinessDataDto businessData ; //事件包含的业务数据,对下单事件,为下单时的订单OrderDto

??? private String? role; //触发事件的角色,如buyer(买家)、seller(卖家)、timer(超时定时器)等

??? private int actorId;? //事件触发人的id,在我们的系统中,主要用于买卖家

??? private Date eventTime; //触发事件时间

??? private String eventSource; //事件源

??? private String eventSerial; //事件流水号,唯一,类似uuid

?

?? public BusinessEvent(String eventType,Integer businessKey,BusinessDataDto businessData){
???????? ...
??? }


??? ...

???
?? /*deliver方法用来交付事件,就是将事件通过事件通道传给事件引擎*/

??? public abstract ResultDto? deliver();
}

?

?

同步事件类SyncBusinessEvent

?

public class SyncBusinessEvent <ResultDto,BusinessDataDto> extends BusinessEvent <ResultDto,BusinessDataDto>{?? ????

?

?

?? public SyncBusinessEvent(String eventType,Integer businessKey,BusinessDataDto businessData){
???????? ...
??? }
???
?? /*将事件通过事件通道传给事件引擎,并等待事件处理结果*/
??? public ResultDto? deliver(){
??????? //获取事件通道eventChannel

?????? EventChannel eventChannel = EventChannelFactory.getEventChannel();
?????? return (ResultDto) eventChannel.syncSend(this);?? //同步发送事件,返回事件处理结果。

??? }
}

?

使用方法如下:

/*买家在前台业务应用中下单时,业务应用创建下单事件,CreateOrderResult,OrderDto均为业务应用的具体Java类

下单事件为启动流程的初始事件,没有businessKey,所以构造函数第二个参数传null。返回值类型CreateOrderResult中包含有businessKey,就是tradeId属性,初始事件处理拦截器中需要用到该属性来建立businessKey和流程实例id的绑定关系*/

BusinessEvent <CreateOrderResult,OrderDto> event =? new SyncBusinessEvent<CreateOrderResult,OrderDto>("submitOrder",null,orderDto);
? //调用deliver方法交付事件,得到下单处理结果

CreateOrderResult? result = event.deliver();

?

在实际应用中,可以为每个流程从该类再派生一个子类,在每个子类中为processName赋值(写死为对应的流程)。

?

异步事件类AsyncBusinessEvent

?

public class AsyncBusinessEvent <BusinessDataDto> extends BusinessEvent <Boolean,BusinessDataDto>{?? ????

?

?? public AsyncBusinessEvent(String eventType,Integer businessKey,BusinessDataDto businessData){
???????? ...
??? }
???
?? /*交付事件,不等待事件处理结果。

??????? 返回值为TRUE表示事件引擎已成功接收异步事件

? */

? ??? public Boolean? deliver(){
??????? //获取事件通道eventChannel

?????? EventChannel eventChannel = EventChannelFactory.getEventChannel();

?????? return (Boolean) eventChannel.asyncSend(this);?? //异步发送事件,事件引擎收到就返回,不返回事件处理结果。

??? }
}

?

交付异步事件的demo如下:

BusinessEvent<Boolean,XXXDto>? event = new AsyncBusinessEvent<XXXDto>(......);? //XXXDto为一个具体的java类

Boolean deliverResult = event.deliver();

?

?

1.2事件通道EventChannel接口

事件通道用来接收业务应用 交付(deliver)的业务事件,它提供两个方法syncSend和asyncSend,分别用来同步发送和异步发送事件。

?

北向接口还包括查询流程实例当前状态的接口和根据角色查询节点url的接口(例如买家和买家在同一个流程节点可以有不同的html页面url来操作和查看订单与交易)。

?

2.南向接口

南向接口为业务服务组件的接口,流程引擎根据事件中的eventType属性调用对应的业务组件接口方法(在流程定义文件中eventHanderMap中定义了每种eventType对应的业务组件和事件处理方法名)。

可以统一定义一个泛型java interface,也可自由定义,不用泛型(这样每个组件的方法名可不一样,业务语义更强),只要业务组件的事件处理方法的参数类型和返回值与对应事件的业务数据类型、返回值类型一致即可。
例如,对处理下单事件的业务服务组件,其处理下单事件的createOrder方法签名可能定义如下(自由定义):

public class CreateOrderServiceImpl implements CreateOrderService{

?

??? //? 该方法值返回类型CreateOrderResult和OrderDto参数类型和 1.1下单事件BusinessEvent中的类型一致

??? public? CreateOrderResult? createOrder(OrderDto orderDto) {

???????????? ...

???? }

???? ...

如果南向接口统一定义(泛型),接口可定义为:
interface BusinessEventHandler<ResultDto,BusinessDataDto>{
??????? ResultDto? handleBusiness(BusinessDataDto);
}
??
可见handleBusiness方法的业务语义没有createOrder方法强。

?

3.初始事件的处理

?事件类中的processName(流程名称)加上businessKey可唯一映射到一个流程实例id,业务应用和业务服务组件通常不关注流程实例id,也就是希望流程实例id是透明的。为了保持透明,需要在开始事件处理中建立processNme+businessKey与流程实例id的绑定关系。

? 为了建立绑定关系,在开始节点的事件eventHandler中配置拦截器,从eventHandler的返回值属性中得到businessKey。

?

?

?

?

?

读书人网 >软件架构设计

热点推荐