Activiti工作流之流程变量_空城1995的博客-程序员宝宝

技术标签: java  activiti  

1.什么是流程变量

流程变量在 activiti 中是一个非常重要的角色,流程运转有时需要靠流程变量,业务系统和 activiti 结合时少不了流程变量,流程变量就是 activiti 在管理工作流时根据管理需要而设置的变量。

比如在请假流程流转时如果请假天数大于 3 天则由总经理审核,否则由人事直接审核,请假天数就可以设置为流程变量,在流程流转时使用。

注意:

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

2.流程变量作用域

流程变量的作用域默认是一个流程实例(processInstance),也可以是一个任务(task)或一个执行实例(execution),这三个作用域流程实例的范围最大,可以称为 global 变量,任务和执行实例仅仅是针对一个任务和一个执行实例范围,范围没有流程实例大,称为 local 变量。

  • global 变量中变量名不允许重复,设置相同名称的变量,后设置的值会覆盖前设置的变量值。

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

  • Local 变量名也可以和 global 变量名相同,没有影响。

3.流程变量使用方法

第一步:设置流程变量

第二步:通过UEL表达式使用流程变量

(1)可以在assginee处设置UEL表达式,表达式的值为任务的负责人,比如${assignee}

(2)可以在连线上设置UEL表达式,决定流程走向,比如${num>3}

4.使用Global变量控制流程

(1)需求

员工创建请假申请单,由部门经理审核,部门经理审核通过后请假 3 天及以下由人事经理直接审核,3 天以上先由总经理审核,总经理审核通过再由人事经理存档。

(2)流程定义

流程审批的人为方便测试设置为固定值:

填写请假申请单:zhangsan

部门经理审批:lisi

总经理审批:wangwu

人事经理存档:zhaoliu

 

根据请假天数走不同的分支:

 

(3)启动流程时设置

在启动流程时设置流程变量,变量的作用域是整个流程实例。

通过 map<key,value>设置流程变量,map 中可以设置多个变量,这个 key 就是流程变量的名字。

// 启动流程时设置流程变量 
    @Test
    public void startProcessInstance() {
        // 流程定义key
        String processDefinitionKey = "";
        Holiday holiday = new Holiday();
        holiday.setNum(3f);
        // 定义流程变量
        Map<String, Object> variables = new HashMap<>();
        //变量名是num,变量值是holiday.getNum(),变量名也可以是一个对象
        variables.put("num", holiday.getNum());
        //1.创建ProcessEngineer对象
        ProcessEngine processEngine = ProcessEngines.getDefaultProcessEngine();
        //2.获取runtimeService
        RuntimeService runtimeService = processEngine.getRuntimeService();
        ProcessInstance processInstance = runtimeService
                .startProcessInstanceByKey(processDefinitionKey, variables);
        System.out.println(" 流 程 实 例 id:" + processInstance.getProcessInstanceId());
    }

(4)创建请假实体类对象

/**
 * 请假实体类:
 *    注意POJO类型,一定要实现Serializable接口,否则在存储这个pojo时就会报异常
 */
@Data
public class Holiday implements Serializable {
    private Integer id;
    private String holidayName;//申请人的名字
    private Date beginDate;//开始时间
    private Date endDate;//结束日期
    private Float num;//请假天数
    private String reason;//事由
    private String type;//请假类型

}

(4)流程定义部署

    //新的请假流程定义的部署
    public static void main(String[] args) {
        //1.得到ProcessEngine
        ProcessEngine processEngine = ProcessEngines.getDefaultProcessEngine();
​
        //2.得到RepositoryService对象
        RepositoryService repositoryService = processEngine.getRepositoryService();
​
        //3.部署
        Deployment deploy = repositoryService.createDeployment()
                .addClasspathResource("diagram/holiday4.bpmn")
                .addClasspathResource("diagram/holiday4.png")
                .name("请假流程-流程变量")
                .deploy();
​
        System.out.println(deploy.getId());
        System.out.println(deploy.getName());
    }

(5)启动流程实例

    //启动流程实例,同时还要设置流程变量的值
    // act_ge_bytearray
    // act_ru_variable
    public static void main(String[] args) {
        //1.得到ProcessEngine
        ProcessEngine processEngine = ProcessEngines.getDefaultProcessEngine();
​
        //2.得到RuntimeService
        RuntimeService runtimeService =  processEngine.getRuntimeService();
​
        //3.流程定义的key问题
        String key = "holiday4";
        Map<String ,Object> map = new HashMap<>();
​
        Holiday holiday = new Holiday();
        holiday.setNum(5F);
        map.put("holiday",holiday);
​
        //4.启动流程实例,并且设置流程变量的值
        ProcessInstance processInstance = runtimeService.startProcessInstanceByKey(key, map);
​
        //5.输出实例信息
        System.out.println(processInstance.getName());
        System.out.println(processInstance.getProcessDefinitionId());
​
    }

(6)执行流程

依次执行zhangsan,lisi,wangwu,zhaoliu的任务

    public static void main(String[] args) {
        //完成任务  zhangsan  -----lisi----判断流程变量的请假天数,1天----分支:人事经理存档(zhaoliu)
        //1.得到ProcessEngine
        ProcessEngine processEngine = ProcessEngines.getDefaultProcessEngine();
​
        //2.得到TaskService
        TaskService taskService = processEngine.getTaskService();
​
        //3.查询当前用户是否有任务
        String key = "holiday4";
        Task task = taskService.createTaskQuery().processDefinitionKey(key)
                .taskAssignee("zhangsan").singleResult();
​
        //4.判断task!=null,说明当前用户有任务
        if(task!=null){
            taskService.complete(task.getId());
            System.out.println("任务执行完毕");
        }
​
    }

通过创建流程实例时设置的请假天数num变量,可以发现当num>3的时候,在通过部门经理审批后,会先走总经理审批。当num=3的时候,在通过部门经理审批后,就可以直接到达人事经理存档环节。

(7)global变量的其它设置方法

global除了在启动流程时设置,还可以在以下步骤中设置

  • 任务办理时设置

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

    public static void main(String[] args) {
        //1.得到ProcessEngine
        ProcessEngine processEngine = ProcessEngines.getDefaultProcessEngine();
​
        //2.得到TaskService
        TaskService taskService = processEngine.getTaskService();
​
        //3.查询当前用户是否有任务
        String key = "holiday4";
        Task task = taskService.createTaskQuery().processDefinitionKey(key)
                .taskAssignee("zhangsan").singleResult();
​
        //初始化一些参数
        Map<String ,Object> map = new HashMap<>();
​
        Holiday holiday = new Holiday();
        holiday.setNum(5F);
        map.put("holiday",holiday);
​
        //4.判断task!=null,说明当前用户有任务
        if(task!=null){
            taskService.complete(task.getId(),map);//完成任务时,设置流程变量的值
            System.out.println("任务执行完毕");
        }
​
    }
  • 通过当前流程实例设置

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

    public static void main(String[] args) {
        //1.得到ProcessEngine
        ProcessEngine processEngine = ProcessEngines.getDefaultProcessEngine();
​
        //2.得到RuntimeService
        RuntimeService runtimeService =  processEngine.getRuntimeService();
​
        //3.流程定义的key问题   myProcess_1
        //Map<String ,Object> map = new HashMap<>();
​
        Holiday holiday = new Holiday();
        holiday.setNum(5F);
       // map.put("holiday",holiday);
​
        //4.通过实例id,来设置流程变量
        //第一个参数:流程实例的id
        //第二个参数:流程变量名
        //第三个变量:流程变量名,所对应的值
        runtimeService.setVariable("2501","holiday",holiday);
​
    }
  • 通过当前任务设置

    public static void main(String[] args) {    
        //当前待办任务id String taskId="1404";
        //1.得到ProcessEngine
        ProcessEngine processEngine = ProcessEngines.getDefaultProcessEngine();
        TaskService taskService = processEngine.getTaskService(); 
        Holiday holiday = new Holiday();
        holiday.setNum(3f);
        //通过任务设置流程变量
        taskService.setVariable("1404", "holiday", holiday); 
        //一次设置多个值
        //taskService.setVariables(taskId, variables)
    }

5.设置local流程变量

(1)任务办理时设置

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

    // 办理任务时设置local流程变量
    @Test
    public void completTask() { //任务id
        ProcessEngine processEngine = ProcessEngines.getDefaultProcessEngine();
        String taskId = "1404";
        TaskService taskService = processEngine.getTaskService();
        // 定义流程变量
        Map<String, Object> variables = new HashMap<String, Object>();
        Holiday holiday = new Holiday();
        holiday.setNum(3f);
        // 定义流程变量
        variables.put("holiday", holiday);
        // 设置local变量,作用域为该任务 
        // taskService.setVariablesLocal(tasked, variables);
        taskService.complete(taskId);
    }

(2)通过当前任务设置

    @Test
    public void setLocalVariableByTaskId(){
        ProcessEngine processEngine = ProcessEngines.getDefaultProcessEngine();
        //当前待办任务id
        String taskId="1404";
        TaskService taskService = processEngine.getTaskService(); Holiday holiday = new Holiday ();
        holiday.setNum(3f);
        //通过任务设置流程变量
        taskService.setVariableLocal(taskId, "holiday", holiday); 
        //一次设置多个值
        //taskService.setVariablesLocal(taskId, variables)
    }

 

版权声明:本文为博主原创文章,遵循 CC 4.0 BY-SA 版权协议,转载请附上原文出处链接和本声明。
本文链接:https://blog.csdn.net/fy_java1995/article/details/100825013

智能推荐

PyQt5登陆工具.V2.0_漂泊_人生的博客-程序员宝宝

from PyQt5.Qt import *import sysimport mathclass AccountTool:#帐户判定类 ACCOUNT_ERROR=1 PWD_ERROR=2 SUCCESS=3 @staticmethod#定义静态方法 def check_login(account,pwd): #把帐号和密码发送给...

VBox虚拟机CentOS7系统搭建gitlab_hustlei的博客-程序员宝宝

VBox上centos网络配置CentOS在VBox上安装好后会存在以下问题:不能上网主机不能查看到CentOS虚拟机的存在,比如没法获取CentOS虚拟机ip。不能上网是因为DNS没有配置。主机不能查看CentOS虚拟机ip是因为没有配置静态ip。gitlab是通过网页访问的,主机不能访问centos虚拟机ip就没法在主机上连接gitlab。怎么配置呢?Vbox上centos配置...

搜索04 Mine Sweeper_久许的博客-程序员宝宝

题目链接DescriptionThe game Minesweeper is played on an n by n grid. In this grid are hidden m mines, each at a distinct grid location. The player repeatedly touches grid positions. If a position with...

D. Kavi on Pairing Duty(dp)__kikyou-的博客-程序员宝宝

传送门题意:给定正整数n,不超过1e6 。坐标轴上有2*n个点,分别在1 2 3…2n 。两个点连成线段,每种连法都可以得到n个线段。good pairing指,这个连法下的n个线段,任意两个线段要么长度相等,要么有包含关系。问一共有多少个good pairing.分析:我们令dp[i]表示n==i时题目给的样例特别良心,拿n==3来说:①只考虑最边上的1 6连起来,有一种连法,可以贡献1*dp[n-1]种连法②把1 2 5 6四个点连起来,且1 6不能连(避免和第①种重复),这样还是

随便推点

python用来自动修改pdf_Python自动化办公:批量Pdf转换Word_weixin_39727402的博客-程序员宝宝

昨天说到把Word转换为PDF,《用Python批量把Word转换为Pdf》。没想到还蛮受大家欢迎的,我们今天继续。我们经常在网络下载一些Pdf文件,Pdf非常好用,但是我们需要观看的时候;可能需要进行一些备注、或者修改就比较麻烦了。今天给大家介绍下,怎么用Python批量把Pdf转化为Word。1、环境准备python3pdfminer3kpython-docxPDF转Word功能所需的依赖包如...

STM32CUBEMX创建工程使用PWM控制LED呼吸灯——学习笔记_忄曼忄曼的博客-程序员宝宝

想学一下定时器,然后在查阅资料的时候,发现定时器的功能很强大,所以通过学习一个实例来验证一下,本次是通过定时器的PWM功能实现呼吸灯。实验的硬件平台是STM32F103ZET6,软件是MDK5,STM32CUBEMX. 在学习cubemx之后发现这个软件是真的强大。首先勾选引脚,在RCC的HSE选择Crystal/Ceramic Resonator...

Spring学习笔记四: 从Spring容器中获取Bean_衣舞晨风的博客-程序员宝宝

通过BeanFactory获取bean实例package org.jiankunking.utils;import org.springframework.beans.BeansException;import org.springframework.beans.factory.BeanFactory;import org.springframework.beans.factory.BeanFa

js基础-闭包基本概念及应用_泛酸桂花酒的博客-程序员宝宝

什么是闭包简单理解就是,函数包含函数,内部函数就是闭包 //简单理解就是,函数包含函数,内部函数就是闭包 function outFun(){ let a = 20 function innerFun(){ console.log(a); } return innerFun } //控制台打印了变了20,证明可以获取函数内部变量,内部函数没有执行完不会释放变量a占用的内存空间

如何修改Springboot Application的启动类注解默认值_spring初始化时修改注解的值_架构师三狼的博客-程序员宝宝

业务背景微服务拆分,原有的核心业务抽出公共的核心依赖工程,在现有启动类的基础上,封装了很多核心默认的注解配置,避免应用单独使用注解(如Fegin\ComponentScan\ServletComponentScan等)导致核心服务不可用,需要在SpringBoot Application启动时,部分BeanDefinitionRegistrar执行之前把核心的配置信息添加到注解中,做到动态修改注解的效果。SpringBoot SpringApplicationRunListener解决在Spring上

angular 控件css_Angular_weixin_39816062的博客-程序员宝宝

本篇文章介绍的是关于angularjs1.x升级angularjs2+方案,还有介绍了angularjs1.x和angularjs2+的并行,现在我们就一起来看这篇文章吧angular1.x 升级 angular2+ 方案我给大家提供的是angular1.x和angular5并行,...这次给大家带来Angular使用UI框架、控件,Angular使用UI框架、控件的注意事项有哪些,下面就是实战案...

推荐文章

热门文章

相关标签