Activiti 流程变量

Source

转载自:http://blog.csdn.net/caoyue_new/article/details/52171472
###Person.java

package com.activiti.test;

import java.io.Serializable;

public class Person implements Serializable {

    private static final long serialVersionUID = -606400410705925986L;
    private String name;

    public String getName() {
        return name;
    }

    public void setName(String name) {
        this.name = name;
    }
}

###VaribablesTest.java

package com.activiti.test;

import java.util.Date;
import java.util.List;

import org.activiti.engine.ProcessEngine;
import org.activiti.engine.ProcessEngines;
import org.activiti.engine.RuntimeService;
import org.activiti.engine.TaskService;
import org.activiti.engine.history.HistoricVariableInstance;
import org.activiti.engine.task.Task;
import org.junit.Test;

public class VariablesTest {

    ProcessEngine processEngine = ProcessEngines.getDefaultProcessEngine();

/**
     * 部署流程定义
     */
    @Test
    public void deploy() {
        InputStream in = this.getClass().getClassLoader().getResourceAsStream("diagrams/leave.zip");
        ZipInputStream zipInputStream = new ZipInputStream(in);
        Deployment deploy = processEngine.getRepositoryService()
                .createDeployment()
                .name("请假流程")
                .addZipInputStream(zipInputStream)
                .deploy();
        System.out.println("部署ID:" + deploy.getId());
        System.out.println("部署名称:" + deploy.getName());
    }

    /**
     * 启动流程实例
     */
    @Test
    public void startProcessInstance() {
        ProcessInstance pi = processEngine.getRuntimeService().startProcessInstanceByKey("Leave");
        System.out.println("流程定义的ID:" + pi.getProcessDefinitionId());
        System.out.println("流程实例的ID:" + pi.getId());
    }

    /**
     * 设置流程变量(将变量存放在任务中) 
     * 流程变量的作用域就是流程实例,所以只要设置就行了,不用管在哪个阶段设置
     */
    @Test
    public void setVariables() {
        TaskService taskService = processEngine.getTaskService();
        String assignee = "张三";//任务办理人
        String processInstanceId = "37501"; //流程实例ID
        //获取当前任务
        Task task = taskService.createTaskQuery()
                .taskAssignee(assignee)
                .processInstanceId(processInstanceId)
                .singleResult();
        //设置任务变量 (变量中存放基本数据类型)
        taskService.setVariable(task.getId(), "请假人", "crystal");
        taskService.setVariable(task.getId(), "请假天数", 2);
        taskService.setVariable(task.getId(), "请假日期", new Date());
        //变量中存放javabean对象,前提:让javabean对象实现implements java.io.Serializable
        Person p = new Person();
        p.setName("翠花");
        taskService.setVariable(task.getId(), "人员信息", p);
        taskService.complete(task.getId());
    }

    /**
     * 获取流程变量
     */
    @Test
    public void queryVariables() {
        TaskService taskService = processEngine.getTaskService();
        String assignee = "李四";//任务办理人
        String processInstanceId = "37501"; //流程实例ID
        //获取当前任务
        Task task = taskService.createTaskQuery()
                .taskAssignee(assignee)
                .processInstanceId(processInstanceId)
                .singleResult();
        /**一:变量中存放基本数据类型*/
        //String stringValue = (String) taskService.getVariable(task.getId(), "请假人");
        //Integer integerValue = (Integer) taskService.getVariable(task.getId(), "请假天数");
        //Date dateValue = (Date) taskService.getVariable(task.getId(), "请假日期");
        //System.out.println(stringValue+"     "+integerValue+"     "+dateValue);
        /**二:变量中存放javabean对象,前提:让javabean对象实现implements java.io.Serializable*/
        /**
         * 获取流程变量时注意:流程变量如果是javabean对象,除了要求实现Serializable之外,
         * 同时要求流程变量对象的属性不能发生发生变化,否则抛出异常
         * 解决方案:在设置流程变量的时候,在javabean的对象中使用:
         * private static final long serialVersionUID = -8065294171680448312L;
         */
        Person p = (Person) taskService.getVariable(task.getId(), "人员信息");
        System.out.println(p.getName());
    }

    /**
     * 查询流程变量的历史表
     */
    @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()+"\n"+hvi.getProcessInstanceId()+"\n"+hvi.getVariableName()+"\n"+hvi.getVariableTypeName()+"\n"+hvi.getValue());
                System.out.println("==============================================");
            }
        }
    }
}

###说明:

1) 流程变量的获取针对流程实例(即1个流程),每个流程实例获取的流程变量时不同的
2) 使用基本类型获取流程变量,在 taskService 中使用任务 ID,流程变量的名称,获取流程变量的值。
3) Javabean 类型设置获取流程变量,除了需要这个 javabean 实现了Serializable 接口外,还要求流程变量对象的属性不能发生变化,否则抛出异常。解决方案,固定序列化 ID。
设置变量的时机

###设置流程变量
runtimeService.setVariable(executionId, variableName, value)//表示使用执行对象ID,和流程变量的名称,设置流程变量的值(一次只能设置一个值)
runtimeService.setVariables(executionId, variables)//表示使用执行对象ID,和Map集合设置流程变量,map集合的key就是流程变量的名称,map集合的value就是流程变量的值(一次设置多个值)
taskService.setVariable(taskId, variableName, value)//表示使用任务ID,和流程变量的名称,设置流程变量的值(一次只能设置一个值)
taskService.setVariables(taskId, variables)//表示使用任务ID,和Map集合设置流程变量,map集合的key就是流程变量的名称,map集合的value就是流程变量的值(一次设置多个值)
runtimeService.startProcessInstanceByKey(processDefinitionKey, variables);//启动流程实例的同时,可以设置流程变量,用Map集合
taskService.complete(taskId, variables)//完成任务的同时,设置流程变量,用Map集合
获取流程变量
runtimeService.getVariable(executionId, variableName);//使用执行对象ID和流程变量的名称,获取流程变量的值
runtimeService.getVariables(executionId);//使用执行对象ID,获取所有的流程变量,将流程变量放置到Map集合中,map集合的key就是流程变量的名称,map集合的value就是流程变量的值
runtimeService.getVariables(executionId, variableNames);//使用执行对象ID,获取流程变量的值,通过设置流程变量的名称存放到集合中,获取指定流程变量名称的流程变量的值,值存放到Map集合中
taskService.getVariable(taskId, variableName);//使用任务ID和流程变量的名称,获取流程变量的值
taskService.getVariables(taskId);//使用任务ID,获取所有的流程变量,将流程变量放置到Map集合中,map集合的key就是流程变量的名称,map集合的value就是流程变量的值
taskService.getVariables(taskId, variableNames);//使用任务ID,获取流程变量的值,通过设置流程变量的名称存放到集合中,获取指定流程变量名称的流程变量的值,值存放到Map集合中

1)RuntimeService对象可以设置流程变量和获取流程变量
2)TaskService对象可以设置流程变量和获取流程变量
3)流程实例启动的时候可以设置流程变量
4)任务办理完成的时候可以设置流程变量
5)流程变量可以通过名称/值的形式设置单个流程变量
6)流程变量可以通过Map集合,同时设置多个流程变量 Map集合的key表示流程变量的名称 Map集合的value表示流程变量的值
###扩展:setVariable和setVariableLocal的区别

setVariable: 设置流程变量的时候,流程变量名称相同的时候,后一次的值替换前一次的值,而且可以看到TASK_ID的字段不会存放任务ID的值
setVariableLocal:
1)设置流程变量的时候,针对当前活动的节点设置流程变量,如果一个流程中存在2个活动节点,对每个活动节点都设置流程变量,即使流程变量的名称相同,后一次的版本的值也不会替换前一次版本的值,它会使用不同的任务ID作为标识,存放2个流程变量值,而且可以看到TASK_ID的字段会存放任务ID的值。
2)还有,使用 setVariableLocal 说明流程变量绑定了当前的任务,当流程继续执行时,下个任务获取不到这个流程变量(因为正在执行的流程变量中没有这个数据),所有查询正在执行的任务时不能查询到我们需要的数据,此时需要查询历史的流程变量。