举个例子:比如我们有一个任务 可能需要多人审批,审批通过的条件可能比较多样,比如五个人审批。3个人审批过了就算过了,再或者有一个人权限比较高,拥有一票否决权。 即是其余所有人都过了,他点了个否定 就算不过了,这种就是会签。
我们从上面可以清楚看到,这个流程有两个任务节点,分别是多实例任务节点,和任务2. 任务2就是普通的userTask,多实例任务1 其实也是userTask,
只不过是参数设置不同罢了,下面我们上流程的xml定义文件。
<definitions xmlns="http://www.omg.org/spec/BPMN/20100524/MODEL" xmlns:xsi="http://www.w3.org/2001/XMLSchema-instance" xmlns:xsd="http://www.w3.org/2001/XMLSchema" xmlns:flowable="http://flowable.org/bpmn" xmlns:bpmndi="http://www.omg.org/spec/BPMN/20100524/DI" xmlns:omgdc="http://www.omg.org/spec/DD/20100524/DC" xmlns:omgdi="http://www.omg.org/spec/DD/20100524/DI" typeLanguage="http://www.w3.org/2001/XMLSchema" expressionLanguage="http://www.w3.org/1999/XPath" targetNamespace="http://www.flowable.org/processdef">
<process id="multiinstance" name="MultiInstance" isExecutable="true">
<documentation>测试多实例模型documentation>
<startEvent id="startEvent1" flowable:formFieldValidation="true">startEvent>
<userTask id="sid-AFB0AD6E-5B65-457F-8E99-F3B8104CBA95" name="多实例任务1" flowable:assignee="${assignee}" flowable:formFieldValidation="true">
<extensionElements>
<modeler:initiator-can-complete xmlns:modeler="http://flowable.org/modeler">modeler:initiator-can-complete>
extensionElements>
<multiInstanceLoopCharacteristics isSequential="false" flowable:collection="assigneeList" flowable:elementVariable="assignee">
<loopCardinality>5loopCardinality>
<completionCondition>${nrOfCompletedInstances/nrOfInstances >= 0.50}completionCondition>
multiInstanceLoopCharacteristics>
userTask>
<sequenceFlow id="sid-78DB6DB5-22CF-406D-9B4A-B4F14A7E062B" sourceRef="startEvent1" targetRef="sid-AFB0AD6E-5B65-457F-8E99-F3B8104CBA95">sequenceFlow>
<userTask id="sid-F1BBCD6F-3153-4139-9101-D3C8C2F6151C" name="任务2" flowable:formFieldValidation="true">userTask>
<sequenceFlow id="sid-B452CC02-56EA-46D2-8485-FB5B788200C1" sourceRef="sid-AFB0AD6E-5B65-457F-8E99-F3B8104CBA95" targetRef="sid-F1BBCD6F-3153-4139-9101-D3C8C2F6151C">sequenceFlow>
<endEvent id="sid-15CEF7DC-E073-484D-9B36-4EB3DA9A059F">endEvent>
<sequenceFlow id="sid-69D6B9D5-A369-4708-B74B-2DECD1D0F308" sourceRef="sid-F1BBCD6F-3153-4139-9101-D3C8C2F6151C" targetRef="sid-15CEF7DC-E073-484D-9B36-4EB3DA9A059F">sequenceFlow>
process>
<bpmndi:BPMNDiagram id="BPMNDiagram_multiinstance">
<bpmndi:BPMNPlane bpmnElement="multiinstance" id="BPMNPlane_multiinstance">
<bpmndi:BPMNShape bpmnElement="startEvent1" id="BPMNShape_startEvent1">
<omgdc:Bounds height="30.0" width="30.0" x="90.0" y="150.0">omgdc:Bounds>
bpmndi:BPMNShape>
<bpmndi:BPMNShape bpmnElement="sid-AFB0AD6E-5B65-457F-8E99-F3B8104CBA95" id="BPMNShape_sid-AFB0AD6E-5B65-457F-8E99-F3B8104CBA95">
<omgdc:Bounds height="80.0" width="100.0" x="300.0" y="120.0">omgdc:Bounds>
bpmndi:BPMNShape>
<bpmndi:BPMNShape bpmnElement="sid-F1BBCD6F-3153-4139-9101-D3C8C2F6151C" id="BPMNShape_sid-F1BBCD6F-3153-4139-9101-D3C8C2F6151C">
<omgdc:Bounds height="80.0" width="100.0" x="630.0" y="125.0">omgdc:Bounds>
bpmndi:BPMNShape>
<bpmndi:BPMNShape bpmnElement="sid-15CEF7DC-E073-484D-9B36-4EB3DA9A059F" id="BPMNShape_sid-15CEF7DC-E073-484D-9B36-4EB3DA9A059F">
<omgdc:Bounds height="28.0" width="28.0" x="1095.0" y="151.0">omgdc:Bounds>
bpmndi:BPMNShape>
<bpmndi:BPMNEdge bpmnElement="sid-69D6B9D5-A369-4708-B74B-2DECD1D0F308" id="BPMNEdge_sid-69D6B9D5-A369-4708-B74B-2DECD1D0F308">
<omgdi:waypoint x="729.9499999999999" y="165.0">omgdi:waypoint>
<omgdi:waypoint x="1095.0" y="165.0">omgdi:waypoint>
bpmndi:BPMNEdge>
<bpmndi:BPMNEdge bpmnElement="sid-B452CC02-56EA-46D2-8485-FB5B788200C1" id="BPMNEdge_sid-B452CC02-56EA-46D2-8485-FB5B788200C1">
<omgdi:waypoint x="399.9499999999835" y="160.0">omgdi:waypoint>
<omgdi:waypoint x="515.0" y="160.0">omgdi:waypoint>
<omgdi:waypoint x="515.0" y="165.0">omgdi:waypoint>
<omgdi:waypoint x="629.9999999999847" y="165.0">omgdi:waypoint>
bpmndi:BPMNEdge>
<bpmndi:BPMNEdge bpmnElement="sid-78DB6DB5-22CF-406D-9B4A-B4F14A7E062B" id="BPMNEdge_sid-78DB6DB5-22CF-406D-9B4A-B4F14A7E062B">
<omgdi:waypoint x="119.94999834279307" y="165.0">omgdi:waypoint>
<omgdi:waypoint x="210.0" y="165.0">omgdi:waypoint>
<omgdi:waypoint x="210.0" y="160.0">omgdi:waypoint>
<omgdi:waypoint x="299.9999999999682" y="160.0">omgdi:waypoint>
bpmndi:BPMNEdge>
bpmndi:BPMNPlane>
bpmndi:BPMNDiagram>
definitions>
上面是整个流程定义,内容比较繁多,下面我们主要看一下多实例任务1的节点内容片段进行详解:
<userTask id="sid-AFB0AD6E-5B65-457F-8E99-F3B8104CBA95" name="多实例任务1" flowable:assignee="${assignee}" flowable:formFieldValidation="true">
<extensionElements>
<modeler:initiator-can-complete xmlns:modeler="http://flowable.org/modeler">modeler:initiator-can-complete>
extensionElements>
<multiInstanceLoopCharacteristics isSequential="false" flowable:collection="assigneeList" flowable:elementVariable="assignee">
<loopCardinality>5loopCardinality>
<completionCondition>${nrOfCompletedInstances/nrOfInstances >= 0.50}completionCondition>
multiInstanceLoopCharacteristics>
userTask>
上面我们已经知道了,会签的应用场景,有点想投票一样的感觉,既然是多个人参与的场景,也就意味着这是一个多人的任务,所以就有了上面的多实例任务,什么叫多实例任务呢?就是这个任务会产生多个实例,想java 的类和实例的关系一样,你需要多少个实例你new多少次这个类就行了。所以这个多实例任务是可以通过配置参数,来决定执行这个任务的时候会产生多少个一样的任务的实例,来给每个指定人的人执行,然后汇总结果,来判断是否通过。也就是说还会有个条件来判断是否通过。
至于是多少个实例呢?这个是通过
<loopCardinality>5loopCardinality>
配置的吗,这里我们配置的是5个实例,也就是说要把它分给五个人执行。
理解了上面我们再看一下上面的属性
false 代表并行,true代表串行,是什么意思呢?并行就是上面这5个任务可以同时执行,不受约束,串行就是一个个轮着来执行。
flowable:assignee="${assignee}"
该属性代表任务分配给谁,这里用的EL表达式,因为我们可能将五个不同的任务分配给五个不同的人,而且可能是我们运行时决定的(就是提前不能确定)。
flowable:collection=“assigneeList”
这里是一个运行时的变量的名字,举个例子我们运行时变量里面必须有个变量名字叫assigneeList
flowable:elementVariable=“assignee”
这里的assignee对应于上面的assigneeList, 如果 assigneeList是一个集合类型,那么assignee就对应于集合中的一个单元,然后,上面的EL表达式${assignee} 对应的就是这些单元。类似于Mybatis中的foreach标签。
<foreach collection="list" item="emp" separator=";">
INSERT INTO t_employee(username, gender, email) VALUES
(#{emp.username}, #{emp.gender}, #{emp.email})
foreach>
assigneeList对应于上面的list, assignee对应于上面的emp。
5
${nrOfCompletedInstances/nrOfInstances >= 0.50}
${nrOfCompletedInstances/nrOfInstances >= 0.50}
当我们启动一个上面的流程定义实例的时候传入的数据结构参数如下:
{
"deployId":"multiinstance:1:f9d0c4e2-2873-11ea-9aeb-1c872c5f4209",
"processKey":"multiinstance",
"processStarter":"sunlutong",
"varibales":{
"assigneeList":[
"m1",
"m2",
"m3",
"m4",
"m5"
]
}
}
实例化后,返回的流程实例ID是:22b6508d-2b76-11ea-af60-1c872c5f4209
进入到多实例任务
节点之后,根据实例ID22b6508d-2b76-11ea-af60-1c872c5f4209
。我们看一下实时的该实例的任务在表ACT_RU_TASK的数据表现:
我们可以看到上面自动生成了五个任务实例,assignee正是我们上面传入的参数assigneeList中的数据。
再来看一下多实例任务相关的实时的属性表,ACT_RU_VARIABLE表中的数据状态如下:
我们可以看到除了自己传入的参数assignee,assigneeList,会自动生成一些任务属性。
我们上面设置的完成属性是完成的实例超过50%就算完成了实例,也就是说我们只要完成三个实例就会结束多任务节点
进入到 任务2
。
ACT_RU_TASK表得数据:
我们可以看到此时上面的assignee的任务消失了。
ACT_RU_VARIABLE表得数据:
我们可以看到数据nrOfCompletedInstances变成了1,
发现表ACT_RU_TASK和表ACT_RU_VARIABLE的多任务实例相关的数据都没了。
以上就是会签。