作者:胡长城
在阅读此篇文档的时候,首先需要对jBpm有些了解。好歹知道jBpm最主要的基本元素就是三个:State,Action,Transition
其State相当于我们通常所说的Task,而Transition则有根XPDL的Transition很类似了。那么Action呢?
jBpm我想,其最大的特色就是提供了一套比较简单但是很实用的Event(Action)处理机制。不过,这套Event依然还有很多缺陷,比如不能自定义Event Type(这个通常是有些用处的),不能热部署(或插入)等等,而且只适合后台程序调用的执行。
jBpm jPDL所描述的主要几个元素,大多都可以挂Action(一个或多个),除了End-State(结束位置)。相应信息规则可以参考http://jbpm.org/2/jpdl.html (最好首先仔细读读)。
jBpm描述这样的许可:在流程运行的不同时期、不同地点,可能会激活特定的Event。而这特定的Event是由一系列类型相的Action组成的。jBpm提供这些Action底层接口,而开发者可以根据这个接口,来实现具体的执行体。
<o:p> </o:p>
这个最基本的接口就是org.jbpm.delegation.ActionHandler。
public interface ActionHandler {<o:p></o:p> void execute( ExecutionContext executionContext );<o:p></o:p> }<o:p></o:p> |
<o:p> </o:p>
jBpm提供了一些EventType(很不爽的是,开发者必须遵循这些EventType),即使你在你个流程定义xml文件中没有为某一个元素(比如Transtion)中的Action指明类型,但是在流程定义加载的时候,会将这些没有指明的Action,根据其当前所在的元素,而赋予默认的类型。
下面这个例子,是TransitionImpl(Transtion所对应的对象)所为其下的Action提供了默认“动作类型”
public EventType getDefaultEventType() {<o:p></o:p> return EventType.TRANSITION;<o:p></o:p> }<o:p></o:p> |
<o:p> </o:p>
那么,jBpm提供了哪些Event类型呢?
具体可以参考一下 EventType类的javadoc:
http://jbpm.org/2/javadoc/org/jbpm/model/definition/EventType.html
那么这些的action是在哪儿调用的,以及如何调用的呢?
比如,一个state元素允许定义三种EventType:STATE_ENTER,STATE_AFTER_ASSIGNMENT,STATE_LEAVE。
那么引擎在执行时,当一个token 从transition移到其所连接的State,并被这个State所接受的时候,其就会激活这个State对象的acceptToken方法(参见StateImpl类)。而在这个acceptToken方法中,就需要执行 EventType为STATE_ENTER和STATE_AFTER_ASSIGNMENT的所有Action。
<o:p> </o:p>
下框显示了如何调用action的执行:
public void acceptToken(ExecutionContextImpl executionContext) <o:p></o:p> throws ExecutionException {<o:p></o:p> ······ <o:p></o:p> executeActions( EventType.STATE_ENTER, executionContext );<o:p></o:p> ······<o:p></o:p> executeActions( EventType.STATE_AFTER_ASSIGNMENT, executionContext );<o:p></o:p> }<o:p></o:p> |
说到这儿,估计即使我不说了,想来也可以猜到jBpm是如何处理的···
下面让我们来看看着个executeActions方法,其是在ElementImpl这个基类中。
public void executeActions( EventType eventType, <o:p></o:p> ExecutionContextImpl executionContext ) throws DelegationException { <o:p></o:p> TokenImpl token = (TokenImpl) executionContext.getToken();<o:p></o:p> Iterator iter = actions.iterator();<o:p></o:p> while (iter.hasNext()) {<o:p></o:p> ActionImpl action = (ActionImpl) iter.next();<o:p></o:p> if ( eventType == action.getEventType() ) {<o:p></o:p> action.execute( executionContext );<o:p></o:p> }<o:p></o:p> }<o:p></o:p> }<o:p></o:p> |