上一篇我們看了流程執行時的流程實例,任務,和執行對象,我們接着看流程變量。
流程變量
1.流程圖
流程變量在整個工作流中扮演很重要的作用。例如:請假流程中有請假天數、請假原因等一些參數都爲流程變量的範圍。流程變量的作用域範圍是只對應一個流程實例。也就是說各個流程實例的流程變量是不相互影響的。流程實例結束完成以後流程變量還保存在數據庫中(存放到流程變量的歷史表中)。
2.部署流程定義
private final ProcessEngine processEngine = ProcessEngines.getDefaultProcessEngine();
/**
* 功能: 部署流程定義(從InputStream).<br/>
* date: 2014年12月23日 下午3:40:40 <br/>
*
* @author [email protected]
*/
@Test
public void deploymentProcessDefinitionByInputStream() {
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());
}
3.啓動流程實例
/**
* 功能: 啓動流程實例.<br/>
* date: 2014年12月23日 下午3:45:37 <br/>
*
* @author [email protected]
*/
@Test
public void startProcessInstance() {
// 流程定義的key
String processDefinitionKey = "processVariables";
ProcessInstance pi = processEngine.getRuntimeService()// 獲取正在執行的流程實例和執行對象相關的Service
.startProcessInstanceByKey(processDefinitionKey); // 使用流程定義的key啓動流程實例
// key
// 對應processVariables.bpmn中的Id屬性
System.out.println(pi.getId()); // 流程實例Id 2201
System.out.println(pi.getProcessDefinitionId()); // 流程定義Id
// processVariables:1:1604
}
act_ru_task 任務表
任務ID 執行對象ID 流程實例ID
4.設置流程變量
/**
* 功能: 設置流程變量.<br/>
* date: 2014年12月23日 下午3:58:36 <br/>
*
* @author [email protected]
*/
@Test
public void setVariables() {
TaskService taskService = processEngine.getTaskService();
// 任務Id
String taskId = "2704";
/** 1.使用基本數據類型設置流程變量 **/
taskService.setVariableLocal(taskId, "請假天數", 3); // 與任務ID綁定
taskService.setVariable(taskId, "請假日期", new Date());
taskService.setVariable(taskId, "請假原因", "回家養病,大概一週把!");
/** 2.使用Javabean類型設置流程變量 **/
User user = new User();
user.setId(10);
user.setName("小紅");
taskService.setVariable(taskId, "用戶信息", user);
System.out.println("設置成功!");
}
說明:
1)流程變量的作用域就是流程實例,所以只要設置就行了,不用管在哪個階段設置
2)基本類型設置流程變量,在taskService中使用任務ID,定義流程變量的名稱,設置流程變量的值
3)Javabean類型設置流程變量,需要這個javabean實現了Serializable接口
4)設置流程變量的時候,向act_ru_variable這個表添加數據
act_ru_variable #正在執行的流程變量表
5.獲取流程變量
/**
* 功能: 獲取流程變量.<br/>
* date: 2014年12月23日 下午3:59:11 <br/>
*
* @author [email protected]
*/
@Test
public void getVariables() {
TaskService taskService = processEngine.getTaskService();
// 任務Id
String taskId = "2204";
/** 1.基本數據類型獲取流程變量 */
Integer days = (Integer) taskService.getVariable(taskId, "請假天數");
Date date = (Date) taskService.getVariable(taskId, "請假日期");
String comment = (String) taskService.getVariable(taskId, "請假原因");
System.out.println("請假天數:" + days + "\n 請假日期:" + date + "\n 請假原因:" + comment);
/** 2.Javabean類型獲取流程變量 */
User u = (User) taskService.getVariable(taskId, "用戶信息");
System.out.println("id:" + u.getId() + " name:" + u.getName());
}
說明:
1)流程變量的獲取針對流程實例(1個流程),每個流程實例獲取的流程變量是不同的
2)使用基本類型獲取流程變量,在taskService中使用任務ID,流程變量的名稱,獲取流程變量的值。
3)Javabean類型設置獲取流程變量,除了需要這個javabean實現了Serializable接口外,還要求流程變量對象的屬性不能發生變化,否則拋出異常。解決方案,固定序列化ID
6.模擬設置和獲取流程變量
/**
* 功能: 模擬設置和獲取流程變量.<br/>
* date: 2014年12月23日 下午4:00:11 <br/>
*
* @author [email protected]
*/
@Test
public void setAndGetVariables() {
RuntimeService runtimeService = processEngine.getRuntimeService();
TaskService taskService = processEngine.getTaskService();
/** 設置流程變量 **/
// runtimeService.setVariable(executionId, variableName, value);
// runtimeService.setVariables(executionId, variables);
// taskService.setVariable(taskId, variableName, value);
// 使用任務Id,和流程變量的名稱,設置流程變量的值
// taskService.setVariables(taskId, variables);使用任務Id,和Map集合設置流程變量,設置多個值
// runtimeService.startProcessInstanceByKey(processDefinitionKey,variables);啓動流程實例的同時,可以設置流程變量,使用Map集合
// taskService.complete(taskId, variables);完成任務的同時,設置流程變量,使用Map集合
/** 獲取流程變量 **/
// runtimeService.getVariable(executionId,variableName);使用執行對象Id和流程變量名稱,獲取值
// runtimeService.getVariables(executionId);使用執行對象Id,獲取所有的流程變量,返回Map集合
// runtimeService.getVariables(executionId,variableNames);使用執行對象Id,獲取流程變量的值,通過設置流程變量的名稱存放到集合中,獲取指定流程變量名稱的流程變量的值,值存放到Map中
// taskService.getVariable(taskId,variableName);使用任務Id和流程變量名稱,獲取值
// taskService.getVariables(taskId);使用任務Id,獲取所有的流程變量,返回Map集合
// taskService.getVariables(taskId,variableNames);使用任務Id,獲取流程變量的值,通過設置流程變量的名稱存放到集合中,獲取指定流程變量名稱的流程變量的值,值存放到Map中
}
說明:
1)RuntimeService對象可以設置流程變量和獲取流程變量
2)TaskService對象也可以設置流程變量和獲取流程變量
3)流程實例啓動的時候可以設置流程變量
4)任務辦理完成的時候可以設置流程變量
5)流程變量可以通過名稱/值的形式設置單個流程變量
6)流程變量可以通過Map集合,同時設置多個流程變量,Map集合的key表示流程變量的名稱,value表示流程變量的值
7.查詢歷史的流程變量
/**
* 功能: 查詢歷史的流程變量.<br/>
* date: 2015年1月4日 下午4:42:17 <br/>
*
* @author [email protected]
*/
@Test
public void findHistoryProcessVariables() {
List<HistoricVariableInstance> list = processEngine.getHistoryService()//
.createHistoricVariableInstanceQuery() // 創建一個歷史的流程變量查詢對象
.variableName("請假天數").list();
if (null != list && list.size() > 0) {
for (HistoricVariableInstance hvi : list) {
System.out.println(hvi.getId() + " " + hvi.getProcessInstanceId() + " " + hvi.getVariableName() + " "
+ hvi.getVariableTypeName() + " " + hvi.getValue());
System.out.println("###################################");
}
}
}
說明:歷史的流程變量查詢,指定流程變量的名稱,查詢act_hi_varinst表(也可以針對,流程實例ID,執行對象ID,任務ID查詢)。
8.流程變量支持的類型
從圖中的官方文檔可以看出包括了大部分封裝類型和Date、String和實現了Serializable接口的類的類型。
總結:
1.流程變量
在流程執行或者任務執行的過程中,用於設置和獲取變量,使用流程變量在流程傳遞的過程中傳遞業務參數。
對應的表:
act_ru_variable:正在執行的流程變量表
act_hi_varinst:流程變量歷史表
2.setVariable和setVariableLocal的區別
setVariable:設置流程變量的時候,流程變量名稱相同的時候,後一次的值替換前一次的值,而且可以看到TASK_ID的字段不會存放任務ID的值
setVariableLocal:
1)設置流程變量的時候,針對當前活動的節點設置流程變量,如果一個流程中存在2個活動節點,對每個活動節點都設置流程變量,即使流程變量的名稱相同,後一次的版本的值也不會替換前一次版本的值,它會使用不同的任務ID作爲標識,存放2個流程變量值,而且可以看到TASK_ID的字段會存放任務ID的值
例如act_hi_varinst 表的數據:不同的任務節點,即使流程變量名稱相同,存放的值也是不同的。
如圖:
2)還有,使用setVariableLocal說明流程變量綁定了當前的任務,當流程繼續執行時,下個任務獲取不到這個流程變量(因爲正在執行的流程變量中沒有這個數據),所有查詢正在執行的任務時不能查詢到我們需要的數據,此時需要查詢歷史的流程變量。