企业🤖AI智能体构建引擎,智能编排和调试,一键部署,支持私有化部署方案 广告
![](https://img.kancloud.cn/ae/3c/ae3c16005e6612fb273abd0be9095751_1225x174.png) 包含网关可以看做是排他网关和并行网关的结合体。 <br/> 和排他网关一样,你可以在外出顺序流上定义条件,包含网关会解析它们。 但是主要的区别是包含网关可以选择多于一条顺序流,这和并行网关一样。 <br/> 包含网关的功能是基于进入和外出顺序流的: * **分支**: 所有外出顺序流的条件都会被解析,结果为`true`的顺序流会以并行方式继续执行, 会为每个顺序流创建一个分支。 * **汇聚**: 所有并行分支到达包含网关,会进入等待状态, 直到每个包含流程 token 的进入顺序流的分支都到达。 这是与并行网关的最大不同。换句话说,包含网关只会等待被选中执行了的进入顺序流。 在全部汇聚之后,流程会穿过包含网关继续执行。 <br/> 如果包含网关设置的条件中,流程变量不存在,报错。 ```java org.flowable.engine.common.api.FlowableException: Unknown property used in expression: ${evection.num>=3} ``` <br/> 演示,步骤如下: **1. 流程定义** :-: ![](https://img.kancloud.cn/a3/03/a3039c34464a77a65648a2632b0ee0d4_898x683.png) `evection-inclusive.bpmn` **2. java程序** ```java public class FlowableGatewayInclusive { /** * 1. 部署流程 */ @Test public void testDeployment() { //1、获取ProcessEngine ProcessEngine processEngine = ProcessEngines.getDefaultProcessEngine(); //2、获取RepositoryService RepositoryService repositoryService = processEngine.getRepositoryService(); //3、部署流程 Deployment deployment = repositoryService.createDeployment() .addClasspathResource("bpmn/evection-inclusive.bpmn") .name("出差申请流程") .deploy(); //流程部署id:72501 System.out.println("流程部署id:" + deployment.getId()); //流程部署名称:出差申请流程 System.out.println("流程部署名称:" + deployment.getName()); } /** * 2. 启动流程实例,设置流程变量 */ @Test public void startProcess() { //获取流程引擎 ProcessEngine processEngine = ProcessEngines.getDefaultProcessEngine(); //获取RunTimeService RuntimeService runtimeService = processEngine.getRuntimeService(); //流程key String key = "evection-inclusive"; //创建变量集合 Map<String, Object> map = new HashMap<String, Object>(); //创建出差pojo对象 Evection evection = new Evection(); //设置出差天数 evection.setNum(4d); //定义流程变量,把出差pojo对象放入map map.put("evection", evection); //启动流程实例,并设置流程变量的值(把map传入) ProcessInstance processInstance = runtimeService .startProcessInstanceByKey(key, map); //流程定义id: evection-inclusive:1:72504 System.out.println("流程定义id: " + processInstance.getProcessDefinitionId()); //流程实例id: 75001 System.out.println("流程实例id: " + processInstance.getProcessInstanceId()); //流程版本: 1 System.out.println("流程版本: " + processInstance.getProcessDefinitionVersion()); } /** * 3. 完成个人任务 */ @Test public void completTask() { //流程Key String key = "evection-inclusive"; //任务负责人 String assingee = "tom"; //获取流程引擎 ProcessEngine processEngine = ProcessEngines.getDefaultProcessEngine(); //获取taskservice TaskService taskService = processEngine.getTaskService(); //查询任务 Task task = taskService.createTaskQuery() .processDefinitionKey(key) .taskAssignee(assingee) .singleResult(); if (task != null) { //根据任务id来完成任务 taskService.complete(task.getId()); //tom完成了任务{id=75008, name=出差申请} System.out.println(task.getAssignee() + "完成了任务{id=" + task.getId() + ", name=" + task.getName() + "}"); } } } ``` **3. 测试结果** (1)当流程执行到第一个包含网关后,会根据条件判断,下一步要走哪几个分支。 ```sql mysql> select * from act_ru_task; | ID_ | REV_ | EXECUTION_ID_ | PROC_INST_ID_ | PROC_DEF_ID_ | TASK_D...E_TYPE_ | SCOPE_DEFI... +-------+------+---------------+---------------+----------------------------+-----...------+----------------... | 77504 | 1 | 75005 | 75001 | evection-inclusive:1:72504 | NULL | . .. | 人事经理 | N. .. | 77508 | 1 | 77502 | 75001 | evection-inclusive:1:72504 | NULL | . .. | 项目经理 | N. .. +-------+------+---------------+---------------+----------------------------+-----...------+----------------... ``` (2)当人事经理节点与项目经理节点的任务<mark>都完成</mark>后第二个包含网关才会走下一个分支。 ```sql mysql> select * from act_ru_task; +-------+------+---------------+---------------+---------------------...----+--------------------... | ID_ | REV_ | EXECUTION_ID_ | PROC_INST_ID_ | PROC_DEF_ID_ ..._TYPE_ | SCOPE_DEFINIT... +-------+------+---------------+---------------+---------------------...----+--------------------... | 82504 | 1 | 77502 | 75001 | evection-inclusive:1:72504 | ... | 总经理 | NULL ... +-------+------+---------------+---------------+---------------------...----+--------------------... ``` >[info]小结:在分支时,需要判断条件,**符合条件的分支,将会执行**,符合条件的分支最终才进行汇聚。