Flowable-多实例
  4BbmSa234H9N 2023年11月02日 87 0



目录

  • 概述
  • 概念
  • 多实例配置
  • 图形标记
  • XML内容
  • 界面操作
  • 视频教程
  • 演示demo



BPMN2.0 中引入了多实例的概念,它是在业务流程中定义“重复”环节的一个方法,Flowable


对其予以了支持。配置为多实例的活动在流程运行时会创建多个活动实例,既可以顺序依次执行也


可以并行同时执行,效果相当于在这个活动上循环反复执行,并在满足设置的结束条件后退出循环。


BPMN 中的多种节点可以设置为多实例,从而在流程中实现各种“重复”执行的特性,满足特定的


需求场景。本章将介绍 Flowable 中的多实例的配置方法,并结合示例介绍多实例在多种常见的活动


或子流程上的应用。

概述

BPMN 中的多实例活动是实现循环的方式之一。虽然循环总是可以通过活动连接网关将后续顺
序流指向自己或前面的活动来实现,但是多实例活动是可以在某些情况下实现起来更简单。如果想
让某些特定的活动重复执行多次,我们可以将该活动设置为多实例,让其按照配置来执行相应的次
数。

概念

多实例活动是在业务流程中定义重复环节的方式。从开发角度讲,多实例相当于循环,它可以
根据给定的集合,为每个元素顺序或并行地执行某个环节,甚至是一个子流程。
所谓多实例是在一个普通的活动上添加了额外的属性定义(被称作“多实例特性”),这样活
动在运行时被执行多次。以下几种活动可以设置为多实例活动:

  • 用户任务(User Task)
  • 脚本任务(Script Task)
  • 服务任务(Java Service Task)
  • Web 服务任务(Web Service Task)
  • 业务规则任务(Business Rule Task)
  • 电子邮件任务(Email Task)
  • 手动任务(Manual Task)
  • 接收任务(Receive Task)
  • (嵌入式)子流程(Embedded Sub-Process)
  • 调用活动(Call Activity)
    需要注意的是,网关(Gateway)和事件(Event)不能设置为多实例的。
    按照 BPMN 2.0 规范的要求,在 Flowable 的设计中,为每个实例创建的执行的父执行都有如表所示的变量:

多实例的父执行内置变量

变量名

含义

nrOfInstances

实例总数。

nrOfActiveInstances

当前活动的(尚未完成的)实例数量。对于串行多实例来说,这个值始终是 1。

nrOfCompletedInstances

已经完成的实例的数量。

以上这三个变量值可以通过 execution.getVariable(x)方法获取。
另外,每个创建的执行都会有一个执行本地变量,如表 24.2 所示,它对于其它执行不可见,
并且不存储在流程实例级别:

多实例的子执行内置变量

变量名

含义

loopCounter

表示特定实例的在循环的索引值。loopCounter 变量可以使用 flowable 的 elementIndexVariable 属性重命名。

多实例配置

图形标记

如果一个活动被设置为多实例,则在活动底部用三条短线表示。通过短线的朝向决定多实例的
类型,三条竖线表示是并行多实例(并行执行),三条横线表示串行多实例(顺序执行)。如图所示:

Flowable-多实例_前端

XML内容

如果要将一个活动设置为多实例活动 ,需要为该活动的XML元素必须设置一个
multiInstanceLoopCharacteristics 子元素:

<multiInstanceLoopCharacteristics isSequential="false|true">
...
</multiInstanceLoopCharacteristics>
  1. 多实例类型的配置

其中,isSequential属性表示多实例的类型,isSequential="false"表示是并行多实例 ,
isSequential="true"表示是串行多实例。

  1. 多实例的数量计算
    在进入活动时会计算一次多实例的数量,Flowable 提供了多种配置方法进行配置:

2.1. 使用 loopCardinality 子元素指定
这种方法是使用 loopCardinality 子元素直接指定一个数字作为多实例的数量:

<multiInstanceLoopCharacteristics isSequential="false|true">
         <loopCardinality>6</loopCardinality>
    </multiInstanceLoopCharacteristics>

使用这种方式时,也可以配置为执行结果为整数的表达式:

<multiInstanceLoopCharacteristics isSequential="false|true">
    <loopCardinality>${nrOfOrders-nrOfCancellations}</loopCardinality>
</multiInstanceLoopCharacteristics>

2.2、使用 loopDataInputRef 子元素指定
另一种定义实例数的方法是使用 loopDataInputRef 子元素指定设置一个类型为集合的流程变量
名。对于集合中的每个元素,都会创建一个实例。另外,也可以使用 inputDataItem 子元素配置存
储集合元素的变量名(可选)。以用户任务为例,使用方式见如下的示例:

<userTask id="userTask1" name="多实例用户任务" flowable:assignee="${assignee}">
    <multiInstanceLoopCharacteristics isSequential="false">
        <loopDataInputRef>assigneeList</loopDataInputRef>
        <inputDataItem name="assignee" />
    </multiInstanceLoopCharacteristics>
</userTask>

上面通过 loopDataInputRef 子元素指定了类型为集合的 assigneeList 流程变量,同时通过
inputDataItem 子元素设置 assignee。假设 assigneeList 变量的值包括 zhangsan、lisi、wangwu,那么
在以上的配置中,三个用户任务会同时创建(并行多实例)。并且,每个执行都会拥有一个名为
assignee 的流程变量,它会包含集合中的对应元素,在本例中用于分配用户任务。
使用这种方式配置,存在以下两个缺点:1)loopDataInputRef 和 inputDataItem 的名称不太好
记;2)根据 BPMN 2.0 格式定义,它们不能包含表达式。为了解决这个问题,Flowable 提供了下面
的第3种方式。
2.3、通过 collection 和 elementVariable 属性指定
为了解决第②种方式中存在的问题,Flowable 为 multiInstanceCharacteristics 引入了 collection 和
elementVariable 属性:

<userTask id="userTask1" name="多实例用户任务" flowable:assignee="${assignee}">
  <multiInstanceLoopCharacteristics isSequential="true"
  flowable:collection="${myTaskUserService.getUsersOfTask()}"
  flowable:elementVariable="assignee" >
  </multiInstanceLoopCharacteristics>
  </userTask>

对比一下可以看出,这里其实是使用 collection 属性替代了第2种方式的 loopDataInputRef 子
元素,使用 elementVariable 属性替代了 inputDataItem 子元素,不同之处是 collection 属性可以配置
为一个表达式,使用起来更加灵活。
需要注意的是,collection 属性会作为表达式进行解析。如果表达式执行结果为字符串而不是
集合,不论是因为本身配置的就是静态字符串值,还是表达式执行结果为字符串,这个字符串都会
被当做变量名,其变量值为实际的集合。我们看下面的示例:

<userTask id="userTask1" name="多实例用户任务" flowable:assignee="${assignee}">
<multiInstanceLoopCharacteristics isSequential="true"
flowable:collection="assigneeList" flowable:elementVariable="assignee" >
</multiInstanceLoopCharacteristics>
</userTask>

在以上配置中,需要将集合存储在 assigneeList 流程变量中。
为了进一步说明,我们再看下一个示例:

<userTask id="userTask1" name="多实例用户任务" flowable:assignee="${assignee}">
<multiInstanceLoopCharacteristics isSequential="true"
flowable:collection="${myTaskUserService.getCollectionVariableName()}"
flowable:elementVariable="assignee" >
</multiInstanceLoopCharacteristics>
</userTask>

在以上配置中,如果表达式 myTaskUserService.getCollectionVariableName()执行结果是一个字
符串值,引擎就会用这个字符串值作为变量名,获取流程变量保存的集合。
3、多实例结束条件配置
Flowable 默认在所有的实例都完成后,多实例活动才结束。 同时, Flowable 提供了
completionCondition 子元素用于配置评估是否结束多实例的表达式,这个表达式在每个实例结束时
执行一次,如果表达式计算结果为 true,则当前多实例中所有剩余的实例将被销毁,并且多实例活
动结束,流程离开当前活动继续执行;如果表达式计算结果为 false,则继续等待剩下的实例完成。
我们看下面一个示例:

<userTask id="miTasks" name=" " flowable:assignee="${assignee}">
<multiInstanceLoopCharacteristics isSequential="false"
flowable:collection="assigneeList" flowable:elementVariable="assignee" >
<completionCondition>${nrOfCompletedInstances/nrOfInstances >=
0.5 }</completionCondition>
</multiInstanceLoopCharacteristics>
</userTask>

在以上配置中,将会为 assigneeList 集合的每个元素创建一个并行的实例。当 50%的任务完成
时,其他任务就会被删除,流程继续往下执行。

界面操作

Flowable-多实例_bpmnjs_02

视频教程

多实例

演示demo

用户多实例

本文中内容和案例出自贺波老师的书《深入Activiti流程引擎:核心原理与高阶实战》,书中的介绍更全面、详细,推荐给大家。


【版权声明】本文内容来自摩杜云社区用户原创、第三方投稿、转载,内容版权归原作者所有。本网站的目的在于传递更多信息,不拥有版权,亦不承担相应法律责任。如果您发现本社区中有涉嫌抄袭的内容,欢迎发送邮件进行举报,并提供相关证据,一经查实,本社区将立刻删除涉嫌侵权内容,举报邮箱: cloudbbs@moduyun.com

  1. 分享:
最后一次编辑于 2023年11月08日 0

暂无评论

推荐阅读
  E929ZvlRxyUs   2023年12月23日   37   0   0 前端url前端URL
4BbmSa234H9N