ICode9

精准搜索请尝试: 精确搜索
首页 > 其他分享> 文章详细

工作流学习日志 -(Activiti7进阶)

2021-04-13 10:33:39  阅读:570  来源: 互联网

标签:task 进阶 实例 流程 任务 Activiti7 日志 processEngine id


工作流学习日志 -(Activiti7进阶)

文章目录


前言

开发OA人力资源管理系统时在人员调动时、请假审批等需要使用到工作流,以此作为学习契机。
工作流学习日志(基础-概念、基本api使用)


一、流程实例

流程实例(ProcessInstance)通过流程定义(ProcessDefinition)创建,代表了流程定义的实例。

1. 添加业务标识(BusinessKey)

BusinessKey:业务标识,通常是业务表的主见id,业务标识和流程实例一一对应。存储业务标识就是根据业务标识来关联查询业务系统的数据。其中的业务和流程是分开的,activiti主要是控制流程,而不是控制所有的的业务,所以需要使用有一张其他的表表示业务,最后可以进行关联。

例如:出差流程是一个流程实例,可以将出差单(业务)id作为BusinessKey存储到activiti中。将来查询activiti流程实例的信息就可以获取到对应的出差单(业务)id从而关联到业务系统数据库中的出差单信息。

添加businessKey并启动流程实例代码:

//1.获取流程引擎
ProcessEngine processEngine = ProcessEngines.getDefaultProcessEngine();

//2.获取RuntimeService
RuntimeService runtimeService = processEngine.getRuntimeService();

//3.添加businessKey(可以指某用户Id,开启一个新的工作流程 例如为1001)
ProcessInstance processInstance = runtimeService
        .startProcessInstanceByKey("myBusinessTrip", "1001");

System.out.println("流程业务名称="+processInstance.getBusinessKey());

添加成功后可以在Activiti数据库act_ru_execution中查看到存储的businessKey。

查询关联的businessKey:

// 获取processEngine 
ProcessEngine processEngine = ProcessEngines.getDefaultProcessEngine(); 
// 获取TaskService 
TaskService taskService = processEngine.getTaskService(); 
// 获取RuntimeService 
RuntimeService runtimeService = processEngine.getRuntimeService(); 
// 查询流程定义的对象 
Task task = taskService.createTaskQuery() 
	.processDefinitionKey("myEvection1") 
	.taskAssignee("张三") .singleResult(); 
// 使用task对象获取实例id 
String processInstanceId = task.getProcessInstanceId(); 
// 使用实例id,获取流程实例对象 
ProcessInstance processInstance = runtimeService
	.createProcessInstanceQuery() 
	.processInstanceId(processInstanceId) 
	.singleResult(); 
// 使用processInstance,得到 businessKey 
String businessKey = processInstance.getBusinessKey(); 
System.out.println("businessKey=="+businessKey); }

2. 查询流程实例

流程在运行的过程中可以查询流程实例的状态,当前运行节点等信息

// 流程定义key 
String processDefinitionKey = "evection"; ProcessEngine processEngine = ProcessEngines.getDefaultProcessEngine(); 
// 获取RunTimeService 
RuntimeService runtimeService = processEngine.getRuntimeService(); 
List<ProcessInstance> list = runtimeService .createProcessInstanceQuery()
 .processDefinitionKey(processDefinitionKey)// .list();
 
for (ProcessInstance processInstance : list) { 
	System.out.println("----------------------------"); 
	System.out.println("流程实例id:" + processInstance.getProcessInstanceId()); 
	System.out.println("所属流程定义id:" + processInstance.getProcessDefinitionId()); 
	System.out.println("是否执行完成:" + processInstance.isEnded()); 
	System.out.println("是否暂停:" + processInstance.isSuspended()); 
	System.out.println("当前活动标识:" + processInstance.getActivityId()); 
}

3. 挂起、激活流程实例

某些情况下流程变更需要当前运行的流程暂停而不是直接删除,那么可以将流程进行挂起,流程挂起后将不能继续执行流程,需要激活后才能继续执行。

例如:当审批员有变更的时候,那么审批的流程需要进行暂停,待审批员变更完成后才能继续进行执行;或者在非工作日时不能进行流程执行操作。

①. 全部流程实例挂起、激活

  • 将整个流程定义为挂起状态,该流程定义下的所有流程实例将全部挂起。
  • 流程定义为挂起状态后,该流程定义将不允许启动新的流程实例,同时该流程定义定义下的所有流程实例将全部挂起暂停执行。

代码如下:

//1.获取流程引擎
ProcessEngine processEngine = ProcessEngines.getDefaultProcessEngine();
//2.获取RepositoryService
RepositoryService repositoryService = processEngine.getRepositoryService();
//3.获取到流程定义的查询对象
ProcessDefinition processDefinition = repositoryService.createProcessDefinitionQuery()
        .processDefinitionKey("myBusinessTrip")
        .singleResult();
//4.查询processDefinition流程定义的状态
boolean suspended = processDefinition.isSuspended();
//5.如果挂起,那么激活流程定义
String definitionId = processDefinition.getId();
if (suspended) {
    //参数1:流程定义id,参数2:流程是否激活,参数3:流程激活时间
    repositoryService.activateProcessDefinitionById(definitionId,true,null);
    System.out.println("流程定义id为:"+definitionId+"激活成功");
} else{
    //6.如果正在活动,那么将流程定义挂起
    //参数1:流程定义id,参数2:流程是否挂起,参数3:流程挂起时间
    repositoryService.suspendProcessDefinitionById(definitionId,true,null);
    System.out.println("流程定义id为:"+definitionId+"挂起成功");
}

②. 单个流程实例挂起、激活

操作流程实例的对象,针对单个流程执行挂起操作,某个流程实例挂起则此流程不再继续进行执行,完成该流程实例的当前任务将报异常。

代码如下:

//1.获取processEngine 引擎
ProcessEngine processEngine = ProcessEngines.getDefaultProcessEngine();
//2.获取runtimeService
RuntimeService runtimeService = processEngine.getRuntimeService();
//3.根据processInstanceId获取指定的流程实例查询对象
ProcessInstance processInstance = runtimeService.createProcessInstanceQuery()
        .processInstanceId("2501")
        .singleResult();
//4.根据processInstance流程实例获取其状态
boolean suspended = processInstance.isSuspended();
//5.如果为挂起状态,那么激活
String instanceId = processInstance.getId();
if(suspended){
    runtimeService.activateProcessInstanceById(instanceId);
    System.out.println("流程实例对象Id="+instanceId+",已经激活");
}else {
    //6.如果流程实例的状态为激活状态,那么将其挂起
    runtimeService.suspendProcessInstanceById(instanceId);
    System.out.println("流程实例对象Id="+instanceId+",已经挂起");
}
  • 测试如果任务实例被挂起之后那么是否可以完成任务
  • 如果任务激活状态:那么执行成功
  • 如果为挂起状态:抛出异常Cannot complete a suspended task
//1.获取流程引擎processEngine
ProcessEngine processEngine = ProcessEngines.getDefaultProcessEngine();
//2.获取对应的taskService
TaskService taskService = processEngine.getTaskService();
//3.根据taskService获取对应的流程任务查询
Task task = taskService.createTaskQuery()
        .processInstanceId("2501")//根据流程实例id进行查询
        .taskAssignee("lisi")
        .singleResult();

System.out.println("流程实例id="+task.getProcessInstanceId());
System.out.println("任务Id="+task.getId());
System.out.println("任务负责人="+task.getAssignee());
System.out.println("任务名称="+task.getName());

//4.根据taskId完成对应的任务
taskService.complete(task.getId());
}

二、个人任务

1. 分配任务负责人

①. 固定分配方式

直接在BPMN editor中将property为Assignee的值value设置为固定值,例:张三
在这里插入图片描述

②. 表达式分配

表达式分配可以解决固定分配情况下的assignee无法动态获取值的问题。

UEL表达式

Activiti使用UEL表达式,UEL是java EE6规范的一部分,UEL(Unified Expression Language)即统一表达式语言,activiti支持两个UEL表达式:UEL-value和UEL-method。

1)UEL-value:
可以直接设置一个变量assignee0,该变量为activiti的一个流程变量。
在这里插入图片描述
也可以通过调用某个类中的属性获取值,例如user是activiti中一个流程变量,user.assignee表示通过调用user的getter方法获取值。
在这里插入图片描述
2)UEL-method方式
UserBean是spring容器中的一个bean,表示调用该bean的getUserId()方法。
在这里插入图片描述
3)UEL-method与UEL-value结合

再比如: ${ldapService.findManagerForEmployee(emp)} ldapService 是 spring 容器的一个 bean, findManagerForEmployee 是该 bean 的一个方法,emp 是 activiti 流程变量, emp 作为参数传到
ldapService.findManagerForEmployee 方法中。

4)其他

表达式支持解析基础类型、 bean、 list、 array 和 map,也可作为条件判断。 如下: ${order.price > 100 && order.price < 250}

在启动流程实例时设置流程变量,如下:

//1.获取流程引擎
ProcessEngine processEngine = ProcessEngines.getDefaultProcessEngine();
//2.获取runtimeService
RuntimeService runtimeService = processEngine.getRuntimeService();
//3.启动定义的流程,startProcessInstanceByKey两参数,一:流程实例的key,二:流程中定义的负责人名称使用map进行封装
//使用map封装负责人的值,可以在act_ru_variable数据表中查看设置的map值
Map map = new HashMap();
map.put("assignee0","张三");
map.put("assignee1","李四");
map.put("assignee2","王五");
map.put("assignee3","赵六");
runtimeService.startProcessInstanceByKey("myProcess_1",map);
//4.输出
System.out.println("流程启动成功="+processEngine.getName());

执行成功后可以在数据库act_ru_variable表中看到刚才map中的数据

:由于使用了表达式分配,必须保证在任务执行过程表达式执行成功,比如: 某个任务使用了表达式${order.price > 100 && order.price < 250},当执行该任务时必须保证 order 在 流程变量中存在,否则 activiti 异常。

③. 监听器分配

Activiti中也有内置的监听器可以用来完成流程中的业务。可以使用任务监听器(Task Listener)指定负责人,那么在流程设计时可以不需要指定assignee。任务监听器是发生对应的任务相关事件时执行自定义java逻辑或表达式。

在这里插入图片描述
Event事件中包含了4个触发事件:

  1. create:任务创建后触发
  2. Assignment:任务分配后触发
  3. Delete:任务完成后触发
  4. ALL:所有事件发生都触发

代码如下:(定义任务监听类必须实现org.activiti.engine.delegate.TaskListener接口)

public class TestListener implements TaskListener {

    @Override
    public void notify(DelegateTask delegateTask) {
        //判断
        if("创建申请".equals(delegateTask.getName()) && "create".equals(delegateTask.getEventName())){
            delegateTask.setAssignee("张三");
        } 
    }
    
}

:使用监听器分配的方式,按照监听事件去执行监听类的notify方法,如果不能正常执行也会影响任务的执行。

2. 查询任务

查询任务负责人的待办任务,代码如下:

//选择负责人
String assignee = "zhangsan";

//获取到processEngine
ProcessEngine processEngine = ProcessEngines.getDefaultProcessEngine();

//获取到taskService
TaskService taskService = processEngine.getTaskService();

//使用TaskService根据流程的key和任务负责人查询任务
List<Task> list = taskService.createTaskQuery()
        .processDefinitionKey("myBusinessTrip")//流程的key
        .taskAssignee(assignee)//查询该负责人的任务
        .list();

//遍历获取任务内容
for (Task task : list) {
    System.out.println("流程实例:"+task.getProcessInstanceId());
    System.out.println("任务id:"+task.getId());
    System.out.println("任务负责人:"+task.getAssignee());
    System.out.println("任务名称:"+task.getName());
}

代码如下(示例):

data = pd.read_csv(
    'https://labfile.oss.aliyuncs.com/courses/1283/adult.data.csv')
print(data.head())

3. 办理任务

:实际应用中,完成任务前需要检验任务的负责人是否具有该任务的办理权限

String assignee = "zhangsan";

//1.创建processEngine
ProcessEngine processEngine = ProcessEngines.getDefaultProcessEngine();

//2.获取到TaskService
TaskService taskService = processEngine.getTaskService();

//完成任务前,需要检验该负责人是否可以完成当前任务
//检验方法:根据任务的id和任务负责人查询当前任务,如果查到该用户有权限,那么就完成。

//3.使用TaskService中的方法(使用任务id)完成任务
//taskService.complete("2505");

//4.根据流程的key以及负责人名称获取对应的任务id,动态进行完成任务
Task task = taskService.createTaskQuery()
        .processDefinitionKey("myBusinessTrip")//流程的key
        .taskAssignee(assignee)//任务负责人名称
        .singleResult();//获取单个task任务

System.out.println("任务的id="+task.getProcessDefinitionId());
System.out.println("任务id="+task.getId());
System.out.println("任务的名称="+task.getName());
System.out.println("任务的负责人="+task.getAssignee());

//5.动态获取任务id完成任务
taskService.complete(task.getId());

三. 流程变量

1. 概念

流程变量的activiti中是一个非常重要的角色,流程运转有时需要靠流程变量,业务系统和activiti结合时少不了流程变量,流程变量就是activiti在管理工作流时根据管理需要而设置的变量。比如:在出差申请流程流转时如果出差天数大于3天那么由总经理审核,否则由部门经理进行审核,在这里的出差天数就可以设置为流程变量,在流程运转时使用。

:流程变量中可以存储业务数据,可以通过activiti的api查询流程变量从而实现查询业务流程,单一一般不这样做,因为业务数据查询由业务系统负责,activiti设置流程变量是为了流程执行需要而创建。

2. 流程变量类型

:如果需要将pojo存储在流程变量中,那么必须实现序列化接口serializable。为了防止由于新增字段无法反序列化,需要生成serialVersionUID。

类型名称:

  • string
  • integer
  • short
  • long
  • double
  • Boolean
  • date
  • binary
  • serializable

3. 流程变量作用域

流程变量作用域可以是一个流程实例(processInstance)、任务(task)、执行实例(execution)

①. global变量

流程变量的默认作用域是流程实例。当一个流程变量的作用域为流程实例时,可以称为 global 变量

如: Global变量:userId(变量名)、zhangsan(变量值)
global 变量中变量名不允许重复,设置相同名称的变量,后设置的值会覆盖前设置的变量值。

②. local变量

任务和执行实例仅仅是针对一个任务和一个执行实例范围,范围没有流程实例大, 称为 local 变量。

Local 变量由于在不同的任务或不同的执行实例中,作用域互不影响,变量名可以相同没有影响。Local 变量名也可以和 global 变量名相同,没有影响。

4. 流程变量的使用方法

①. 在属性上使用UEL表达式

在assignee设置UEL表达式设置为任务的负责人

②. 在连线上使用UEL表达式

在连线上设置UEL表达式,可以决定流程的走向,UEL表达式结果为布尔类型。如图:
在这里插入图片描述

③. 设置global变量

通过设置global变量控制流程走向

在部门经理审核前设置流程变量,变量值为出差单信息(包括出差天数),部门经理审核后可以根据流程变量的值决定流程走向。

在设置流程变量时,可以在启动流程时设置,也可以在任务办理时设置

创建POJO对象

/**
 * 流程封装的业务类
 * 出差申请pojo
 */
public class BusinessTrip implements Serializable {
    /**
     * 主键id
     */
    private Long id;
    /**
     * 出差申请单名称
     */
    private String businessName;
    /**
     * 出差天数
     */
    private Double num;
    /**
     * 预计开始时间
     */
    private Date beginDate;
    /**
     * 预计结束时间
     */
    private Date endDate;
    /**
     * 目的地
     */
    private String destination;
    /**
     * 出差事由
     */
    private String reason;

    public Long getId() {
        return id;
    }

    public void setId(Long id) {
        this.id = id;
    }

    public String getBusinessName() {
        return businessName;
    }

    public void setBusinessName(String businessName) {
        this.businessName = businessName;
    }

    public Double getNum() {
        return num;
    }

    public void setNum(Double num) {
        this.num = num;
    }

    public Date getBeginDate() {
        return beginDate;
    }

    public void setBeginDate(Date beginDate) {
        this.beginDate = beginDate;
    }

    public Date getEndDate() {
        return endDate;
    }

    public void setEndDate(Date endDate) {
        this.endDate = endDate;
    }

    public String getDestination() {
        return destination;
    }

    public void setDestination(String destination) {
        this.destination = destination;
    }

    public String getReason() {
        return reason;
    }

    public void setReason(String reason) {
        this.reason = reason;
    }
}

启动流程时设置变量
在启动流程时设置流程变量,变量的作用域是整个流程实例。通过Map设置流程变量,map中可以设置多个变量,key就是流程变量的名字

流程变量作用域是一个流程实例,流程变量使用Map存储,同一个流程实例设置变量map中key相同,后者覆盖前者。

        //1.创建流程引擎
        ProcessEngine processEngine = ProcessEngines.getDefaultProcessEngine();

        //2.获取runtimeService
        RuntimeService runtimeService = processEngine.getRuntimeService();

        //获取到流程的key
        String processInstanceKey = "buiness-global1";
        //设置任务负责人参数
        BusinessTrip businessTrip = new BusinessTrip();
        businessTrip.setNum(3d);
        Map variable = new HashMap();
        variable.put("businessTrip",businessTrip);
        variable.put("assignee0","张三员工1");
        variable.put("assignee1","李四部门经理1");
        variable.put("assignee2","王五总经理1");
        variable.put("assignee3","赵六财务1");

        //3.根据processInstance的id以及传入的参数进行开启流程
        ProcessInstance processInstance = runtimeService
                .startProcessInstanceByKey(processInstanceKey, variable);

        //4.输出
        System.out.println("流程实例名称="+processInstance.getName());
        System.out.println("流程定义id=="+processInstance.getProcessDefinitionId());

任务办理时设置变量

在完成任务时设置流程变量,该流程变量只有在该任务完成后其他结点才可以使用该变量,它的作用域是整个流程实例,如果设置的流程变量的key在流程实例中已存在相同的名字,则后设置的变量替换前边设置的变量。

//1.获取流程引擎
ProcessEngine processEngine = ProcessEngines.getDefaultProcessEngine();

//2.获取到taskService
TaskService taskService = processEngine.getTaskService();

/*//3.获取需要进行查询的参数67501
String processInstanceId = "55001";
String assignee = "赵六财务";*/

String processInstanceId = "85001";
String assignee = "赵六财务1";

BusinessTrip businessTrip = new BusinessTrip();
businessTrip.setNum(2d);
Map<String, Object> map = new HashMap<>();
map.put("businessTrip",businessTrip);

//4.创建任务查询
Task task = taskService.createTaskQuery()
        .processInstanceId(processInstanceId)
        .taskAssignee(assignee)
        .singleResult();

if (task != null){
    //5.如果task不为空,那么完成任务。
    taskService.complete(task.getId(),map);
    System.out.println("任务执行完成");
}

通过当前流程实例设置

通过流程实例id设置全局变量,该流程实例必须未执行完成

// 当前流程实例执行 id,通常设置为当前执行的流程实例 
String executionId="2601"; 
// 获取processEngine 
ProcessEngine processEngine = ProcessEngines.getDefaultProcessEngine(); 
// 获取RuntimeService 
RuntimeService runtimeService = processEngine.getRuntimeService(); 
// 创建出差pojo对象 
Evection evection = new Evection(); 
// 设置天数 
evection.setNum(3d); 
// 通过流程实例 id设置流程变量
runtimeService.setVariable(executionId, "evection", evection); 
// 一次设置多个值 
// runtimeService.setVariables(executionId, variables)

  • 如果UEL表达式中流程变量名不存在则报错
  • 如果UEL表达式中流程变量值为空null,流程不安UEL表达式去执行,而流程结束。
  • 如果UEL表达式都不符合条件,流程结束
  • 如果连线不设置条件,会走flow需要小的那条线

四. 组任务

1. 需求

在流程定义中在任务结点的 assignee 固定设置任务负责人,在流程定义时将参与者固定设置在.bpmn 文件中,如果临时任务负责人变更则需要修改流程定义,系统可扩展性差。

针对这种情况可以给任务设置多个候选人,可以从候选人中选择参与者来完成任务。

2. 设置任务候选人

在流程图中任务节点的配置中设置candidate-users(候选人),多个候选人之间用逗号分开。
在这里插入图片描述

3. 组任务

组任务办理流程

①. 查询组任务

指定候选人,查询该候选人当前的待办任务

//设置需要获取到的任务查询的条件
String processDefinitionKey = "testcandidate";
String candidateUser = "王副部门经理";
//1.获取流程引擎
ProcessEngine processEngine = ProcessEngines.getDefaultProcessEngine();
//2.获取taskService
TaskService taskService = processEngine.getTaskService();
//3.使用service获取到任务查询list
List<Task> list = taskService.createTaskQuery()
        .processDefinitionKey(processDefinitionKey)
        .taskCandidateUser(candidateUser)
        .list();
//4.输出信息
for (Task task : list) {
    System.out.println("----------------------------");
    System.out.println("流程实例id:" + task.getProcessInstanceId());
    System.out.println("任务id:" + task.getId());
    System.out.println("任务负责人:" + task.getAssignee());
    System.out.println("任务名称:" + task.getName());
}

②. 拾取(claim)任务

该任务的所有候选人都能拾取。将候选人的组任务变成个人任务,原来候选人就变成该任务的负责人。

//1.设置需要获取的任务查询条件
String taskId = "105002";
String candidateUser = "王副部门经理";
//2.获取流程引擎
ProcessEngine processEngine = ProcessEngines.getDefaultProcessEngine();
//3.获取taskService
TaskService taskService = processEngine.getTaskService();
//4.创建任务查询
Task task = taskService.createTaskQuery()
        .taskId(taskId)
        .taskCandidateUser(candidateUser)
        .singleResult();
//5.如果该任务查询出来存在
if(task != null){
    //根据任务的id以及拾取候选人为负责人
    taskService.claim(task.getId(),candidateUser);
    System.out.println("任务id--"+taskId+"--的候选人--"+candidateUser+"拾取任务完成");
}

如果拾取后不想办理该任务,需要将已经拾取的个人任务归还到组里,将个人任务变成了组任务。

//1.设置需要获取的任务查询条件
String taskId = "105002";
String assignee = "王副部门经理";
//2.获取流程引擎
ProcessEngine processEngine = ProcessEngines.getDefaultProcessEngine();
//3.获取taskService
TaskService taskService = processEngine.getTaskService();
//4.创建任务查询
Task task = taskService.createTaskQuery()
        .taskId(taskId)
        .taskAssignee(assignee)
        .singleResult();
//5.如果该任务查询出来存在
if(task != null){
    //根据任务的id设置负责人为null即为归还负责人
    taskService.setAssignee(task.getId(),null);
    System.out.println("任务id--"+taskId+"--的负责人--"+assignee+"归还任务完成");
}

任务的交接,实质上就是讲assignee进行修改

String taskId = "105002";
String assignee = "王副部门经理";
String candidateUser = "李部门经理";
//1.获取流程引擎
ProcessEngine processEngine = ProcessEngines.getDefaultProcessEngine();
//2.获取taskService
TaskService taskService = processEngine.getTaskService();
//3.根据taskService获取到任务查询
Task task = taskService.createTaskQuery()
        .taskId(taskId)
        .taskAssignee(assignee)
        .singleResult();
//4.如果能够查询出来任务,那么就将任务的负责人进行交接
if(task != null){
    taskService.setAssignee(task.getId(),candidateUser);
    System.out.println("任务id--"+taskId+"--的负责人--"+assignee+"交接任务给"+candidateUser+"完成");
}

③. 查询个人任务

查询方法同个人人物部分,根据assignee查询用户负责的个人任务。

④. 办理个人任务

同以前的完成任务

五. 网关

网管主要是用来控制流程的流向。我们在前面学习了使用UEL表达式的方式直接在连线上来控制流程,但该方法并有时候会造成创建两次流程实例的情况,导致不能按照我们设定的要求进行走向;如果条件都不满足,流程就结束了(异常结束)。所以一般还需要网关进行控制流程走向。
在这里插入图片描述

1. 排他网关ExclusiveGateway

①. 概念

排他网关,用在流程中实现决策,当流程执行了该网关,所有的分支会判断条件是否为true。如果为true则执行该分支。

  • 排他网关只会选择一个为true的分支执行,如果有两个分支的条件都是true,那么排他网关会选择id值较小的一条分支进行执行。
  • 如果排他网关控制的所有分支都不满足true,那么系统会跑出异常。

②. 用法

用法和以前一样,部署、开启流程实例、完成执行实例。

图片如下:
在这里插入图片描述

2. 并行网关ParallelGateway

并行网关允许多个分支并行执行,也可以将多条分支汇聚到一起,并行网关的功能基于进入和外出顺序流的:

  • fork分支:通过并行网关后将一条流程分成多条分支成外出顺序流,
  • join汇聚:所有到达并行网关后,再次等待的进入分支,直到所有进入顺序流的分支都到达之后,流程就会汇聚网关。

:如果同一个并行网关有多个进入和多个外出顺序流,他就同时具有了分支和汇聚的功能,这时,网关会先汇聚所有进入的顺序流,然后再切分成多个并行分支。与其他网关主要区别是,并行网关不会解析条件,即使顺序流定义了条件,也会忽略执行。
在这里插入图片描述

3. 包含网关InclusiveGetaway

包含网关可以看做排他网关和并行网关的结合体。

可以和排他网关一样,在顺序流上定义条件,包含网关会解析他们,但是主要区别是包含网关可以选择多与一条顺序流,这和并行网关一样。

如图所示:无论什么条件都会进入到人是审批中。接着从技术经理或项目经理满足条件的一个进行汇聚。
在这里插入图片描述

总结

提示:这里对文章进行总结:
例如:以上就是今天要讲的内容,本文仅仅简单介绍了pandas的使用,而pandas提供了大量能使我们快速便捷地处理数据的函数和方法。

标签:task,进阶,实例,流程,任务,Activiti7,日志,processEngine,id
来源: https://blog.csdn.net/weixin_46621774/article/details/115612158

本站声明: 1. iCode9 技术分享网(下文简称本站)提供的所有内容,仅供技术学习、探讨和分享;
2. 关于本站的所有留言、评论、转载及引用,纯属内容发起人的个人观点,与本站观点和立场无关;
3. 关于本站的所有言论和文字,纯属内容发起人的个人观点,与本站观点和立场无关;
4. 本站文章均是网友提供,不完全保证技术分享内容的完整性、准确性、时效性、风险性和版权归属;如您发现该文章侵犯了您的权益,可联系我们第一时间进行删除;
5. 本站为非盈利性的个人网站,所有内容不会用来进行牟利,也不会利用任何形式的广告来间接获益,纯粹是为了广大技术爱好者提供技术内容和技术思想的分享性交流网站。

专注分享技术,共同学习,共同进步。侵权联系[81616952@qq.com]

Copyright (C)ICode9.com, All Rights Reserved.

ICode9版权所有