网关用来控制流程的流向
只有一个分支可以使用
排他网关,用来在流程中实现决策。 当流程执行到这个网关,所有分支都会判断条件是否为true,如果为true则执行该分支,
注意:排他网关只会选择一个为true的分支执行。如果有两个分支条件都为true,排他网关会选择id值较小的一条分支去执行。
为什么要用排他网关? 不用排他网关也可以实现分支,如:在连线的condition条件上设置分支条件。
在连线设置condition条件的缺点:如果条件都不满足,流程就结束了(是异常结束)。
如果 使用排他网关决定分支的走向,如下:
如果从网关出去的线所有条件都不满足则系统抛出异常。
org.activiti.engine.ActivitiException: No outgoing sequence flow of the exclusive gateway 'exclusivegateway1' could be selected for continuing the process
at org.activiti.engine.impl.bpmn.behavior.ExclusiveGatewayActivityBehavior.leave(ExclusiveGatewayActivityBehavior.java:85)
总结:虽然可以直接在连线上面进行判断条件,但是如果不使用排他网关,当条件都
为false的时候,直接结束流程了;
如果使用了排他网关,当条件都为false,那么会抛出错误,这样使用者就会知道了
哪个地方出错
排他网关图标,红框内:
在部门经理审核后,走排他网关,从排他网关出来的分支有两条,一条是判断出差天数是否大于3天,另一条是判断出差天数是否小于等于3天。
设置分支条件时,如果所有分支条件都不是true,报错:
org.activiti.engine.ActivitiException: No outgoing sequence flow of the exclusive gateway 'exclusivegateway1' could be selected for continuing the process
at org.activiti.engine.impl.bpmn.behavior.ExclusiveGatewayActivityBehavior.leave(ExclusiveGatewayActivityBehavior.java:85)
并行网关允许将流程分成多条分支,也可以把多条分支汇聚到一起,并行网关的功能是基于进入和外出顺序流的:
l fork分支:
并行后的所有外出顺序流,为每个顺序流都创建一个并发分支。
l join汇聚:
所有到达并行网关,在此等待的进入分支, 直到所有进入顺序流的分支都到达以后, 流程就会通过汇聚网关。
注意,如果同一个并行网关有多个进入和多个外出顺序流, 它就同时具有分支和汇聚功能。 这时,网关会先汇聚所有进入的顺序流,然后再切分成多个并行分支。
与其他网关的主要区别是,并行网关不会解析条件。 即使顺序流中定义了条件,也会被忽略。
总结:并行网关的线上面,写上条件也没有用,在并行网关的后面分支都要执行完成之后,才会走下一个任务,不然,只要有一个分支没有完成,后面的任务就不会走
说明:
技术经理和项目经理是两个execution分支,在act_ru_execution表有两条记录分别是技术经理和项目经理,act_ru_execution还有一条记录表示该流程实例。
待技术经理和项目经理任务全部完成,在汇聚点汇聚,通过parallelGateway并行网关。
并行网关在业务应用中常用于会签任务,会签任务即多个参与者共同办理的任务。
并行网关图标,红框内:
我们首先创建一个流程,然后执行代码,将我们画的流程图部署到数据库
以上是画好的bump的文件,然后执行代码,进行部署到数据库
执行完成以上的代码,数据库里面就已经保存了
然后启动流程实例,就是执行一个代码,相当于创建一个申请单
/**
* 启动流程实例,相当于申请提交申请单,并且要设置流程变量
*/
@Test
public void testStartProcess(){
// 1、创建ProcessEngine
ProcessEngine processEngine = ProcessEngines.getDefaultProcessEngine();
// 2、获取RunTimeService
RuntimeService runtimeService = processEngine.getRuntimeService();
// 流程定义key
String key = "paraller";
// 创建变量集合
Map<String, Object> map = new HashMap<String, Object>();
// 创建出差pojo对象
Evection evection = new Evection();
evection.setNum(4d);
//定义流程变量,把出差的pojo对象放入map里面
map.put("evection",evection);
// 3、根据流程定义Id启动流程
ProcessInstance processInstance = runtimeService
.startProcessInstanceByKey(key,map);
// 输出内容
System.out.println("流程定义id:" + processInstance.getProcessDefinitionId());
System.out.println("流程实例id:" + processInstance.getId());
System.out.println("当前活动Id:" + processInstance.getActivityId());
//
// 流程定义id:myJtxx:1:4
// 流程实例id:2501
// 当前活动Id:null
}
以上就是创建一个申请单了,
从数据库可以看到,当前的流程实例,只有tom正在执行,我们现在对tom进行完成
/**
* 测试完成个人任务
*/
@Test
public void completTask(){
String key ="paraller";
String assingee = "tom";
// 获取引擎
ProcessEngine processEngine = ProcessEngines.getDefaultProcessEngine();
// 获取操作任务的服务 TaskService
TaskService taskService = processEngine.getTaskService();
// 完成任务,参数:流程实例id,完成zhangsan的任务
// 根据用户查询是否有任务
Task task = taskService.createTaskQuery()
.processDefinitionKey(key)
.taskAssignee(assingee)//这个是当前改谁执行了
.singleResult();
if(task != null){
taskService.complete(task.getId());
System.out.println("流程实例id="+task.getProcessInstanceId());
System.out.println("任务Id="+task.getId());
System.out.println("任务负责人="+task.getAssignee());
System.out.println("任务名称="+task.getName());
}
}
tom 一走完,这个正在执行的任务就变为并行网关后面的两个分支了,数据库里面就有两个了
所以,我们可以看到,走并行网关,不会走并行网关上面的分支条件,所有的分支都会走;
[ACT_RU_EXECUTION] 再看这个表,这个就是流程执行实例表;
一个是正在执行的任务;一个是正在执行任务的实例;
我们选择一个分支进行完成
以上是jerry完成了;我们查看数据库,就是正在需要的做的任务里面,现在只剩一个了
包含网关可以看做是排他网关和并行网关的结合体。
和排他网关一样,你可以在外出顺序流上定义条件,包含网关会解析它们。 但是主要的区别是包含网关可以选择多于一条顺序流,这和并行网关一样。
包含网关的功能是基于进入和外出顺序流的:
l 分支:
所有外出顺序流的条件都会被解析,结果为true的顺序流会以并行方式继续执行, 会为每个顺序流创建一个分支。
l 汇聚:
所有并行分支到达包含网关,会进入等待状态, 直到每个包含流程token的进入顺序流的分支都到达。 这是与并行网关的最大不同。换句话说,包含网关只会等待被选中执行了的进入顺序流。 在汇聚之后,流程会穿过包含网关继续执行。
扫码关注腾讯云开发者
领取腾讯云代金券
Copyright © 2013 - 2025 Tencent Cloud. All Rights Reserved. 腾讯云 版权所有
深圳市腾讯计算机系统有限公司 ICP备案/许可证号:粤B2-20090059 深公网安备号 44030502008569
腾讯云计算(北京)有限责任公司 京ICP证150476号 | 京ICP备11018762号 | 京公网安备号11010802020287
Copyright © 2013 - 2025 Tencent Cloud.
All Rights Reserved. 腾讯云 版权所有