LC/Activiti7Demo/workflow.md

280 lines
20 KiB
Markdown
Raw Normal View History

## WordFlow 工作流引擎
是一种按照预定义规则【需要符合BPMN规范】进行部署将业务和节点的流程进行分离【特定形式进行关联】
### 二、什么是Activiti7
Activiti 是一个工作流引擎, activiti 可以将业务系统中复杂的业务流程抽取出来,使用专门的
建模语言BPMN2.0)进行定义,业务系统按照预先定义的流程进行执行
https://www.activiti.org
2.2 Activiti7内部核心机制
1⃣业务流程图要规范化需要遵守一套标准。
2⃣业务流程图本质上就是一个XML文件而XML可以存放所要的数据。
3⃣读取业务流程图的过程就是解析XML文件的过程。
4⃣读取一个业务流程图的结点就相当于解析一个XML的结点进一步将数据插入到MySQL表中形成一条记录。
5⃣将一个业务流程图的所有节点都读取并存入到MySQL表中。
6⃣后面只要读取MySQL表中的记录就相当于读取业务流程图的一个节点。
7⃣业务流程的推进后面就转换为读取表中的数据并且处理数据结束的时候这一行数据就可以删除了。
### BPMN
BPMNBusiness Process Model And Notation业务流程模型和符号是由BPMIBusiness Process Management Initiative开发的一套的业务流程建模符号使用BPMN提供的符号可以创建业务流程。2004年5月发布了BPMN1.0规范。
> [processOn BPMN 概念](https://www.processon.com/knowledge/bpmndiagram)
>
> ### BPMN 的核心元素
> - 活动:活动是 BPMN 中最基本的元素之一,它代表了业务流程中的一个具体任务或操作。可以自动/手动、
> - 事件:事件是 BPMN 中用于表示流程中的特定时刻或状态的元素。例如,开始事件、结束事件、中间事件等。
> - 网关:网关用于控制流程的执行路径,可以实现并行、条件、互斥等多种逻辑。
> - 泳道:泳道用于将流程分解为多个并行的部分,每个泳道代表一个独立的执行路径。
> 一个BPMN的例子
> - 当事人填写请假单启动流程后把请假单ID绑定到流程中
> - 部门经理对请假单进行审核;
> - 然后人事经理进行复核并进行备案;
> - 最后请假流程结束。
### Activiti支持的数据库
- Activiti的运行需要数据库的支撑支持如下:
- h2
- MySQL
- Oracle
- Db2
- postgres
- mysql
- 在Navicat工具中创建`activiti`的数据库,用于后续的实验.
### Activiti使用步骤
> 2.4.1 整合Activiti
> Activiti是一个工作流引擎业务系统使用Activiti来对系统的业务流程进行自动化管理为了方便业务系统访问操作Activiti的接口或功能通常将Activiti和业务系统的环境集成在一起。
> 2.4.2 业务流程建模
> 使用Activiti流程建模工具(Activity-designer)定义业务流程(.bpmn文件)。
> .bpmn文件就是业务流程定义文件通过xml定义业务流程。
> 如果使用其他公司开发的工作引擎一般都提供了可视化的建模工具Process Designer用于生成流程定义文件建模工具操作直观一般都支持图形化拖拽方式、多窗口的用户界面、丰富的过程图形元素、过程元素拷贝、粘贴、删除等功能。
> 2.4.3 部署业务流程
> 向Activiti部署业务流程定义(.bpmn文件)。
> 使用Activiti提供的API向Activiti中部署.bpmn文件一般情况下还需要一起部署业务流程的图片.png
> 2.4.4 启动流程实例
> 启动一个流程实例表示开始一次业务流程的运行比如员工请假流程部署完成如果张三要请假就可以启动一个流程实例如果李四要请假也需要启动一个流程实例两个流程的执行互不影响就好比定义一个Java类实例化两个Java对象一样部署的流程就好比Java类启动一个流程实例就好比new一个Java对象。
> 2.4.5 查询待办任务
> 因为现在系统的业务流程已经交给Activiti管理通过Activiti就可以查询当前流程执行到哪里了当前用户需要办理什么任务了这些Activiti帮我们管理了而不像传统方式中需要我们在SQL语句中的WHERE条件中指定当前查询的状态值是多少。
> 2.4.6 处理待办任务
> 用户查询待办任务后就可以办理某个任务如果这任务办理完成还需要其他用户办理比如采购单创建后由部门经理审核这个过程也是由Activiti帮我们完成了不需要我们在代码中硬编码指定下一个任务办理人了
> 2.4.7 结束流程
> 当任务办理完成没有下一个任务/结点了,这个流程实例就完成了。
### Service总览
![img](http://42.192.130.83:9000/picgo/imgs/v2-c33ee3444141b1a2c3b45ef88db771df_1440w.jpg_repeat_1731401329594__239673.png)
- RepositoryService Activiti的资源管理接口管理和控制流程发布包和流程定义的操作
- RuntimeService Activiti的流程运行管理接口流程执行相关的信息
- TaskService Activiti的任务管理接口
- HistoryService Activiti的历史管理接口
- ManagementService Activiti的引擎管理接口管理和维护功能
#### 数据表解读
Activiti 使用到的表都是 ACT_ 开头的,表名的第二部分表示用途。
##### ACT_GE_ GE 表示 general 全局通用数据及设置,各种情况都使用的数据。
> #### 全局通用数据ACT_GE_*
>
> | ACT_GE_BYTEARRAY | 二进制数据表,存储通用的流程定义和流程资源。 |
> | ---------------- | ---------------------------------------------------- |
> | ACT_GE_PROPERTY | 系统相关属性,属性数据表存储整个流程引擎级别的数据。 |
##### ACT_HI_ HI 表示 history 历史数据表,包含着程执行的历史相关数据。
##### ACT_RE_ RE 表示 repository 存储,包含的是静态信息。
##### ACT_RU_ RU 表示 runtime 运行时运行时的流程变量用户任务变量职责job等运行时数据。Activiti 只存储实例执行期间的运行时数据,当流程实例结束时,将删除这些记录 salvio修
## 流程定义 ProcessDefinition
```java
@Autowired
private RepositoryService repositoryService;
@Test
void queryProcessDe() {
List<ProcessDefinition> processDefinitions = repositoryService.createProcessDefinitionQuery().list();
for (ProcessDefinition processDefinition : processDefinitions) {
System.out.println("流程定义ID:" + processDefinition.getId());
System.out.println("流程定义名称:" + processDefinition.getName());
System.out.println("流程定义key:" + processDefinition.getKey());
System.out.println("流程定义版本:" + processDefinition.getVersion());
System.out.println("流程部署ID:" + processDefinition.getDeploymentId());
System.out.println("流程定义资源名称:" + processDefinition.getResourceName());
System.out.println("流程定义图片资源名称:" + processDefinition.getDiagramResourceName());
System.out.println("流程定义描述:" + processDefinition.getDescription());
System.out.println("流程定义分类:" + processDefinition.getCategory());
System.out.println("======================================================");
}
/**
* Opening JDBC Connection
* ==> Preparing: select distinct RES.* from ACT_RE_PROCDEF RES order by RES.ID_ asc LIMIT ? OFFSET ?
* ==> Parameters: 2147483647(Integer), 0(Integer)
* <== Columns: ID_, REV_, CATEGORY_, NAME_, KEY_, VERSION_, DEPLOYMENT_ID_, RESOURCE_NAME_, DGRM_RESOURCE_NAME_, DESCRIPTION_, HAS_START_FORM_KEY_, HAS_GRAPHICAL_NOTATION_, SUSPENSION_STATE_, TENANT_ID_, ENGINE_VERSION_
* <== Row: Part1_Deployment:1:0c957bc0-a0c1-11ef-9820-6ac6acfdceec, 1, http://www.activiti.org/processdef, Part1_Deployment, Part1_Deployment, 1, 0c82b70d-a0c1-11ef-9820-6ac6acfdceec, bpmn/leave.bpmn, bpmn/leave.png, null, 0, 1, 1, , null
* <== Total: 1
* Closing JDBC Connection [Transaction-aware proxy for target Connection [HikariProxyConnection@1566233058 wrapping com.mysql.cj.jdbc.ConnectionImpl@17796f47]]
* 流程定义ID:Part1_Deployment:1:0c957bc0-a0c1-11ef-9820-6ac6acfdceec
* 流程定义名称:Part1_Deployment
* 流程定义key:Part1_Deployment
* 流程定义版本:1
* 流程部署ID:0c82b70d-a0c1-11ef-9820-6ac6acfdceec
* 流程定义资源名称:bpmn/leave.bpmn
* 流程定义图片资源名称:bpmn/leave.png
* 流程定义描述:null
* 流程定义分类:http://www.activiti.org/processdef
* ======================================================
*/
}
```
## 流程实例 ProcessInstance
```java
/**
* 初始化流程实例
*/
@Test
public void initProcessInstance() {
// 流程定义KEY
String processDefinitionKey = "Part1_Deployment";
// 业务表KEY用于把业务数据与Activiti7流程数据相关联
String businessKey = "4208169753200945";
// 参数
Map<String, Object> variables = new HashMap<>(16);
ProcessInstance processInstance = this.runtimeService
.startProcessInstanceByKey(processDefinitionKey, businessKey, variables);
System.out.println("流程实例ID" + processInstance.getProcessInstanceId());
/**
* Opening JDBC Connection
* ==> Preparing: select * from ACT_RE_PROCDEF where KEY_ = ? and (TENANT_ID_ = '' or TENANT_ID_ is null) and VERSION_ = (select max(VERSION_) from ACT_RE_PROCDEF where KEY_ = ? and (TENANT_ID_ = '' or TENANT_ID_ is null))
* ==> Parameters: Part1_Deployment(String), Part1_Deployment(String)
* <== Columns: ID_, REV_, CATEGORY_, NAME_, KEY_, VERSION_, DEPLOYMENT_ID_, RESOURCE_NAME_, DGRM_RESOURCE_NAME_, DESCRIPTION_, HAS_START_FORM_KEY_, HAS_GRAPHICAL_NOTATION_, SUSPENSION_STATE_, TENANT_ID_, ENGINE_VERSION_
* <== Row: Part1_Deployment:1:0c957bc0-a0c1-11ef-9820-6ac6acfdceec, 1, http://www.activiti.org/processdef, Part1_Deployment, Part1_Deployment, 1, 0c82b70d-a0c1-11ef-9820-6ac6acfdceec, bpmn/leave.bpmn, bpmn/leave.png, null, 0, 1, 1, , null
* <== Total: 1
* ==> Preparing: select * from ACT_RU_VARIABLE where TASK_ID_ = ?
* ==> Parameters: b25c87dd-a0c3-11ef-8ba8-68c6acfdcef0(String)
* <== Total: 0
* ==> Preparing: insert into ACT_HI_TASKINST ( ID_, PROC_DEF_ID_, PROC_INST_ID_, EXECUTION_ID_, NAME_, PARENT_TASK_ID_, DESCRIPTION_, OWNER_, ASSIGNEE_, START_TIME_, CLAIM_TIME_, END_TIME_, DURATION_, DELETE_REASON_, TASK_DEF_KEY_, FORM_KEY_, PRIORITY_, DUE_DATE_, CATEGORY_, TENANT_ID_ ) values ( ?, ?, ?, ?, ?, ?, ?, ?, ?, ?, ?, ?, ?, ?, ?, ?, ?, ?, ?, ? )
* ==> Parameters: b25c87dd-a0c3-11ef-8ba8-68c6acfdcef0(String), Part1_Deployment:1:0c957bc0-a0c1-11ef-9820-6ac6acfdceec(String), b25a64f9-a0c3-11ef-8ba8-68c6acfdcef0(String), b25ab31a-a0c3-11ef-8ba8-68c6acfdcef0(String), UserTask(String), null, null, null, admin(String), 2024-11-12 14:59:44.325(Timestamp), null, null, null, null, sid-192966db-031d-4a50-886d-379935dd9bc1(String), null, 50(Integer), null, null, (String)
* <== Updates: 1
* ==> Preparing: insert into ACT_HI_PROCINST ( ID_, PROC_INST_ID_, BUSINESS_KEY_, PROC_DEF_ID_, START_TIME_, END_TIME_, DURATION_, START_USER_ID_, START_ACT_ID_, END_ACT_ID_, SUPER_PROCESS_INSTANCE_ID_, DELETE_REASON_, TENANT_ID_, NAME_ ) values ( ?, ?, ?, ?, ?, ?, ?, ?, ?, ?, ?, ?, ?, ? )
* ==> Parameters: b25a64f9-a0c3-11ef-8ba8-68c6acfdcef0(String), b25a64f9-a0c3-11ef-8ba8-68c6acfdcef0(String), 4208169753200945(String), Part1_Deployment:1:0c957bc0-a0c1-11ef-9820-6ac6acfdceec(String), 2024-11-12 14:59:44.311(Timestamp), null, null, null, sid-26d6e725-878e-411d-b23d-6df4ae3cbd24(String), null, null, null, (String), null
* <== Updates: 1
* ==> Preparing: insert into ACT_HI_ACTINST ( ID_, PROC_DEF_ID_, PROC_INST_ID_, EXECUTION_ID_, ACT_ID_, TASK_ID_, CALL_PROC_INST_ID_, ACT_NAME_, ACT_TYPE_, ASSIGNEE_, START_TIME_, END_TIME_, DURATION_, DELETE_REASON_, TENANT_ID_ ) values (?, ?, ?, ?, ?, ?, ?, ?, ?, ?, ?, ?, ?, ?, ?) , (?, ?, ?, ?, ?, ?, ?, ?, ?, ?, ?, ?, ?, ?, ?)
* ==> Parameters: b25ada2b-a0c3-11ef-8ba8-68c6acfdcef0(String), Part1_Deployment:1:0c957bc0-a0c1-11ef-9820-6ac6acfdceec(String), b25a64f9-a0c3-11ef-8ba8-68c6acfdcef0(String), b25ab31a-a0c3-11ef-8ba8-68c6acfdcef0(String), sid-26d6e725-878e-411d-b23d-6df4ae3cbd24(String), null, null, null, startEvent(String), null, 2024-11-12 14:59:44.314(Timestamp), 2024-11-12 14:59:44.316(Timestamp), 2(Long), null, (String), b25b4f5c-a0c3-11ef-8ba8-68c6acfdcef0(String), Part1_Deployment:1:0c957bc0-a0c1-11ef-9820-6ac6acfdceec(String), b25a64f9-a0c3-11ef-8ba8-68c6acfdcef0(String), b25ab31a-a0c3-11ef-8ba8-68c6acfdcef0(String), sid-192966db-031d-4a50-886d-379935dd9bc1(String), b25c87dd-a0c3-11ef-8ba8-68c6acfdcef0(String), null, UserTask(String), userTask(String), admin(String), 2024-11-12 14:59:44.317(Timestamp), null, null, null, (String)
* <== Updates: 2
* ==> Preparing: insert into ACT_HI_IDENTITYLINK (ID_, TYPE_, USER_ID_, GROUP_ID_, TASK_ID_, PROC_INST_ID_) values (?, ?, ?, ?, ?, ?)
* ==> Parameters: b25cd5fe-a0c3-11ef-8ba8-68c6acfdcef0(String), participant(String), admin(String), null, null, b25a64f9-a0c3-11ef-8ba8-68c6acfdcef0(String)
* <== Updates: 1
* ==> Preparing: insert into ACT_RU_EXECUTION (ID_, REV_, PROC_INST_ID_, BUSINESS_KEY_, PROC_DEF_ID_, ACT_ID_, IS_ACTIVE_, IS_CONCURRENT_, IS_SCOPE_,IS_EVENT_SCOPE_, IS_MI_ROOT_, PARENT_ID_, SUPER_EXEC_, ROOT_PROC_INST_ID_, SUSPENSION_STATE_, TENANT_ID_, NAME_, START_TIME_, START_USER_ID_, IS_COUNT_ENABLED_, EVT_SUBSCR_COUNT_, TASK_COUNT_, JOB_COUNT_, TIMER_JOB_COUNT_, SUSP_JOB_COUNT_, DEADLETTER_JOB_COUNT_, VAR_COUNT_, ID_LINK_COUNT_) values (?, 1, ?, ?, ?, ?, ?, ?, ?, ?, ?, ?, ?, ?, ?, ?, ?, ?, ?, ?, ?, ?, ?, ?, ?, ?, ?, ?) , (?, 1, ?, ?, ?, ?, ?, ?, ?, ?, ?, ?, ?, ?, ?, ?, ?, ?, ?, ?, ?, ?, ?, ?, ?, ?, ?, ?)
* ==> Parameters: b25a64f9-a0c3-11ef-8ba8-68c6acfdcef0(String), b25a64f9-a0c3-11ef-8ba8-68c6acfdcef0(String), 4208169753200945(String), Part1_Deployment:1:0c957bc0-a0c1-11ef-9820-6ac6acfdceec(String), null, true(Boolean), false(Boolean), true(Boolean), false(Boolean), false(Boolean), null, null, b25a64f9-a0c3-11ef-8ba8-68c6acfdcef0(String), 1(Integer), (String), null, 2024-11-12 14:59:44.311(Timestamp), null, false(Boolean), 0(Integer), 0(Integer), 0(Integer), 0(Integer), 0(Integer), 0(Integer), 0(Integer), 0(Integer), b25ab31a-a0c3-11ef-8ba8-68c6acfdcef0(String), b25a64f9-a0c3-11ef-8ba8-68c6acfdcef0(String), null, Part1_Deployment:1:0c957bc0-a0c1-11ef-9820-6ac6acfdceec(String), sid-192966db-031d-4a50-886d-379935dd9bc1(String), true(Boolean), false(Boolean), false(Boolean), false(Boolean), false(Boolean), b25a64f9-a0c3-11ef-8ba8-68c6acfdcef0(String), null, b25a64f9-a0c3-11ef-8ba8-68c6acfdcef0(String), 1(Integer), (String), null, 2024-11-12 14:59:44.313(Timestamp), null, false(Boolean), 0(Integer), 0(Integer), 0(Integer), 0(Integer), 0(Integer), 0(Integer), 0(Integer), 0(Integer)
* <== Updates: 2
* ==> Preparing: insert into ACT_RU_TASK (ID_, REV_, NAME_, PARENT_TASK_ID_, DESCRIPTION_, PRIORITY_, CREATE_TIME_, OWNER_, ASSIGNEE_, DELEGATION_, EXECUTION_ID_, PROC_INST_ID_, PROC_DEF_ID_, TASK_DEF_KEY_, DUE_DATE_, CATEGORY_, SUSPENSION_STATE_, TENANT_ID_, FORM_KEY_, CLAIM_TIME_) values (?, 1, ?, ?, ?, ?, ?, ?, ?, ?, ?, ?, ?, ?, ?, ?, ?, ?, ?, ? )
* ==> Parameters: b25c87dd-a0c3-11ef-8ba8-68c6acfdcef0(String), UserTask(String), null, null, 50(Integer), 2024-11-12 14:59:44.317(Timestamp), null, admin(String), null, b25ab31a-a0c3-11ef-8ba8-68c6acfdcef0(String), b25a64f9-a0c3-11ef-8ba8-68c6acfdcef0(String), Part1_Deployment:1:0c957bc0-a0c1-11ef-9820-6ac6acfdceec(String), sid-192966db-031d-4a50-886d-379935dd9bc1(String), null, null, 1(Integer), (String), null, null
* <== Updates: 1
* ==> Preparing: insert into ACT_RU_IDENTITYLINK (ID_, REV_, TYPE_, USER_ID_, GROUP_ID_, TASK_ID_, PROC_INST_ID_, PROC_DEF_ID_) values (?, 1, ?, ?, ?, ?, ?, ?)
* ==> Parameters: b25cd5fe-a0c3-11ef-8ba8-68c6acfdcef0(String), participant(String), admin(String), null, null, b25a64f9-a0c3-11ef-8ba8-68c6acfdcef0(String), null
* <== Updates: 1
* Closing JDBC Connection [Transaction-aware proxy for target Connection [HikariProxyConnection@621103114 wrapping com.mysql.cj.jdbc.ConnectionImpl@4ac2b4c6]]
* 流程实例IDb25a64f9-a0c3-11ef-8ba8-68c6acfdcef0
*/
}
/**
* 查询流程实例
*/
@Test
public void getProcessInstance() {
String processInstanceId = "b25a64f9-a0c3-11ef-8ba8-68c6acfdcef0";
ProcessInstance processInstance = this.runtimeService.createProcessInstanceQuery()
.processInstanceId(processInstanceId)
.singleResult();
System.out.println("ProcessInstanceId" + processInstance.getProcessInstanceId());
System.out.println("ProcessDefinitionId" + processInstance.getProcessDefinitionId());
System.out.println("isEnded" + processInstance.isEnded());
System.out.println("isSuspended" + processInstance.isSuspended());
/**
* Opening JDBC Connection
* ==> Preparing: select distinct RES.* , P.KEY_ as ProcessDefinitionKey, P.ID_ as ProcessDefinitionId, P.NAME_ as ProcessDefinitionName, P.VERSION_ as ProcessDefinitionVersion, P.DEPLOYMENT_ID_ as DeploymentId, S.PROC_INST_ID_ AS PARENT_PROC_INST_ID_ from ACT_RU_EXECUTION RES inner join ACT_RE_PROCDEF P on RES.PROC_DEF_ID_ = P.ID_ left outer join ACT_RU_EXECUTION S on RES.SUPER_EXEC_ = S.ID_ WHERE RES.PARENT_ID_ is null and RES.ID_ = ? and RES.PROC_INST_ID_ = ? order by RES.ID_ asc LIMIT ? OFFSET ?
* ==> Parameters: b25a64f9-a0c3-11ef-8ba8-68c6acfdcef0(String), b25a64f9-a0c3-11ef-8ba8-68c6acfdcef0(String), 2147483647(Integer), 0(Integer)
* <== Columns: ID_, REV_, PROC_INST_ID_, BUSINESS_KEY_, PARENT_ID_, PROC_DEF_ID_, SUPER_EXEC_, ROOT_PROC_INST_ID_, ACT_ID_, IS_ACTIVE_, IS_CONCURRENT_, IS_SCOPE_, IS_EVENT_SCOPE_, IS_MI_ROOT_, SUSPENSION_STATE_, CACHED_ENT_STATE_, TENANT_ID_, NAME_, START_TIME_, START_USER_ID_, LOCK_TIME_, IS_COUNT_ENABLED_, EVT_SUBSCR_COUNT_, TASK_COUNT_, JOB_COUNT_, TIMER_JOB_COUNT_, SUSP_JOB_COUNT_, DEADLETTER_JOB_COUNT_, VAR_COUNT_, ID_LINK_COUNT_, ProcessDefinitionKey, ProcessDefinitionId, ProcessDefinitionName, ProcessDefinitionVersion, DeploymentId, PARENT_PROC_INST_ID_
* <== Row: b25a64f9-a0c3-11ef-8ba8-68c6acfdcef0, 1, b25a64f9-a0c3-11ef-8ba8-68c6acfdcef0, 4208169753200945, null, Part1_Deployment:1:0c957bc0-a0c1-11ef-9820-6ac6acfdceec, null, b25a64f9-a0c3-11ef-8ba8-68c6acfdcef0, null, 1, 0, 1, 0, 0, 1, null, , null, 2024-11-12 14:59:44.311, null, null, 0, 0, 0, 0, 0, 0, 0, 0, 0, Part1_Deployment, Part1_Deployment:1:0c957bc0-a0c1-11ef-9820-6ac6acfdceec, Part1_Deployment, 1, 0c82b70d-a0c1-11ef-9820-6ac6acfdceec, null
* <== Total: 1
* Closing JDBC Connection [Transaction-aware proxy for target Connection [HikariProxyConnection@1118158255 wrapping com.mysql.cj.jdbc.ConnectionImpl@77eb0e47]]
* ProcessInstanceIdb25a64f9-a0c3-11ef-8ba8-68c6acfdcef0
* ProcessDefinitionIdPart1_Deployment:1:0c957bc0-a0c1-11ef-9820-6ac6acfdceec
* isEndedfalse
* isSuspendedfalse
*/
// 查询流程实例列表
List<ProcessInstance> processInstanceList = this.runtimeService.createProcessInstanceQuery().list();
if (!CollectionUtils.isEmpty(processInstanceList)) {
processInstanceList.forEach(pi -> {
System.out.println("ProcessInstanceId" + pi.getProcessInstanceId());
System.out.println("ProcessDefinitionId" + pi.getProcessDefinitionId());
System.out.println("isEnded" + pi.isEnded());
System.out.println("isSuspended" + pi.isSuspended());
});
}
// 挂起流程实例
this.runtimeService.suspendProcessInstanceById(processInstanceId);
// 激活流程实例
this.runtimeService.activateProcessInstanceById(processInstanceId);
// 删除流程实例
this.runtimeService.deleteProcessInstance(processInstanceId, "测试删除流程实例");
}
```
## **流程符号**
### 事件 Event
![img](http://42.192.130.83:9000/picgo/imgs/v2-7abf29716c8a87df55a503f537b86230_1440w.jpg_repeat_1731401500483__988588.png)
### **网关 GateWay**
![img](http://42.192.130.83:9000/picgo/imgs/v2-f27e0ae9d25d13b7b0cc90fceaffd732_1440w.jpg_repeat_1731401505552__805264.png)
- 排他网关:只有一条路径会被选择
- 并行网关:所有路径都会被选择
- 包容网关:可以在网关上设置条件,**为每个输出设置计算**
- 事件网关:进入等待状态,**等待事件后转为活动状态**
### 流向 Flow
![img](http://42.192.130.83:9000/picgo/imgs/v2-9f863cc8aa78ed965a8a50349bcd3304_1440w.jpg_repeat_1731401793171__863727.png)
##