jBPM4实现基本活动(上)

开发 后端
这一章解释了流程定义的基础,流程虚拟机给予的功能 以及活动实现是如何构建的。 同时,客户端API被用来执行包含了那些活动实现的流程。

5.1. ActivityBehaviour

PVM库没有包含完整的流程结构。 作为替代的是,活动的运行时行为被委派给一个ActivityBehaviour。 换句话讲,ActivityBehaviour是一个接口, 它用来在纯java环境实现流程结构的运行时行为。

  1. public interface ActivityBehaviour extends Serializable {   
  2.  
  3.   void execute(ActivityExecution execution) throws Exception;   
  4.  
  5. }   

当一个活动行为被调用时,它就处于执行传播的全部控制中。 换句话说,一个活动行为可以决定下一步应该执行什么执行。 比如,可以使用execution.take(Transition)获得一个转移, 或者使用execution.waitForSignal()进入等待阶段。 万一活动行为没有调用任何上述的执行传播方法, 执行将 按默认方式执行。

5.2. ActivityBehaviour实例

我们会启动一个非常原始的hello world例子。 一个Display活动会将一条信息打印到控制台:

  1. public class Display implements ActivityBehaviour {   
  2.  
  3.   String message;   
  4.  
  5.   public Display(String message) {   
  6.     this.message = message;   
  7.   }   
  8.  
  9.   public void execute(ActivityExecution execution) {   
  10.     System.out.println(message);   
  11.   }   
  12. }   

让我们使用这个活动构建我们第一个流程定义:

Display实例流程

Display实例流程  

图 5.1. Display实例流程

TODO add ProcessBuilder example code

现在我们可以像下面这样执行流程:

Execution execution = processDefinition.startExecution();

startExecution的调用会在控制台打印hello world:

hello
world

一个总是值得提醒的事情是活动可以使用属性进行配置。 在Display例子中,你可以看到message属性在两种使用方法中配置的不同。 通过配置属性,我们可以写出可复用的活动。 它们可以在以后每次使用在流程中都进行不同的配置。 这是一个基本的部分, 将流程语言构建在流程虚拟机之上。

其他需要解释的部分是 这个活动实现没有包含任何执行传播的功能。 当一个新流程实例启动时, 执行会定位到初始活动,那个活动会被执行。 Display.execute方法用来决定默认的执行传播。 具体的,这意味着活动自己 没有调用任何执行传播的方法。 那种情况下,默认的传播会执行。默认传播会选择第一个转移,如果这个转移存在的话。 如果没有,它会结束这个执行。 这揭示了为什么a活动和b活动都被执行, 而在b活动执行完执行会停止。

关于默认流程行为的更多细节可以 在第 7.3 节 “默认执行行为”找到。

5.3. ExternalActivityBehaviour

外部活动是负责流程执行由外部转移进来的活动, 外部的意思是来自流程系统的外部。 这意味着这个执行流程对于系统来说,这是一个等待状态。 这个执行会一直等待到外部触发器调用。

为了处理外部触发器,ExternalActivityBehaviour 为ActivityBehaviour添加了一个方法:

  1. public interface ExternalActivity extends Activity {   
  2.  
  3.   void signal(Execution execution,   
  4.               String signal,   
  5.               Map parameters) throws Exception;   
  6.  
  7. }   

就像普通的活动,当一个执行到达一个活动, 外部活动行为的execute方法会被调用。 在外部活动中,execute方法会传递另一个系统的响应, 然后通过调用execution.waitForSignal() 进入等待状态。 比如在execute方法中,响应可能是由一个人传入, 通过在任务管理系统中创建一个任务入口, 然后等待到这个人完成这个任务。

一旦活动行为已经处于等待状态, 然后执行会等待到调用signal方法。 执行会委派signal给ExternalActivityBehaviour对象 分配给当前的活动。

所以活动的signal方法 会在等待期间,在执行获得一个外部触发器的时候调用。 signal方法中,响应会传递给后面的流程执行。 比如,当一个人完成了一个任务,任务管理系统 会在执行中调用signal方法。

一个signal可选择使用signal名字和一个参数map。 活动行为拦截signal和参数的最常用方式是 signal对应选择的外出转移, 参数作为执行中的变量。但那些只是例子, 它一直等到活动使用singal和它期望的参数。

5.4. ExternalActivity实例

这里是一个简单等待状态实现的第一个例子:

  1. public class WaitState implements ExternalActivity {   
  2.  
  3.   public void execute(ActivityExecution execution) {   
  4.     execution.waitForSignal();   
  5.   }   
  6.  
  7.   public void signal(ActivityExecution execution,   
  8.                      String signalName,   
  9.                      Map parameters) {   
  10.     execution.take(signalName);   
  11.   }   
  12. }   

execute方法调用execution.waitForSignal()。 execution.waitForSignal()的调用 会使流程执行进入等待状态, 直到一个外部触发器出现。

signal方法使用signal参数对应的转移名称 来选择转移。所以当一个执行获得一个外部触发器, signal名称被拦截,作为外部转移的名称, 执行会被传播到那个转移上。

这里是从a到b有一个转移的相同的流程。 这时候,两个活动的行为都是WaitState。
外部活动实例流程

外部活动实例流程  

图 5.2. 外部活动实例流程

  1. ClientProcessDefinition processDefinition = ProcessFactory.build()   
  2.     .activity("a").initial().behaviour(new WaitState())   
  3.       .transition().to("b")   
  4.     .activity("b").behaviour(new WaitState())   
  5. .done();  

让我们为流程定义启动一个新流程实例:

ClientExecution execution = processDefinition.startProcessInstance();

启动这个流程会执行a中的WaitState活动。 WaitState.execute会调用 ActivityExecution.waitForSignal。 所以当processDefinition.startProcessInstance()返回, 执行会一直处在a活动。

assertEquals("a", execution.getActivityName());

然后我们提供了外部触发器, 通过调用signal方法。

execution.signal();

execution.signal()会委派给当前活动。 所以在这种情况下就是a活动里的 WaitState活动。WaitState.signal会调用 ActivityExecution.take(String transitionName)。 当我们没有提供一个signal名称,第一个名字是null会被选中。 我们指定的a的唯一转移没有名字,所以会选中这个。 然后这个转移指向b。 当执行到达b活动, b活动中的WaitState活动会被执行。 就像我们上面看到的,执行会在b一直等待, 这时signal会返回, 离开的执行指向b活动。

assertEquals("b", execution.getActivityName());

【编辑推荐】

  1. jBPM与Spring整合浅析
  2. jBPM 4.0配置浅析
  3. jBPM4的架构
  4. 浅谈jBPM下MySQL的配置
  5. 简单介绍jBPM与SSH的完整实例
责任编辑:yangsai 来源: BlogJava
相关推荐

2009-06-26 09:32:35

jBPM4基本活动

2009-06-24 14:57:03

jBPM4架构

2009-06-26 13:51:49

jBPM4高级图形执行

2009-06-29 14:42:54

2010-01-20 09:23:38

jBPM高级交互模式jBPM四眼原则

2016-12-27 10:17:36

UbuntuLinuxSamba4

2009-06-24 16:23:29

jBPM 4.0配置

2010-05-12 16:13:04

2018-06-22 15:25:31

LinuxDocker容器管理

2009-06-11 13:53:35

jBPM用户指南

2009-06-25 17:13:51

jBPM与Spring

2019-10-08 14:02:18

Linux命令终端会话

2009-06-23 15:49:00

Liferay Por

2009-06-23 15:30:20

jBPMMySQL

2022-05-07 09:30:08

watchtailLinux 系统

2014-07-31 13:41:36

程序员

2009-06-11 13:43:21

jBPM用户指南jBPM 4.0

2009-06-11 14:00:34

jBPM用户指南jBPM范例

2022-10-18 08:28:38

运营活动实现逻辑整体协作

2019-12-03 18:31:55

联通/云时代/创新
点赞
收藏

51CTO技术栈公众号