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


    一、前言

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

    二、正文

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

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

    如图:

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

    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:

    部署流程定义:

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


    运行结果:

        部署ID:701

        部署名称:流程定义

    启动流程实例:

    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.  
       
    11.  
      System.out.println("流程实例ID:" + pi.getId());
    12.  
      System.out.println("流程定义ID:" + pi.getProcessDefinitionId());
    13.  
      System.out.println("流程实例ID" + pi.getProcessInstanceId());
    14.  
       
    15.  
      }


    运行结果:

        流程实例ID:801

        流程定义ID:processVariables:1:704

        流程实例ID801

    查询任务

    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的方法,同意获取流程变量也是不一样的:

    使用基本数据类型:

    设置流程变量

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

    运行结果:

        设置流程变量成功!

    获取流程变量

    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.  
       
    15.  
      System.out.println("请假天数:" + days);
    16.  
      System.out.println("请假日期:" + date);
    17.  
      System.out.println("请假原因:" + reason);
    18.  
       
    19.  
      }


    运行结果:

        请假天数:7

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

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

    使用javabean

    JavaBeanPerson

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



    设置流程变量

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


    运行结果:

        设置流程变量成功!

    获取流程变量

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


    运行结果:

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

    查询历史流程变量

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

    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.  
       
    19.  
      }


     

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

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

    三、总结

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

  • 相关阅读:
    LR和SVM的相同和不同
    Logistic Regression理论总结
    LibSVM源码剖析(java版)
    CTR预估中的贝叶斯平滑方法(二)参数估计和代码实现
    支持向量机(SVM)中的 SMO算法
    《这就是搜索引擎》框架图
    Leetcode 初刷(1)
    tf中softmax_cross_entropy_with_logits与sparse_softmax_cross_entropy_with_logits
    python 判断是否为中文
    sklearn使用小记GridSearchCV
  • 原文地址:https://www.cnblogs.com/sea520/p/13645581.html
Copyright © 2020-2023  润新知