1. 流程圖
流程變量在整個工作流中扮演很重要的作用。例如:請假流程中有請假天數、請假原因等一些參數都爲流程變量的範圍。流程變量的作用域範圍是只對應一個流程實例。也就是說各個流程實例的流程變量是不相互影響的。流程實例結束完成以後流程變量還保存在數據庫中(存放到流程變量的歷史表中)。
例如:
即:
2. 部署流程定義
/**
* this.getClass().getClassLoader().getResourceAsStream("testVariables.bpmn")從classspath根目錄下加載指定名稱的文件
* this.getClass().getResourceAsStream("testVariables.bpmn") 從當前包下載指定名稱的文件
* this.getClass().getResourceAsSteam("/testVariables.bpmn") 從classpath根目錄下加載指定名稱的文件
* @throws Exception
* /
// 部署流程定義
@Test
public void deploy_inputstream() throws Exception {
InputStream inputStream = this.getClass().getResourceAsSteam("/diagrams/testVariables.bpmn");
InputStream inputStreamPng = this.getClass().getResourceAsStream("/diagrams/testVariables.png");
Deployment deployment = processEngine.getRepositoryService()
.createDeployment()
.name("審批流程(流程變量)")
.addInputStream("testVariables1.bpmn", inputStream)//指定資源名稱
.addInputStream("testVariables1.png", inputStreamPng)//指定資源名稱
.deploy();// 發佈流程
System.out.println(deployment.getId()+" "+deployment.getName());
}
說明:
· 輸入流加載資源文件的3種方式
InputStream inputStream = this.getClass().getClassLoader().getResourceAsStream("diagrams/testVariables.bpmn");
InputStream inputStreamPng = this.getClass().getClassLoader().getResourceAsStream("diagrams/testVariables.png");
InputStream inputStream = this.getClass().getClass().getResourceAsStream("testVariables.bpmn");
InputStream inputStreamPng = this.getClass().getResourceAsStream("testVariables.png");
<font color=red>*this.getClass().getClassLoader().getResourceAsStream("testVariables.bpmn")//從classpath根目錄下加載指定名稱的文件</font>
<font color=red>*this.getClass().getResourceAsStream("testVariables.bpmn")//從當前包下加載指定名稱的文件</font>
<font color=red>*this.getClass().getResourceAsStream("/testVariables.bpmn")//從classpath根目錄下加載指定名稱的文</font>件
3. 啓動流程實例
// 啓動 流程
@Test
public void startProcess() throws Exception {
String processDefinitionKey = "myVariables";
// 在啓動時設置流程變量
ProcessInstance pi = processEngine.getRuntimeService().startProcessInstanceByKey(processDefinitionKey);
System.out.println("pid:"+pi.getId());
}
4. 設置流程變量
/**設置流程變量*/
@Test
public void setVariables() {
// 獲取執行的Service
TaskService taskService = processEngine.getTaskService();
// 指定辦理人
String assigneeUser = "張三";
// 流程實例ID
String processInstanceId = "1101";
Task task = taskService.createTaskQuery()//創建任務查詢
.taskAssignee(assigneeUser)//指定辦理人
.processInstanceId(processInstanceId)//指定流程實例ID
.singleResult();
/**一:變量中存放基本數據類型*/
taskService.setVarriable(task.getId(), "請假人", "張無忌123456");// 使用流程變量的名稱和流程變量的值設置流程變量,一次只能設置一個值
taskService.setVariableLocal(task.getId(),"請假天數", 6);
taskservice.setVariable(task.getId(), "請假日期", new Date());
/**二:變量中存放javabean對象,前提:讓javabean對象實現implements java.io.Serializable*/
Person p = new Person();
p.setId(1L);
p.setName("翠花");
taskService.setVariable(task.getId(), "人員信息", p);
}
說明:
- 流程變量的作用域就是流程實例,所以只要設置就行了,不用管在哪個階段設置
- 基本類型設置流程變量,在taskService中使用任務ID,定義流程變量的名稱,設置流程變量的值。
3) Javabean類型設置流程變量,需要這個javabean實現了Serializable接口 - 設置流程變量的時候,向act_ru_variable這個表添加數據
5. 獲取流程變量
/**獲取流程變量*/
@Test
public void getVariables() {
// 獲取執行的Service
TaskService taskService = processEngine.getTaskService();
// 指定辦理人
String assigneeUser = "李四";
// 流程實例ID
String processInstanceId = "1101";
Task task = taskService.createTaskQuery()//創建任務查詢
.taskAssignee(assigneeUser)//指定辦理人
.processInstanceId(processInstanceId)//指定流程實例ID
.singleResult();
/**一: 變量中存放基本數據類型*/
String stringValue = (String) taskService.getVariable(task.getId(), "請假人");
Integer integerValue = (integer) taskService.getVariableLocal(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 = -2452345243523452345L;
* /
Person p = (Person)taskService.getVariable(task.getId(), "人員信息");
System.out.pringln(p.getId());
System.out.println(p.getName());
}
說明:
1) 流程變量的獲取針對流程實例(即1個流程),每個流程實例獲取的流程變量時不同的
2) 使用基本類型獲取流程變量,在taskService中使用任務ID,流程變量的名稱,獲取流程變量的值。
3) Javabean類型設置獲取流程變量,除了需要這個javabean實現了Serializable接口外,還要求流程變量對象的屬性不能發生變化,否則拋出異常。解決方案,固定序列化ID。
6. 模擬流程變量的設置和獲取的場景
public void setAndGetvariables() {
RuntimeService runtimeService = processEngine.getRuntimeService();
TaskService taskService = processEngine.getTaskService();
// ==============================================
// 設置變量的方法
// 通過Execution設置一個變量
runtimeService.setVariable(executionId, name, value);
// 通過Execution設置多個變量
runtimeService.setVariable(executionId, variablesMap);
// 通過Task設置一個變量
taskService.setVariable(taskId, variableName, value);
// 在啓動流程實例時,同時也設置一些流程變量
taskService.complete(taskId, variables);
// =============================================
// 獲取變量的方法
// 通過Excution獲取一個變量
runtimeService.getVariable(executionId, variableName);
// 通過Execution獲取所有變量的信息,存放在Map集合中
runtimeService.getVariables(executionId);
// 通過Execution獲取指定流程變量名稱的變量值得信息,存放到Map集合中
runtimeService.getVariables(executionId, variableNames);
// 通過Task獲取一個變量
taskService.getVariable(taskId, variableName);
// 通過Task獲取所有變量的信息,存放到Map集合中
taskService.getVariables(taskId);
// 通過Task獲取指定流程變量名稱的變量值信息,存放到Map集合中
taskService.getVariables(taskId, variableNames);
}
說明:
1) RuntimeService對象可以設置流程變量和獲取流程變量
2) TaskService對象可以設置流程變量和獲取流程變量
3) 流程實例啓動的時候可以設置流程變量
4) 任務辦理完成的時候可以設置流程變量
5) 流程變量可以通過名稱/值的形式設置單個流程變量
6) 流程變量可以通過Map集合,同時設置多個流程變量
Map集合的key表示流程變量的名稱
Map集合的value表示流程變量的值
8. 流程變量的支持的類型
如圖是從官網列出來的流程變量的類型:
從圖中可以看出包括了大部分封裝類型和Date、String和實現了Serializable接口的類的類型。
9. 總結
1. 流程變量
在流程執行或者任務執行的過程中,用於設置和獲取變量,使用流程變量在流程傳遞的過程中傳遞業務參數。
對應的表:
act_ru_variable:正在執行的流程變量表
act_hi_varinst:流程變量歷史表
2. 擴展知識:setVariable和setVariableLocal的區別
setVariable:設置流程變量的時候,流程變量名稱相同的時候,後一次的值替換前一次的值,而且可以看到TASK_ID的字段不會存放任務ID的值
setVariableLocal:
- 設置流程變量的時候,針對當前活動的節點設置流程變量,如果一個流程中存在2個活動節點,對每個活動節點都設置流程變量,即使流程變量的名稱相同,後一次的版本的值也不會替換前一次版本的值,它會使用不同的任務ID作爲標識,存放2個流程變量值,而且可以看到TASK_ID的字段會存放任務ID的值
例如act_hi_varinst 表的數據:不同的任務節點,即使流程變量名稱相同,存放的值也是不同的。
如圖:
- 還有,使用setVariableLocal說明流程變量綁定了當前的任務,當流程繼續執行時,下個任務獲取不到這個流程變量(因爲正在執行的流程變量中沒有這個數據),所有查詢正在執行的任務時不能查詢到我們需要的數據,此時需要查詢歷史的流程變量。