流程实例
1.什么是流程实例
**流程实例(ProcessInstance)**代表流程定义的执行实例。
一个流程实例包含了所有的运行节点。我们可以利用这个对象来了解当前流程实例的进度等信息。
例如:用户或程序按照流程定义内容发起一个流程,就是一个流程实例
流程定义和流程实例的图解:
2.启动流程实例
流程定义部署后,就可以通过activiti去管理流程的执行,执行流程表示流程的一次执行。
比如部署出差流程后,某个用户申请出差就需要执行这个出差流程,另一用户同样也可以执行这个出差流程,两个流程实例之间是互不影响的,每个执行的都是单独的流程实例。
启动流程实例时,指定businessKey
,就会在act_ru_exection
表中存储businessKey
BusinessKey:业务标识,通常为业务表的主键,业务标识与流程实例对应。业务标识来源于业务系统,存储的业务标识就是为了关联查询业务系统数据。
比如:启动一个出差流程实例,就可以将出差申请单的id作为业务标识存到activiti中,将来查询activiti流程实例信息时,就可以查出业务标识,从而查询出业务系统到中的出差单详细信息。
2.1启动流程实例编码
/**
* 启动实例,添加业务标识businessKey
*/
@Test
public void addBusinessKey() {
//得到processEngine
ProcessEngine processEngine = ProcessEngines.getDefaultProcessEngine();
//得到runtimeService
RuntimeService runtimeService = processEngine.getRuntimeService();
/**
* 启动实例,同时指定业务标识businessKey
* startProcessInstanceByKey(String processDefinitionKey, String businessKey)
* processDefinitionKey:流程定义的key
* businessKey:业务标识,根据业务参数传入
*/
ProcessInstance processInstance = runtimeService.startProcessInstanceByKey("evection", "1001");
//输出流程实例信息中的业务标识
System.out.println("业务标识:" + processInstance.getBusinessKey());
}
2.2启动流程实例操作表说明
启动流程实例,操作表如下:
流程实例执行表,记录当前流程实例的执行情况,一个流程实例运行完成,此表的流程实例相关记录也会删除。
该表中总会有一条记录的主键id和流程实例id相同。
任务参与者表,记录当前参与任务的用户或组
流程实例历史表
流程启动,会在此表插入一条记录,流程实例运行完成不会删除。
任务历史表,记录所有任务
开始一个任务,不仅在act_ru_task
表插入记录,也会在历史任务表插入一条记录,任务历史表的主键就是任务id,任务完成此表记录不删除。
活动历史表,记录所有活动
活动包括任务,所以此表中不仅记录了任务,还记录了流程执行过程的其他活动,比如开始事件、结束事件。
3.查询流程实例
流程在运行过程中可以查询流程实例的状态,当前运行节点等信息
/**
* 查询流程实例
*/
@Test
public void queryTaskProcess() {
//流程定义key
String processDefinitionKey = "evection";
//获取ProcessEngine
ProcessEngine processEngine = ProcessEngines.getDefaultProcessEngine();
//获取runtimeService
RuntimeService runtimeService = processEngine.getRuntimeService();
//获取流程实例
List<ProcessInstance> instanceList = runtimeService
.createProcessInstanceQuery()
.processDefinitionKey(processDefinitionKey)
.list();
instanceList.forEach(instance -> {
System.out.println("========================");
System.out.println("流程实例id:" + instance.getId());
System.out.println("所属流程定义id:" + instance.getProcessDefinitionId());
System.out.println("是否执行完成:" + instance.isEnded());
System.out.println("是否暂停:" + instance.isSuspended());
System.out.println("当前活动标识id:" + instance.getActivityId());
});
}
4.关联BusinessKey
需求:
在activiti实际应用时,查询流程实例列表时可能要显示业务系统的一些相关信息,比如:查询当前运行的出差流程列表需要列出出差单名称、出差天数等信息,而出差天数等信息是由业务系统定义的,存在业务系统中,并没有在activiti数据库中存储,所以无法通过activiti查询到出差天数信息。
实现:
当查询流程实例时,通过businessKey(业务标识)关联查询业务系统的出差单表,查询出出差天数等信息。但是前提是,在启动流程实例的时候,需要将businessKey存储到activiti中,一般存相关业务操作表的主键id。
添加businessKey方式为:
ProcessInstance processInstance = runtimeService.startProcessInstanceByKey("evection", "1001");
之后可以从activiti中获取businessKey,再通过businessKey去获取对应业务表中的数据。
获取businessKey方式为:
String businessKey = processInstance.getBusinessKey();
在activiti的act_ru_execution
表中,字段BUSINESS_KEY
就是存放业务KEY的
5.挂起/激活流程实例
在某些情况下,由于流程变更需要将当前运行的流程暂停而不是直接删除,就需要暂停流程,不再继续执行。
5.1全部流程实例挂起/激活
操作流程定义为挂起状态,该流程定义下边所有的流程实例全部暂停。
流程定义为挂起状态,该流程定义将不允许启动新的流程实例,同时该流程定义下所有的流程实例将全部挂起暂停执行,完成流程定义下的流程实例将会抛异常
/**
* 全部流程实例挂挂起===》直接将对应的流程定义挂起,该流程定义下的所有流程实例挂起
* 全部流程实例挂激活===》直接将对应的流程定义激活,该流程定义下的所有流程实例激活
*/
@Test
public void suspendAllProcessInstance() {
//获取processEngine
ProcessEngine processEngine = ProcessEngines.getDefaultProcessEngine();
//获取RepositoryService
RepositoryService repositoryService = processEngine.getRepositoryService();
//查询流程定义对象
ProcessDefinition processDefinition = repositoryService
.createProcessDefinitionQuery()
.processDefinitionKey("evection")
.singleResult();
//得到当前流程定义是否为挂起状态
boolean suspended = processDefinition.isSuspended();
//流程定义id
String processDefinitionId = processDefinition.getId();
//判断是否挂起
if (suspended) {
//如果是挂起,执行激活操作
//参数1:流程定义id 参数2:是否激活 参数3:激活时间
repositoryService.activateProcessDefinitionById(processDefinitionId, true, null);
System.out.println("流程定义:" + processDefinitionId + ",已激活");
} else {
//如果是激活,执行挂起操作
//参数1:流程定义id 参数2:是否挂起 参数3:挂起时间
repositoryService.suspendProcessDefinitionById(processDefinitionId, true, null);
System.out.println("流程定义:" + processDefinitionId + ",已挂起");
}
}
5.2单个流程实例挂起/激活
操作流程实例对象,针对单个流程执行挂起/激活操作,当某个流程实例挂起后则此流程不再继续执行,完成该流程实例将会抛出异常。
/**
* 单个流程实例挂起与激活
*/
@Test
public void suspendSingleProcessInstance() {
//获取processEngine
ProcessEngine processEngine = ProcessEngines.getDefaultProcessEngine();
//获取RuntimeService
RuntimeService runtimeService = processEngine.getRuntimeService();
//查询流程实例对象
ProcessInstance processInstance = runtimeService
.createProcessInstanceQuery()
//流程实例id根据自己的数据填写
.processInstanceId("30001")
.singleResult();
//得到当前流程实例是否是挂起状态
boolean suspended = processInstance.isSuspended();
//流程实例id
String processInstanceId = processInstance.getId();
//判断是否挂起
if (suspended) {
//如果是挂起,执行激活操作
//参数1:流程实例id
runtimeService.activateProcessInstanceById(processInstanceId);
System.out.println("流程实例:" + processInstanceId + ",已激活");
} else {
//如果是激活,执行挂起状态
//参数1:流程实例id
runtimeService.suspendProcessInstanceById(processInstanceId);
System.out.println("流程实例:" + processInstanceId + ",已挂起");
}
当流程定义或者某个流程实例挂起,完成流程实例将会抛出异常。