说说 jBPM 流程定义语言(8)—— sub-process(子流程活动)
发布日期:2021-06-29 21:10:01 浏览次数:3 分类:技术文章

本文共 4737 字,大约阅读时间需要 15 分钟。

当我们的流程复杂到一定程度时,就需要按照一定规则把业务拆分成若干子流程,这样业务模块之间才能明晰易于划分。

jBPM4 提供了 sub-process – 子流程活动,这可以在 “ 主干流程 ” 定义中调用其他的流程定义,从而 “ 组装 ” 我们的流程定义 。在运行到子流程活动时,工作流引擎将创建一个子流程实例,然后等待直到完成,当子流程实例完成后,流程就会流向下一个节点。

sub-process 活动的属性:

属性 类型 默认值 是否必需 描述
sub-process-id 字符串 sub-process-id 与 sub_process-key,必需其一 流程定义的 ID 标识,可以通过一个流程的 ID 去引用此流程定义的指定版本 。
sub-process-key 字符串 sub-process-id 与 sub_process-key,必需其一 流程 key 标识,通过 key 去引用流程定义,也就意味着引用了该流程定义的最新版本 。 注意,该流程定义的最新版本会在每次活动实例执行时计算得出 。
outcome 表达式 当 sub-process 活动的 transition 元素具有 outcome-value 时必需 当子流程活动执行结束时执行的表达式 。 表达式值用来匹配流出转移中的 outcome-value 元素值,起到选择 sub-process 活动下一步流向的作用 。

sub-process 活动的元素:

元素 聚合关系 描述
parameter-in 0..* 子流程输入参数。即声明一个变量,在创建子流程实例时传入。
parameter-out 0..* 子流程输出参数。即声明一个变量,在子流程实例结束时,返回父流程实例。

sub-process 的 parameter-in – 子流程活动输入元素的属性:

属性 类型 默认值 是否必需 描述
subvar 字符串 必需 被赋值的子流程变量的名称。
var 字符串 var 与 expr 必需二选一 从父流程中输入的变量名称。
expr 字符串 var 与 expr 必需二选一 此表达式会在父流程中被解析,结果值会被输入到对应的子流程变量中。
lang 字符串 EL 表达式 可选 表达式使用的脚本语言。

sub-process 的 parameter-out – 子流程活动输出元素的属性:

属性 类型 默认值 是否必需 描述
var 字符串 必需 输出的目标 – 父流程中的变量名称。
subvar 字符串 subvar 与 expr 必需二选一 子流程中需要被输出的变量名称。
expr 字符串 subvar 与 expr 必需二选一 此表达式会在子流程中被解析,结果会被传入到对应的父流程变量中。
lang 字符串 EL 表达式 可选 表达式使用的脚本语言。

sub-process 活动的 outcome 元素必须有与之相呼应的 outcome-value 元素,这个 outcome-value 元素被定义在子流程活动的流出转移( transition )中 。

sub-process transition 的 outcome-value 元素:

元素 聚合关系 描述
outcome-value 0..1 它是一个值表达式 。 子流程活动结束时,如果子流程中某个转移的 outcome-value 值与子流程的 outcome 值相匹配,那么,父流程会通过此转移 。 注意:这个 outcome-value 值是在 transition 元素中定义的 。

1 流程变量

父子流程是通过流程变量来传递数据的:父流程在子流程启动把值输入,子流程结束时把值输出。

假设有这样一个场景,父流程中的一个节点是审查,而这个节点是通过子流程实现的:

父流程定义

jPDL:

这里引用了下面定义的子流程:

子流程定义

在实际的业务中,存在着各种各样的子流程,它们会被其他流程所引用。

jPDL:

测试代码:

//创建变量,并设置Map
variables = new HashMap<>();variables.put("document", "This document");//带父变量发起流程实例ProcessInstance processInstance = executionService.startProcessInstanceByKey ("SubProcessDocument", variables);//获取用户任务列表List
taskList = taskService.findPersonalTasks("deniro");Task task = taskList.get(0);//获取任务变量(来自父流程)String document = (String) taskService.getVariable(task.getId(), "document");assertEquals("This document", document);//在子流程任务上设置新变量 result(实践一般来自于用户填写的表单)variables = new HashMap<>();variables.put("result", "accept");// result 作为子流程变量返回给父流程实例taskService.setVariables(task.getId(), variables);taskService.completeTask(task.getId());//完成任务,结束子流程实例processInstance = executionService.findProcessInstanceById(processInstance.getId());//断言父流程已完成子流程活动,并到达了 wait 节点assertNotNull(processInstance.findActiveExecutionIn("等待"));//验证父流程的 reviewResult 变量值(它是子流程的输出结果)String result = (String) executionService.getVariable(processInstance.getId(), "reviewResult");assertEquals("accept", result);

注意:如果是在 eclipse 中使用 jBPM 的插件来生成的 jPDL ,jPDL 会默认生成 sub-process-id,这样就无法通过 id 来得到子流程的定义信息(因为我们在子流程中没有定义 ID,用的是 sub-process-key)。

2 决定父流程流出转移(使用 outcome 属性)

现在,我们使用 sub-process 活动的 outcome 属性来决定父流程的流出转移。

带多个流出转移的父流程定义

jPDL:

子流程定义与之前的定义相同:

子流程定义

测试代码:

//带父变量发起流程实例ProcessInstance processInstance = executionService.startProcessInstanceByKey        ("SubProcessDocument2");//获取用户任务列表List
taskList = taskService.findPersonalTasks("deniro");Task task = taskList.get(0);//在子流程任务上设置新变量 result,这个值会被传递给 outcome 属性以决定父流程的走向Map
variables = new HashMap<>();variables.put("result", "同意");// result 作为子流程变量返回给父流程实例taskService.setVariables(task.getId(), variables);taskService.completeTask(task.getId());//完成任务,结束子流程实例processInstance = executionService.findProcessInstanceById(processInstance.getId());//断言父流程已完成子流程活动,并到达了“下一步”节点assertNotNull(processInstance.findActiveExecutionIn("下一步"));

3 决定父流程流出转移(使用子流程的 end 活动)

这种方法比 outcome 属性更容易理解。因为一个流程可以定义多个 end 活动,那么我们可以为子流程定义多个不同名称的 end 活动,这些 end 活动名称会自动与父流程的流出转移名称做同名关联。

父流程的定义与上一个父流程定义相比,仅少了 outcome 属性:

带多个流出转移的父流程定义

jPDL:

具有多个 end 活动的子流程定义

jPDL:

测试代码:

//带父变量发起流程实例ProcessInstance processInstance = executionService.startProcessInstanceByKey        ("SubProcessDocument3");//获取用户任务列表List
taskList = taskService.findPersonalTasks("deniro");Task task = taskList.get(0);// 让任务流向 “同意”转移taskService.completeTask(task.getId(),"同意");//完成任务,结束子流程实例processInstance = executionService.findProcessInstanceById(processInstance.getId());//断言父流程已完成子流程活动,并到达了“下一步”节点assertNotNull(processInstance.findActiveExecutionIn("下一步"));

转载地址:https://deniro.blog.csdn.net/article/details/79455591 如侵犯您的版权,请留言回复原文章的地址,我们会给您删除此文章,给您带来不便请您谅解!

上一篇:说说 MD5 加密后的类型(16位与 32位的区别)
下一篇:说说在 Android 中如何实现强制下线功能

发表评论

最新留言

网站不错 人气很旺了 加油
[***.192.178.218]2024年04月22日 22时45分14秒