activiti流程变量

1. 什么是流程变量

流程变量在activiti中是一个非常重要的角色,流程运转有时就需要流程变量,流程变量就是activiti在管理工作流时根据管理需要而设置的变量。

前面我们用到的使用${assignee0}的方式分配负责人,就是流程变量

也可以设置别的流程变量,比如:出差申请流程如果出差天数大于3天由总经理审核,否则由财务审核,这里出差天数就可以设置一个流程变量进行管理。

注意:虽然流程变量中可以存储业务数据,通过activiti查询流程变量实现查询业务数据,但是不建议这么操作,因为业务数据是由业务系统提供的,activiti工作流流程变量只是负责流程执行而创建的。太多的业务数据当做流程变量容易造成数据紊乱。

2. 流程变量类型

如果是pojo对象存储到流程变量中,必须实现序列化接口Serializable,为防止由于新增字段无法发序列化,需要生成serialVersionUID

3. 流程变量的作用域

流程变量的作用域可以是一个流程实例(ProcessInstance),也可以是一个任务(Task)或者是一个执行实例(execution)

3.1 global变量

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

注意:global变量中变量名不允许重复,设置相同的变量名,后设置的值会覆盖之前设置的值。

3.2 local变量

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

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

4. 流程变量的使用方法

4.1 在属性上使用UEL表达式

可以在向assignee这样的属性上使用UEL表达式,该表达式的值为任务的负责人,比如:${assignee},assignee就是一个流程变量名称。

activiti获取UEL表达式的值,即流程变量assignee的值,将该值作为任务负责人进行任务分配。

4.2 在连线上使用UEL表达式

可以在连线上使用UEL表达式,决定流程的走向。

比如:${price < 100},price就是一个流程变量的值,uel表达式的结果为布尔值,根据uel表达式的值true,来确定流程的走向。

5. 设置global流程变量

不同的工具设计流程不太一样,请自己选择,本文使用的是Camunda Modeler

5.1 需求

员工创建出差申请单,由部门经理审核,部门经理审核通过后出差3天及以下由财务直接审批,出差3天以上由总经理审批,总经理审批后再由财务审批。

5.2 流程定义

**1)出差天数大于3连线条件 **

选中连线,然后设计流程变量条件${num>3},当然也可以设计成${evection.num>3},evection是一个对象且该对象必须要进行序列化。

注意这里的连线是:Conditional Flow,切换成这个连线再设计流程变量

2)出差天数小于等于3连线条件

选中连线,然后设计流程变量条件${num<=3},同样也可以设计成${evection.num<=3},evection是一个对象且该对象必须要进行序列化。

5.3 设计global流程变量

在部门经理审核前设计流程变量,变量值为出差天数,部门经理审核后可以根据流程变量的值来决定流程的走向。

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

5.4 启动流程时设置流程变量

测试为了方便数据查询,删除数据库,重新部署新的流程。

在启动流程时设置流程变量,变量的作用域是整个流程实例,具体操作是,通过Map设置键值对的方式去设置流程变量,key是流程变量的名称,value是流程变量的值。

注意:这里有个问题,使用Camunda Modeler工具设计的流程配置的负责人assignee变量值,在代码中通过map传入不生效,是由于assignee 的前缀为camunda,activity解析不到该标签。

解决办法:将camunda 替换为 activiti,命名空间改为activity的命名空间

<definitions xmlns="http://www.omg.org/spec/BPMN/20100524/MODEL" xmlns:xsi="http://www.w3.org/2001/XMLSchema-instance" xmlns:bpmndi="http://www.omg.org/spec/BPMN/20100524/DI" xmlns:omgdc="http://www.omg.org/spec/DD/20100524/DC" xmlns:omgdi="http://www.omg.org/spec/DD/20100524/DI" xmlns:camunda="http://camunda.org/schema/1.0/bpmn" xmlns:xsd="http://www.w3.org/2001/XMLSchema" xmlns:activiti="http://activiti.org/bpmn" targetNamespace="http://www.activiti.org/processdef" exporter="Camunda Modeler" exporterVersion="3.0.0">

/*** 启动流程实例*/@Testpublic void startProcess() {//获取流程引擎ProcessEngine processEngine = ProcessEngines.getDefaultProcessEngine();//获取RuntimeServiceRuntimeService runtimeService = processEngine.getRuntimeService();//流程定义keyString key = "evection-variable";//定义流程变量mapMap<String, Object> map = new HashMap<>();//设置出差天数,key值就是我们在流程图设计时添加的流程变量名称//这里设置出差天数为3,按流程设计,经理审批完是由财务直接审核map.put("num", 3);//设置负责人流程变量的值map.put("assignee0", "张三");map.put("assignee1", "李经理");map.put("assignee2", "王总经理");map.put("assignee3", "赵财务");//启动流程实例,将流程变量通过map传入//该流程变量的作用域是一个流程实例ProcessInstance instance = runtimeService.startProcessInstanceByKey(key, map);//输出System.out.println("流程定义id:" + instance.getProcessDefinitionId());System.out.println("流程实例名称:" + instance.getName());System.out.println("流程实例id:" + instance.getProcessInstanceId());}

流程实例启动完成后,进行完成个人任务

    /*** 完成个人任务*/@Testpublic void completePersonalTask() {//流程定义keyString key = "evection-variable";//任务负责人:先完成张三,再完成李经理的,然后根据配置的出差天数流程变量,最后应该是直接有财务直接审批//String assignee = "张三";String assignee = "李经理";//获取流程引擎ProcessEngine processEngine = ProcessEngines.getDefaultProcessEngine();//获取TaskServiceTaskService taskService = processEngine.getTaskService();//根据流程定义key和任务负责人查询任务Task task = taskService.createTaskQuery()//查询可能有多个,这里测试只有一条数据可以这么直接查询,建议实际业务根据别的条件进行查询.processDefinitionKey(key).taskAssignee(assignee).singleResult();if (task != null) {taskService.complete(task.getId());System.out.println("任务已完成");}}

任务由李经理执行完成后,根据配置条件,出差天数3天,应该直接有财务直接进行审核,查看act_run_task任务表:

5.5 完成任务时设置流程变量

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

这里在完成创建出差申请单任务时设置流程变量,即完成张三的任务

为了演示,删库之后重新部署测试,注意部署完后启动实例,不用给num变量设置值了

启动流程实例后,查询act_ru_variable表只有四个流程变量

    /*** 任务办理时设置流程变量* 这里测试出差天数num流程变量,所以在启动流程实例的时候不用设置num,只设置任务负责人即可*/@Testpublic void completeTask() {//流程定义keyString key = "evection-variable";//任务idString taskId = "7501";//任务负责人String assignee = "张三";//获取流程引擎ProcessEngine processEngine = ProcessEngines.getDefaultProcessEngine();//获取TaskServiceTaskService taskService = processEngine.getTaskService();//       创建变量集合Map<String, Object> map = new HashMap<>();/*** 可以使用对象的方式设置* Evection evection = new Evection();* evection.setNum(2d);* map.put("evection",evection);*/map.put("num", 3);//查询任务Task task = taskService.createTaskQuery().processDefinitionKey(key).taskId(taskId).taskAssignee(assignee).singleResult();if (task != null) {//完成任务并设置流程变量taskService.complete(task.getId(), map);System.out.println(task.getId() + "任务已完成");}}

执行上面的代码完成个人任务,并给出差天数num流程变量设置值。

查询act_ru_variable表可以看到出差天数流程变量值正常设置

根据流程图或者act_ru_task表的数据可以看到当前任务由李经理审核完成,用之前完成个人任务的代码执行流程任务

    /*** 完成个人任务*/@Testpublic void completePersonalTask() {//流程定义keyString key = "evection-variable";//任务负责人:先完成张三,再完成李经理的,然后根据配置的出差天数流程变量,最后应该是直接有财务直接审批//String assignee = "张三";String assignee = "李经理";//获取流程引擎ProcessEngine processEngine = ProcessEngines.getDefaultProcessEngine();//获取TaskServiceTaskService taskService = processEngine.getTaskService();//根据流程定义key和任务负责人查询任务Task task = taskService.createTaskQuery()//查询可能有多个,这里测试只有一条数据可以这么直接查询,建议实际业务根据别的条件进行查询.processDefinitionKey(key).taskAssignee(assignee).singleResult();if (task != null) {taskService.complete(task.getId());System.out.println("任务已完成");}}

任务完成后刷新act_ru_task表可以看到流程走到财务了,因为num=3直接由财务审核

5.6 通过当前执行流程实例设置流程变量

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

    /*** 通过当前执行的流程实例执行id设置变量* 这里测试出差天数num流程变量,所以在启动流程实例的时候不用设置num,只设置任务负责人即可*/@Testpublic void setGlobalVariableByExecutionId() {//获取流程引擎ProcessEngine processEngine = ProcessEngines.getDefaultProcessEngine();//当前流程实例执行id,通常为当前执行的流程实例String executionId = "";//获取RuntimeServiceRuntimeService runtimeService = processEngine.getRuntimeService();//       创建变量集合Map<String, Object> map = new HashMap<>();/*** 可以使用对象的方式设置* Evection evection = new Evection();* evection.setNum(2d);* runtimeService.setVariable(executionId, "evection", evection);*/map.put("num", 3);runtimeService.setVariables(executionId, map);/*** 可以通过getVariables获取到已设置的流程变量*/Map<String, Object> variables = runtimeService.getVariables(executionId);variables.forEach((k,v) -> {System.out.println(k +" "+ v);});}

为了方便测试数据查看,清空数据库,重新部署,然后启动流程实例,在act_ru_task表拿到EXECUTION_ID的值,该值就是当前流程实例执行ID

执行完成后,再去查看act_ru_variable表可查询到流程变量num的数据。

注意:EXECUTION_ID必须是当前未结束的流程实例的执行id

5.7 通过当前任务设置流程变量

任务id必须是当前待办任务id,在act_ru_task表中存在,如果任务结束,则会报错。

    /*** 通过当前任务设置流程变量* 这里测试出差天数num流程变量,所以在启动流程实例的时候不用设置num,只设置任务负责人即可*/@Testpublic void setGlobalVariableByTask() {//获取流程引起ProcessEngine processEngine = ProcessEngines.getDefaultProcessEngine();//当前任务idString taskId = "2509";//获取TaskServiceTaskService taskService = processEngine.getTaskService();//设置流程变量Map<String, Object> map = new HashMap<>();map.put("num", 5);taskService.setVariables(taskId, map);Map<String, Object> variables = taskService.getVariables(taskId);variables.forEach((k, v) -> {System.out.println(k + ":" + v);});}

可以直接通过上面的数据进行测试,不用重新部署创建流程实例了。执行完成后,会发现变量表的num值更新成了5。

5.8 数据库表说明

设置流程变量会在当前执行流程变量表插入记录,同时也会在历史流程变量表也插入记录。

//当前流程变量表
SELECT * FROM act_ru_variable

记录当前运行流程实例可使用的流程变量,包括 global和local变量

Id_:主键

Type_:变量类型

Name_:变量名称

Execution_id_:所属流程实例执行id,global和local变量都存储

Proc_inst_id_:所属流程实例id,global和local变量都存储

Task_id_:所属任务id,local变量存储

Bytearray_:serializable类型变量存储对应act_ge_bytearray表的id

Double_:double类型变量值

Long_:long类型变量值

Text_:text类型变量值

 #历史流程变量表
SELECT * FROM act_hi_varinst

记录所有已创建的流程变量,包括 global和local变量

字段意义参考当前流程变量表。

6. 设置local流程变量

6.1 任务办理时设置

任务办理时设置local流程变量,当前运行的流程实例只能在该任务结束前使用,任务结束后无法在当前流程实例使用,可以通过历史任务查询。

    /*** 处理任务时设置local流程变量*/@Testpublic void setLocalVariableByComplete() {//任务idString taskId = "7503";//获取流程引擎ProcessEngine processEngine = ProcessEngines.getDefaultProcessEngine();//获取TaskServiceTaskService taskService = processEngine.getTaskService();//定义local流程变量Map<String, Object> map = new HashMap<>();map.put("num", 10);taskService.setVariablesLocal(taskId, map);taskService.complete(taskId);}
6.2 通过当前任务设置
    /*** 处理任务时设置local流程变量*/@Testpublic void setLocalVariableByComplete() {//任务idString taskId = "7503";//获取流程引擎ProcessEngine processEngine = ProcessEngines.getDefaultProcessEngine();//获取TaskServiceTaskService taskService = processEngine.getTaskService();//定义local流程变量Map<String, Object> map = new HashMap<>();map.put("num", 10);taskService.setVariablesLocal(taskId, map);//taskService.complete(taskId);}

任务id必须是当前待办任务,act_ru_task表中存在

Local变量在任务结束后无法在当前流程实例执行中使用,如果后续的流程执行需要用到此变量则会报错。

6.3 查询历史local流程变量
    /*** 查询历史local变量*/@Testpublic void queryHistoricLocalVariable() {ProcessEngine processEngine = ProcessEngines.getDefaultProcessEngine();//查询local流程变量HistoryService historyService = processEngine.getHistoryService();List<HistoricTaskInstance> list = historyService.createHistoricTaskInstanceQuery().includeTaskLocalVariables().list();for (HistoricTaskInstance taskInstance : list) {System.out.println("任务id:" + taskInstance.getId());System.out.println("任务local变量:" + taskInstance.getTaskLocalVariables());}}

注意:查询历史流程变量,特别是查询pojo变量需要经过反序列化,不推荐使用。

【activiti】流程变量相关推荐

  1. Activiti——流程变量(六)

    Activiti--流程变量 转自:http://lib.csdn.net/article/java/66665?knId=268 流程变量在整个工作流中扮演很重要的作用.例如:请假流程中有请假天数. ...

  2. activiti流程变量

    import org.activiti.engine.*; import org.activiti.engine.repository.Deployment; import org.activiti. ...

  3. 学习笔记之-Activiti7工作流引擎,概述,环境搭建,类关系图,使用Activiti BPMN visualizer,流程变量,组任务 网关,Activiti整合Spring SpringBoot

    本篇学习笔记是观看黑马程序员Activiti7视频而得 Activiti7 一.工作流介绍 1.1 概念 工作流(Workflow),就是通过计算机对业务流程自动化执行管理.它主要解决的是" ...

  4. Activiti工作流之流程变量

    1.什么是流程变量 流程变量在 activiti 中是一个非常重要的角色,流程运转有时需要靠流程变量,业务系统和 activiti 结合时少不了流程变量,流程变量就是 activiti 在管理工作流时 ...

  5. Activiti第二篇【管理流程定义、执行任务和流程实例、流程变量】

    tags: Activiti 上篇Activiti只是一个快速入门案例,这篇就讲定义.部署.查看任务等等的一些细节[涉及到的数据库表.对象等等]... 管理流程定义 管理流程定义主要涉及到以下的4张表 ...

  6. Activiti工作流(三)——流程变量

    流程变量可以是流程中一系列参数,比如办理人(Assignee),消息(message)等.这些流程变量使得activiti能够应用于更为复杂的业务中,使得流程变得更加灵活可控. 场景(一) 图一:没有 ...

  7. 《Activiti/Flowable  深入BPM工作流》-什么是流程变量?

               <Activiti/Flowable  深入BPM工作流>-什么是流程变量? 一. 问题:         1. 什么是流程变量?        2. 什么是glob ...

  8. flowable工作流 流程变量_业务流程 BPM、工作流引擎、Flowable、Activiti

    特点 基于 Flowable(Activiti)生来具有的稳定工作流引擎 支持在线流程设计器,流程导入导出,符合 BPMN 规范,中国式工作流 支持流程办理.退回.自由流.会签.并行.串行.服务任务等 ...

  9. 《Activiti/Flowable  深入BPM工作流》-如何设置local流程变量?

    <Activiti/Flowable  深入BPM工作流>-如何设置local流程变量? 一. 问题:  1. 什么是local流程变量?     2. 如何设置local流程变量?   ...

最新文章

  1. CSDN博客获取积分规则!不是下载积分!如何快速增长积分!
  2. 【Python】Python简单入门
  3. 【大数据-Hadoop】Hadoop架构
  4. 程序中添加动态用户密码
  5. Hive的两种操作模式
  6. 《深入理解LINUX网络技术内幕》小记1
  7. vue .prettierrc文件常见配置, 以及配置 Prettier - Code formatter 插件 格式化
  8. 2021年广东工业大学第十五届文远知行杯程序设计竞赛(同步赛) H.有多短 思维
  9. 解决android studio引用远程仓库下载慢(JCenter下载慢)
  10. linux下调用python脚本,Linux下QT调用Python脚本的解决方案,Qt,python,一种,解决办法
  11. 佩斯大学计算机科学世界排名,美国佩斯大学留学推荐 计算机科学专业
  12. mysql 授权 navicat的登录数据库
  13. 经典的CSS代码(转)
  14. 网易云音乐API 安装及部署 全过程【本地跑项目以及远端部署 均详解】
  15. 输入一个二阶矩阵并计算主对角线元素的和 C语言
  16. vue_shop项目的一些重要点~
  17. window10家庭版安装docker记录
  18. ET-B31H-M@B人机界面密码开门显示“未配置”
  19. NLP之句子相似度之入门篇
  20. 一个智能客服系统的设计思路

热门文章

  1. mysql必知必会的数据_MySQL必知必会--汇 总 数 据
  2. Unity丛林战争学习02_TCP_解决分包和黏包的问题
  3. 鱼眼:一:一分钟详解鱼眼镜头标定基本原理及实现
  4. 攻防世界-PWN-house of grey-Linux系统文件泄漏
  5. POJ2325 Persistent Numbers
  6. 在python中创建一个具有特定大小的空列表
  7. 使用IE浏览器下载时候窗口一闪而过
  8. strust框架下默认Action default-action-ref 出现HTTP Status 500错误
  9. 学大数据专业后悔死了?学大数据以后好就业吗?
  10. android测试版微信7.0下载地址,微信7.0.7下载地址-微信 7.0.7安卓内测版下载-西西软件下载...