Activiti进阶
Activiti进阶
1.流程实例
一个流程实例包含所有的运行节点,可以利用这个对象获取当前流程实例的进度信息。
Activiti流程和业务关系:
启动流程实例 并添加BusinessKey(业务标识)
流程定义部署在acti后,就可以在系统中通过activiti去管理该流程的执行,执行流程表示流程的一次执行。
比如部署系统出差流程后,入股哦某个用户要申请出差这时就需要执行这个流程,如果另外一个用户也要申请出差则也需要执行该流程,互不影响。
启动流程实例时,指定的businesskey,就会在act_ru_exection#流程实例的执行表中存储businesskey
businesskey:业务标识,主键,业务标识和流程实例一一对应。业务标识来源于业务系统。存储业务标识就是根据业务标识来关联查询业务系统的数据。
比如:出差流程启动一实例,就将出差单id作为业务表示存储到acti表中,将查询acti的流程实例信息就可以获取出差单的id从而关联查询业务系统数据库得到出差单信息。
/**
* 添加业务Key到Activiti表
*/
@Test
public void addBusinessKey() {
//获取流程引擎
ProcessEngine processEngine = ProcessEngines.getDefaultProcessEngine();
//获取RuntimeService
RuntimeService runtimeService = processEngine.getRuntimeService();
//启动流程的过程中,添加BussinessKey
//参数:流程定义的key;businessKey,存出差单的id
ProcessInstance instance = runtimeService.startProcessInstanceByKey("myEvection", "1001");
//输出
System.out.println("businessKey=" + instance.getBusinessKey());
}
挂起,激活流程实例
全部流程实例挂起,将不允许启动新的流程实例,同时该流程定义下所有的流程实例将全部暂停执行。
2.个人任务
分配任务责任人
2.1固定分配
在业务流程建模时指定固定的任务负责人
2.1表达式分配
由于固定分配方式,任务只管一步一步执行,执行到每一个任务将按照bpmn的配置去分配任务负责人。
UEL表达式:activiti使用UEL表达式
编写代码配置负责人
/**
* 启动流程实例
*/
@Test
public void testStartProcess() {
//1.创建ProcessEngine
ProcessEngine processEngine = ProcessEngines.getDefaultProcessEngine();
//2.获取Runtimeservice
RuntimeService runtimeService = processEngine.getRuntimeService();
//设定assignee的值,用来替换uel表达式
HashMap<String, Object> assigneeMap = new HashMap<String, Object>();
assigneeMap.put("assignee0", "创建人");
assigneeMap.put("assignee1", "经理");
assigneeMap.put("assignee2", "总经理");
assigneeMap.put("assignee3", "财务");
//3.根据流程定义的id启动流程‘
ProcessInstance instance = runtimeService.startProcessInstanceByKey("myEvection1", assigneeMap);
//4.输出内容
System.out.println("流程定义id:" + instance.getProcessDefinitionId());
System.out.println("流程实例id:" + instance.getId());
System.out.println("当前活动id:" + instance.getActivityId());
}
2.3监听器分配
可以使用监听器来完成很多Activiti流程的业务。流程设计时就不需要指定assignee。任务监听器是发生对应的任务相关事件时执行自定义java逻辑或表达式。
Event的选项包含:
Create:任务创建后触发
Assignment:任务分配后触发
Delete:任务完成后触发
All:所有事件发生都触发
创建demo:08-使用监听器设置负责人_哔哩哔哩_bilibili
查询任务
2.4查询任务负责人的待办任务
见入门查询方法。
2.5关联businessKey
需求:在activiti实际应用时,查询代办任务可能要显示出业务系统的相关信息。
比如:查询待审批出差任务列表需要将出差单的日期,出差天数等信息显示。但是这些信息在业务系统中存在,而没有在activiti数据库中,所以无法通过activiti的api查询到出差信息
实现:在查询待办任务时,通过BusinessKey(业务标识)关联查询业务系统的出差单表,查询。
/**
* 获取任务负责人待办任务businessKey
*/
@Test
public void findProcessInstance() {
ProcessEngine processEngine = ProcessEngines.getDefaultProcessEngine();
TaskService taskService = processEngine.getTaskService();
RuntimeService runtimeService = processEngine.getRuntimeService();
Task task = taskService.createTaskQuery()
.processDefinitionKey("testListener")
.taskAssignee("创建人")
.singleResult();
String processDefinitionId = task.getProcessDefinitionId();
ProcessInstance instance = runtimeService.createProcessInstanceQuery()
.processDefinitionId(processDefinitionId)
.singleResult();
String businessKey = instance.getBusinessKey();
System.out.println("businessKey=" + businessKey);
}
办理任务
在实际集中完成前需要校验负责人权限
/**
* 办理个人任务
*/
@Test
public void completTaskByCharge(){
String taskId = "1005";
String assingee = "经理";
ProcessEngine processEngine = ProcessEngines.getDefaultProcessEngine();
TaskService taskService = processEngine.getTaskService();
//完成任务前,需校验该负责人可以完成当期任务
//校验方法:根据任务id和负责人查询当前任务,如果查到该用户有权限,就完成
Task task = taskService.createTaskQuery()
.taskId(taskId)
.taskAssignee(assingee)
.singleResult();
if(task!=null){
taskService.complete(taskId);
System.out.println("任务完成");
}
}
3.流程变量
3.1流程变量
流程运转需要流程变量,业务系统和acti结合时也需要流程变量,流程变量就是acti在管理工作流时根据管理需要而设置的变量。
比如:出差申请流程流转时如果出差天数大于3天则由总经理审核,否则由人事直接审核,出差天数就可以设置为流程变量,在流程流转中使用。
注意:虽然流程变量中可以存储业务数据可以通过acti的api查询流程变量从而实现查询业务数据,但是不建议这样,因为业务数据查询由业务系统负责,acti设置流程变量是为了流程执行需要而创建。
3.2流程变量类型
如果将pojo存储到流程变量中,必须实现序列化接口serializable,为了防止由于新增字段无法反序列化,需要生成SerialVersionUID。
3.3流程变量作用域
可以是一个流程实例或一个任务。或一个执行实例。
Globa变量
流程变量的默认作用域是流程实例。当一个流程变量的作用域为流程实例时,成为global变量。
注意:Global变量:userId(变量名),创建人(变量值)
3.4流程变量使用方法
1.在属性上使用UEL表达式:可在assignee处设置,比如${assignee}
2.在连线上使用UEL表达式:可在连线上设置,决定流程走向,比如${price<100}
3.5使用Global变量控制流程
需求:员工创建出差单,由部门经理审核通过后出差三天以下由财务直接审批,3天上由总经理审批,再由财务审批。
流程定义:
设置global流程变量:
1.创建pojo对象。
2.启动流程时设置变量
//启动流程设置流程变量
@Test
public void testStartProcess() {
ProcessEngine processEngine = ProcessEngines.getDefaultProcessEngine();
RuntimeService runtimeService = processEngine.getRuntimeService();
String key = "myEvection2";
//设置流程变量
Evection evection = new Evection();
HashMap<String, Object> variables = new HashMap<String, Object>();
evection.setNum(2d); //设置出差日期
variables.put("evection", evection); //把流程变量的pojo放入map
variables.put("assignee0", "创建人");
variables.put("assignee1", "部门经理");
variables.put("assignee2", "总经理");
variables.put("assignee3", "财务");
ProcessInstance instance = runtimeService.startProcessInstanceByKey(key, variables);
System.out.println(instance.getId());
}
3.任务办理时设置变量
注意:通过当前任务设置,需指定当前任务id,如果不存在则抛异常。任务办理时可map设置多个变量。
//测试任务办理时添加流程变量
@Test
public void testCompletTask2() {
String key = "myEvection2";
String assignee = "创建人";
ProcessEngine processEngine = ProcessEngines.getDefaultProcessEngine();
//设置流程变量
Evection evection = new Evection();
evection.setNum(2d);
HashMap<String, Object> map = new HashMap<String, Object>();
map.put("evection", evection);
TaskService taskService = processEngine.getTaskService();
Task task = taskService.createTaskQuery()
.processDefinitionKey(key)
.taskAssignee(assignee)
.singleResult();
if (task != null) {
taskService.complete(task.getId(),map); //根据任务id完成任务,在完成任务时设置流程变量
}
}
4.通过当前流程实例设置:通过流程实例id设置全局变量,该流程实例必须未执行完成。
注意:executionId必须当前未结束流程实例的执行id,通常此id设置流程实例的id也可通过runtimeService.getVariable()获取变量。
//通过当前流程实例设置
@Test
public void setGlobalVariableByExectionId(){
String exectionId = "";
ProcessEngine processEngine = ProcessEngines.getDefaultProcessEngine();
RuntimeService runtimeService = processEngine.getRuntimeService();
Evection evection = new Evection();
evection.setNum(3d);
runtimeService.setVariable(exectionId,"evection",evection); //通过流程实例id设置流程变量
// runtimeService.setVariable(exectionId, variables); //一次设置多个变量
}
5.通过当前任务设置
注意:任务id必须是当前待办id,act_ru_task存在
//通过当前任务设置
@Test
public void setGlobalVariableByTaskId(){
String taskId = "4102";
ProcessEngine processEngine = ProcessEngines.getDefaultProcessEngine();
TaskService taskService = processEngine.getTaskService();
Evection evection = new Evection();
taskService.setVariable(taskId,"evection",evection);
}
3.6设置local流程控制
略
4.组任务
4.1需求:在流程定义在任务节点的assignee固定设置任务负责人,在流程定义时将参与者固定设置在.bpmn文件中,如果临时任务负责人变更则需要修改流程定义,系统可扩展性差。
针对这种情况可以设置多个候选人。
4.2设置任务候选人
4.3组任务办理流程
a.查询组任务
指定候选人,查询该候选人当前待办。候选人不能立即办理。
b.拾取组任务
该组任务的所有候选人都能拾取。将候选人的组任务,变成个人任务。原来候选人就变成了该任务的负责人。
如果拾取后不想办理该任务?需将已经拾个人任务归还组里面,将个人任务变成组任务。
c.查询个人任务
d.办理个人任务
查询组任务
//查询组任务
@Test
public void findGroupTaskList(){
String key = "testCandidate";
String candidateUser = "候选人";
ProcessEngine processEngine = ProcessEngines.getDefaultProcessEngine();
TaskService taskService = processEngine.getTaskService();
List<Task> taskList = taskService.createTaskQuery()
.processDefinitionKey(key)
.taskCandidateUser(candidateUser) //根据候选人查询任务
.list();
for (Task task : taskList) {
System.out.println("流程实例id" + task.getProcessDefinitionId());
System.out.println("任务id" + task.getId());
System.out.println("任务负责人" + task.getAssignee());
}
}
拾取任务
//拾取任务
@Test
public void claimTask() {
ProcessEngine defaultProcessEngine = ProcessEngines.getDefaultProcessEngine();
TaskService taskService = defaultProcessEngine.getTaskService();
String taskId = "6001";
String userId = "候选人";
//拾取任务,都可以拾取,需校验资格
Task task = taskService.createTaskQuery()
.taskId(taskId)
.taskCandidateUser(userId)
.singleResult();
if (task != null) {
taskService.claim(taskId, userId);
System.out.println("拾取成功");
}
}
归还任务
//归还任务
@Test
public void assigneeToGroupTask() {
ProcessEngine defaultProcessEngine = ProcessEngines.getDefaultProcessEngine();
TaskService taskService = defaultProcessEngine.getTaskService();
String taskId = "6001";
String assignee = "负责人";
//根据key和负责人查询
Task task = taskService.createTaskQuery()
.taskId(taskId)
.taskAssignee(assignee)
.singleResult();
if (task != null) {
taskService.setAssignee(taskId, null);
System.out.println("拾取成功");
}
}
任务交接
//任务交接
@Test
public void setAssigneeToCandidateUser() {
ProcessEngine processEngine = ProcessEngines.getDefaultProcessEngine();
TaskService taskService = processEngine.getTaskService();
String taskId = "6001";
String userId = "负责人";
String candidateUser = "其他候选人";
//校验userId是都是taskid的负责人,如果是负责人才可以归还组任务
Task task = taskService
.createTaskQuery()
.taskId(taskId)
.taskAssignee(userId)
.singleResult();
if (task != null) {
taskService.setAssignee(taskId, candidateUser);
}
}
5.网关
5.1排他网关
5.2并行网关
并行网关代码测试:08-并行网关流程定义-测试_哔哩哔哩_bilibili
5.3包含网关
包含网关测试:11-包含网关测试_哔哩哔哩_bilibili
5.4事件网关
更多推荐
所有评论(0)