Activiti学习笔记10 — 动态任务分配
动态任务分配使用的两种方式
一、通过特殊表达式,来获取任务信息 ,在流程 UserTask节点上设置 ${流程变量的Key}
1、流程定义
<?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="userDynamicTask1" name="动态任务处理1" isExecutable="true">
<startEvent id="startevent1" name="Start"></startEvent>
<userTask id="休假" name="休假" activiti:assignee="${user}"></userTask>
<sequenceFlow id="flow1" sourceRef="startevent1" targetRef="休假"></sequenceFlow>
<endEvent id="endevent1" name="End"></endEvent>
<sequenceFlow id="flow2" sourceRef="休假" targetRef="endevent1"></sequenceFlow>
</process>
<bpmndi:BPMNDiagram id="BPMNDiagram_userDynamicTask1">
<bpmndi:BPMNPlane bpmnElement="userDynamicTask1" id="BPMNPlane_userDynamicTask1">
<bpmndi:BPMNShape bpmnElement="startevent1" id="BPMNShape_startevent1">
<omgdc:Bounds height="35.0" width="35.0" x="340.0" y="110.0"></omgdc:Bounds>
</bpmndi:BPMNShape>
<bpmndi:BPMNShape bpmnElement="休假" id="BPMNShape_休假">
<omgdc:Bounds height="55.0" width="105.0" x="305.0" y="180.0"></omgdc:Bounds>
</bpmndi:BPMNShape>
<bpmndi:BPMNShape bpmnElement="endevent1" id="BPMNShape_endevent1">
<omgdc:Bounds height="35.0" width="35.0" x="340.0" y="270.0"></omgdc:Bounds>
</bpmndi:BPMNShape>
<bpmndi:BPMNEdge bpmnElement="flow1" id="BPMNEdge_flow1">
<omgdi:waypoint x="357.0" y="145.0"></omgdi:waypoint>
<omgdi:waypoint x="357.0" y="180.0"></omgdi:waypoint>
</bpmndi:BPMNEdge>
<bpmndi:BPMNEdge bpmnElement="flow2" id="BPMNEdge_flow2">
<omgdi:waypoint x="357.0" y="235.0"></omgdi:waypoint>
<omgdi:waypoint x="357.0" y="270.0"></omgdi:waypoint>
</bpmndi:BPMNEdge>
</bpmndi:BPMNPlane>
</bpmndi:BPMNDiagram>
</definitions>

2、发布流程
/**
* 2、发布一个流程:发布通过特殊表达式,来获取任务信息 ${流程变量的Key}的流程
*/
@Test
public void testDeployProcess() {
RepositoryService repositoryService = processEngine.getRepositoryService();
DeploymentBuilder builder = repositoryService.createDeployment();
// 加载发布资源
builder.name("动态任务处理流程1-测试") // 设置流程显示别名
.addClasspathResource("leave3.bpmn") // 设置流程规则文件
.addClasspathResource("leave3.png"); // 设置流程规则的图片
// 发布流程
builder.deploy();
}
3、启动与测试流程
/**
* 3、启动流程、执行任务,并查看状态
*/
@Test
public void testUserTask() {
// 获取RuntimeService服务对象的实例
RuntimeService runtimeService = processEngine.getRuntimeService();
String processDefinitionKey = "userDynamicTask1";
// 自动执行与Key相对应的流程的最高版本
Map<String, Object> variables = new HashMap<String, Object>();
//variables.put("user", "张三");
variables.put("user", "李四");
ProcessInstance processInstance = runtimeService.startProcessInstanceByKey(processDefinitionKey,variables);
String processInstanceId = processInstance.getId();
logger.info("processInstanceId:" + processInstance.getId());
// 获取TaskService服务对象的实例
TaskService taskService = processEngine.getTaskService();
//String assignee = "张三";
String assignee = "李四";
List<Task> tasks = taskService.createTaskQuery().taskAssignee(assignee).list();
Assert.assertEquals(, tasks.size());
Task task = tasks.get();
logger.info("taskName:" + task.getName());
logger.info("taskAssignee:" + task.getAssignee());
Assert.assertEquals("休假",task.getName());
//完成任务
taskService.complete(task.getId());
//检查结束状态
ProcessInstance pInstance = runtimeService
.createProcessInstanceQuery()
.processInstanceId(processInstanceId)
.singleResult();
Assert.assertNull(pInstance);
logger.info("动态任务处理流程1,使用${流程变量的Key}方式成功执行!");
}
4、运行结果
[INFO][2015-12-02 11:44:05,129][com.mcs.activiti.test.TestUserTaskDynamic]processInstanceId:130001
[INFO][2015-12-02 11:44:05,159][com.mcs.activiti.test.TestUserTaskDynamic]taskName:休假
[INFO][2015-12-02 11:44:05,159][com.mcs.activiti.test.TestUserTaskDynamic]taskAssignee:李四
[INFO][2015-12-02 11:44:05,456][com.mcs.activiti.test.TestUserTaskDynamic]动态任务处理流程1,使用${流程变量的Key}方式成功执行!
二、使用任务分配处理器
1、自定义任务分配处理器步骤
1.1、 创建一个类来充分“任务分配处理器”,需要实现TaskListener
1.2、 在实现方式中添加响应的处理逻辑;
1.3、 在流程中,配置/使用任务处理器。
2、创建自定义任务分配处理器,实现TaskListener
package mcs.listener; import org.activiti.engine.delegate.DelegateTask;
import org.activiti.engine.delegate.TaskListener; public class ManagerTaskListenerHandler implements TaskListener { private static final long serialVersionUID = 1L; @Override
public void notify(DelegateTask delegateTask) {
String assignee = "王五";
delegateTask.setAssignee(assignee); //delegateTask.addCandidateUser("王小二");
} }
3、流程定义
<?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="userDynamicTask2" name="动态任务处理2" isExecutable="true">
<startEvent id="startevent1" name="Start"></startEvent>
<endEvent id="endevent1" name="End"></endEvent>
<userTask id="休假" name="休假">
<extensionElements>
<activiti:taskListener event="create" class="mcs.listener.ManagerTaskListenerHandler"></activiti:taskListener>
</extensionElements>
</userTask>
<sequenceFlow id="flow1" sourceRef="startevent1" targetRef="休假"></sequenceFlow>
<sequenceFlow id="flow2" sourceRef="休假" targetRef="endevent1"></sequenceFlow>
</process>
<bpmndi:BPMNDiagram id="BPMNDiagram_userDynamicTask2">
<bpmndi:BPMNPlane bpmnElement="userDynamicTask2" id="BPMNPlane_userDynamicTask2">
<bpmndi:BPMNShape bpmnElement="startevent1" id="BPMNShape_startevent1">
<omgdc:Bounds height="35.0" width="35.0" x="340.0" y="110.0"></omgdc:Bounds>
</bpmndi:BPMNShape>
<bpmndi:BPMNShape bpmnElement="endevent1" id="BPMNShape_endevent1">
<omgdc:Bounds height="35.0" width="35.0" x="340.0" y="270.0"></omgdc:Bounds>
</bpmndi:BPMNShape>
<bpmndi:BPMNShape bpmnElement="休假" id="BPMNShape_休假">
<omgdc:Bounds height="55.0" width="105.0" x="305.0" y="180.0"></omgdc:Bounds>
</bpmndi:BPMNShape>
<bpmndi:BPMNEdge bpmnElement="flow1" id="BPMNEdge_flow1">
<omgdi:waypoint x="357.0" y="145.0"></omgdi:waypoint>
<omgdi:waypoint x="357.0" y="180.0"></omgdi:waypoint>
</bpmndi:BPMNEdge>
<bpmndi:BPMNEdge bpmnElement="flow2" id="BPMNEdge_flow2">
<omgdi:waypoint x="357.0" y="235.0"></omgdi:waypoint>
<omgdi:waypoint x="357.0" y="270.0"></omgdi:waypoint>
</bpmndi:BPMNEdge>
</bpmndi:BPMNPlane>
</bpmndi:BPMNDiagram>
</definitions>


4、发布流程
/**
* 4、发布一个流程:发布通过自定义任务分配处理器的流程
* 自定义任务分配处理器步骤:
* 1、创建一个类来充分“任务分配处理器”,需要实现TaskListener
* 2、在实现方式中添加响应的处理逻辑;
* 3、在流程中,配置/使用任务处理器。
*/
@Test
public void testDeployProcess2() {
RepositoryService repositoryService = processEngine.getRepositoryService();
DeploymentBuilder builder = repositoryService.createDeployment();
// 加载发布资源
builder.name("动态任务处理流程2-测试") // 设置流程显示别名
.addClasspathResource("leave4.bpmn") // 设置流程规则文件
.addClasspathResource("leave4.png"); // 设置流程规则的图片
// 发布流程
builder.deploy();
}
5、启动与测试流程
/**
* 5、启动流程、执行任务,并查看状态
*/
@Test
public void testUserTask2() {
// 获取RuntimeService服务对象的实例
RuntimeService runtimeService = processEngine.getRuntimeService();
String processDefinitionKey = "userDynamicTask2";
// 自动执行与Key相对应的流程的最高版本
ProcessInstance processInstance = runtimeService.startProcessInstanceByKey(processDefinitionKey);
String processInstanceId = processInstance.getId();
logger.info("processInstanceId:" + processInstance.getId()); // 获取TaskService服务对象的实例
TaskService taskService = processEngine.getTaskService();
String assignee = "王五";
List<Task> tasks = taskService.createTaskQuery().taskAssignee(assignee).list();
Assert.assertEquals(, tasks.size());
Task task = tasks.get();
logger.info("taskName:" + task.getName());
logger.info("taskAssignee:" + task.getAssignee());
Assert.assertEquals("休假",task.getName()); //完成任务
taskService.complete(task.getId()); //检查结束状态
ProcessInstance pInstance = runtimeService
.createProcessInstanceQuery()
.processInstanceId(processInstanceId)
.singleResult();
Assert.assertNull(pInstance);
logger.info("动态任务处理流程2,使用自定义任务分配处理器方式成功执行!"); }
6、运行结果
[INFO][2015-12-02 11:46:51,818][com.mcs.activiti.test.TestUserTaskDynamic]processInstanceId:132501
[INFO][2015-12-02 11:46:51,879][com.mcs.activiti.test.TestUserTaskDynamic]taskName:休假
[INFO][2015-12-02 11:46:51,879][com.mcs.activiti.test.TestUserTaskDynamic]taskAssignee:王五
[INFO][2015-12-02 11:46:52,192][com.mcs.activiti.test.TestUserTaskDynamic]动态任务处理流程2,使用自定义任务分配处理器方式成功执行!
Activiti学习笔记10 — 动态任务分配的更多相关文章
- Mybatis学习笔记10 - 动态sql之if判断
示例代码: 接口定义: package com.mybatis.dao; import com.mybatis.bean.Employee; import java.util.List; public ...
- Activiti学习笔记目录
1.Activiti学习笔记1 — 下载与开发环境的配置: 2.Activiti学习笔记2 — HelloWorld: 3.Activiti学习笔记3 — 流程定义: 4.Activiti学习笔记4 ...
- thinkphp学习笔记10—看不懂的路由规则
原文:thinkphp学习笔记10-看不懂的路由规则 路由这部分貌似在实际工作中没有怎么设计过,只是在用默认的设置,在手册里面看到部分,艰涩难懂. 1.路由定义 要使用路由功能需要支持PATH_INF ...
- 《C++ Primer Plus》学习笔记10
<C++ Primer Plus>学习笔记10 <<<<<<<<<<<<<<<<<&l ...
- Spring 源码学习笔记10——Spring AOP
Spring 源码学习笔记10--Spring AOP 参考书籍<Spring技术内幕>Spring AOP的实现章节 书有点老,但是里面一些概念还是总结比较到位 源码基于Spring-a ...
- Activiti 学习笔记记录(2016-8-31)
上一篇:Activiti 学习笔记记录(二) 导读:上一篇学习了bpmn 画图的常用图形标记.那如何用它们组成一个可用文件呢? 我们知道 bpmn 其实是一个xml 文件
- Activiti 学习笔记记录(二)
上一篇:Activiti 学习笔记记录 导读:对于工作流引擎的使用,我们都知道,需要一个业务事件,比如请假,它会去走一个流程(提交申请->领导审批---(批,不批)---->结束),Act ...
- Web Service学习笔记:动态调用WebService
原文:Web Service学习笔记:动态调用WebService 多数时候我们通过 "添加 Web 引用..." 创建客户端代理类的方式调用WebService,但在某些情况下我 ...
- SQL反模式学习笔记10 取整错误
目标:使用小数取代整数 反模式:使用Float类型 根据IEEE754标识,float类型使用二进制格式编码实数数据. 缺点:(1)舍入的必要性: 并不是所有的十进制中描述的信息都能使用二进制存储,处 ...
随机推荐
- adis16405 配置
- kafka单机版的安装、集群部署 及使用
1.安装kafka(单机版) 1.1上传 kafka_2.11-2.0.0.tgz 到 /root/Downloads 1.2解压 tar 包 tar -zxvf kafka_2.11-2.0.0.t ...
- QT MSVC2017 ratio chrono
如果引用了stdint.h可能会引发一些列错误,各种未申明和语法错误. 参加以下帖子解决问题 https://github.com/ftylitak/qzxing/issues/54 When com ...
- 微信小程序开发显示城市天气
本案例实现动态显示城市天气的功能,案例效果如下: 首先分析制作的思路: 1.在app.json文件的pages数组里加上main文件夹和template(模板)文件夹的路径. 2.在main.js文件 ...
- mongodb入门篇
MongoDB 入门篇 分类: NoSQL, 故障解决 undefined 1.1 数据库管理系统 在了解MongoDB之前需要先了解先数据库管理系统 1.1.1 什么是数据? 数据(英语:data) ...
- codeforces 24d Broken robot 期望+高斯消元
题目传送门 题意:在n*m的网格上,有一个机器人从(x,y)出发,每次等概率的向右.向左.向下走一步或者留在原地,在最左边时不能向右走,最右边时不能像左走.问走到最后一行的期望. 思路:显然倒着算期望 ...
- java中的.java和.class的区别
java文件就是这样一个未经编译的源程序,一般是给程序员看的. class文件就是被编译器编译过的java文件,通常是给计算机看的.
- [转]Delphi DLL的创建、静态 以及动态调用
第一章 DLL简单介绍 由于在目前的学习工作中,需要用到DLL文件,就学习了下,在这里作个总结. 首先装简单介绍下DLL: 1,减小可执行文件的大小 DLL技术的产生有很大一部分原因是为了减小可执行 ...
- php数组长度怎么获取
我们可以将元素添加到数组或从数组中删除元素,那么如果我们想要知道数组中存在的元素的总长度或总数,我们就可以使用count() 或sizeof函数. 下面我们就通过简单的示例,给大家介绍php获取数组长 ...
- delphi 压缩
DELPHI 通过ZLib来压缩文件夹 unit Unit1; interface uses ZLib, Windows, Messages, SysUtils, Variants, Classes, ...