Activiti(四)--流程控制

1 流程实例与执行流

    1.1 流程实例与执行流概念

在Activiti中,启动一个流程,会创建一个流程实例,每个流程实例至少会有一个执行流(Execution),当流程实例没有流程分支时,一般情况下只会存在一个执行流;假设流程出现两个分支(如下图所示),此时Activiti将会有三个执行流,第一个为原来流程的著执行流程,而其余两个为子执行流.实际上如果不考虑Activiti的实现,从业务角度看,流程实例的执行流分为两个执行流,此时整个流程中只有两个执行流存在(下图中的分支),自执行流只是对Activiti设计的一个描述
在这里插入图片描述

    1.2 流程实例与执行流对象(ProcessInstance与Execution)

ProcessInstance是一个接口,一个ProcessInstance实例表示一个流程实例,ProcessInstance实际上时执行流(Execution)的子接口,流程实例是一个执行流.ProcessInstance中有Execution没有的属性,例如流程定义和业务主键,当得到的是一个ProcessInstance实例时,就将其看作一个流程实例;当得到一个Execution实例时,他就是一个执行流
流程实例与执行流的数据保存在执行表(ACT_RU_EXECUTION)中,对应的映射实体为ExcutionEntityImpl,其包含以下属性:
id:主键ID
revision:该数据的修订版本号
businessKey:流程实例的业务主键,只有ProcssInstance实例才有该值
parentId:父执行路的ID,在没有流程分支的情况下,流程实例与执行流的父ID为同一条数据,如果出现新的执行流,那么将会设置该值,对应PARENT_ID字段
processDefinitionId:流程定义ID,不管是流程实例数据还是执行流数据,该字段均会被设置为相应的流程定义ID,对应PROC_DEF_ID_字段
superExecutionId:父执行流的ID,如果该执行流是子流程的一部分,则该值不为null,对应SUPER_EXEC_字段
activitiId:当前执行流的动作,一般为流程节点的名称,对应ACT_ID_字段
isActive:该执行流状态是否活跃,如果当前的执行流分为两个子执行流,则当前的执行流被标识为非活跃状态,而两个子执行流则为活跃状态,对应is_activite字段
isConcurrent:执行流是否并行,对应is_concurrent_字段
isScope:是否在执行流范围内
isEventScope:是否在事件范围内
suspensionState:流程中断状态,1为活跃,2为中断

2 启动流程

startProcessInstanceById(String processDefinitionId);//根据流程定义id启动流程,在进行部署时可以得到一个Deployment对象,根据Deployment实例的Id可以查询到ProcessDefinition的实例
startProcessInstanceById(String processDefinitionId,Map<String,Object> variables);//variables为流程参数
startProcessInstanceById(String processDefinitionId,String businessKey);//使用流程定义id和业务主键启动流程,业务主键会被保存到执行表的BUSINESS_KEY_字段
startProcessInstanceById(String processDefinitionId,String businessKey,Map<String,Object> variables);

startProcessInstanceByKey(String processDefinitionKey);//根据流程文件定义的process节点的id启动流程
startProcessInstanceByKey(String processDefinitionKey,Map<String,Object> vatiables); // vatiables为流程参数
startProcessInstanceByKey(String processDefinitionKey,String businessKey);//businessKey业务流程主键
startProcessInstanceByKey(String processDefintionKey,String businessKey,Map<String,Object> variables);

startProcessInstanceByMessage(String messageName);
startProcessInstanceByMessage(String messageName,Map<String,Object> processVariables);
startProcessInstanceByMessage(String messageName,String bussinessKey);
startProcessInstanceByMessage(String messageName,String bussinessKey,Map<String,Object> processVariables);

在这里插入图片描述

3 流程参数

    3.1 设置与查询流程参数

//部署流程描述文件
repositoryService.createDeployment().addClasspathResource("bpmn/variable.bpmn20.xml").deploy();
//启动流程
ProcessInstance pi = runtimeService.startProcessInstanceByKey("vatcationRequest");
//查询流程实例的执行流
Execution exe = runtimeService.createExecutionQuery().processInstanceId(pi.getId()).singleResult();
// 设置流程参数
runtimeService.setVariable(exe.getId(),"days",5);
//查找参数
runtimeService.getVariable(exe.getId(),"days");

    3.2 流程参数的作用域

RuntimeService的setVariableLocal方法与TaskService的setVariableLocal方法类似,使用setVariableLocal方法时,流程参数只作用于设置的执行流,一旦该执行流失效,参数也将失效.使用setVariable方法设置的参数,使用getVariableLocal方法不能获取,而使用setLocalVariable设置的参数 ,则可以使用getVariable方法获取

4 流程操作

    4.1 流程触发

在工作流中,对于用户任务,可以使用TaskService的complete方法将当前流程节点的任务完成,完成后流程就会向前进行,而对于receiveTask等流程节点,则可以使用trigger方法将其触发,是流程往前进行,具体如下:
trigger(String executionId):触发流程中的等待节点,让流程往下执行
trigger(String executionId,Map<String,Object> processVariables)😕/与前面的tragger方法类似,可以设置流程参数
trigger(String executionId,Map<String,Object> processVariables,Map<String,Object> transientVariables);//与前面的triggert方法类似,可以设置临时参数
在这里插入图片描述

    4.2 触发信号事件

事件节点是在流程中记录事件发生的流程元素,BPMN2.0规范中主要有两种类型的事件:捕获事件和抛出事件,如果在一个流程中定义了Catching事件节点,则流程执行到该节点时,会一直等待触发的信号,知道接收到相应的信号后,流程才继续向前执行,此为Catching事件.如果在一个流程中定义了Throwing事件,则当流程执行到该节点时,该事件会自动往下执行,并不需要任何的信号指示,此为Throwing事件.在Catching事件中,如果希望流程继续往下执行,可以使用RuntimeService的signalEventReceived方法抛出信号,Catching事件节点就会捕获到相应信号,让流程继续往下执行.当流程到达信号Catching事件时,事件表(ACT_RU_EVENT_SUBSCR)中会产生相应的事件描述数据,对应的EVENT_TYPE_字段值为signal.如下图:
在这里插入图片描述
在这里插入图片描述

//部署流程
  .....
// 启动流程
ProcessInstance pi = runtimeSevice.startProcessInstanceByKey("testProcess");
// 查询执行流
Execution exe = runtimeService.createExecutionQuery().activityId("userTask1").singleResult();
System.out.println("当前节点:"+exe.getActivityId());

//触发receiveTask
runtimeService.tragger(exe.getId());
//查询当前节点
exe = runtimeService.createExecutionQuery().activityId("signalCatchEvent").singleResult();
System.out.println("调用trigger方法当前节点:"+exe.getActivityId());
// 发送信号给事件,流程结束
runtimeService.signalEventReceived("testSignal");
List exes = runtimeService,createExecutionQuery().processInstanceId(pi.getId()).list();
System.out.println("触发Catching事件后,执行流数量:"+exes.size());

    4.3 触发消息事件

Activiti中除了提供信号事件节点外,还提供了消息事件节点.可以使用messageEventDefinition元素定义一个消息事件,该元素可以被定义在startEvent和intermediateCatchEvent元素中.如果在startEvent中定义了消息事件,就可以使用RunTimeService的 startProcessInstaceByMessage方法来启动流程.如果在intermediateCatchEvent元素下定义了消息事件,那么就意味着该消息事件是一个Catching事件.也就是说,当执行流执行到该节点时,会一直等待触发的消息,直到收到触发的消息后,执行流才会继续往下进行.流程到达消息Catching事件时,会在事件表中产生事件描述数据,对应的EVENT_TYPE_字段值为message
在这里插入图片描述
在这里插入图片描述

// 部署流程描述文件
....
// 启动流程
runtimeService.startProcessInstanceByKey("testProcess");
// 查询当前节点
Execution exe = runtimeService.createExecutionQuery().activityId("messageintermediateacatchevent1").singleResult();
System.out.println("当前流程节点:"+exe.getActivityId());
//触发消息事件
runtimeService.messageEventReceived("testMsg",exe,getId());
//查询当前事件
exe = runtimeService.createExecutionQuery().activityId("usertask1").singleResult();
System.out.println("当前流程节点:"+exe.getActivityId());

    4.4 中断,激活,删除流程

//启动流程
ProcessInstance pi = runtimeService.startProcessInstanceByKey("testProcess");\
//中断流程
runtimeService.suspendProcessInstanceById(pi.getId());

//激活流程
runtimeService.activiteProcessInstanceById(pi.getId());

// 删除流程
runtimeService.deleteProcessInstance(pi.getId(),"abc");

5 流程数据查询

    5.1 执行流查询

List<Execution> exes = runtimeService.createExecutionQuery().processDefinitionKey("testProcess").list();
exes = runtimeService.createExecutionQuery().processInstanceBusinessKey("businessKey").list();
exes = runtimeService.createExecutionQuery().messageEventSubscriptionName("messageName").list();
Execution exe = runtimeService.createExecutionQuery()
	.activityId("messageintermediatecatchevent1")
	.processInstanceId(pi1.getId()).singleResult();
exes = runtimeService.createExecutionQuery().signalEventSubscriptionName("signalName").list();
//根据参数查询执行流
exes = runtimeService.createExecutionQuery().variableValueEquals("name","crazyit").list();
exes = runtimeService.createExecutionQuery().variableValueGreaterThan("days",5).list();
exes = runtimeService.createExecutionQuery().variableValueGreaterThanOrEqual("days",5).list();
exes = runtimeService.createExecutionQuery().variableValueLessThan("days",6).list();
exes = runtimeService.createExecutionQuery().variableValueLessThanOrEqual("days",6).list();

exes = runtimeService.createExecutionQuery().variableValueLike("name","%crazy%").list();
exes = runtimeService.createExecutionQuery().variableValueNotEquals("days",8).list();

    5.2 流程实例查询

List<ProcessInstance> pis = runtimeService.createProcessInstanceQuery().processDefinitionKey("testProcess").list();
pis = runtimeService.crearteProcessInstanceQuery().active().list();
pis = runtimeService.crearteProcessInstanceQuery().processInstanceBusinessKey("key2").list();

//根据多个流程实例ID查询
Set<String> ids = new HashSet<String>();
ids.add(pi1.getId());
ids.add(pi2.getId());
pis = runtimeService.crearteProcessInstanceQuery().processInstanceIds(ids).list();
评论
添加红包

请填写红包祝福语或标题

红包个数最小为10个

红包金额最低5元

当前余额3.43前往充值 >
需支付:10.00
成就一亿技术人!
领取后你会自动成为博主和红包主的粉丝 规则
hope_wisdom
发出的红包
实付
使用余额支付
点击重新获取
扫码支付
钱包余额 0

抵扣说明:

1.余额是钱包充值的虚拟货币,按照1:1的比例进行支付金额的抵扣。
2.余额无法直接购买下载,可以购买VIP、付费专栏及课程。

余额充值