flowable学习笔记(四):动态多实例

news2024/11/24 4:41:14

1.定义流程模板

在这里插入图片描述
【测试用户任务多实例】任务节点配置了以下属性:
集合(多实例):userList。这个创建流程实例时入参需要加上这个参数。
元素变量(多实例):user。工作流创建多实例时会将集合(多实例)的值拆分成元素变量(多实例),这个例子每个实例会有一个入参变量名称是user。
多实例类型:我设置成Parallel(并行)。
完成条件(多实例):${nrOfCompletedInstances/nrOfInstances == 1} 表示全部实例通过提交才算完成。${nrOfCompletedInstances/nrOfInstances >= 0.5} 表示一半的实例通过提交才算完成。
nrOfCompletedInstances:完成实例数。number of Completed Instances
nrOfInstances:总实例数。number of Instances
执行监听器:配置一个执行监听器CommonMoreInstancesExecutionListener,用于打印流程变量。
任务监听器:配置一个任务监听器CommonMoreInstancesTaskListener,用于打印流程变量。

在这里插入图片描述

结束节点配置了以下属性:
执行监听器:配置一个执行监听器CommonEndExecutionListener,用于判断任务节点结束条件。

2.代码

(1)CommonMoreInstancesExecutionListener
package gdut.listener;

import org.flowable.engine.delegate.DelegateExecution;
import org.flowable.engine.delegate.ExecutionListener;
import org.springframework.stereotype.Component;

import java.util.Map;
import java.util.Random;

@Component
public class CommonMoreInstancesExecutionListener implements ExecutionListener {

    @Override
    public void notify(DelegateExecution delegateExecution) {
        System.out.println("CommonMoreInstancesExecutionListener start");
        Map<String, Object> variables = delegateExecution.getVariables();
        System.out.println("CommonMoreInstancesExecutionListener variables is:" + variables);
        System.out.println("CommonMoreInstancesExecutionListener executionId is:" + delegateExecution.getId());
    }
}
(2)CommonMoreInstancesTaskListener
package gdut.listener;

import org.flowable.engine.delegate.TaskListener;
import org.flowable.task.service.delegate.DelegateTask;
import org.springframework.stereotype.Component;

import java.util.Map;

@Component
public class CommonMoreInstancesTaskListener implements TaskListener {

    @Override
    public void notify(DelegateTask delegateTask) {
        System.out.println("CommonMoreInstancesTaskListener start");
        Map<String, Object> variables = delegateTask.getVariables();
        System.out.println("CommonMoreInstancesTaskListener variables is:" + variables);
        System.out.println("CommonMoreInstancesTaskListener executionId is:" + delegateTask.getExecutionId());
        System.out.println("CommonMoreInstancesTaskListener taskId is:" + delegateTask.getId());
    }
}
(3)创建流程实例接口

    //创建流程实例
    @PostMapping("/createFlowInstanceByMap")
    public String createFlowInstanceByMap(@RequestBody JSONObject params) {
        String flowDefinitionName = params.getStr("flowDefinitionName");
        Map<String, Object> paramsMap = BeanUtil.beanToMap(params);

        ProcessInstance processInstance = runtimeService.startProcessInstanceByKey(flowDefinitionName, paramsMap);
        System.out.println("createFlowInstanceByMap instanceId is:" + processInstance.getProcessInstanceId());
        return processInstance.getProcessInstanceId();
    }

3.测试

部署流程定义:
http://localhost:8081/flowable/deployFlowDefinition?fileName=TestMoreInstances.bpmn20.xml

创建流程实例:
http://localhost:8081/flowable/createFlowInstanceByMap
{
“flowDefinitionName”:“TestMoreInstances”,
“userList”:[“liufeifei”, “liushanshan”, “liuhao”]
}

打印输出:

CommonStartExecutionListener start
CommonStartExecutionListener variables is:{userList=["liufeifei","liushanshan","liuhao"], flowDefinitionName=TestMoreInstances}
CommonMoreInstancesExecutionListener start
CommonMoreInstancesExecutionListener variables is:{userList=["liufeifei","liushanshan","liuhao"], flowDefinitionName=TestMoreInstances, commonStartExecutionListener=CommonStartExecutionListener}
CommonMoreInstancesExecutionListener executionId is:caa751e3-875b-11ed-a341-c03c5949a6ca
CommonMoreInstancesExecutionListener start
CommonMoreInstancesExecutionListener variables is:{nrOfActiveInstances=3, userList=["liufeifei","liushanshan","liuhao"], flowDefinitionName=TestMoreInstances, commonStartExecutionListener=CommonStartExecutionListener, loopCounter=0, user=liufeifei, nrOfInstances=3, nrOfCompletedInstances=0}
CommonMoreInstancesExecutionListener executionId is:caaaad4b-875b-11ed-a341-c03c5949a6ca
CommonMoreInstancesTaskListener start
CommonMoreInstancesTaskListener variables is:{nrOfActiveInstances=3, userList=["liufeifei","liushanshan","liuhao"], flowDefinitionName=TestMoreInstances, commonStartExecutionListener=CommonStartExecutionListener, loopCounter=0, user=liufeifei, nrOfInstances=3, nrOfCompletedInstances=0}
CommonMoreInstancesTaskListener executionId is:caaaad4b-875b-11ed-a341-c03c5949a6ca
CommonMoreInstancesTaskListener taskId is:caab4993-875b-11ed-a341-c03c5949a6ca
CommonMoreInstancesExecutionListener start
CommonMoreInstancesExecutionListener variables is:{nrOfActiveInstances=3, userList=["liufeifei","liushanshan","liuhao"], flowDefinitionName=TestMoreInstances, commonStartExecutionListener=CommonStartExecutionListener, loopCounter=1, user=liushanshan, nrOfInstances=3, nrOfCompletedInstances=0}
CommonMoreInstancesExecutionListener executionId is:caaaad4c-875b-11ed-a341-c03c5949a6ca
CommonMoreInstancesTaskListener start
CommonMoreInstancesTaskListener variables is:{nrOfActiveInstances=3, userList=["liufeifei","liushanshan","liuhao"], flowDefinitionName=TestMoreInstances, commonStartExecutionListener=CommonStartExecutionListener, loopCounter=1, user=liushanshan, nrOfInstances=3, nrOfCompletedInstances=0}
CommonMoreInstancesTaskListener executionId is:caaaad4c-875b-11ed-a341-c03c5949a6ca
CommonMoreInstancesTaskListener taskId is:caae7de6-875b-11ed-a341-c03c5949a6ca
CommonMoreInstancesExecutionListener start
CommonMoreInstancesExecutionListener variables is:{nrOfActiveInstances=3, userList=["liufeifei","liushanshan","liuhao"], flowDefinitionName=TestMoreInstances, commonStartExecutionListener=CommonStartExecutionListener, loopCounter=2, user=liuhao, nrOfInstances=3, nrOfCompletedInstances=0}
CommonMoreInstancesExecutionListener executionId is:caaaad4d-875b-11ed-a341-c03c5949a6ca
CommonMoreInstancesTaskListener start
CommonMoreInstancesTaskListener variables is:{nrOfActiveInstances=3, userList=["liufeifei","liushanshan","liuhao"], flowDefinitionName=TestMoreInstances, commonStartExecutionListener=CommonStartExecutionListener, loopCounter=2, user=liuhao, nrOfInstances=3, nrOfCompletedInstances=0}
CommonMoreInstancesTaskListener executionId is:caaaad4d-875b-11ed-a341-c03c5949a6ca
CommonMoreInstancesTaskListener taskId is:cab02b99-875b-11ed-a341-c03c5949a6ca
createFlowInstanceByMap instanceId is:caa5a42e-875b-11ed-a341-c03c5949a6ca

总结:
(1)从上面的打印输出可以发现:flowable是先调用了一次执行监听器,再创建了3个用户任务实例(我请求的参数userList数组长度是3)。
(2)创建的多实例的执行监听器和任务监听器获取到的流程参数,除了创建流程实例的入参,还增加了以下几个变量:
nrOfActiveInstances 活跃的实例数
loopCounter 类似for循环下标 for(int i = 0;i < userList.size();i++) 表示i的值。
nrOfInstances 总的实例数
nrOfCompletedInstances 完成实例数
user 元素变量 获取userList.get(i)的值。
(3)查看flowable数据库表ACT_RU_TASK有三条记录:
select * from ACT_RU_TASK where PROC_INST_ID_ = ‘caa5a42e-875b-11ed-a341-c03c5949a6ca’;
在这里插入图片描述
提交任务
http://localhost:8081/flowable/completeTaskId?taskId=caab4993-875b-11ed-a341-c03c5949a6ca
完成一个任务,结束节点监听器没有执行。ACT_RU_TASK表还有2条记录。
在这里插入图片描述
http://localhost:8081/flowable/completeTaskId?taskId=caae7de6-875b-11ed-a341-c03c5949a6ca
完成第二个任务,结束节点监听器没有执行。ACT_RU_TASK表还有1条记录。
在这里插入图片描述
http://localhost:8081/flowable/completeTaskId?taskId=cab02b99-875b-11ed-a341-c03c5949a6ca
提交第三个任务,结束节点监听器执行了,ACT_RU_TASK表没有记录。
在这里插入图片描述
结束节点执行监听器打印输出:

CommonEndExecutionListener end
CommonEndExecutionListener variables is:{userList=["liufeifei","liushanshan","liuhao"], flowDefinitionName=TestMoreInstances, commonStartExecutionListener=CommonStartExecutionListener}

符合我配置的完成条件,3个实例全部完成,该任务节点才算通过。

bpmn.xml

(1)TestMoreInstances.bpmn20.xml

<?xml version="1.0" encoding="UTF-8"?>
<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" exporter="Flowable Open Source Modeler" exporterVersion="6.7.2">
  <process id="TestMoreInstances" name="TestMoreInstances" isExecutable="true">
    <documentation>测试多实例</documentation>
    <startEvent id="testMoreInstancesStart" name="测试用户任务多实例开始节点" flowable:formFieldValidation="true">
      <extensionElements>
        <flowable:executionListener event="start" delegateExpression="${commonStartExecutionListener}"></flowable:executionListener>
      </extensionElements>
    </startEvent>
    <userTask id="TestMoreUserTaskInstances" name="测试用户任务多实例" flowable:formFieldValidation="true">
      <extensionElements>
        <flowable:executionListener event="start" delegateExpression="${commonMoreInstancesExecutionListener}"></flowable:executionListener>
        <flowable:taskListener event="create" delegateExpression="${commonMoreInstancesTaskListener}"></flowable:taskListener>
      </extensionElements>
      <multiInstanceLoopCharacteristics isSequential="false" flowable:collection="userList" flowable:elementVariable="user">
        <extensionElements></extensionElements>
        <completionCondition>${nrOfCompletedInstances/nrOfInstances == 1}</completionCondition>
      </multiInstanceLoopCharacteristics>
    </userTask>
    <endEvent id="testMoreInstancesEnd" name="测试用户任务多实例结束节点">
      <extensionElements>
        <flowable:executionListener event="start" delegateExpression="${commonEndExecutionListener}"></flowable:executionListener>
      </extensionElements>
    </endEvent>
    <sequenceFlow id="sid-FF142143-F573-4FD7-905A-BBA5E118F13F" sourceRef="testMoreInstancesStart" targetRef="TestMoreUserTaskInstances"></sequenceFlow>
    <sequenceFlow id="sid-90EEDCBB-5375-4A8E-A1C3-C239743F9D96" sourceRef="TestMoreUserTaskInstances" targetRef="testMoreInstancesEnd"></sequenceFlow>
  </process>
  <bpmndi:BPMNDiagram id="BPMNDiagram_TestMoreInstances">
    <bpmndi:BPMNPlane bpmnElement="TestMoreInstances" id="BPMNPlane_TestMoreInstances">
      <bpmndi:BPMNShape bpmnElement="testMoreInstancesStart" id="BPMNShape_testMoreInstancesStart">
        <omgdc:Bounds height="30.0" width="30.0" x="135.0" y="70.0"></omgdc:Bounds>
      </bpmndi:BPMNShape>
      <bpmndi:BPMNShape bpmnElement="TestMoreUserTaskInstances" id="BPMNShape_TestMoreUserTaskInstances">
        <omgdc:Bounds height="80.0" width="100.0" x="285.0" y="45.0"></omgdc:Bounds>
      </bpmndi:BPMNShape>
      <bpmndi:BPMNShape bpmnElement="testMoreInstancesEnd" id="BPMNShape_testMoreInstancesEnd">
        <omgdc:Bounds height="28.0" width="28.0" x="510.0" y="71.0"></omgdc:Bounds>
      </bpmndi:BPMNShape>
      <bpmndi:BPMNEdge bpmnElement="sid-FF142143-F573-4FD7-905A-BBA5E118F13F" id="BPMNEdge_sid-FF142143-F573-4FD7-905A-BBA5E118F13F" flowable:sourceDockerX="15.0" flowable:sourceDockerY="15.0" flowable:targetDockerX="50.0" flowable:targetDockerY="40.0">
        <omgdi:waypoint x="164.94999946593478" y="85.0"></omgdi:waypoint>
        <omgdi:waypoint x="285.0" y="85.0"></omgdi:waypoint>
      </bpmndi:BPMNEdge>
      <bpmndi:BPMNEdge bpmnElement="sid-90EEDCBB-5375-4A8E-A1C3-C239743F9D96" id="BPMNEdge_sid-90EEDCBB-5375-4A8E-A1C3-C239743F9D96" flowable:sourceDockerX="50.0" flowable:sourceDockerY="40.0" flowable:targetDockerX="14.0" flowable:targetDockerY="14.0">
        <omgdi:waypoint x="384.94999999998174" y="85.0"></omgdi:waypoint>
        <omgdi:waypoint x="510.0" y="85.0"></omgdi:waypoint>
      </bpmndi:BPMNEdge>
    </bpmndi:BPMNPlane>
  </bpmndi:BPMNDiagram>
</definitions>

参考

flowable 报错 Waiting for changelog lock…
flowable多实例任务注意事项
Flowable—多实例任务:会签

本文来自互联网用户投稿,该文观点仅代表作者本人,不代表本站立场。本站仅提供信息存储空间服务,不拥有所有权,不承担相关法律责任。如若转载,请注明出处:http://www.coloradmin.cn/o/126650.html

如若内容造成侵权/违法违规/事实不符,请联系多彩编程网进行投诉反馈,一经查实,立即删除!

相关文章

Git复习,GitHub\Gitee的使用,IDEA集成Git

今天想把自己的课设上传到GitHub&#xff0c;因为长久不用&#xff0c;Git的命令忘得差不多了&#xff0c;所以今天把Git重新学一遍。 文章目录Git的介绍Git的安装Git的常用命令工作机制常用命令用户签名初始化本地库查看本地库状态添加暂存区提交本地库查看引用日志信息修改文…

Python常用函数笔记汇总2

1.分组汇总groupby 2.计算空值 # py计算空值 data.isnull().sum(axis0) data.notnull().sum(axis0)# py去重计数 data_op[id_num_op].value_counts().size data_op[id_num_op].size3.保留两位小数 # predict_proba保留两位小数 gnb GaussianNB() pre gnb.fit(X_train,y_tr…

pytest-日志配置

如果想要在run测试用例时&#xff0c;打印出由python的logging的日志&#xff0c;可以在pytest中进行相应的配置 pytest可以将日志输出到控制台或者文件中&#xff0c;分别对应不同的配置项 pytest的日志配置文件主要在pytest.ini文件中进行配置&#xff0c;包括配置日志的格式…

ARM64内存虚拟化分析(5)内存布局更新

1 添加MR 创建的MR需要通过函数memory_region_add_subregion()添加到系统中&#xff0c;提交MR&#xff0c;并最终往KVM提交内存的变化。 过程如下&#xff1a; 将mr设置为subregion的container&#xff1b;设置subregion在虚拟机中的物理地址&#xff1b;调用memory_region_t…

FOHEART H1数据手套_Unity3D SDK开发

本教程介绍使用FOHEART H1数据手套在Unity3D中&#xff0c;显示每段骨骼的位置与旋转信息。 需要准备的软硬件&#xff1a; 1、FOHEART H1数据手套 2、MotionVenus客户端 3、Unity3D软件 4、开发包MotionVenus_U3DPlugin_v2.0_H1GloveDev_SDKTest.unitypackage 1、连接数…

HFSS学习笔记

以下所有操作&#xff0c;都是基于2022版本的HFSS。一、HFSS solution模式选择位置&#xff1a;HFSS-Solution type类型表格。二、单位设置位置&#xff1a;Modeler-Units点击后&#xff0c;通常选用单位为&#xff1a;mm三、绘制物体点击红圈1的draw&#xff0c;右侧有些形状可…

MCU-51:单片机实时时钟

目录一、什么是时钟1.1 实时时钟1.2 时序二、DS1302实时时钟2.1 DS1302介绍2.2 引脚定义和应用电路三、代码演示3.1 数字时钟3.2 DS1302可调时钟注意&#xff1a;一定要看一、什么是时钟 1.1 实时时钟 real time clock&#xff0c;真实时间&#xff0c;就是所谓的xx年x月x日x…

我的统计学学习笔记(持续更新)

目录数据&#xff1a;变量和观测统计学描述统计数据的收集数据的可视化数据的规律性特征统计推断参数估计假设检验贝叶斯统计基础知识&#xff1a;概率论数据&#xff1a;变量和观测 变量(column)、观测(row)、测量(assign number to observation)。 统计学 描述统计 数据…

YOLO-V5 系列算法和代码解析(四)—— 网络结构

文章目录辅助工具网络配置文件网络构建网络推理绘制网络结构辅助工具 借助辅助工具可视化网络结构&#xff0c;达到辅助阅读代码&#xff0c;进而辅助手动绘制结构清晰的网络结构&#xff0c;最终理解整个网络架构的目的&#xff0c;为深入学习【yolo-v5】提供有效的保障。 ten…

阿里妈妈内容风控模型预估引擎的探索和建设

作者&#xff1a;徐雄飞、金禄旸、滑庆波、李治 内容作为营销的重要载体&#xff0c;能够促进信息的交流和传播。在营销场景中&#xff0c;广告高曝光的特性放大了风险外漏带来的一系列问题&#xff0c;因此对内容的风控审核就显得至关重要。本文将为大家分享阿里妈妈内容风控模…

DOM节点操作

节点操作 改变元素节点中的内容可以使用两个相关属性&#xff1a;innerHTML innerText 注意字符串不能换行 innerHTML属性能以HTML语法设置节点中的内容 innerText属性只能以纯文本的形式设置节点中的内容 节点创建 document.createElement()方法用于创建一个指定tagname…

android studio编译慢

前言 android studio编译慢一直就是一个问题&#xff0c;很久以前使用eclipse&#xff0c;编译速度很快&#xff0c;在还没开始正式工作的时候就开始使用android studio&#xff0c;那时候还是0.8 很原始&#xff0c;主要那时候还没开始工作&#xff0c;所以编译快慢没感觉&am…

TikTok Shop跨境服务市场上线;俄罗斯速卖通发布延误通知

让我们一起来看看今日都有哪些新鲜事吧&#xff01;01 TikTok Shop跨境服务市场上线 12月28日消息&#xff0c;服务商是助力商家在TikTok Shop成长非常重要的合作伙伴&#xff0c;TikTok Shop希望通过上线服务市场帮助商家快速了解服务商&#xff0c;筛选符合自身需求的服务商…

【JavaSE成神之路】Java面向对象(上)

哈喽&#xff0c;我是兔哥呀&#xff0c;今天就让我们继续这个JavaSE成神之路&#xff01; 这一节啊&#xff0c;咱们要学习的内容是Java的面向对象。 首先我们回顾一下&#xff0c;之前的章节我们学到了哪些东西。 我们学会了写一个类&#xff0c;然后里面弄一个main方法&am…

layer2 实现方式之状态通道

状态通道也算是一种比较热门的扩容方案&#xff0c;状态通道解决方案通过将链下交互和链上清算隔离开&#xff0c;能够在保障一定程度的非中心化和资产安全性的同时&#xff0c;实现速度更快、费用更低的交易。状态通道作为一种链下扩容方案&#xff0c;从一般到特殊分为通用状…

时光飞逝,博客两周年啦

原文链接&#xff1a;时光飞逝&#xff0c;博客两周年啦 博客自 2020年12月10日 运营以来&#xff0c;已经成功走过两年啦&#xff08;差点成为两年半的博主&#xff09;。 在这两年中&#xff0c;曾替无数网友解答了各种关于建站的疑难杂症&#xff0c;此处略过 30000 字。 …

linux系统动态库的连接

前言&#xff1a;在应用程序开发过程中&#xff0c;难免会用到第三方库&#xff0c;有的是开源的第三方库&#xff0c;有的是不开源的&#xff0c;还有的是自己写的库。上篇文章总结了应用程序调用静态库《linux中静态库编译与使用》&#xff0c;本文总结了几种在应用程序中快速…

八、esp8266建立基本网络服务器

1、网络服务器 (1)网络服务器有很多类型&#xff0c;它们功能十分丰富。通常承担网络服务器工作的设备都是运算能力比较强大的电脑。 (2)ESP8266虽然也能实现网络服务器的一些功能&#xff0c;但是毕竟它的运算能力是无法与那些昂贵的服务器电脑相比较&#xff0c;因此ESP826…

STM32的升级--ICP/ISP/IAP

ICP/ISP/IAP 区别 ICP(In-Circuit Programing): 通过J-Link/SWD等下载器烧写程序&#xff0c;上位机需要借助其他硬件的参与才能更新固件&#xff0c;可以更新MCU的所有存储区域&#xff1b; ISP(In-System Programing): 通过MCU出厂时固化的一个bootloader升级程序&#xff0…

第四节 空间参考类的属性说明

空间参考类&#xff1a;SpatialReference 说明 空间参考类是arcpy下面的一级类&#xff0c;用于定义空间参考的各类信息&#xff0c;主要是坐标信息。 空间参考Spatial Reference与坐标系最大的区别&#xff0c;在于空间参考除了定义坐标系以外&#xff0c;还要定义一系列地理…