一、前言

上一篇文章我们将流程实例的启动与查询,任务的办理查询都进行了介绍,我们这篇文章来介绍activiti中的流程变量。

二、正文

流程变量与我们寻常理解的变量是一样的,仅仅只是是用在了我们activiti中,所以称为流程变量。流程变量在整个工作流扮演着非常重要的角色。

比如,请假流程中有请假天数、请假原因等一些參数都是流程变量使用的范围,流程变量的作用域范围是仅仅相应一个流程实例。

也就是说各个流程实例的流程变量是不互相影响的。流程实例结束完毕以后流程变量还保存在数据库中(存放在流程变量的历史表中)。

如图:

watermark/2/text/aHR0cDovL2Jsb2cuY3Nkbi5uZXQvendrNjI2NTQyNDE3/font/5a6L5L2T/fontsize/400/fill/I0JBQkFCMA==/dissolve/70/gravity/Center" alt="">

关于流程实例的样例,我们先来看下流程图的processVariables.bpmn的配置文件:

<?xml version="1.0" encoding="UTF-8"?>
<definitions xmlns="http://www.omg.org/spec/BPMN/20100524/MODEL" xmlns:xsi="http://www.w3.org/2001/XMLSchema-instance" xmlns:xsd="http://www.w3.org/2001/XMLSchema" xmlns:activiti="http://activiti.org/bpmn" 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" typeLanguage="http://www.w3.org/2001/XMLSchema" expressionLanguage="http://www.w3.org/1999/XPath" targetNamespace="http://www.activiti.org/test">
<process id="processVariables" name="processVariables【流程请假】" isExecutable="true">
<startEvent id="startevent1" name="Start"></startEvent>
<endEvent id="endevent1" name="End"></endEvent>
<userTask id="usertask1" name="提交申请"></userTask>
<sequenceFlow id="flow1" sourceRef="startevent1" targetRef="usertask1"></sequenceFlow>
<userTask id="usertask2" name="审批【总经理】" activiti:assignee="王二"></userTask>
<sequenceFlow id="flow2" sourceRef="usertask1" targetRef="usertask2"></sequenceFlow>
<sequenceFlow id="flow3" sourceRef="usertask2" targetRef="endevent1"></sequenceFlow>
</process>
<bpmndi:BPMNDiagram id="BPMNDiagram_processVariables">
<bpmndi:BPMNPlane bpmnElement="processVariables" id="BPMNPlane_processVariables">
<bpmndi:BPMNShape bpmnElement="startevent1" id="BPMNShape_startevent1">
<omgdc:Bounds height="35.0" width="35.0" x="350.0" y="90.0"></omgdc:Bounds>
</bpmndi:BPMNShape>
<bpmndi:BPMNShape bpmnElement="endevent1" id="BPMNShape_endevent1">
<omgdc:Bounds height="35.0" width="35.0" x="350.0" y="420.0"></omgdc:Bounds>
</bpmndi:BPMNShape>
<bpmndi:BPMNShape bpmnElement="usertask1" id="BPMNShape_usertask1">
<omgdc:Bounds height="55.0" width="105.0" x="315.0" y="190.0"></omgdc:Bounds>
</bpmndi:BPMNShape>
<bpmndi:BPMNShape bpmnElement="usertask2" id="BPMNShape_usertask2">
<omgdc:Bounds height="55.0" width="105.0" x="315.0" y="300.0"></omgdc:Bounds>
</bpmndi:BPMNShape>
<bpmndi:BPMNEdge bpmnElement="flow1" id="BPMNEdge_flow1">
<omgdi:waypoint x="367.0" y="125.0"></omgdi:waypoint>
<omgdi:waypoint x="367.0" y="190.0"></omgdi:waypoint>
</bpmndi:BPMNEdge>
<bpmndi:BPMNEdge bpmnElement="flow2" id="BPMNEdge_flow2">
<omgdi:waypoint x="367.0" y="245.0"></omgdi:waypoint>
<omgdi:waypoint x="367.0" y="300.0"></omgdi:waypoint>
</bpmndi:BPMNEdge>
<bpmndi:BPMNEdge bpmnElement="flow3" id="BPMNEdge_flow3">
<omgdi:waypoint x="367.0" y="355.0"></omgdi:waypoint>
<omgdi:waypoint x="367.0" y="420.0"></omgdi:waypoint>
</bpmndi:BPMNEdge>
</bpmndi:BPMNPlane>
</bpmndi:BPMNDiagram>
</definitions>

一个非常easy的流程图processVariables.png:

部署流程定义:

	/**
* 部署流程定义(从inputStream)
*/
@Test
public void deploymentProcessDefinition_inputStream() {
ProcessEngine processEngine = ProcessEngines.getDefaultProcessEngine(); InputStream inputStreamBpmn = this.getClass().getResourceAsStream(
"/diagrams/processVariables.bpmn");
InputStream inputStreamPng = this.getClass().getResourceAsStream(
"/diagrams/processVariables.png");
Deployment deployment = processEngine.getRepositoryService()// 与流程定义和部署对象相关的Service
.createDeployment()// 创建一个部署对象
.name("流程定义")// 加入部署名称
.addInputStream("processVariables.bpmn", inputStreamBpmn)// 使用资源文件的名称(要求:与资源文件的名称要一致),和输入流完毕部署
.addInputStream("processVariables.png", inputStreamPng)// 使用资源文件的名称(要求:与资源文件的名称要一致),和输入流完毕部署
.deploy();// 完毕部署
System.out.println("部署ID:" + deployment.getId());
System.out.println("部署名称:" + deployment.getName());
}

执行结果:

部署ID:701

部署名称:流程定义

启动流程实例:

	/**
* 启动流程实例
*/
@Test
public void startProcessInstance() {
// 流程定义的key
String processDefinitionKey = "processVariables";
ProcessInstance pi = processEngine.getRuntimeService()// 与正在运行的流程实例和运行对象相关的service
.startProcessInstanceByKey(processDefinitionKey);// 使用流程定义的key启动流程实例,key相应processVariables文件里的id的属性值,使用key值启动,默认是依照最新版本号进行启动 System.out.println("流程实例ID:" + pi.getId());
System.out.println("流程定义ID:" + pi.getProcessDefinitionId());
System.out.println("流程实例ID" + pi.getProcessInstanceId()); }

执行结果:

流程实例ID:801

流程定义ID:processVariables:1:704

流程实例ID801

查询任务

/**
* 查询任务通过流程实例id
*/
@Test
public void findTask(){
String processInstanceId="801";
List<HistoricTaskInstance> list = processEngine.getHistoryService()//与历史数据(历史表)相关的service
.createHistoricTaskInstanceQuery()//创建历史任务实例查询
.processInstanceId(processInstanceId)
.list();
if(list!=null && list.size()>0){
for(HistoricTaskInstance hti:list){
System.out.println(hti.getId()+" "+hti.getName()+" "+hti.getProcessInstanceId()+" "+hti.getStartTime()+" "+hti.getEndTime()+" "+hti.getDurationInMillis());
System.out.println("################################");
}
}
}

执行结果:

804    提交申请   801   Fri Jun 26 10:55:02 CST2015   null   null

################################

关于部署流程定义、启动流程实例和查询正在办理的任务我们前面的文章已经介绍过了。所以我们不再具体介绍。以下開始我们的设置流程变量。设置流程变量我们这里提供了两种方式,各自是使用基本数据类型和使用javabean的方法。允许获取流程变量也是不一样的:

使用基本数据类型:

设置流程变量

/**
* 设置流程变量
*/
@Test
public void setVariables() {
// 与任务相关的service,正在运行的service
TaskService taskService = processEngine.getTaskService(); // 任务ID
String taskId = "804"; // 1.设置流程变量,使用基本数据类型
taskService.setVariable(taskId, "请假天数", 7);// 与任务ID邦德
taskService.setVariable(taskId, "请假日期", new Date());
taskService.setVariableLocal(taskId, "请假原因", "回去探亲,一起吃个饭123"); System.out.println("设置流程变量成功。"); }

执行结果:

设置流程变量成功!

获取流程变量

/**
* 获取流程变量
*/
@Test
public void getVariables() {
// 与任务(正在运行的service)
TaskService taskService = processEngine.getTaskService();
// 任务Id
String taskId = "804";
// 1.获取流程变量,使用基本数据类型
Integer days = (Integer) taskService.getVariable(taskId, "请假天数");
Date date = (Date) taskService.getVariable(taskId, "请假日期");
String reason = (String) taskService.getVariable(taskId, "请假原因"); System.out.println("请假天数:" + days);
System.out.println("请假日期:" + date);
System.out.println("请假原因:" + reason); }

执行结果:

请假天数:7

请假日期:Fri Jun 2611:07:28 CST 2015

请假原因:回去探亲,一起吃个饭123

使用javabean

JavaBean的Person类

package com.tgb;

import java.io.Serializable;
import java.util.Date; public class Person implements Serializable { private static final long serialVersionUID = 361866001729020143L;
//请假天数
private int id;
//请假人
private String name;
//请假原因
private String note;
//请假时间
private Date date;
public Date getDate() {
return date;
}
public void setDate() {
this.date = new Date();
}
public String getNote() {
return note;
}
public void setNote(String note) {
this.note = note;
}
public int getId() {
return id;
}
public void setId(int id) {
this.id = id;
}
public String getName() {
return name;
}
public void setName(String name) {
this.name = name;
}
}

设置流程变量

/**
* 设置流程变量
*/
@Test
public void setVariables() {
// 与任务相关的service,正在运行的service
TaskService taskService = processEngine.getTaskService(); // 任务ID
String taskId = "804"; // 设置流程变量。使用javaBean方法
/**
* 当一个javaBean(实现序列号)放置到流程变量中。要求javabean的属性不能在发生变化 假设发生变化,再获取时,抛出异常
*
* 解决方式:在person对象中加入: private static final long
* serialVersionUID="6757393795687480331L"; 同一时候实现序列号接口
*
*/
Person p = new Person();
p.setName("翠花");
p.setId(20);
p.setDate();;
p.setNote("回去探亲,一起吃个饭123");
taskService.setVariable(taskId, "人员信息(加入固定版本号)", p); System.out.println("设置流程变量成功!"); }

执行结果:

设置流程变量成功!

获取流程变量

/**
* 获取流程变量
*/
@Test
public void getVariables() {
// 与任务(正在运行的service)
TaskService taskService = processEngine.getTaskService();
// 任务Id
String taskId = "804"; // 2.获取流程变量。使用javaBean类型
Person p = (Person)taskService.getVariable(taskId, "人员信息(加入固定版本号)");
System.out.println(" 请假人: "+p.getName()+" 请假天数: "+p.getId()+" 请假时间:"+ p.getDate()+ " 请假原因: "+p.getNote()); }

执行结果:

请假人: 翠花  请假天数:  20  请假时间:Fri Jun 26 11:13:44 CST 2015  请假原因: 回去探亲,一起吃个饭123

查询历史流程变量

能够依据变量名称查询该变量的全部历史信息

能够依据变量名称查询该变量的全部历史信息
/**
* 查询流程变量的历史表
*/
@Test
public void findHistoryProcessVariables(){
List<HistoricVariableInstance> list = processEngine.getHistoryService()
.createHistoricVariableInstanceQuery()//创建一个历史的流程变量查询对象
.variableName("请假原因")
.list();
if (list!=null &&list.size()>0) {
for (HistoricVariableInstance hvi : list) {
System.out.println(hvi.getId()+" "+hvi.getProcessInstanceId()+" "+hvi.getVariableName()
+" "+hvi.getVariableTypeName()+" "+hvi.getValue());
System.out.println("########################################");
}
} }

流程变量支持的数据类型:

流程变量支持的数据类型包含:TypeName、string、integer、short、long、double、boolean、data、binary、serializable,我们能够看出流程变量支持的包含了大部分封装类型和Date、String和实现了Serializable接口的类的类型。

三、总结

我们这篇文章将流程变量的相关知识进行了介绍,除了介绍流程变量的相关定义外还通过详细代码样例介绍了通过不同方式来设置和获取流程变量以及流程变量支持的数据类型。

工作流学习——Activiti流程变量五步曲的更多相关文章

  1. 工作流学习——Activiti流程变量五步曲 (zhuan)

    http://blog.csdn.net/zwk626542417/article/details/46648139 ***************************************** ...

  2. Activiti流程变量五步曲 ——by fightingKing

    http://blog.csdn.net/zwk626542417/article/details/46648139 一.前言 上一篇文章我们将流程实例的启动与查询,任务的办理查询都进行了介绍,我们这 ...

  3. 工作流学习——Activiti整体认识二步曲 (zhuan)

    http://blog.csdn.net/zwk626542417/article/details/46594505 ***************************************** ...

  4. 工作流学习——Activiti流程实例、任务管理四步曲 (zhuan)

    http://blog.csdn.net/zwk626542417/article/details/46646565 ***************************************** ...

  5. 工作流学习——Activiti流程定义管理三步曲 (zhuan)

    http://blog.csdn.net/zwk626542417/article/details/46602419 ***************************************** ...

  6. C语言程序设计入门学习五步曲(转发)

    笔者在从事教学的过程中,听到同学抱怨最多的一句话是:老师,上课我也能听懂,书上的例题也能看明白,可是到自己动手做编程时,却不知道如何下手.发生这种现象的原因有三个: 一.所谓的看懂听明白,只是很肤浅的 ...

  7. iOS 之美:iOS Delegate 使用五步曲

    在iOS 开发中, 搞清楚Delegate 是需要花些时间的. Delegate 本来是软件架构设计的一种理念.对于像手机这样一个有限的设备,我们需要充分考虑到:内存要尽量省着用: 视图之间的关系要清 ...

  8. Activiti流程变量

    流程变量在整个工作流中扮演很重要的作用 例如:请假流程中有请假天数.请假原因等一些参数都为流程变量的范围.流程变量的作用域范围是流程实例.也就是说各个流程实例的流程变量是不相互影响的. 添加流程变量 ...

  9. JDK1.8简单配置环境变量---两步曲

    鄙人最近重新装完系统之后,在安装和配置jdk1.8的时候,发现网上许多教程配置jdk环境变量时都还在沿用传统的方式配置,但是随着技术的更新,完全没有必要那么麻烦了. 下载和安装jdk的教程,在这里就不 ...

随机推荐

  1. mysql管理和基本操作

    进去mysql:mysql –uroot –p 重启数据库:[root@nanaLinux ~]# /etc/init.d/mysqld restart 1.Mysql忘记root密码 // 查看my ...

  2. docker从零开始网络(七) 配置daemon和容器

    启用IPv6支持 在Docker容器或swarm服务中使用IPv6之前,需要在Docker守护程序中启用IPv6支持.之后,您可以选择将IPv4或IPv6(或两者)与任何容器,服务或网络一起使用. 注 ...

  3. 学习apache commons lang3的源代码 (2):RandomStringUtils

    本文,主要是分析类;RandomStringUtils. 下面这个方法的:count:表示要生成的数量(比如4个字符组成的字符串等) start,end,表示限定的范围,比如生成ascii码的随机等. ...

  4. RESTful 接口实现简明指南

    REST 简介 REST 是一个术语的缩写,REpresentational State Transfer,中文直译「表征状态转移」,这是个很拗口的词.我的建议是先不要强行理解,直接看怎么做,等对实施 ...

  5. 自定义的一个JDBC工具类

    package JDBCutils; import java.io.File;import java.io.FileInputStream;import java.sql.Connection;imp ...

  6. hiho一下第134周 1468 : 2-SAT·hihoCoder新春晚会

    1468 : 2-SAT·hihoCoder新春晚会 时间限制:10000ms 单点时限:1000ms 内存限制:256MB 描述 hihoCoder新春晚会正在紧张地筹备中.晚会分为上半场和下半场, ...

  7. leetcode122 Best Time to Buy and Sell Stock

    题意:有一个数组,第i个数据代表的是第i天股票的价格,每天只能先卖出再买进(可以不卖出也可以不买进),求最大收益. 思路:自己去弄几个数组比划比划就知道了,比如[1,2,5,3,6],第一天买进,第二 ...

  8. JVM内存溢出及配置

    一.Java JVM内存介绍 JVM管理两种类型的内存,堆和非堆.按照官方的说法:“Java 虚拟机具有一个堆,堆是运行时数据区域,所有类实例和数组的内存均从此处分配.堆是在 Java 虚拟机启动时创 ...

  9. [xsy1515]小学生数学题

    题意:求$\begin{align*}\left(\sum\limits_{i=1}^n\dfrac 1i\right)\%\ p^k\end{align*}$ 数学真是太可爱了== 直接推公式 设$ ...

  10. jQuery当中的事件(第六章ppt)

    bink绑定事件 hover合成事件 代码示例: <!DOCTYPE html> <html> <head> <title>test1.html< ...