一、流程实例定义
流程实例:按照流程定义内容发起一个流程就是一个流程实例,流程实例是动态的。
二、启动流程实例
流程定义部署在activiti后,就可以在系统中通过activiti去管理该流程的执行,执行流程标识流程的一次执行。
比如部署系统请假流程后,如果莫用户要申请请假流程这时就需要执行这个流程,如果另外一个用户也要申请请假则也需要执行该流程,每个流程互相不影响,每个执行是单独的流程实例。
@Test
public void test2(){
//1.得到ProcessEngine对象
ProcessEngine processEngine = ProcessEngines.getDefaultProcessEngine();
//2.得到RunService对象
RuntimeService runtimeService = processEngine.getRuntimeService();
//3.创建流程实例 流程定义的key需要知道 holiday
ProcessInstance processInstance = runtimeService.startProcessInstanceByKey("holiday");
//4.输出实例的相关信息
System.out.println("流程部署ID"+processInstance.getDeploymentId());//null
System.out.println("流程定义ID"+processInstance.getProcessDefinitionId());//holiday:1:4
System.out.println("流程实例ID"+processInstance.getId());//2501
System.out.println("活动ID"+processInstance.getActivityId());//null
}
三、Businesskey(业务标识)
启动流程实例时,指定的businesskey,就会在act_ru_execution(流程实例的执行表)中存储businesskey。
BusinessKey:业务标识,通常为业务表的主键,业务标识和流程实例一一对应。(业务标识来源于业务系统,存储业务标识就是根据业务标识来关联查询业务系统的数据。)
比如:请假流程启动一个流程实例,就可以将请假单的id作为业务标识存储到activiti中,将来查询activiti的流程实例信息就可以获取请假单的id从而关联查询业务系统数据库得到请假单信息。
@Test
public void test3(){
//启动流程实例,添加businessKey
//实际上就是向act_ru_execution表中的businessKey的字段中存入业务标识
//1.得到ProcessEngine对象
ProcessEngine processEngine = ProcessEngines.getDefaultProcessEngine();
//2.得到RuntimeService对象
RuntimeService runtimeService = processEngine.getRuntimeService();
//3.启动流程实例,同时还要指定业务标识businessKey 它本身就是请假单的id
//第一个参数:是指流程定义key
//第二个参数:业务标识businessKey
ProcessInstance processInstance = runtimeService.startProcessInstanceByKey("holiday", "20240724");
//4.输出processInstance相关的属性,取出businessKey使用:processInstance.getBusinessKey()
System.out.println(processInstance.getBusinessKey());
}
四、操作数据库表
启动流程实例,操作如下数据库表:
4.1 act_ru_execution(流程实例执行表)
记录当前流程实例的执行情况
说明:
流程实例执行,如果当前只有一个分支时,一个流程实例只有一条记录且执行表的主键id和流程实例id相同,如果当前有多个分支正在运行则改执行表中有多条记录,存在执行表的主键和流程实例id不同的记录。不论当前有几个分支总会有一条记录的执行表的主键和流程实例id相同。一个流程实例运行完成,次表中于流程实例相关的记录删除。
4.2 act_ru_task(任务执行表)
记录当前执行的任务
说明:
启动流程实例,流程当前执行到第一个任务节点,此表会插入一条记录表示当前任务的执行情况,如果任务完成则记录删除。
4.3 act_ru_identitylink(任务参与者)
记录当前参与任务的用户或组
4.4 act_hi_procinst(流程实例历史表)
流程实例启动,会在此表插入一条记录,流程实例运行完成记录u而不会删除。
4.5 act_hi_taskinst(任务历史表)
记录所有活动
开始一个任务,不仅在act_ru_task表插入记录,也会在历史任务表插入一条记录,任务历史表的主键就是任务id,任务完成此表记录不删除。
4.6 act_hi_actinst(活动历史表)
记录所有活动
活动包括任务,所以此表中不仅记录了任务,还记录了流程执行过程中的其他活动,比如开始事件、结束事件。
五、查询流程实例
5.1 查询流程实例
@Test
public void test5(){
//1.得到ProcessEngine对象
ProcessEngine processEngine = ProcessEngines.getDefaultProcessEngine();
//2.获取RunTimeService
RuntimeService runtimeservice = processEngine.getRuntimeService();
List<ProcessInstance> list=runtimeservice
.createProcessInstanceQuery()
.processDefinitionKey("holiday")
.list();
for(ProcessInstance processInstance:list){
System.out.println("----------------------------");
System.out.println("流程实例id:" + processInstance.getProcessInstanceId());
System.out.println("所属流程定义id:" + processInstance.getProcessDefinitionId());
System.out.println("是否执行完成:" + processInstance.isEnded());
System.out.println("是否暂停:" + processInstance.isSuspended());
System.out.println("当前活动标识 :" + processInstance.getActivityId());
}
}
5.2 关联businessKey
需求:
在activiti实际应用时,查询流程实例列表时可能要显示出业务系统的一些相关信息,比如:查询当前运行的请假流程列表需要将请假单名称、请假天数等信息显示出来,请假天数等信息在业务系统中存在,而并没有在activiti数据库中存在,所以是无法通过activiti的api查询到请假天数等信息。
实现:
在查询流程实例时,通过businessKey(业务标识)关联查询业务系统的请假单表,查询出请假天数等信息。
通过下面的代码就可以获取activiti中所对应实例保存的业务Key。而这个业务Key一般都会保存相关联的业务操作表的主键,再通过主键ID去查询业务信息,比如通过请假单的ID,去查询更多的请假信息(请假人,请假时间,请假天数,请假事由等)
StringbusinessKey = processInstance.getBusinessKey();
六、挂起、激活流程实例
某些情况可能由于流程变更需要将当前运行的流程暂停而不是直接删除,流程暂停后将不会继续执行。
6.1 全部流程实例挂起
操作流程定义为挂起状态,改流程定义下边所有的流程实例全部暂停:
流程定义为挂起状态该流程定义将不允许启动新的流程实例,同时该流程定义下的所有流程实例将全部挂起暂停执行。
@Test
public void test6(){
//1.得到ProcessEngine对象
ProcessEngine processEngine = ProcessEngines.getDefaultProcessEngine();
//2.得到RepositoryService
RepositoryService repositoryService = processEngine.getRepositoryService();
//3.查询流程定义的对象
ProcessDefinition processDefinition = repositoryService.createProcessDefinitionQuery()
.processDefinitionKey("holiday").singleResult();
//4.得到当前流程定义的实例是否都为暂停状态
boolean suspended = processDefinition.isSuspended();
String processDefinitionId = processDefinition.getId();
//5.判断
if(suspended){
//说明是暂停,就可以激活操作
repositoryService.activateProcessDefinitionById(processDefinitionId,true
,null);
System.out.println("流程定义:"+processDefinitionId+"激活");
}else{
repositoryService.suspendProcessDefinitionById(processDefinitionId,true,null);
System.out.println("流程定义:"+processDefinitionId+"挂起");
}
6.2 单个流程实例挂起
操作流程实例对象,针对单个流程执行挂起操作,某个流程实例挂起则此流程不在继续执行,完成该流程实例的当前任务将报异常。
@Test
public void test7(){
//1.得到ProcessEngine对象
ProcessEngine processEngine = ProcessEngines.getDefaultProcessEngine();
//2.得到RuntimeService
RuntimeService runtimeService = processEngine.getRuntimeService();
//3.查询流程实例对象
ProcessInstance processInstance = runtimeService.createProcessInstanceQuery()
.processInstanceId("2501").singleResult();
//4.得到当前流程定义的实例是否都为暂停状态
boolean suspended = processInstance.isSuspended();
String processInstanceId = processInstance.getId();
//5.判断
if(suspended){
//说明是暂停,就可以激活操作
runtimeService.activateProcessInstanceById(processInstanceId);
System.out.println("流程:"+processInstanceId+"激活");
}else{
runtimeService.suspendProcessInstanceById(processInstanceId);
System.out.println("流程定义:"+processInstanceId+"挂起");
}
}