activiti会签 多实例例子
在实际的业务中,可能存在存在这么一种情况,当流程运行到某一个环节时,可能需要同时多个人的参与,才可以完成此环节。此时就可以用到activiti的多实例来解决此问题。
一、将一个节点设置成多实例的方法:
要把一个节点设置为多实例,节点xml元素必须设置一个multiInstanceLoopCharacteristics
子元素。
当isSequential=true时,表示的顺序执行,即虽然该节点有多条任务,但只有上一条执行完,才可以执行下一条。
当isSequential=false时,表示的并行执行,即该节点下的多条任务可以同时执行。
二、设置会签环节的参与者:
<strong>activiti:collection:用于执行该会签环节的参与参与的人,此处是使用的一个名叫pers的流程变量
</strong>
<strong>activiti:elementVariable:此处表示的是每一个分支都有一个名叫per的流程变量,和上方的activiti:assignee结合使用就可以执行该分支应该由谁来处理。</strong>
三.指定会签环节的结束条件:
当画红线的部分返回一个true的时候,该会签环节结束。进入下一个流程执行的环节.
completionCondition中写的是juel表达式。其中的mulitiInstance如果是和spring整合了,就是spring管理的bean的id,否则就是流程变量的key.
四、会签环节中涉及的几个默认的流程变量
1.nrOfInstances 该会签环节中总共有多少个实例
2.nrOfActiveInstances 当前活动的实例的数量,即还没有 完成的实例数量。
3.nrOfCompletedInstances 已经完成的实例的数量
五、代码如下:
1.分配会签环节的人:
/**
* 分配下一环节会签的人
*
* @author huan
*
*/
public class AssgineeMultiInstancePer implements JavaDelegate {
@Override
public void execute(DelegateExecution execution) throws Exception {
System.out.println("设置会签环节的人员.");
execution.setVariable("pers", Arrays.asList("张三", "李四", "王五", "赵六"));
}
}
2.多实例判断完成的条件:(注意:有于我没有和spring整合,所以此类要实现Serializable接口)
/**
* 多实例完成的条件判断
* @author huan
*/
public class MulitiInstanceCompleteTask implements Serializable {
private static final long serialVersionUID = 1L;
public boolean completeTask(DelegateExecution execution) {
System.out.println("总的会签任务数量:" + execution.getVariable("nrOfInstances") + "当前获取的会签任务数量:" + execution.getVariable("nrOfActiveInstances") + " - " + "已经完成的会签任务数量:" + execution.getVariable("nrOfCompletedInstances"));
System.out.println("I am invoked.");
return false;
}
}
3.会签环节中的一个监听器:
/**
* 测试会签过程中监听器的执行情况
* @author huan
*/
public class TestLinstener implements TaskListener {
private static final long serialVersionUID = -5754522101489239675L;
@Override
public void notify(DelegateTask delegateTask) {
System.out.print(delegateTask.getId() + " - " + delegateTask.getProcessInstanceId() + " - " + delegateTask.getEventName() + " - " + delegateTask.getTaskDefinitionKey());
}
}
4.测试代码:
/**
* 测试会签
* @author huan
*/
public class TestMultiInstance {
@Test
public void testProcess() {
ProcessEngine processEngine = ProcessEngines.getDefaultProcessEngine();
RepositoryService repositoryService = processEngine.getRepositoryService();
RuntimeService runtimeService = processEngine.getRuntimeService();
TaskService taskService = processEngine.getTaskService();
Deployment deploy = repositoryService.createDeployment()//
.name("会签流程测试")//
.addInputStream("multiInstances.bpmn", this.getClass().getResourceAsStream("multiInstances.bpmn"))//
.addInputStream("multiInstances.png", this.getClass().getResourceAsStream("multiInstances.png"))//
.deploy();
System.out.println(deploy.getId() + " " + deploy.getName());
Map<String, Object> variables = new HashMap<String, Object>();
variables.put("mulitiInstance", new MulitiInstanceCompleteTask());
ProcessInstance pi = runtimeService.startProcessInstanceByKey("multiInstances",variables);
System.out.println(pi.getId() + " " + pi.getActivityId());
Task task1 = taskService.createTaskQuery().processInstanceId(pi.getId()).taskAssignee("张三").singleResult();
System.out.println(task1.getId() + " - " + task1.getAssignee() + " - " + task1.getProcessInstanceId() + " - " + task1.getProcessDefinitionId());
Task task2 = taskService.createTaskQuery().processInstanceId(pi.getId()).taskAssignee("李四").singleResult();
System.out.println(task2.getId() + " - " + task2.getAssignee() + " - " + task2.getProcessInstanceId() + " - " + task2.getProcessDefinitionId());
Task task3 = taskService.createTaskQuery().processInstanceId(pi.getId()).taskAssignee("王五").singleResult();
System.out.println(task3.getId() + " - " + task3.getAssignee() + " - " + task3.getProcessInstanceId() + " - " + task3.getProcessDefinitionId());
Task task4 = taskService.createTaskQuery().processInstanceId(pi.getId()).taskAssignee("赵六").singleResult();
if (task4 != null) {
System.out.println(task4.getId() + " - " + task4.getAssignee() + " - " + task4.getProcessInstanceId() + " - " + task4.getProcessDefinitionId());
}
Task task5 = taskService.createTaskQuery().processInstanceId(pi.getId()).taskAssignee("钱七").singleResult();
System.out.println(task5);
taskService.complete(task1.getId());
taskService.complete(task2.getId());
taskService.complete(task3.getId());
Task task6 = taskService.createTaskQuery().processInstanceId(pi.getId()).taskAssignee("钱七").singleResult();
System.out.println(task6);
taskService.complete(task4.getId());
Task task7 = taskService.createTaskQuery().processInstanceId(pi.getId()).taskAssignee("钱七").singleResult();
System.out.println(task7);
taskService.complete(task7.getId());
ProcessInstance processInstance = runtimeService.createProcessInstanceQuery().processInstanceId(pi.getId()).singleResult();
if (null == processInstance) {
System.out.println("流程完成.");
}
}
}
5.流程文件:
<?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:activiti="http://activiti.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.activiti.org/test">
<process id="multiInstances" name="流程会签测试" isExecutable="true">
<startEvent id="startevent1" name="Start"></startEvent>
<sequenceFlow id="flow1" sourceRef="startevent1" targetRef="A001"></sequenceFlow>
<serviceTask id="A001" name="设置下一环节的人" activiti:class="com.huan.activiti.liuyang.会签.AssgineeMultiInstancePer"></serviceTask>
<userTask id="B001" name="会签环节" activiti:assignee="${per}">
<extensionElements>
<activiti:taskListener event="complete" class="com.huan.activiti.liuyang.会签.TestLinstener"></activiti:taskListener>
</extensionElements>
<multiInstanceLoopCharacteristics isSequential="false" activiti:collection="pers" activiti:elementVariable="per">
<completionCondition>${mulitiInstance.completeTask(execution)}</completionCondition>
</multiInstanceLoopCharacteristics>
</userTask>
<sequenceFlow id="flow2" sourceRef="A001" targetRef="B001"></sequenceFlow>
<userTask id="C001" name="会签后的环节" activiti:assignee="钱七"></userTask>
<sequenceFlow id="flow3" sourceRef="B001" targetRef="C001"></sequenceFlow>
<endEvent id="endevent1" name="End"></endEvent>
<sequenceFlow id="flow4" sourceRef="C001" targetRef="endevent1"></sequenceFlow>
</process>
<bpmndi:BPMNDiagram id="BPMNDiagram_multiInstances">
<bpmndi:BPMNPlane bpmnElement="multiInstances" id="BPMNPlane_multiInstances">
<bpmndi:BPMNShape bpmnElement="startevent1" id="BPMNShape_startevent1">
<omgdc:Bounds height="35.0" width="35.0" x="100.0" y="240.0"></omgdc:Bounds>
</bpmndi:BPMNShape>
<bpmndi:BPMNShape bpmnElement="A001" id="BPMNShape_A001">
<omgdc:Bounds height="71.0" width="117.0" x="190.0" y="222.0"></omgdc:Bounds>
</bpmndi:BPMNShape>
<bpmndi:BPMNShape bpmnElement="B001" id="BPMNShape_B001">
<omgdc:Bounds height="55.0" width="105.0" x="380.0" y="230.0"></omgdc:Bounds>
</bpmndi:BPMNShape>
<bpmndi:BPMNShape bpmnElement="C001" id="BPMNShape_C001">
<omgdc:Bounds height="55.0" width="105.0" x="561.0" y="230.0"></omgdc:Bounds>
</bpmndi:BPMNShape>
<bpmndi:BPMNShape bpmnElement="endevent1" id="BPMNShape_endevent1">
<omgdc:Bounds height="35.0" width="35.0" x="740.0" y="240.0"></omgdc:Bounds>
</bpmndi:BPMNShape>
<bpmndi:BPMNEdge bpmnElement="flow1" id="BPMNEdge_flow1">
<omgdi:waypoint x="135.0" y="257.0"></omgdi:waypoint>
<omgdi:waypoint x="190.0" y="257.0"></omgdi:waypoint>
</bpmndi:BPMNEdge>
<bpmndi:BPMNEdge bpmnElement="flow2" id="BPMNEdge_flow2">
<omgdi:waypoint x="307.0" y="257.0"></omgdi:waypoint>
<omgdi:waypoint x="380.0" y="257.0"></omgdi:waypoint>
</bpmndi:BPMNEdge>
<bpmndi:BPMNEdge bpmnElement="flow3" id="BPMNEdge_flow3">
<omgdi:waypoint x="485.0" y="257.0"></omgdi:waypoint>
<omgdi:waypoint x="561.0" y="257.0"></omgdi:waypoint>
</bpmndi:BPMNEdge>
<bpmndi:BPMNEdge bpmnElement="flow4" id="BPMNEdge_flow4">
<omgdi:waypoint x="666.0" y="257.0"></omgdi:waypoint>
<omgdi:waypoint x="740.0" y="257.0"></omgdi:waypoint>
</bpmndi:BPMNEdge>
</bpmndi:BPMNPlane>
</bpmndi:BPMNDiagram>
</definitions>
7.流程图:
如若那个地方写的不对,欢迎指出。
activiti会签 多实例例子的更多相关文章
- activiti官网实例项目activiti-explorer之扩展流程节点属性2
情景需求:需要查找activiti-explorer项目中获取流程id的方法,然后根据流程id获取相应字段在节点属性中添加内容. 大致流程:拿取整个流程id获取对应表单属性,在页面节点属性中展示对应表 ...
- Activiti的流程实例及挂起激活(七)
1.1什么是流程实例 参与者(可以是用户也可以是程序)按照流程定义内容发起一个流程,这就是一个流程实例.是动态的.流程定义和流程实例的图解: 1.2启动流程实例 流程定义部署在 activiti 后, ...
- Activiti的流程实例【ProcessInstance】与执行实例【Execution】
最近,我在做流程引擎Activiti相关的东西,刚开始时的一个知识点困扰了我许久,那就是Activiti的ProcessInstance与Execution的区别,这是一个Activiti的难点,能够 ...
- JSAAS的Activiti会签开发扩展处理
1.什么是会签? 在流程业务管理中,任务是通常都是由一个人去处理的,而多个人同时处理一个任务,这种任务我们称之为会签任务.这种业务需求很常见,如一个请款单,领导审批环节中,就需要多个部门领导签字.在流 ...
- activiti并发多实例子流程任务处理
一直在搞工作流(activiti),总结一下关于工作流(activiti)中同时并发处理多个子流程的操作方法. 先说下我要实现的业务: 1.办公室发通知(在系统申报页面上,勾选科室,被选中的科室执行第 ...
- activiti整合开发实例总结
参考手册:http://www.mossle.com/docs/activiti/ 一.applicationContext.xml中引入activiti相关配置的xml文件 <!-- begi ...
- activiti官网实例项目activiti-explorer之获取流程节点
如上图在保存步骤中添加获取节点信息方法nodes(); 方法如下: //获取所有节点 JsonNode modelNode = new ObjectMapper().readTree(repos ...
- activiti官网实例项目activiti-explorer实操详情
参考链接:https://www.xuchuruo.cn/Activiti-modeler%E6%95%B4%E5%90%88%E5%88%B0Spring.html 按照链接文章提示操作完成之后,启 ...
- [UE4] C++实现Delegate Event实例(例子、example、sample)
转自:http://aigo.iteye.com/blog/2301010 虽然官方doc上说Event的Binding方式跟Multi-Cast用法完全一样,Multi-Cast论坛上也有很多例子, ...
随机推荐
- PHP设计模式之享元模式
享元模式,"享元"这两个字在中文里其实并没有什么特殊的意思,所以我们要把它拆分来看."享"就是共享,"元"就是元素,这样一来似乎就很容易理解 ...
- symfony2显示调试工具栏
1. app/config/config_dev.yml framework: templating: engines: ['twig'] router: resource: "%kerne ...
- xml字符串转成数组(php)
1 $str = '<xml> 2 <ToUserName> <![CDATA[gh_fc0a06a20993]]> </ToUserName> 3 & ...
- [原创]OpenEuler20.03安装配置PostgreSQL13.4详细图文版
OpenEuler安装配置PostgreSQL 编写时间:2021年9月18日 作者:liupp 邮箱:liupp@88.com 序号 更新内容 更新日期 更新人 1 完成第一至三章内容编辑: 202 ...
- Java基础系列(13)- 包机制
包机制 为了更好的组织类,Java提供了包机制,用于区别类名的命名空间 包语句的语法格式为: package pkg1[. pkg2[. pkg3...]]; 一般利用公司域名倒置作为报名 为了能够使 ...
- Docker系列(5)- 常用命令(1) | 帮助命令
帮助命令 [root@localhost ~]# docker version #显示docker的版本信息 [root@localhost ~]# docker info #显示docker的系统信 ...
- Linux系列(26) - 强制杀死进程
查进程 ps -ef ps -aux #上述两个均可 例子:ps -ef | grep "vim canshu2" 强杀进程 kill -s 9 进程id #命令格式 例子:ki ...
- Shell系列(7)- 通配符
通配符 通配符 作用 ? 匹配一个任意字符 * 匹配0个或任意多个任意字符,也就是可以匹配任何内容 [] 匹配中括号中任意一个字符.例如:[abc]代表一定匹配一个字符,或者是a,或者是b,或者是c. ...
- django2获取url所有路径
根据原文链接:https://segmentfault.com/a/1190000017378464,整理 第一步:先导入项目根的urls.py路径 from ceshiproject import ...
- 鸿蒙内核源码分析(调度队列篇) | 内核有多少个调度队列 | 百篇博客分析OpenHarmony源码 | v6.05
百篇博客系列篇.本篇为: v06.xx 鸿蒙内核源码分析(调度队列篇) | 内核有多少个调度队列 | 51.c.h .o 任务管理相关篇为: v03.xx 鸿蒙内核源码分析(时钟任务篇) | 触发调度 ...