流程实例系列
RuntimeService 运行服务类
核心功能 启动实例、查询与实例相关的一些信息
是Flowable的流程执行服务类。可以从这个类中获取很多关于流程执行相关的信息。
实现类为RuntimeServiceImpl
提供了一系列根据自身业务场景启动流程实例的API
流程定义、执行实例、流程实例概念
-
流程定义类 可以从这里获得资源文件。类似于java类
-
流程实例 代表流程定义的执行实例,比如张三请了一天假,他就必须发出一个流程实例的申请
-
一个流程实例包括了所有的运行节点。 我们可以用这个对象来了解当前流程实例的进度信息等
-
流程实例就表示一个流程从开始到结束的最大流程分支,即一个流程中流程实例只有一个。
-
流程实例通常也可以叫做执行实例的根节点
执行实例.
-
public interface ProcessInstance extends Execution
-
从源代码中可以看出 ProcessInstance就是Execution
-
启动流程的时候会首先创建流程实例,然后创键执行实例
-
流程运转的过程中永远执行的是自己对应的执行实例
-
当所有的执行实例按照规则执行完毕之后,这实例随之结束
-
flowable用这个对象去描述流程执行的每一个节点
-
流程按照流程定义的规则执行一次的过程,就可以表示执行对象Execution
-
一个流程中,执行对象可以存在多个,但是流程实例只能有一个
-
执行实例的父级或者父级的父级为流程实例
-
执行实例可能会暂停到某一个活动节点,需要我们去通过特定的API去完成,然后执行实例继续往下走
流程实例启动
使用RuntimeService启动流程实例
操作的是act_ru_execution表,如果是用户任务节点,同时也会在act_ru_task添加一条记录
/**
* 部署流程
*/
@Test
public void deploy() {
DeploymentBuilder deploymentBuilder = repositoryService.createDeployment()
.category("leave")
.name("请假流程")
.addClasspathResource("leave.bpmn");
//流程部署
Deployment deploy = deploymentBuilder.deploy();
System.out.println(deploy.getId());
}
/**
* 启动流程实例 根据key
*/
@Test
public void startProcessInstanceByKey() {
String processDefinitionKey = "leave";
ProcessInstance processInstance = runtimeService.startProcessInstanceByKey(processDefinitionKey);
System.out.println(processInstance.getId()+","+processInstance.getActivityId());
}
查询个人任务 TaskService(act_ru_task)
/**
* 查询个人任务
*/
@Test
public void createTaskQuery() {
String assignee = "张三";
String processDefinitionKey = "leave";
List<Task> list = taskService.createTaskQuery()
.taskAssignee(assignee)
.processDefinitionKey(processDefinitionKey).list();
list.forEach(v -> System.out.println(v.getId() + " "
+ v.getName() + " " + v.getTaskDefinitionKey()
+ " " + v.getExecutionId() + " " + v.getProcessInstanceId() + " " + v.getCreateTime()));
}
-
从processEngine中应该得到TaskService
-
使用TaskService获取到任务查询对象TaskQuery
-
为查询对象添加过滤条件,使用taskAssignee指定任务的办理者(即查询指定用户的待办任务),同时可以添加分页排序等过滤条件
-
调用list方法进行查询
-
任务id、名称、办理人、创建时间可以从act_ru_task表中查到
完成个人任务
/** * 完成个人任务 */ @Test public void completeTask() { String taskId = "20006"; taskService.complete(taskId); }
对于执行完的任务,Flowable将从act_ru_task表中删除该任务,下一个任务会被插入进来(这两个操作是在一个事物中)
查询流程状态
/** * 查询流程实例状态 判断流程正在执行还是结束 */ @Test public void createProcessInstanceQuery() { String processInstanceId = "30001"; ProcessInstance processInstance = runtimeService.createProcessInstanceQuery() .processInstanceId(processInstanceId).singleResult(); if (processInstance != null) { System.out.println("当前流程实例正在运行"); } else { System.out.println("当前流程实例正在运行"); } } /** * 查询执行实例状态 判断流程正在执行还是结束 */ @Test public void createExecutionQuery() { List<Execution> list = runtimeService.createExecutionQuery().list(); list.forEach(v-> System.out.println(v.getId()+","+v.getActivityId())); }
历史流程实例查询historyService(act_hi_procinst)
HistoryService 用于查询act_hi 开头的表
/**
* 查询历史流程实例
*/
@Test
public void createHistoricProcessInstanceQuery() {
String processInstanceId = "20001";
HistoricProcessInstance historicProcessInstance = historyService.createHistoricProcessInstanceQuery().processInstanceId(processInstanceId).singleResult();
System.out.println("流程实例id"+historicProcessInstance.getId());
System.out.println("流程定义id"+historicProcessInstance.getProcessDefinitionId());
System.out.println("开始时间"+historicProcessInstance.getStartTime());
System.out.println("结束时间"+historicProcessInstance.getEndTime());
}
历史活动信息查询 (act_hi_actinst)
历史活动表 act_hi_actinst 活动节点的数据都会存储在这个表中
/**
* 查询历史活动节点
* select RES.*
* FROM ACT_HI_ACTINST RES order by RES.ID_ asc;
*/
@Test
public void createHistoricActivityInstanceQuery() {
List<HistoricActivityInstance> list = historyService.createHistoricActivityInstanceQuery().list();
list.forEach(v -> System.out.println(v.getId()));
}
历史任务查询(act_hi_taskinst)
/**
* 查询历史任务
* select distinct RES.*
* FROM ACT_HI_TASKINST RES order by RES.ID_ asc;
*/
@Test
public void createHistoricTaskInstanceQuery() {
List<HistoricTaskInstance> list = historyService.createHistoricTaskInstanceQuery().list();
list.forEach(v -> System.out.println(v.getId()));
}
act_hi_taskinst表中的end_time有值,说明任务完成了。为空则任务还在运行,没有结束
act_hi_taskinst表之后存储任务节点的数据,其他节点的数据不会存储在这个表中
流程实例涉及到的5张表
act_ru_execution:正在执行的信息
act_hi_procinst:已经执行完的历史流程实例信息
act_hi_actinst:存放历史所有完成的活动
act_ru_task: 正在执行的任务信息
act_hi_taskinst:已经执行完的历史任务信息
流程发起人设置
/**
* 设置流程实例的启动人
*/
@Test
public void setAuthenticatedUserId() {
String authenticatedUserId = "tyy";
identityService.setAuthenticatedUserId(authenticatedUserId);
String processDefinitionKey = "leave";
ProcessInstance processInstance = runtimeService.startProcessInstanceByKey(processDefinitionKey);
System.out.println(processInstance.getId() + "," + processInstance.getActivityId());
}
/**
* 设置流程实例的启动人
*/
@Test
public void setAuthenticatedUserId2() {
String authenticatedUserId = "tyy2";
Authentication.setAuthenticatedUserId(authenticatedUserId);
String processDefinitionKey = "leave";
ProcessInstance processInstance = runtimeService.startProcessInstanceByKey(processDefinitionKey);
System.out.println(processInstance.getId() + "," + processInstance.getActivityId());
}
开始节点 initator 跟启东人配合才有意义,否则没有意义
dataObject使用 (act_ru_variable)
flowable允许开发人员在流程文档中为流程或者子流程定义dataObject元素,该元素可以指定变量的id,名称,数据类型等,支持的数据类型有string、boolean、datetime、double、int、long等。流程实例启动时会将dataObject元素的信息自动转换为流程实例变量的存在,变量名称对应dataobject元素中定义的“name”值
/**
* 获取dataObject
* select *
* FROM ACT_RU_VARIABLE
* WHERE EXECUTION_ID_ = '40001' and NAME_= '天数' and TASK_ID_ is null;
*/
@Test
public void getDataObject() {
String executionId = "40001";
String dataObject = "天数";
DataObject dataObject1 = runtimeService.getDataObject(executionId, dataObject);
if (dataObject1 != null) {
System.out.println(dataObject1.getDataObjectDefinitionKey());
System.out.println(dataObject1.getDescription());
System.out.println(dataObject1.getExecutionId());
System.out.println(dataObject1.getName());
System.out.println(dataObject1.getValue());
System.out.println(dataObject1.getType());
}
}
/**
* select *
* FROM ACT_RU_VARIABLE
* WHERE EXECUTION_ID_ = '40001' and TASK_ID_ is null;
*/
@Test
public void getDataObject2() {
String executionId = "40001";
Map<String, DataObject> dataObjects = runtimeService.getDataObjects(executionId);
dataObjects.forEach((s, dataObject) -> {
System.out.println(dataObject.getDataObjectDefinitionKey());
System.out.println(dataObject.getDescription());
System.out.println(dataObject.getExecutionId());
System.out.println(dataObject.getName());
System.out.println(dataObject.getValue());
System.out.println(dataObject.getType());
});
}
流程实例删除
/**
* 流程实例删除
*/
@Test
public void deleteProcessInstance() {
String processInstanceId = "30001";
String deleteReason = "测试删除";
runtimeService.deleteProcessInstance(processInstanceId, deleteReason);
}
/**
*级联删除
*/
package com.webcreate.runtimeservicetest;
import org.flowable.common.engine.impl.AbstractEngineConfiguration;
import org.flowable.common.engine.impl.interceptor.Command;
import org.flowable.common.engine.impl.interceptor.CommandContext;
import org.flowable.engine.ProcessEngineConfiguration;
import org.flowable.engine.impl.cfg.ProcessEngineConfigurationImpl;
public class DeleteProcessInstanceIdCaCadeCmd implements Command<Void> {
String processInstanceId = "";
String deleteReason = "";
public DeleteProcessInstanceIdCaCadeCmd(String processInstanceId, String deleteReason) {
this.processInstanceId = processInstanceId;
this.deleteReason = deleteReason;
}
@Override
public Void execute(CommandContext commandContext) {
AbstractEngineConfiguration currentEngineConfiguration = commandContext.getCurrentEngineConfiguration();
if (currentEngineConfiguration != null) {
ProcessEngineConfigurationImpl processEngineConfiguration = (ProcessEngineConfigurationImpl) currentEngineConfiguration;
processEngineConfiguration.getExecutionEntityManager().deleteProcessInstance(processInstanceId, deleteReason, true);
}
return null;
}
}
/**
* 流程实例删除 级联删除
*/
@Test
public void deleteProcessInstance2() {
String processInstanceId = "32501";
String deleteReason = "测试删除";
managementService.executeCommand(new DeleteProcessInstanceIdCaCadeCmd(processInstanceId, deleteReason));
}
流程实例获取运行的活动节点
/**
* ### 流程实例获取运行的活动节点
*/
@Test
public void getActiveActivityIds() {
String executionId = "35004";
List<String> activeActivityIds = runtimeService.getActiveActivityIds(executionId);
activeActivityIds.forEach(v -> System.out.println(v));
}
流程实例启动
/**
* ### 根据流程定义ID启动流程
*/
@Test
public void startProcessInstanceById() {
String processDefinitionId="dataobject:1:37504";
runtimeService.startProcessInstanceById(processDefinitionId);
}
/**
* 启动流程实例 根据key
*/
@Test
public void startProcessInstanceByKey() {
String processDefinitionKey = "leave";
ProcessInstance processInstance = runtimeService.startProcessInstanceByKey(processDefinitionKey);
System.out.println(processInstance.getId()+","+processInstance.getActivityId());
}
流程实例的挂起与激活
/**
* 判断流程定义是否被挂起
*/
@Test
public void isProcessDefinitionSuspended() {
String processDefinitionId = "leave:1:45004";
boolean processDefinitionSuspended = repositoryService.isProcessDefinitionSuspended(processDefinitionId);
System.out.println(processDefinitionSuspended);
}
/**
* 流程定义挂起
* SUSPENSION_STATE_ = 2 表示被挂起
* SUSPENSION_STATE_ = 1 没有被挂起
*/
@Test
public void suspendProcessDefinitionById() {
String processDefinitionId = "leave:1:45004";
repositoryService.suspendProcessDefinitionById(processDefinitionId);
}
/**
* 流程定义激活
*/
@Test
public void activateProcessDefinitionById() {
String processDefinitionId = "leave:1:45004";
repositoryService.activateProcessDefinitionById(processDefinitionId);
}
/**
* 流程定义挂起 同时挂起流程实例
*/
@Test
public void activateProcessDefinitionById2() {
String processDefinitionId = "leave:1:45004";
repositoryService.suspendProcessDefinitionById(processDefinitionId, true, null);
}
通过runtimeService挂起流程实例