工作流学习——Activiti流程变量五步曲

一、前言

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

二、正文

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

例如,请假流程中有请假天数、请假原因等一些参数都是流程变量使用的范围,流程变量的作用域范围是只对应一个流程实例。也就是说各个流程实例的流程变量是不互相影响的。流程实例结束完成以后流程变量还保存在数据库中(存放在流程变量的历史表中)。

如图:

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

[html] view plain copy

  1. <?xml version="1.0" encoding="UTF-8"?>
  2. <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">
  3. <process id="processVariables" name="processVariables【流程请假】" isExecutable="true">
  4. <startEvent id="startevent1" name="Start"></startEvent>
  5. <endEvent id="endevent1" name="End"></endEvent>
  6. <userTask id="usertask1" name="提交申请"></userTask>
  7. <sequenceFlow id="flow1" sourceRef="startevent1" targetRef="usertask1"></sequenceFlow>
  8. <userTask id="usertask2" name="审批【总经理】" activiti:assignee="王二"></userTask>
  9. <sequenceFlow id="flow2" sourceRef="usertask1" targetRef="usertask2"></sequenceFlow>
  10. <sequenceFlow id="flow3" sourceRef="usertask2" targetRef="endevent1"></sequenceFlow>
  11. </process>
  12. <bpmndi:BPMNDiagram id="BPMNDiagram_processVariables">
  13. <bpmndi:BPMNPlane bpmnElement="processVariables" id="BPMNPlane_processVariables">
  14. <bpmndi:BPMNShape bpmnElement="startevent1" id="BPMNShape_startevent1">
  15. <omgdc:Bounds height="35.0" width="35.0" x="350.0" y="90.0"></omgdc:Bounds>
  16. </bpmndi:BPMNShape>
  17. <bpmndi:BPMNShape bpmnElement="endevent1" id="BPMNShape_endevent1">
  18. <omgdc:Bounds height="35.0" width="35.0" x="350.0" y="420.0"></omgdc:Bounds>
  19. </bpmndi:BPMNShape>
  20. <bpmndi:BPMNShape bpmnElement="usertask1" id="BPMNShape_usertask1">
  21. <omgdc:Bounds height="55.0" width="105.0" x="315.0" y="190.0"></omgdc:Bounds>
  22. </bpmndi:BPMNShape>
  23. <bpmndi:BPMNShape bpmnElement="usertask2" id="BPMNShape_usertask2">
  24. <omgdc:Bounds height="55.0" width="105.0" x="315.0" y="300.0"></omgdc:Bounds>
  25. </bpmndi:BPMNShape>
  26. <bpmndi:BPMNEdge bpmnElement="flow1" id="BPMNEdge_flow1">
  27. <omgdi:waypoint x="367.0" y="125.0"></omgdi:waypoint>
  28. <omgdi:waypoint x="367.0" y="190.0"></omgdi:waypoint>
  29. </bpmndi:BPMNEdge>
  30. <bpmndi:BPMNEdge bpmnElement="flow2" id="BPMNEdge_flow2">
  31. <omgdi:waypoint x="367.0" y="245.0"></omgdi:waypoint>
  32. <omgdi:waypoint x="367.0" y="300.0"></omgdi:waypoint>
  33. </bpmndi:BPMNEdge>
  34. <bpmndi:BPMNEdge bpmnElement="flow3" id="BPMNEdge_flow3">
  35. <omgdi:waypoint x="367.0" y="355.0"></omgdi:waypoint>
  36. <omgdi:waypoint x="367.0" y="420.0"></omgdi:waypoint>
  37. </bpmndi:BPMNEdge>
  38. </bpmndi:BPMNPlane>
  39. </bpmndi:BPMNDiagram>
  40. </definitions>

一个很简单的流程图processVariables.png:

部署流程定义:

[java] view plain copy

  1. /**
  2. * 部署流程定义(从inputStream)
  3. */
  4. @Test
  5. public void deploymentProcessDefinition_inputStream() {
  6. ProcessEngine processEngine = ProcessEngines.getDefaultProcessEngine();
  7. InputStream inputStreamBpmn = this.getClass().getResourceAsStream(
  8. "/diagrams/processVariables.bpmn");
  9. InputStream inputStreamPng = this.getClass().getResourceAsStream(
  10. "/diagrams/processVariables.png");
  11. Deployment deployment = processEngine.getRepositoryService()// 与流程定义和部署对象相关的Service
  12. .createDeployment()// 创建一个部署对象
  13. .name("流程定义")// 添加部署名称
  14. .addInputStream("processVariables.bpmn", inputStreamBpmn)// 使用资源文件的名称(要求:与资源文件的名称要一致),和输入流完成部署
  15. .addInputStream("processVariables.png", inputStreamPng)// 使用资源文件的名称(要求:与资源文件的名称要一致),和输入流完成部署
  16. .deploy();// 完成部署
  17. System.out.println("部署ID:" + deployment.getId());
  18. System.out.println("部署名称:" + deployment.getName());
  19. }

运行结果:

部署ID:701

部署名称:流程定义

启动流程实例:

[java] view plain copy

  1. /**
  2. * 启动流程实例
  3. */
  4. @Test
  5. public void startProcessInstance() {
  6. // 流程定义的key
  7. String processDefinitionKey = "processVariables";
  8. ProcessInstance pi = processEngine.getRuntimeService()// 与正在执行的流程实例和执行对象相关的service
  9. .startProcessInstanceByKey(processDefinitionKey);// 使用流程定义的key启动流程实例,key对应processVariables文件中的id的属性值,使用key值启动,默认是按照最新版本进行启动
  10. System.out.println("流程实例ID:" + pi.getId());
  11. System.out.println("流程定义ID:" + pi.getProcessDefinitionId());
  12. System.out.println("流程实例ID" + pi.getProcessInstanceId());
  13. }

运行结果:

流程实例ID:801

流程定义ID:processVariables:1:704

流程实例ID801

查询任务

[java] view plain copy

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

运行结果:

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

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

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

使用基本数据类型:

设置流程变量

[java] view plain copy

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

运行结果:

设置流程变量成功!

获取流程变量

[java] view plain copy

  1. /**
  2. * 获取流程变量
  3. */
  4. @Test
  5. public void getVariables() {
  6. // 与任务(正在执行的service)
  7. TaskService taskService = processEngine.getTaskService();
  8. // 任务Id
  9. String taskId = "804";
  10. // 1.获取流程变量,使用基本数据类型
  11. Integer days = (Integer) taskService.getVariable(taskId, "请假天数");
  12. Date date = (Date) taskService.getVariable(taskId, "请假日期");
  13. String reason = (String) taskService.getVariable(taskId, "请假原因");
  14. System.out.println("请假天数:" + days);
  15. System.out.println("请假日期:" + date);
  16. System.out.println("请假原因:" + reason);
  17. }

运行结果:

请假天数:7

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

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

使用javabean

JavaBean的Person类

[java] view plain copy

  1. package com.tgb;
  2. import java.io.Serializable;
  3. import java.util.Date;
  4. public class Person implements Serializable {
  5. private static final long serialVersionUID = 361866001729020143L;
  6. //请假天数
  7. private int id;
  8. //请假人
  9. private String name;
  10. //请假原因
  11. private String note;
  12. //请假时间
  13. private Date date;
  14. public Date getDate() {
  15. return date;
  16. }
  17. public void setDate() {
  18. this.date = new Date();
  19. }
  20. public String getNote() {
  21. return note;
  22. }
  23. public void setNote(String note) {
  24. this.note = note;
  25. }
  26. public int getId() {
  27. return id;
  28. }
  29. public void setId(int id) {
  30. this.id = id;
  31. }
  32. public String getName() {
  33. return name;
  34. }
  35. public void setName(String name) {
  36. this.name = name;
  37. }
  38. }

设置流程变量

[java] view plain copy

  1. /**
  2. * 设置流程变量
  3. */
  4. @Test
  5. public void setVariables() {
  6. // 与任务相关的service,正在执行的service
  7. TaskService taskService = processEngine.getTaskService();
  8. // 任务ID
  9. String taskId = "804";
  10. // 设置流程变量,使用javaBean方法
  11. /**
  12. * 当一个javaBean(实现序列号)放置到流程变量中,要求javabean的属性不能在发生变化 如果发生变化,再获取时,抛出异常
  13. *
  14. * 解决方案:在person对象中添加: private static final long
  15. * serialVersionUID="6757393795687480331L"; 同时实现序列号接口
  16. *
  17. */
  18. Person p = new Person();
  19. p.setName("翠花");
  20. p.setId(20);
  21. p.setDate();;
  22. p.setNote("回去探亲,一起吃个饭123");
  23. taskService.setVariable(taskId, "人员信息(添加固定版本)", p);
  24. System.out.println("设置流程变量成功!");
  25. }

运行结果:

设置流程变量成功!

获取流程变量

[java] view plain copy

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

运行结果:

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

查询历史流程变量

可以根据变量名称查询该变量的所有历史信息

[java] view plain copy

  1. 可以根据变量名称查询该变量的所有历史信息
  2. /**
  3. * 查询流程变量的历史表
  4. */
  5. @Test
  6. public void findHistoryProcessVariables(){
  7. List<HistoricVariableInstance> list = processEngine.getHistoryService()
  8. .createHistoricVariableInstanceQuery()//创建一个历史的流程变量查询对象
  9. .variableName("请假原因")
  10. .list();
  11. if (list!=null &&list.size()>0) {
  12. for (HistoricVariableInstance hvi : list) {
  13. System.out.println(hvi.getId()+"     "+hvi.getProcessInstanceId()+"   "+hvi.getVariableName()
  14. +"   "+hvi.getVariableTypeName()+"    "+hvi.getValue());
  15. System.out.println("########################################");
  16. }
  17. }
  18. }

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

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

三、总结

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

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

时间: 2024-12-05 01:03:04

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

工作流学习——Activiti整体认识二步曲

前言 在上一篇文章中我们将工作流的相关概念.activiti的前世今生.activiti与jbpm的比较进行学习,这篇文章我们正式进行activiti的学习,activiti的整个学习我们主要通过例子的形式来理解.今天我们主要是准备下activiti的环境,在数据库中创建activiti默认的23张表以及activiti核心对象ProcessEngine最后是一个activiti的简单demo. 环境准备 相关软件及版本: jdk版本:Jdk1.8 IDE:eclipse 数据库:mysql A

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

http://blog.csdn.net/zwk626542417/article/details/46594505 *********************************************** 一.前言 在上一篇文章中我们将工作流的相关概念.activiti的前世今生.activiti与jbpm的比较进行学习,这篇文章我们正式进行activiti的学习,activiti的整个学习我们主要通过例子的形式来理解.今天我们主要是准备下activiti的环境,在数据库中创建activ

工作流学习——Activiti流程实例、任务管理四步曲

一.前言 上一篇文章中我们将Activiti流程定义管理的知识进行了介绍,这篇文章我们继续Activiti流程实例和任务管理的学习. 二.正文 流程实例(ProcessInstance ) 流程实例(ProcessInstance)和上一篇文章中流程定义(ProcessDefinition)的关系,与类和实例对象的关系有点像,ProcessDefinition是整个流程步骤的说明而ProcessInstance就是指流程定义从开始到结束的那个最大的执行路线. 执行对象(Execution) 提到

工作流学习——Activiti流程定义管理三步曲

一.前言 在上一篇文章我们通过一个小demo对Activiti进行了宏观的介绍,让大家对Activiti有了整体的认识,这篇文章我们来学习具体的流程定义管理的CRUD. 二.正文 流程定义是什么 ProcessDefinition(流程定义)就是一个流程的步骤说明,比如我们接下来要说的这个流程,申请人王三发起提交申请,李四作为部门经理进行审批,审批完成后,此申请到达下一级总经理王五,进行审批.就这么整个流程说明其实就是流程定义,不过在Activiti中整个流程定义是以helloworld.bpm

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

http://blog.csdn.net/zwk626542417/article/details/46602419 **************************************************************** 一.前言 在上一篇文章我们通过一个小demo对Activiti进行了宏观的介绍,让大家对Activiti有了整体的认识,这篇文章我们来学习具体的流程定义管理的CRUD. 二.正文 流程定义是什么 ProcessDefinition(流程定义)就是一个流

从一名打工者蜕变成一名企业家的五步曲

无数打工者每天皆梦想能于某天开创自己的公司.其总觉得自己拥有着进入一个领域并打造出一个成功的事业所需的正确的技能或者正确的创业点子.但,这些人到现在都还是只是在脑袋里意淫着而已,他们并没有真正的付诸行动去开始追求他们的创业点子.这又是为何呢? 如果你有一个可以创业的点子但又没有真正放手去干,那是因为什么原因拖了你后腿呢? 对于很多有抱负的企业家来说,缺乏如何启动一个可以催生出一家公司的项目的蓝图,让他们举步维艰.大部分人甚至不知道如何举出第一步,剩下一部分人却又不确定这种职业生涯是否是他们自己想

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

笔者在从事教学的过程中,听到同学抱怨最多的一句话是:老师,上课我也能听懂,书上的例题也能看明白,可是到自己动手做编程时,却不知道如何下手.发生这种现象的原因有三个: 一.所谓的看懂听明白,只是很肤浅的语法知识,而我们编写的程序或软件是要根据要解决问题的实际需要控制程序的流程,如果你没有深刻地理解C语言的语句的执行过程(或流程),你怎么会编写程序解决这些实际问题呢? 二.用C语言编程解决实际问题,所需要的不仅仅是C语言的编程知识,还需要相关的专业知识.例如,如果你不知道长方形的面积公式,即使C语言

iOS 之美:iOS Delegate 使用五步曲

在iOS 开发中, 搞清楚Delegate 是需要花些时间的. Delegate 本来是软件架构设计的一种理念.对于像手机这样一个有限的设备,我们需要充分考虑到:内存要尽量省着用: 视图之间的关系要清晰. 如果你所开发的App ,仅仅是一个demo,是体现不出架构优势的. 但当你的App 需要处理海量数据, 而视图之间的关系又颇为复杂时,你将不得不考虑这些问题.视图之间的关系,不仅仅是跳转,更重要的是视图之间数据的传递.当视图A 发生变化时,如何将这个变化告知视图B 呢? 举个例子吧. 如下图所

Kali Linux渗透测试五步曲

Kali Linux的设计目的是渗透测试.不管渗透测试者的起点是白盒测试.黑盒测试,还是灰盒测试,在用Kali或其它工具进行渗透测试时,总要遵循一些步骤. 第一步:侦察阶段 在发动攻击之前,渗透测试者应当尽量多地了解目标环境和系统的特点.渗透测试者找到的目标信息越多,就越有更好的机会确认最容易和最快的成功方法.与白盒测试相比,黑盒测试要求进行更多的侦察,因为测试者并没有获得太多的数据.侦察服务可能包括调查目标的互联网足迹.监视资源.监视人员.过程等,扫描网络信息(如IP地址和系统类型),社会工程