网关 复杂分支流程
1、网关
网关是控制流程流向的重要组件,一般和流程变量配合使用。对于复杂分支流程时,只用变量很难控制。
- 排他网关 ExclusiveGateway
- 并行网关 ParallelGateway
- 包含网关 InclusiveGateway
- 事件网关 EventGateway 用起来比较复杂,很少使用
2、排他网关 ExclusiveGateway
流程中实现决策,当流程执行到这个网关时,所有分支都会判断是否TRUE。排他网关只会选择1个TRUE分支执行,当多个分支都满足时,选择ID值较小的分支执行。
<process id="exclusiveGateway" isClosed="false" isExecutable="true" processType="None">
<startEvent id="_2" name="StartEvent"/>
<userTask activiti:assignee="jake" activiti:exclusive="true" id="_3" name="填写请假单"/>
<exclusiveGateway gatewayDirection="Unspecified" id="_4" name="ExclusiveGateway"/>
<userTask activiti:assignee="manager" activiti:exclusive="true" id="_5" name="总经理审批"/>
<userTask activiti:assignee="finance" activiti:exclusive="true" id="_6" name="财务审批"/>
<endEvent id="_7" name="EndEvent"/>
<sequenceFlow id="_8" sourceRef="_2" targetRef="_3"/>
<sequenceFlow id="_9" sourceRef="_3" targetRef="_4"/>
<sequenceFlow id="_11" name="小于3天" sourceRef="_4" targetRef="_6">
<conditionExpression xsi:type="tFormalExpression"><![CDATA[${day<=3}]]></conditionExpression>
</sequenceFlow>
<sequenceFlow id="_13" sourceRef="_5" targetRef="_6"/>
<sequenceFlow id="_14" sourceRef="_6" targetRef="_7"/>
<sequenceFlow id="_15" name="day>3" sourceRef="_4" targetRef="_5">
<conditionExpression xsi:type="tFormalExpression"><![CDATA[${day>3}]]></conditionExpression>
</sequenceFlow>
</process>
2.1、流程部署、启动流程、提交流程和之前都一样的操作
package com.hongying.activiti;
import com.hongying.model.Evection;
import lombok.extern.slf4j.Slf4j;
import org.activiti.engine.*;
import org.activiti.engine.history.HistoricActivityInstance;
import org.activiti.engine.history.HistoricActivityInstanceQuery;
import org.activiti.engine.repository.Deployment;
import org.activiti.engine.runtime.ProcessInstance;
import org.activiti.engine.task.Task;
import org.junit.Test;
import java.util.HashMap;
import java.util.List;
import java.util.Map;
/**
* @author zyk
* @version 1.0.0
* @ClassName ExclusiveGatewayTest
* @Description 排他网关
* @createTime 2021年06月27日 18:14:00
*/
@Slf4j
public class ExclusiveGatewayTest {
@Test
public void deployDemployment(){
ProcessEngine defaultProcessEngine = ProcessEngines.getDefaultProcessEngine();
RepositoryService repositoryService = defaultProcessEngine.getRepositoryService();
Deployment deploy = repositoryService.createDeployment()
.addClasspathResource("bpmn/ExclusiveGateway.bpmn")
.name("排他网关")
.deploy();
log.info("请假流程部署,ID:{}",deploy.getId());
log.info("请假流程部署,Name:{}",deploy.getName());
}
/**
* 开启请假流程2,请假大于3天给总经理审批;
*/
@Test
public void startProcess(){
ProcessEngine processEngine = ProcessEngines.getDefaultProcessEngine();
RuntimeService runtimeService = processEngine.getRuntimeService();
Map<String,Object> variables=new HashMap<>();
variables.put("day",5);
//开启流程传递变量
ProcessInstance myLeave2 = runtimeService.startProcessInstanceByKey("exclusiveGateway", variables);
log.info("开启新流程2:{}",myLeave2.getId());
//打印历史信息
printNextProcessInfo(myLeave2.getId());
}
/**
* 当前负责人完成任务
*/
@Test
public void completeProcess(){
ProcessEngine processEngine = ProcessEngines.getDefaultProcessEngine();
TaskService taskService = processEngine.getTaskService();
List<Task> tasks = taskService.createTaskQuery().processDefinitionKey("exclusiveGateway")
.taskAssignee("finance").list();
for(Task t:tasks){
log.info("任务:{}-已被:{} 处理,变量:{}",t.getName(),t.getAssignee(),t.getProcessVariables());
//完成任务
taskService.complete(t.getId());
//打印历史信息,及待处理人
printNextProcessInfo(t.getProcessInstanceId());
}
}
/**
* 查看下一个结点处理人
* @param instanceId
*/
private void printNextProcessInfo(String instanceId){
ProcessEngine processEngine = ProcessEngines.getDefaultProcessEngine();
HistoryService historyService = processEngine.getHistoryService();
HistoricActivityInstanceQuery instanceQuery = historyService.createHistoricActivityInstanceQuery();
//根据流程实例ID查询
instanceQuery.processInstanceId(instanceId);
instanceQuery.orderByHistoricActivityInstanceStartTime().asc();
List<HistoricActivityInstance> history = instanceQuery.list();
for(HistoricActivityInstance hi:history){
log.info(hi.getActivityId());
log.info(hi.getActivityName());
log.info(hi.getProcessDefinitionId());
log.info(hi.getProcessInstanceId());
log.info(hi.getAssignee());
}
}
}
3、并行网关 ParallelGateway
并行网关将流程分成多条分支,也可以把多条分支汇聚一起。
基于进入和外出顺序流:
fork分支:并行后的所有外出顺序流,为每个顺序流都创建一个分支。
join汇聚:所有达到并行网关的分支都会等待其他分支达到,都达到后会同时通过。
与其他网关主要区别就是,并行网关并不会解析条件,即使连线上有条件也会忽略;
并行网关是成对出现的,第一个fork分流、第二个汇聚;只有分流,没有汇聚,流程不完整,是无法结束的;
4、包含网关 InclusiveGateway
是排他网关和并行网关的结合体,多个并行审核时,可能有些分支需要条件判断;
连线上可以有Condition条件,有则会解析,没有时,直接Fork流程分派;
包含网关也是成对出现的;
5、事件网关 EventGateway
事件网关用的不是很多,这里只是记录一下,有机会在仔细研究