【activiti】网关

2023-11-05

activiti网关

网关是用来控制流程的走向的。

1. 排他网关–ExclusiveGateway

1.1 什么是排他网关

排他网关,用来在流程中实现决策。当执行到这个网关时,会根据判断条件去选择执行某一条分支。

注意:排他网关只会选择一个为true的分支执行。如果有两个分支条件都为true,排他网关会选择id值较小的一条分支去执行

为什么用排他网关?

img

不用排他网关也可以实现分支,比如之前通过流程变量,在连线的condition条件上设置分支条件,但设置condition条件有个缺点:如果条件都不满足,流程就结束了(并且是异常结束)。

而从网关出去的条件都不满足是直接抛出异常。

1.2 流程定义

排他网关流程图:这里的为了测试网关,任务负责人直接在设计流程的时候设置assignee属性了,不通过流程变量设置了

image-20211208145357643

1.3 测试

部署排他网关流程,启动流程实例:

    /**
     * 部署流程
     */
    @Test
    public void deployment() {
        //流程引擎
        ProcessEngine processEngine = ProcessEngines.getDefaultProcessEngine();
        //获取RepositoryService
        RepositoryService repositoryService = processEngine.getRepositoryService();
        //部署
        Deployment deploy = repositoryService
                .createDeployment()
                .name("排他网关流程")
                .addClasspathResource("bpmn/exclusivegateway.bpmn20.xml")
                .addClasspathResource("bpmn/exclusivegateway.png")
                .deploy();
        //部署信息
        System.out.println("流程id:" + deploy.getId());
        System.out.println("流程名:" + deploy.getName());
    }

    /**
     * 启动流程实例
     */
    @Test
    public void startProcessInstance() {
        //流程引擎
        ProcessEngine processEngine = ProcessEngines.getDefaultProcessEngine();
        //通过runtimeService启动流程
        RuntimeService runtimeService = processEngine.getRuntimeService();
        runtimeService.startProcessInstanceByKey("exclusivegateway");
    }

完成个人任务:

    /**
     * 张三完成个人任务
     */
    @Test
    public void completeTask() {
        //流程引擎
        ProcessEngine processEngine = ProcessEngines.getDefaultProcessEngine();
        //获取taskService调用api完成任务
        TaskService taskService = processEngine.getTaskService();
        //测试直接从数据库act_ru_task表查看任务id,然后根据taskId完成任务
        //按设计流程,需要完成两次才会走到排他网关条件
        taskService.complete("2505");
    }

    /**
     * 经理完成个人任务
     */
    @Test
    public void completeTask() {
        //流程引擎
        ProcessEngine processEngine = ProcessEngines.getDefaultProcessEngine();
        //获取taskService调用api完成任务
        TaskService taskService = processEngine.getTaskService();
        //测试直接从数据库act_ru_task表查看任务id,然后根据taskId完成任务
        //按设计流程,需要完成两次才会走到排他网关条件

        /**
         * 网关条件在执行网关前的任务中设置网关中的流程变量值,或者启动流程实例的时候设置
         */
        //设置排他网关条件,出差天数num
        Map<String, Object> map = new HashMap<>();
        //设置4天,所以经理任务完成后,流程走到总经理
        map.put("num", 4);

        taskService.complete("5002", map);
    }

查询act_ru_task表:流程任务走到了总经理审批,因为设置的出差天数num=4,在排他网关中我们设置了出差天数>3需要由总经理审批。

image-20211208214155742

注意:如果网关中的条件都不满足的话,会报异常

2. 并行网关–ParallelGateway

2.1 什么是并行网关

并行网关是将流程分成多条分支,和将多条分支再次汇聚到一起,并行网关是基于进入和外出顺序流的:

fork分支:

流程分成多条顺序流分支执行

join汇聚:

多条分支到达并行网关,先到的分支需要等待别的分支,直到所有的顺序流分支都到达以后,流程就会通过汇聚网关通向下一个任务节点。

如果同一个并行网关具有多个进入和多个外出顺序流,它就同时具有分支和汇聚功能。此时该网关需要先汇聚所有进入的顺序流,然后再切分成多个并行分支。

注意:并行网关不会解析条件,即时顺序流中定义了条件也会忽略。

2.2 流程定义

并行网关流程图:负责人已提前在流程设计中写死了,后面代码直接用,不再通过流程变量设置

image-20211208224344262

2.3 测试

部署并行网关流程,启动流程实例:

    /**
     * 部署并行网关
     */
    @Test
    public void deployment() {
        //流程引起
        ProcessEngine processEngine = ProcessEngines.getDefaultProcessEngine();
        //通过RepositoryService部署
        RepositoryService repositoryService = processEngine.getRepositoryService();
        Deployment deploy = repositoryService.createDeployment()
                .addClasspathResource("bpmn/parallelway.bpmn20.xml")
                .addClasspathResource("bpmn/parallelway.png")
                .name("并行网关流程")
                .deploy();

        //输出信息
        System.out.println("流程id:" + deploy.getId());
        System.out.println("流程名称:" + deploy.getName());
    }

    /**
     * 启动流程实例
     */
    @Test
    public void startProcessInstance() {
        //流程引起
        ProcessEngine processEngine = ProcessEngines.getDefaultProcessEngine();
        //通过RuntimeService启动流程实例
        RuntimeService runtimeService = processEngine.getRuntimeService();

        //设置流程变量出差天数num
        Map<String, Object> map = new HashMap<>();
        map.put("num", 4);
        //启动流程实例的时候,同时设置流程变量,也可以在完成任务的时候设置,但必须在使用流程变量之前
        ProcessInstance instance = runtimeService.startProcessInstanceByKey("parallelway", map);

        //输出内容
        System.out.println("流程定义id:" + instance.getProcessDefinitionId());
        System.out.println("流程实例id:" + instance.getId());
        System.out.println("当前活动id:" + instance.getActivityId());
    }

完成个人任务:

    /**
     * 完成个人任务
     */
    @Test
    public void completeTask() {
        //流程引擎
        ProcessEngine processEngine = ProcessEngines.getDefaultProcessEngine();
        //TaskService完成任务
        TaskService taskService = processEngine.getTaskService();

        //任务id
        String taskId = "2506";
        //完成任务,出差天数流程变量已经在启动流程实例的时候设置过了,这里可以不用设置了,重复设置会覆盖之前的
        taskService.complete(taskId);
    }

在这里插入图片描述

当完成启动流程实例后的第一个任务后,查询act_ru_task表会有两条数据:

在这里插入图片描述


即使我们并行网关设置了条件,且代码中设置的流程变量只满足了一个条件,但依旧产生了两条任务,也就是并行网关并不会去解析我们设置的条件的,并行网关分支之后,必须要等多个分支任务都完成后汇聚到一起,再流转到下一节点任务。

按当前流程来看:完成申请出差任务后,需要等到项目经理和技术经理都审批后,才会由总经理或者结束任务。

接下来,继续通过个人任务代码,需要完成项目经理和技术经理的任务,如果只完成一个任务,那么任务表中还是停留在并行网关的一个分支任务,并没有通向下一个节点

image-20211208224811156

分支任务都完成后,走到总经理审批,因为这里有个排他网关,我们的出差天数是4天,所以根据条件走到总经理审批节点。

image-20211208224921977

总结:只有所有分支达到汇聚点,并行网关才会执行完成;并行的分支任务执行不分前后,由任务的负责人去完成即可

3. 包含网关–InclusiveGateway

3.1 什么是包含网关

包含网关可以看做排他网关和并行网关的结合体,和排他网关一样,可以在外出顺序流上定义条件,包含网关会解析他们,但排他网关只会选择其中一条执行,但包含网关可以选择多条顺序流,同并行网关一样。

包含网关的功能是基于进入和外出顺序流的:

分支:

所有外出顺序流的条件都会被解析,满足条件的顺序流会以并行任务的方式继续执行。

汇聚:

所有并行分支到达包含网关,会进入等待状态,直到所有满足条件的分支都到达后,流程会穿过包含网关继续执行。

3.2 流程定义

出差天数大于3天由项目经理审批,出差天数小于等于3天由技术经理审批,且必须经过人事经理审批。

所以在包含网关通向项目经理和技术经理审批任务的分支连线上需要设置condition条件

image-20211209215528234

3.3 测试

部署包含网关,启动流程实例:

    /**
     * 部署流程
     */
    @Test
    public void deployment() {
        //流程引擎
        ProcessEngine processEngine = ProcessEngines.getDefaultProcessEngine();
        //创建RepositoryService进行部署
        RepositoryService repositoryService = processEngine.getRepositoryService();
        Deployment deployment = repositoryService.createDeployment()
                .name("包含网关流程")
                .addClasspathResource("bpmn/inclusivegateway.bpmn20.xml")
                .addClasspathResource("bpmn/inclusivegateway.png")
                .deploy();
        //输出信息
        System.out.println("流程key:" + deployment.getKey());
        System.out.println("流程名称:" + deployment.getName());
    }

    /**
     * 启动流程实例
     */
    @Test
    public void startProcessInstance() {
        //流程引擎
        ProcessEngine processEngine = ProcessEngines.getDefaultProcessEngine();
        //创建RuntimeService,通过其启动流程实例
        RuntimeService runtimeService = processEngine.getRuntimeService();

        //设置流程变量--出差天数
        Map<String, Object> map = new HashMap<>();
        map.put("num", 5);

        ProcessInstance processInstance = runtimeService.startProcessInstanceByKey("inclusivegateway", map);
        //输出流程实例信息
        System.out.println("流程实例id:" + processInstance.getId());
        System.out.println("流程定义id:" + processInstance.getProcessDefinitionId());
        System.out.println("流程定义key:" + processInstance.getProcessDefinitionKey());
    }

启动流程实例之后,查询act_ru_task任务表,会有一条创建出差单任务

image-20211209222129564

完成上面的任务,任务id为2506

/**
     * 完成个人任务
     */
    @Test
    public void completeTask() {
        //流程引擎
        ProcessEngine processEngine = ProcessEngines.getDefaultProcessEngine();
        //创建TaskService
        TaskService taskService = processEngine.getTaskService();

        String taskId = "2506";
        taskService.complete(taskId);
    }

查询act_ru_execution流程实例执行表:

第一条记录:包含网关分支

后两条记录代表要执行的分支,分别为人事经理审批和项目经理审批。可通过主键id关联act_ru_task任务表查询具体任务信息。只有两条要执行的分支,是因为我们设置的出差天数5天,只满足了项目经理审批的条件,技术经理的并不满足,而人事经理在流程设计中是必须要经过的

注意这里2503记录的ACT_ID_值 Task_0dpxs8x

在这里插入图片描述

查询act_ru_task任务表:同样有两个待执行的任务

image-20211209223032400

通过完成个人任务代码,先执行项目经理审批,然后查询任务表:act_ru_task

在这里插入图片描述

此时,act_ru_task表只有人事经理审批任务。

查询流程实例执行表:act_ru_execution:刷新后,项目经理的那条记录的ACT_ID_值已经更新,人事经理的那条记录并未更新,因为我们只完成了项目经理的任务,项目经理实例执行的ACT_ID_变成了第二个包含网关节点的ID,人事经理的依旧停留在当前的状态中

在这里插入图片描述

所以,我们需要接着执行人事经理的任务

通过完成个人任务代码,先执行人事经理审批,然后查询任务表:act_ru_task

image-20211209224418881

此时,根据设置的条件,任务走到了总经理审批,说明我们后面设置的排他网关也生效了。

接着查询流程实例执行表:包含网关的分支记录已经没有了,包含网关执行完成,分支和汇聚就从act_ru_execution中删除。
在这里插入图片描述

总结:在包含网关分支时,符合条件的分支将会执行,符合条件的分支也将需要汇聚后才可通向下一个节点。

4. 事件网关–EventGateway

4.1 什么是事件网关

事件网关允许根据事件判断流向。网关的每个外出顺序流都需要连接到一个中间捕获事件,当流程到达一个基于事件网关,网关会进入等待状态:暂停执行。与此同时,会为每个外出顺序流创建相对的事件订阅。流程的走向完全是由中间事件的选择,而由哪个事件来决定则是由最先触发的事件来决定的。

事件网关的外出顺序流和普通的顺序流不同,这些顺序流不会真正的"执行",相反,他们让流程引擎去决定,当执行到达一个基于事件的网关时,需要订阅什么事件。需要考虑以下条件:

  • 事件网关必须要有两条或以上的外出顺序流
  • 事件网关后,只能使用intermediateCatchEvent类型(activiti不支持基于事件网关后连接receiveTask)
  • 连接到事件网关的中间捕获事件必须只有一个入口顺序流
4.2 流程定义

设计一个有三个走向的事件网关。后面紧接着定时器事件、信号事件和消息事件,然后在后面分别跟着三个task任务,task任务可以告知我们流程是怎么走的。通过设置task任务的监听器可以更详细的知道整个流程的执行过程。

本文内容由网友自发贡献,版权归原作者所有,本站不承担相应法律责任。如您发现有涉嫌抄袭侵权的内容,请联系:hwhale#tublm.com(使用前将#替换为@)

【activiti】网关 的相关文章

  • 删除Activiti表单

    DROP TABLE IF EXISTS ACT RE DEPLOYMENT DROP TABLE IF EXISTS ACT GE PROPERTY DROP TABLE IF EXISTS ACT HI ACTINST DROP TAB
  • 使用activiti总结--发布,办理,查询

    接上一篇文章 xff0c 使用创建好的流程图 xff0c 总结一下activiti发布到查询使用的方法和测试代码 流程图 1 引用配置文件 activiti cfg xml xff0c 不引用或者引用失败的话在创建流引擎的时候会报空指针异常
  • activiti报错:org.activiti.engine.ActivitiTaskAlreadyClaimedException: Task ‘12502‘ is already claimed

    在运行activiti时 报错信息如下 Exception in thread main org activiti engine ActivitiTaskAlreadyClaimedException Task 12502 is alrea
  • Activiti7 监听器【十四】

    Activiti 7系列文章目录 文章代码下载 Activiti7 工作流设计器 一 Activiti7 创建表 二 Activiti7 表结构介绍 三 Activiti7 设计器创建流程 四 Activiti7 部署流程 五 Activi
  • activiti7-4-流程激活和挂起

    我是一个目录 1 分析 2 全部流程实例的挂起和激活 3 单个流程实例挂起 1 分析 如果公司制度发生变化 1 原本没有批完的流程怎么办 例如 30人没有处理完 怎么办 看公司制度了 有可能 按原来的走 也有可能全部打回 重新发起 全部按照
  • activiti学习(五)——执行监听器与任务监听器的基本使用

    本文介绍执行监听器与任务监听器的基本原理和使用方法 当流程途径连线或者节点的时候 会触发对应的事件类型 执行监听器与任务监听器在生产中经常会用在几个方面 动态分配节点处理人 通过前一个节点设置的变量 在运行到下一个节点时设置对应的处理人 当
  • Activiti使用教程

    1 概念 首先需要分清三个概念 流程 流程实例 任务实例 Activiti提供4个bean来操作流程 RepositoryService RuntimeService TaskService HistoryService 2 流程 针对于某
  • activiti5.17.0流程图及节点显示

    引用 activiti流程图上获取各节点的信息获取 这篇文章写得很好 揭示了图片点击出现信息的方法 于是我也做了 只不过有些改动 可能是activiti的版本不同的原因 jsp页面 通过流程实例id进行操作
  • 2023最新版本Activiti7系列-身份服务

    身份服务 在流程定义中在任务结点的 assignee 固定设置任务负责人 在流程定义时将参与者固定设置在 bpmn 文件中 如果临时任务负责人变更则需要修改流程定义 系统可扩展性差 针对这种情况可以给任务设置多个候选人或者候选人组 可以从候
  • Springboot集成activiti的配置文件ActivitiConfig

    Configuration public class ActivitiConfig Bean public ProcessEngineConfiguration processEngineConfiguration DataSource d
  • activiti7-1-环境准备(idea)

    activiti7环境准备 1 首先安装插件 2 然后建库 3 pom 4 配置文件 4 1 log4j properties 4 2 activiti cfg xml 5 测试类生成表 6 目录结构 7 最后的操作 务必看一看 又回到cs
  • Activiti / Camunda 用变量改变边界计时器

    我有一个关于 Activiti Camunda 中用户任务的计时器边界事件的特殊问题 启动流程时 我使用流程变量设置计时器持续时间 并使用边界定义中的表达式来解析该变量 边界事件是在用户任务上定义的
  • 使用 Maven 集成 Activiti Modeler

    如何将 Activiti Modeler 集成到自己的 Web 应用程序中并保留 Maven 建议的所有优点 问题是Maven中的Activiti Modeler是Activiti Explorer的一部分 网上有一些问题来自那些想要开发自
  • 【工作流Activiti】了解工作流

    1 什么是工作流 工作流 Workflow 就是通过计算机对业务流程自动化执行管理 它主要解决的是 使在多个参与者之间按照某种预定义的规则自动进行传递文档 信息或任务的过程 从而实现某个预期的业务目标 或者促使此目标的实现 通俗来讲 就是业
  • 如何将候选用户列表传递给 alfresco 中的 activiti 工作流任务?

    我希望能够传递作为任务候选者的用户列表 用户是从数据列表中检索的 不能作为一个组使用 Activiti candidateUsers 似乎是正确的方法 假设已获取用户并将其设置在变量 ipw reviwers 中
  • Alfresco:在另一个任务中显示任务字段(查看它们)

    我正在将新的工作流程部署到 alfresco 4 0 e 我有一个 formkey cwf submitLeaveTask 的任务 这是代码
  • 动态设置用户任务受让人

    我必须在 activiti 中创建需要以下用例的流程 1 表单有一个人员搜索字段 2 当有人填写表单并使用填充姓名的人员搜索字段完成任务时 我需要将分配的下一个任务的名称设置为可以对下一个任务执行操作的用户 如何使用 activiti 引擎
  • Activiti 6.0.0 完成任务时无法获取表单属性

    我是 Activiti 6 0 0 的新手 我创建了一个包含用户任务的进程 第二个用户任务有两个表单属性 但是当我完成第一个用户任务并尝试完成第二个用户任务时 表单属性不显示 我无法完成用户任务 下面是我的 bpm 流程
  • 如何获取控制器中流程实例的ID?

    我的环境 Alfresco Share v5 2 d r134641 b15 Aikau 1 0 101 3 Spring Surf 5 2 d Spring WebScripts 6 13 Freemarker 2 3 20 alfres
  • 合并 BPM 图表的最佳实践

    我们在 Java 环境中使用 Alfresco 活动图 这些图是有版本的 我们确实使用 GIT 我们经常会遇到合并分支的合并冲突 解决这个问题确实很痛苦 因为我们必须比较文件的文本内容来检查差异 有时 重新应用更改比合并更轻松 是否有合并此

随机推荐

  • go 进阶 三方库之 go-redis

    目录 一 基础 初始化连接 使用示例 1 常用操作与string 2 操作hash类型 3 操作list 4 操作set 5 操作zset 6 发布与订阅 7 事物操作 8 执行Lua脚本 二 基于redis实现分布式锁 封装锁结构体 lu
  • 机器学习——生成分类数据的坐标系边界需要用到的技术方法

    0 前言 如果遇到一种应用场景需要将x轴数据和y轴数据所有点映射到坐标系中 需要得到坐标系中x和y映射的坐标点 就要用到meshgrid把x和y映射到坐标系中 然后把得到的结果用ravel把结果转成一维的 用np c 把x数据和y数据堆叠在
  • HTML01

    若有 double p x 10 int i 5 使指针变量 p指向元素 x 5 的语句为 正确答案 A 你的答案 A 正确 p x i p x p x i p x i 设函数fun和实参数组的说明形式为 void fun char ch
  • 解决Microsoft Visual C++ 14.0 or greater is required. Get it with “Microsoft C++ Build Tools“报错

    Microsoft Visual C 14 0 or greater is required Get it with Microsoft C Build Tools 具体报错如下 Building wheel for cyac pyproj
  • 老猿学5G:融合计费基于流计费的触发器Triggers

    前往老猿Python博文目录 一 概述 每个触发条件都是一个可计费事件 SMF中的功能体CTF在用户上网时达到一定条件就会向CHF上报流量 而CTF什么时候触发流量上报是由CTF中的触发器来控制的 当用户UE发起上网行为时 SMF中的CTF
  • 汇编逆向-Qt

    Qt源码解析 索引 汇编逆向 授权破解示例分析 问题模拟 运行环境 x64dbg Windows 10 Qt5 12 3 示例代码 使用Qt显示当前时间 模拟一般授权软件的时间判断逻辑 当时间超过授权日期后就提示授权过期 没有Qt经验的同学
  • Java中方法定义和调用的学习

    方法其实就是若干语句的功能集合 参数 原料 就是进入方法的数据 返回值 原产物 就是从方法中出来的数据 定义方法的完整格式 修饰符 返回值类型 方法名称 参数类型 参数名称 方法体 return 返回值 修饰符 现阶段的固定写法 publi
  • VSCode 之 设置 settings.json 配置文件

    这篇文章主要介绍了 VSCode settings json 配置 文中通过示例代码介绍的非常详细 对大家的学习或者工作具有一定的参考学习价值 VSCode 从插件库里安装 eslint 和 prettier 两个 插件 也 实现自动格式化
  • 微信小程序怎么和后台服务器交互

    要实现微信小程序和后台服务器之间的交互 可以使用以下方式 1 小程序发起HTTP请求 后台服务器接收和处理请求 返回相应结果 这是最常用的方式 可以使用小程序提供的wx request API来发送HTTP请求 后台服务器可以使用任何语言和
  • 获取动画状态机中动画片段的时间长度

    获取动画状态机中动画片段的长度 非常简单的代码 public float GetClipLength Animator animator string clipName if null animator string IsNullOrEmp
  • wps保存后怎么恢复

    单击窗口左上角的 WPS文字 或WPS表格 在出现的菜单中单击 备份管理 也可以通过任务窗格 文件菜单等 好多入口 单击右下角的 查看其他备份 按钮 找一下有没有你要的历史文档
  • jenkins学习笔记第十六篇 Jenkins·配置 Publish Over SSH 插件——访问远程服务器

    一般而言 Jenkins 不单单需要做到将远程仓库里的代码进行编译或者打包 还需要将编译后的代码上传到远程服务器 并且执行一些其他的命令 即 Github代码 编译得到war包 上传远程服务器 执行远程命令 Jenkins 是通过 SSH
  • STM32笔记15--串口通信基本原理

    15 1 串行通信接口背景知识 15 2 STM32F1串口框图讲解 参考资料 STM32开发指南 库函数 5 3 usart串口文件夹 第九章 串口实验 1 串行通信接口背景知识 首先 处理器与外部通信有两种常见方式 并行通信和串行通信
  • 架构的概念与介绍

    1 什么是架构和架构本质 在软件行业 对于什么是架构 都有很多的争论 每个人都有自己的理解 此君说的架构和彼君理解的架构未必是一回事 LInux有架构 MySQL有架构 JVM也有架构 使用Java开发 MySQL存储 跑在Linux上的业
  • r语言聚类分析_【SPSS数据分析】SPSS聚类分析(R型聚类)的软件操作与结果解读 ——【杏花开生物医药统计】...

    在上一讲中 我们讲述了针对样本进行聚类的分析方法 Q型聚类 今天我们将详细讲解针对变量数据进行的聚类分析 系统聚类之R型聚类 我们要将数据变量进行聚类 但不知道要分成几类 或者没有明确的分类指标的时候 就需要用到R型聚类 R型聚类分析不但可
  • 根据Sql生成ER图

    原文 https blog csdn net qq 17010367 article details 79212850 commentsedit 1 根据SQL文件生成ER图 首先准备好SQL文件 然后在PowerDesigner 里 点击
  • 字符串表达式校验&求值(C#实现) - 附代码

    一 参考文献 严蔚敏 数据结构 C语言版 二 功能演示 1 测试例子 2 测试结果 三 对表达式进行校验 怎么对输入的字符串表达式进行校验呢 1 对表达式按操作符进行拆分 返回一个字符串数组 代码 private static string
  • Oracle数据库删除重复数据

    Oracle数据库中如何删除重复数据 第一种情况 部分字段重复数据的删除 先查询出那些数据是重复的 select 字段1 字段2 count from 表名 group by 字段1 字段2 having count gt 1 将上面的大于
  • TIA博途S7-1200学习笔记——指令集

    目录 1 位逻辑运算操作 1 1 常开触点 1 2 常闭触点 1 3 取反触点 1 4 线圈 1 5 赋值取反 1 6 复位输出 1 7 置位输出 1 8 置位位域 1 9 复位位域 2 10 SR置位 复位触发器 1 11 RS复位 置位
  • 【activiti】网关

    activiti网关 网关是用来控制流程的走向的 1 排他网关 ExclusiveGateway 1 1 什么是排他网关 排他网关 用来在流程中实现决策 当执行到这个网关时 会根据判断条件去选择执行某一条分支 注意 排他网关只会选择一个为t