Flowable进阶学习(四)任务分配与流程变量
创始人
2024-05-16 01:32:42
0

文章目录

  • 一、任务分配
    • 1. 固定分配
    • 2. 表达式分配
      • 值表达式:Value expression
      • 方法表达式:Method expression
    • 3. 监听器分配
  • 二、流程变量
    • 1. 全局变量
    • 2. 局部变量
    • 案例:

一、任务分配

1. 固定分配

在绘制流程图时或在流程文件中通过Assignee来指定的方式。
在这里插入图片描述在这里插入图片描述

2. 表达式分配

Flowable使用UEL(Unified Expression Language)进行表达式解析。Flowable支持两种UEL表达式:UEL-value和UEL-method。

值表达式:Value expression

解析为一个值,默认情况下,所有流程变量都可以使用。所有的SpringBean也可以使用在表达式里。eg:${myVar}${myBean.myProperty}

  1. 创建流程文件
    在这里插入图片描述在这里插入图片描述

  2. 启动一个流程实例

    /**
    * 启动流程实例
    */
    @Test
    public void test2_run_proc() {Map params = new HashMap<>();params.put("assignee0", "whx");params.put("assignee1", "huathy");ProcessInstance processInstance = processEngine.getRuntimeService().startProcessInstanceById("qjlc23:1:4", params);System.out.println("processInstance.getName() = " + processInstance.getName());Map processVariables = processInstance.getProcessVariables();for (String key : processVariables.keySet()) {System.out.println("params => " + key + "~" + processVariables.get(key));}
    }
    
  3. 通过查看表数据变动,可以看到ASSIGNEE_的值为whx,可见表达式已经被解析。
    在这里插入图片描述在这里插入图片描述
    在这里插入图片描述

    -- ACT_RU_TASK
    ID_ |REV_|EXECUTION_ID_|PROC_INST_ID_|PROC_DEF_ID_|TASK_DEF_ID_|SCOPE_ID_|SUB_SCOPE_ID_|SCOPE_TYPE_|SCOPE_DEFINITION_ID_|NAME_ |PARENT_TASK_ID_|DESCRIPTION_|TASK_DEF_KEY_                           |OWNER_|ASSIGNEE_|DELEGATION_|PRIORITY_|CREATE_TIME_           |DUE_DATE_|CATEGORY_|SUSPENSION_STATE_|TENANT_ID_|FORM_KEY_|CLAIM_TIME_|IS_COUNT_ENABLED_|VAR_COUNT_|ID_LINK_COUNT_|SUB_TASK_COUNT_|
    ----+----+-------------+-------------+------------+------------+---------+-------------+-----------+--------------------+------+---------------+------------+----------------------------------------+------+---------+-----------+---------+-----------------------+---------+---------+-----------------+----------+---------+-----------+-----------------+----------+--------------+---------------+
    7507|   1|7504         |7501         |qjlc23:1:4  |            |         |             |           |                    |提交请假申请|               |            |sid-04330515-D69E-4BA7-94FE-492984A4E5A0|      |whx      |           |       50|2023-01-21 23:41:58.912|         |         |                1|          |         |           |                1|         0|             0|              0|
    
  4. 完成流程实例

    /*** 完成任务*/
    @Test
    public void test2_complete_proc() {TaskService taskService = processEngine.getTaskService();Task task = taskService.createTaskQuery().processInstanceId("7501").taskAssignee("whx").singleResult();taskService.complete(task.getId());
    }
    
  5. 查看数据库ACT_RU_TASK表(可见节点名称与任务指派人已变化) 在这里插入图片描述

方法表达式:Method expression

调用一个方法,可以带参或者不带。当调用无参方法的时候,要确保方法名后面添加空括号(避免与值表达式混淆)。传递的参数可以是字面值,也可以是表达式,会进行自动解析。eg:

${printer.print()}
${myBean.addNewOrder('orderName')}
${myBean.do(myvar, execution)}

myBean是spring容器中的一个Bean对象,表示调用bean的addNewOrder方法。

3. 监听器分配

可以使用监听器来完成很多flowable的流程业务。
我们在此处使用监听器来完成负责人的指定,那么我们在流程设计的时候就不需要指定assignee。

  1. 创建一个监听器类
package org.flowable.listener;import org.flowable.engine.delegate.TaskListener;
import org.flowable.task.service.delegate.DelegateTask;/*** @author Huathy* @date 2023-01-22 12:28* @description 自定义监听器*/
public class MyTaskListener implements TaskListener {/*** 监听器触发的方法** @param delegateTask*/@Overridepublic void notify(DelegateTask delegateTask) {System.out.println("==》MyTaskListener监听器触发");System.out.println("delegateTask.getName() = " + delegateTask.getName());// 当满足条件则设置任务分配人为huathy否则为whxif ("提交请假申请".equals(delegateTask.getName()) && "create".equalsIgnoreCase(delegateTask.getEventName())) {delegateTask.setAssignee("huathy");} else {delegateTask.setAssignee("whx");}}
}
  1. 设计流程,导出流程文件
    在这里插入图片描述3. 部署流程
    @Test
    public void test1_deploy() {RepositoryService repositoryService = processEngine.getRepositoryService();Deployment deploy = repositoryService.createDeployment().addClasspathResource("请假流程23-02.bpmn20.xml").name("测试请假流程2023-02").deploy();System.out.println("deploy.getName() = " + deploy.getName());System.out.println("deploy.getId() = " + deploy.getId());
    }
    

二、流程变量

流程实例按步骤执行时,需要使用一些数据。在Flowable中,这些数据称作变量(variable),并存储到数据库中。变量可以用在表达式中(例如在排他网关中用于选择正确的出口路径),也可以在Java服务任务(service task)中用于调用外部服务(例如为服务提供输入或结果存储),等等。
咯iu成实例可以持有变量(称作流程变量process variables),用户任务以执行(excutions)——流程当前活动节点的指针——也可以持有变量。流程实例可以持有任意数量的变量,每个变量存储为ACT_RU_VARIABLE数据库表的一行记录。
所有的startProcessInstanceXXX方法都有一个可选参数,用于在流程实例创建及启动时设置变量。eg:在RuntimeService中:

ProcessInstance startProcessInstanceById(String processDefinitionId, Map variables);

也可以在流程执行中加入变量,eg:RuntimeService

void setVariable(String executionId, String variableName, Object value);
void setVariableLocal(String executionId, String variableName, Object value);
void setVariables(String executionId, Map variables);
void setVariablesLocal(String executionId, Map variables);

实例关系:通常情况下没有子流程的,流程实例与执行实例一一对应。
实例关系

1. 全局变量

流程变量的默认作用域是流程实例。当一个流程变量的作用域为流程实例的时候,可以称为global变量。eg:userId。
global变量中变量名不可重复,设置相同名称的变量,新值会覆盖旧值。

2. 局部变量

任务和执行实例仅仅是针对要给任务和一个执行实例的范围,范围没有流程实例大,成为local变量。
local变量由于在不同的任务或不同的执行实例中,作用域互不影响,变量名可以相同。local变量名也可以与global变量名相同。

案例:

员工创建出差申请单,由上级领导审批通过后,根据天数判断,3天内可由财务审批通过,3天以上需要流转到总经理审批,再由财务审批。

员工出差流程图

package com.hx;import org.flowable.engine.*;
import org.flowable.engine.history.HistoricActivityInstance;
import org.flowable.engine.impl.cfg.StandaloneInMemProcessEngineConfiguration;
import org.flowable.engine.repository.Deployment;
import org.flowable.engine.runtime.ProcessInstance;
import org.flowable.task.api.Task;
import org.junit.Before;
import org.junit.Test;import java.util.HashMap;
import java.util.List;
import java.util.Map;/*** @author Huathy* @date 2022-05-12 23:40* @description* 1.首先部署流程   2.运行流程实例   3.提交出差申请   4.更新流程变量* 5.完成上级审批   6.观察数据库变化*/
public class Test6_Demo1_Evection {ProcessEngineConfiguration configuration = null;ProcessEngine processEngine = null;@Beforepublic void before() {// 通过 ProcessEngineConfiguration 构建我们需要的 ProcessEngineconfiguration = new StandaloneInMemProcessEngineConfiguration();// 配置相关数据库连接configuration.setJdbcDriver("com.mysql.cj.jdbc.Driver");configuration.setJdbcUsername("root");configuration.setJdbcPassword("admin");configuration.setJdbcUrl("jdbc:mysql://127.0.0.1:3306/flowable1?serverTimeZone=UTC&nullCatalogMeansCurrent=true");// 如果数据库中的表结构不存在则新建configuration.setDatabaseSchemaUpdate(ProcessEngineConfiguration.DB_SCHEMA_UPDATE_TRUE);processEngine = configuration.buildProcessEngine();}@Testpublic void test_deploy() {// 2. 获取 RepositoryServiceRepositoryService repositoryService = processEngine.getRepositoryService();// 3. 完成流程部署操作Deployment deploy = repositoryService.createDeployment()// 关联要部署的流程文件.addClasspathResource("出差申请流程.bpmn20.xml").name("出差申请流程2023").deploy();  // 部署流程System.out.println("deploy.getId() => " + deploy.getId());System.out.println("deploy.getName() => " + deploy.getName());}@Testpublic void test_run_proc() {RuntimeService runtimeService = processEngine.getRuntimeService();Map params = new HashMap<>();params.put("assignee0", "whx");params.put("assignee1", "hx1");params.put("assignee2", "hx2");params.put("assignee3", "huathy");runtimeService.startProcessInstanceById("CCSQLC:1:4", params);}@Testpublic void test_complete_task1() {TaskService taskService = processEngine.getTaskService();Task task = taskService.createTaskQuery().processInstanceId("2501").singleResult();// 获取当前流程实例的所有变量Map processVariables = task.getProcessVariables();processVariables.put("num", 2);taskService.complete(task.getId(), processVariables);}/*** 根据taskID来更新本地(实例)变量*/@Testpublic void test_update_variables_local() {TaskService taskService = processEngine.getTaskService();Task task = taskService.createTaskQuery().processInstanceId("2501").singleResult();// 获取当前流程实例的所有变量Map processVariables = task.getProcessVariables();processVariables.put("num", 6);taskService.setVariablesLocal(task.getId(), processVariables);}/*** 根据taskID来更新流程变量*/@Testpublic void test_update_variables() {TaskService taskService = processEngine.getTaskService();Task task = taskService.createTaskQuery().processInstanceId("2501").singleResult();// 获取当前流程实例的所有变量。当局部变量和全局变量都存在的时候,取出来的是局部变量。Map processVariables = task.getProcessVariables();processVariables.put("num", 5);taskService.setVariables(task.getId(), processVariables);}/*** 完成上级审批*/@Testpublic void test_complete_task2() {TaskService taskService = processEngine.getTaskService();Task task = taskService.createTaskQuery().processInstanceId("2501").singleResult();taskService.complete(task.getId());}
}

每次完成任务后,查看数据库中的运行时变量表的变化。可以观察到局部变量在任务完成后被删除存入了历史变量表。随后再进行任务流转。
在这里插入图片描述在完成上级领导审批节点后,观察ACT_RU_TASK表,也可以看到节点流转到了财务审批。说明这里使用的是全局变量进行判断。局部变量已经在上一任务完成时被删除。
在这里插入图片描述

相关内容

热门资讯

【NI Multisim 14...   目录 序言 一、工具栏 🍊1.“标准”工具栏 🍊 2.视图工具...
银河麒麟V10SP1高级服务器... 银河麒麟高级服务器操作系统简介: 银河麒麟高级服务器操作系统V10是针对企业级关键业务...
不能访问光猫的的管理页面 光猫是现代家庭宽带网络的重要组成部分,它可以提供高速稳定的网络连接。但是,有时候我们会遇到不能访问光...
AWSECS:访问外部网络时出... 如果您在AWS ECS中部署了应用程序,并且该应用程序需要访问外部网络,但是无法正常访问,可能是因为...
Android|无法访问或保存... 这个问题可能是由于权限设置不正确导致的。您需要在应用程序清单文件中添加以下代码来请求适当的权限:此外...
北信源内网安全管理卸载 北信源内网安全管理是一款网络安全管理软件,主要用于保护内网安全。在日常使用过程中,卸载该软件是一种常...
AWSElasticBeans... 在Dockerfile中手动配置nginx反向代理。例如,在Dockerfile中添加以下代码:FR...
AsusVivobook无法开... 首先,我们可以尝试重置BIOS(Basic Input/Output System)来解决这个问题。...
ASM贪吃蛇游戏-解决错误的问... 要解决ASM贪吃蛇游戏中的错误问题,你可以按照以下步骤进行:首先,确定错误的具体表现和问题所在。在贪...
月入8000+的steam搬砖... 大家好,我是阿阳 今天要给大家介绍的是 steam 游戏搬砖项目,目前...