子流程是一种特殊的流程活动,它可以包含其他的流程元素,例如流程任务、流程网关、流程事件和顺序流等,它是一个较大的流程的组成部分,或者可以将其看作流程中的一个容器,用于存放其他流程活动。
1 子流程
在BPMN规范中定义了5种子流程:
- 嵌入式子流程
- 调用式子流程
- 事件子流程
- 事务子流程
- 特别子流程
Activiti 5支持前4个子流程,Activiti 6新增了对特别子流程(Ad Hoc Sub Process)的支持。
2 嵌入式子流程
2.1 概念
嵌入式子流程是将整个子流程都会被完整地定义在父流程中。如果不使用子流程,同样也会将这些流程活动定义到主流程中,与子流程的效果一样,但是如果想为某部分流程活动添加特定的事件范围,那么此时使用嵌入式子流程就很有必要。
假设当前有一个ATM机操作的业务流程,其中的转账可以分为若干个步骤,当其中一个步骤出现异常时,可以触发流程补偿或者取消等边界事件,因此可以将转账相关的流程活动划归为一个子流程,然后为子流程加入边界事件,这样相当于为转账的全部步骤划定了事件范围。
在Activiti中,子流程中只能有一个无指定开始事件,不能有其他类型的开始事件。BPMN2.0规范允许子流程没有开始事件或者结束事件,但是当前的Activiti对此不支持。
2.2 模型
图1所示为一个含有子流程的流程图,对应的流程文件内容如代码清单如图2所示。
图中的流程含有一个嵌入式子流程,该子流程中有一个ServiceTask,对应的类为com.wang.activiti包下的EmbededJavaDelegate,它实现了JavaDelegate,嵌入式子流程中有一个错误边界事件,如果边界事件被触发,执行流会到达name=errorTask
用户任务。
3 代码调用
3.1 EmbededJavaDelegate.java
public class EmbededJavaDelegate implements JavaDelegate {
@Override
public void execute(DelegateExecution arg0) {
System.out.println("执行子流程Service Task的Java Delegate, 抛出错误");
throw new BpmnError("myError");
}
}
EmbededJavaDelegate的execute()会抛出BpmnError,图中子流程的错误边界事件会被触发,流程到达“Error Task”。
3.2 EmbededSubProcess.java
部署文件代码如下:
public class EmbededSubProcess {
public static void main(String[] args) {
// 创建流程引擎
ProcessEngine engine = ProcessEngines.getDefaultProcessEngine();
// 得到流程存储服务组件
RepositoryService repositoryService = engine.getRepositoryService();
// 得到运行时服务组件
RuntimeService runtimeService = engine.getRuntimeService();
TaskService taskService = engine.getTaskService();
// 部署流程文件
repositoryService.createDeployment().addClasspathResource("diagram/demo426.bpmn").deploy();
// 启动流程
ProcessInstance pi = runtimeService.startProcessInstanceByKey("demo426");
// 查询任务
Task task = taskService.createTaskQuery().processInstanceId(pi.getId()).singleResult();
System.out.println("当前任务:" + task.getName());
}
}
3.3 输出结果
4 数据流转
在Activiti的实现中,如果执行流到达子流程,会创建新的执行流数据act_ru_execution
表的数据,该执行流数据的PARENT_ID_
字段值为主执行流的ID,即主执行流遇到子流程时,会创建新的执行流来执行该子流程。接下来,看一下数据如何流转。
act_ru_execution表
act_hi_actinst表
从xml中可知,当执行到id=sub2
的时候,程序会调用EmbededJavaDelegate.java
的execute
的方法,抛出错误事件,然后流程会到达Error Task
用户任务。
因此,在act_hi_actinst表中也同样看到数据ACT_ID_=sub2
的下一步会执行到ACT_ID_=e1
的ACT_NAME_
为错误开始。
3.4 更多文档
本文学习自疯狂工作流讲义。
更多文档请参考疯狂工作流讲义———基于Activiti 6.x的应用开发