![](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]小结:在分支时,需要判断条件,**符合条件的分支,将会执行**,符合条件的分支最终才进行汇聚。
- Activiti流程引擎
- 工作流介绍
- Activiti是什么
- Activiti流程处理步骤
- Activiti环境搭建
- 搭建步骤
- 表结构介绍
- ActivitiAPI结构
- 认识流程符号
- 流程设计器的使用
- 流程处理步骤
- 乱码问题
- 流程实例
- 流程实例是什么
- 业务标识
- 查询流程实例
- 挂起/激活流程实例
- 个人任务
- 分配任务负责人
- 查询待办任务
- 办理权限
- 流程变量
- 流程变量类型
- 流程变量作用域
- 使用流程变量控制流程
- 组任务
- 设置任务候选人
- 组任务办理流程
- 网关
- 4种网关类型
- 排他网关
- 并行网关
- 包含网关
- 事件网关
- Spring整合Activiti
- SpringBoot整合Activiti
- Flowable流程引擎
- Flowable是什么
- Flowable与Activiti
- Flowable环境搭建
- FlowableAPI
- 流程引擎API与服务
- 流程处理步骤
- 流程部署
- 流程部署方式
- 流程定义版本
- 删除已部署的流程
- 下载资源
- 流程实例
- 什么是流程实例
- 业务标识
- 查询流程实例
- 挂起/激活流程实例
- 分配任务负责人
- 固定分配
- UEL表达式分配
- 监听器分配
- 办理权限
- 流程变量
- 流程变量类型
- 流程变量作用域
- 流程变量控制流程
- 组任务
- 设置任务候选人
- 组任务办理流程
- 网关
- 排他网关
- 并行网关
- 包含网关
- 事件网关
- 历史查询
- 查询历史
- Spring整合Flowable
- 配置文件整合
- 配置类整合
- SpringBoot整合Flowable