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)舍入的必要性: 并不是所有的十进制中描述的信息都能使用二进制存储,处 ...
随机推荐
- Socket/TCP粘包、多包和少包, 断包
转发: https://blog.csdn.net/pi9nc/article/details/17165171 为什么TCP 会粘包 前几天,调试mina的TCP通信, 第一个协议包解析正常,第二个 ...
- pcre2 正则库
\S+ 不能匹配到字符串末尾的最后一个字段
- 绿盟-WEB应用漏洞扫描系统
************************************************** WEB应用漏洞扫描系统 一.工具的介绍与使用 ************************** ...
- 结合Poi实现可读取Excel的文件选择对话框
第一步:ApachePoi的jar包导全,不全会出现异常. 第二步:写就完事了:此例为读取特定模板的excel,仅供参考,根据实际需求改写. package 自建包; import java.awt. ...
- 39-Ubuntu-用户管理-04-usermod设置主组和附加组
主组:通常在新建用户时指定,在/etc/passwd的第4列GID显示主组名. 附加组:在/etc/group中最后一列显示该组的用户列表,用于指定用户的附加权限. 1.修改用户的主组 sudo us ...
- 【洛谷】P1349广义斐波那契
题目链接:https://www.luogu.org/problemnew/show/P1349 题意:现在定义fib数列为 an = p * an-1 + q * an-2求第n项%m的答案. 题解 ...
- Ansible随笔8
自定义模块的开发模式 1.决定自定义模块的存放路径 编辑/etc/ansible/ansible.cfg文件,修改library = /usr/share/ansible/. 这样就告诉ansible ...
- (Struts2学习系列四)Struts2指定配置文件
我们的每个action都在struts.xml里配置的话,就会出现很多的xml语句,单单一个struts.xml就会变得很大,所以我们会在struts.xml里使用include引入其他的.xml文件 ...
- Sublime Text3中MarkDown的使用
前言 当我们想要在Sublime文本编辑器中编辑markdown时,需要先安装markdown插件,因为Sublime里默认没有安装该插件,同时在编辑markdown文本时可以实时预览编辑效果. 具体 ...
- Python自学:第四章 复制列表(1)
# -*- coding: GBK -*- my_foods = ['pizza', 'falafel', 'carrot cake'] friend_foods = my_foods[:] prin ...