• Acvitivi网关(十一)


    1排他网关

    1.1 什么是排他网关

    排他网关(也叫异或(XOR)网关,或叫基于数据的排他网关),用来在流程中实现决策。 当流程
    执行到这个网关,所有分支都会判断条件是否为 true,如果为 true 则执行该分支,
    注意,排他网关只会选择一个为 true 的分支执行(即使有两个分支条件都为 true, 排他网关也会只
    选择一条分支去执行)
    为什么要用排他网关?
    不用排他网关也可以实现分支,如下图:

     上图中,在连线的 condition 条件上设置分支条件。
    缺点:
    如果条件都不满足,不使用排他网关,流程就结束了(是异常结束)
    如果 使用排他网关决定分支的走向,如下:

     如果从网关出去的线所有条件都不满足则系统抛出异常。

    说明 :经过排他网关必须要有一条且只有一条分支走

    测试没有排他网关的

    //1.部署流程定义
        public static void main(String[] args) {
            //1.创建ProcessEngine对象
            ProcessEngine processEngine = ProcessEngines.getDefaultProcessEngine();
    
            //2.得到RepositoryService实例
            RepositoryService repositoryService = processEngine.getRepositoryService();
    
            //3.进行部署
            Deployment deployment = repositoryService.createDeployment()
                    .addClasspathResource("diagram/day05/holiday4.bpmn")  //添加bpmn资源
                    //.addClasspathResource("diagram/day05/holiday4.png")
                    .name("请假申请单流程")
                    .deploy();
    
            //4.输出部署的一些信息
            System.out.println(deployment.getName());
            System.out.println(deployment.getId());
        } 
      //2.启动流程实例
       public static void main(String[] args) {
                //1.得到ProcessEngine对象
                ProcessEngine processEngine = ProcessEngines.getDefaultProcessEngine();
    
                //2.得到RunService对象
                RuntimeService runtimeService = processEngine.getRuntimeService();
    
            Holiday holiday = new Holiday();
            holiday.setNum(5F);
            Map<String,Object> map = new HashMap<>();
            map.put("holiday",holiday);//流程变量赋值
    
                //3.创建流程实例  流程定义的key需要知道 holiday
                ProcessInstance processInstance = runtimeService.startProcessInstanceByKey("myProcess_1",map);
    
    
                //4.输出实例的相关信息
                System.out.println("流程定义ID"+processInstance.getProcessDefinitionId());//holiday:1:4
                System.out.println("流程实例ID"+processInstance.getId());//2501
        }
      //3.填写请假单的任务要执行完成
        public static void main(String[] args) {
            //1.得到ProcessEngine对象
            ProcessEngine processEngine = ProcessEngines.getDefaultProcessEngine();
    
            //2.得到TaskService对象
            TaskService taskService = processEngine.getTaskService();
    
            //3.查询当前用户的任务
            Task task = taskService.createTaskQuery()
                    .processDefinitionKey("myProcess_1")
                    .taskAssignee("lishi")
                    .singleResult();
    
            //4.处理任务,结合当前用户任务列表的查询操作的话,任务ID:task.getId()
            if(task!=null){
                taskService.complete(task.getId());
                System.out.println("用户任务执行完毕...");
            }
    
    
            //5.输出任务的id
            System.out.println(task.getId());
        }

     

     没有排他,任务会分配到2个人

    测试排他网关

     

        //1.部署流程定义
       public static void main(String[] args) {
            //1.创建ProcessEngine对象
            ProcessEngine processEngine = ProcessEngines.getDefaultProcessEngine();
    
            //2.得到RepositoryService实例
            RepositoryService repositoryService = processEngine.getRepositoryService();
    
            //3.进行部署
            Deployment deployment = repositoryService.createDeployment()
                    .addClasspathResource("diagram/day05/holiday5.bpmn")  //添加bpmn资源
                    //.addClasspathResource("diagram/day05/holiday5.png")
                    .name("请假申请单流程")
                    .deploy();
    
            //4.输出部署的一些信息
            System.out.println(deployment.getName());
            System.out.println(deployment.getId());
        }
      //2.启动流程实例
       public static void main(String[] args) {
                //1.得到ProcessEngine对象
                ProcessEngine processEngine = ProcessEngines.getDefaultProcessEngine();
    
                //2.得到RunService对象
                RuntimeService runtimeService = processEngine.getRuntimeService();
    
            Holiday holiday = new Holiday();
            holiday.setNum(5F);
            Map<String,Object> map = new HashMap<>();
            map.put("holiday",holiday);//流程变量赋值
    
                //3.创建流程实例  流程定义的key需要知道 holiday
                ProcessInstance processInstance = runtimeService.startProcessInstanceByKey("holidayExclusive",map);
    
    
                //4.输出实例的相关信息
                System.out.println("流程定义ID"+processInstance.getProcessDefinitionId());//holiday:1:4
                System.out.println("流程实例ID"+processInstance.getId());//2501
        }
     //3.填写请假单的任务要执行完成
        public static void main(String[] args) {
            //1.得到ProcessEngine对象
            ProcessEngine processEngine = ProcessEngines.getDefaultProcessEngine();
    
            //2.得到TaskService对象
            TaskService taskService = processEngine.getTaskService();
    
            //3.查询当前用户的任务
            Task task = taskService.createTaskQuery()
                    .processDefinitionKey("holidayExclusive")
                    .taskAssignee("lisi")
                    .singleResult();
    
            //4.处理任务,结合当前用户任务列表的查询操作的话,任务ID:task.getId()
            if(task!=null){
                taskService.complete(task.getId());
                System.out.println("用户任务执行完毕...");
            }
    
    
            //5.输出任务的id
            System.out.println(task.getId());
        }

     会发现假如排他网关以后,只会产生一个作业,且他的开始时间就是网关的结束时间

     2并行网关

    2.1什么是并行网关

    并行网关允许将流程分成多条分支,也可以把多条分支汇聚到一起,并行网关的功能是基于进
    入和外出顺序流的:
    fork 分支:
    并行后的所有外出顺序流,为每个顺序流都创建一个并发分支。
    join 汇聚:
    所有到达并行网关,在此等待的进入分支, 直到所有进入顺序流的分支都到达以后, 流程就会通
    过汇聚网关。
    注意,如果同一个并行网关有多个进入和多个外出顺序流, 它就同时具有分支和汇聚功能。 这时,
    网关会先汇聚所有进入的顺序流,然后再切分成多个并行分支。
    与其他网关的主要区别是,并行网关不会解析条件。 即使顺序流中定义了条件,也会被忽略。 

     

        //1.部署流程定义  带排他网关,同时还带并行网关
        public static void main(String[] args) {
            //1.创建ProcessEngine对象
            ProcessEngine processEngine = ProcessEngines.getDefaultProcessEngine();
    
            //2.得到RepositoryService实例
            RepositoryService repositoryService = processEngine.getRepositoryService();
    
            //3.进行部署
            Deployment deployment = repositoryService.createDeployment()
                    .addClasspathResource("diagram/day05/holiday6.bpmn")  //添加bpmn资源
                    //.addClasspathResource("diagram/day05/holiday5.png")
                    .name("请假申请单流程")
                    .deploy();
    
            //4.输出部署的一些信息
            System.out.println(deployment.getName());
            System.out.println(deployment.getId());
        }
      //2.启动流程实例
       public static void main(String[] args) {
                //1.得到ProcessEngine对象
                ProcessEngine processEngine = ProcessEngines.getDefaultProcessEngine();
    
                //2.得到RunService对象
                RuntimeService runtimeService = processEngine.getRuntimeService();
    
            Holiday holiday = new Holiday();
            holiday.setNum(5F);
            Map<String,Object> map = new HashMap<>();
            map.put("holiday",holiday);//流程变量赋值
    
                //3.创建流程实例  流程定义的key需要知道 holiday
                ProcessInstance processInstance = runtimeService.startProcessInstanceByKey("holidayParallel",map);
    
    
                //4.输出实例的相关信息
                System.out.println("流程定义ID"+processInstance.getProcessDefinitionId());//holiday:1:4
                System.out.println("流程实例ID"+processInstance.getId());//2501
        }

     开始完成任务,一直流转到并行网关

     //3.填写请假单的任务要执行完成
        public static void main(String[] args) {
            //1.得到ProcessEngine对象
            ProcessEngine processEngine = ProcessEngines.getDefaultProcessEngine();
    
            //2.得到TaskService对象
            TaskService taskService = processEngine.getTaskService();
    
            //3.查询当前用户的任务
            Task task = taskService.createTaskQuery()
                    .processDefinitionKey("holidayParallel")
                    .taskAssignee("zhaoliu")
                    .singleResult();
    
            //4.处理任务,结合当前用户任务列表的查询操作的话,任务ID:task.getId()
            if(task!=null){
                taskService.complete(task.getId());
                System.out.println("用户任务执行完毕...");
            }
    
    
            //5.输出任务的id
            System.out.println(task.getId());
        }

     有并行网关的汇聚结点:说明有一个分支已经到汇聚,等待其它的分支到达。
    当所有分支任务都完成,都到达汇聚结点后:
    流程实例执行表: SELECT * FROM act_ru_execution,执行流程实例不存在,说明流程执行结束。
    总结:所有分支到达汇聚结点,并行网关执行完成。

    3 包含网关

    3.1什么是包含网关

    包含网关可以看做是排他网关和并行网关的结合体。 和排他网关一样,你可以在外出顺序流上
    定义条件,包含网关会解析它们。 但是主要的区别是包含网关可以选择多于一条顺序流,这和并行
    网关一样。
    包含网关的功能是基于进入和外出顺序流的:
    分支:
    所有外出顺序流的条件都会被解析,结果为 true 的顺序流会以并行方式继续执行, 会为每个顺序流
    传智播客——专注于 Java.Net Php、网页平面设计工程师的培训
    北京市昌平区建材城西路金燕龙办公楼一层 电话: 400-618-9090
    创建一个分支。
    汇聚:
    所有并行分支到达包含网关,会进入等待状态, 直到每个包含流程 token 的进入顺序流的分支都
    到达。 这是与并行网关的最大不同。换句话说,包含网关只会等待被选中执行了的进入顺序流。 在
    汇聚之后,流程会穿过包含网关继续执行。
    3.2流程定义:
    企业体检流程,公司全体员工进行常规项检查、抽血化验,公司管理层除常规检查和抽血化验还要
    进行增加项检查。
    图标

     

     员工类型:
    通过流程变量 userType 来表示,如果等于 1 表示普通员工,如果等于 2 表示领导

     

     

     //1.部署流程定义 
        public static void main(String[] args) {
            //1.创建ProcessEngine对象
            ProcessEngine processEngine = ProcessEngines.getDefaultProcessEngine();
    
            //2.得到RepositoryService实例
            RepositoryService repositoryService = processEngine.getRepositoryService();
    
            //3.进行部署
            Deployment deployment = repositoryService.createDeployment()
                    .addClasspathResource("diagram/day05/examine.bpmn")  //添加bpmn资源
                    //.addClasspathResource("diagram/day05/examine.png")
                    .name("体检流程")
                    .deploy();
    
            //4.输出部署的一些信息
            System.out.println(deployment.getName());
            System.out.println(deployment.getId());
        }
      //2.启动流程实例
       public static void main(String[] args) {
                //1.得到ProcessEngine对象
                ProcessEngine processEngine = ProcessEngines.getDefaultProcessEngine();
    
                //2.得到RunService对象
                RuntimeService runtimeService = processEngine.getRuntimeService();
    
            Integer userType = 2;//代表管理者
            Map<String,Object> map = new HashMap<>();
            map.put("userType",userType);//流程变量赋值
    
                //3.创建流程实例  流程定义的key需要知道 holiday
                ProcessInstance processInstance = runtimeService.startProcessInstanceByKey("examine",map);
    
    
                //4.输出实例的相关信息
                System.out.println("流程定义ID"+processInstance.getProcessDefinitionId());//holiday:1:4
                System.out.println("流程实例ID"+processInstance.getId());//2501
        }

    先走到汇聚结点的分支,要等待其它分支走到汇聚。
    等所有分支走到汇聚,包含网关就执行完成。
    包含网关执行完成,分支和汇聚就从 act_ru_execution 删除。
    小结:在分支时,需要判断条件, 符合条件的分支,将会执行,符合条件的分支最终才进行汇聚。

    总结

    如何使用 activiti 开发?
    第一步:部署 activiti 的环境。
    环境包括: jar 包和数据库(25 张表)
    业务系统通过 spring activiti 整合进行开发。
    第二步:使用 activiti 提供流程设计器(和 idea eclipse 集成的 designer)工具进行流程定义
    流程定义生成两个文件: .bpmn .png(不是必须的)。
    第三步;将流程定义文件部署到 activiti 的数据库
    SELECT * FROM act_re_deployment #流程定义部署表
    一次部署插入一条记录,记录流程定义的部署信息
    SELECT * FROM act_re_procdef #流程定义表
    一次部署流程定义信息,如果一次部署两个流程定义,插入两条记录
    建议:一次部署只部署一个流程定义,这样 act_re_deployment act_re_procdef 一对一关系
    常用两个方法:单个文件部署和 zip 文件部署。
    建议单个文件部署。
    第四步: 启动一个流程实例
    业务系统就可以按照流程定义去执行业务流程,执行前需要启动一个流程实例
    根据流程定义来启动一个流程实例。
    指定一个流程定义的 key 启动一个流程实例, activiti 根据 key 找最新版本的流程定义。
    指定一个流程定义的 id 启动一个流程实例。
    启动一个实例需要指定 businesskey(业务标识), businessKey activiti 和业务系统整合时桥梁。
    比如: 请假流程, businessKey 就是请假单 id
    启动一个实例还可以指定流程变量,流程变量是全局变量(生命期是整个流程实例,流程实例结束,
    变量就消失)
    第五步:查询待办任务
    查询个人任务:使用 taskService,根据 assignee 查询该用户当前的待办任务。
    查询组任务:使用 taskService,根据 candidateuser 查询候选用户当前的待办组任务。
    第六步:办理任务
    办理个人任务:调用 taskService complete 方法完成任务。
    如果是组任务,需要先拾取任务,调用 taskService claim 方法拾取任务,拾取任务之后组任务就
    变成了个人任务(该任务就有负责人)。
    网关:
    排他网关:任务执行之后的分支,经过排他网关分支只有一条有效。
    并行网关:任务执行后,可以多条分支,多条分支总会汇聚,汇聚完成,并行网关结束。
    包含网关:是排他网关和并行网关结合体。
     

  • 相关阅读:
    依靠MySQL(frm、MYD、MYI)数据文件恢复
    Centos7.4.1708安装Jumpserver
    Ubuntu16.04安装vmware pro 15激活码
    AIX系统命令
    virtualbox迁移虚拟机
    RedHat Enterprise7 搭建ISCSI
    RedHat Enterprise7 修改为CentOS的yum源
    关于Server2008 R2日志的查看
    Centos7.4.1708搭建syslog服务
    ElasticSearch第四步-查询详解
  • 原文地址:https://www.cnblogs.com/dalianpai/p/11905266.html
Copyright © 2020-2023  润新知