流程例項
流程例項(ProcessInstance)代表流程定義的執行例項。一個流程例項包括了所有的執行節點。我們可以利用這個物件來了解當前流程例項的進度等資訊。例如:使用者或程式按照流程定義內容發起一個流程,這就是一個流程例項
流程定義和流程例項的圖解:
啟動流程例項並新增 BusinessKey(業務標識)
流程定義部署在 activiti 後,就可以在系統中通過 activiti 去管理該流程的執行,執行流程表示流程的一次執行
比如部署系統出差流程後,如果某使用者要申請出差這時就需要執行這個流程,如果另外一個使用者也要申請出差則也需要執行該流程,每個執行互不影響,每個執行是單獨的流程例項
啟動流程例項時,指定的 businesskey,就會在 act_ru_execution 流程例項的執行表中儲存businesskey
Businesskey,業務標識,通常為業務表的主鍵,業務標識和流程例項一一對應。業務標識來源於業務系統。儲存業務標識就是根據業務標識來關聯查詢業務系統的資料
比如:出差流程啟動一個流程例項,就可以將出差單的 id 作為業務標識儲存到 activiti 中,將來查詢 activiti 的流程例項資訊就可以獲取出差單的 id 從而關聯查詢業務系統資料庫得到出差單資訊
/**
* 新增業務 key 到 Activiti 的表
*/
@Test
public void addBusinessKey() {
// 1. 獲取流程引擎
ProcessEngine processEngine = ProcessEngines.getDefaultProcessEngine();
// 2. 獲取 RuntimeService
RuntimeService runtimeService = processEngine.getRuntimeService();
// 3. 啟動流程,新增 BusinessKey
ProcessInstance instance = runtimeService.startProcessInstanceByKey("evection", "1001");
// 4. 輸出
System.out.println("businessKey: " + instance.getBusinessKey());
}
流程定義的其他操作
1. 流程定義查詢
查詢流程相關資訊,包含流程定義,流程部署,流程定義版本
public void queryProcessDefinition() {
// 1. 獲取流程引擎
ProcessEngine processEngine = ProcessEngines.getDefaultProcessEngine();
// 2. 獲取 RepositoryService
RepositoryService repositoryService = processEngine.getRepositoryService();
// 3. 查詢當前所有的流程定義,返回流程定義資訊的集合
ProcessDefinitionQuery definitionQuery = repositoryService.createProcessDefinitionQuery();
List<ProcessDefinition> definitions = definitionQuery.processDefinitionKey("evection")
.orderByProcessDefinitionVersion() // 進行排序
.desc() // 倒序
.list();
// 4. 輸出資訊
for (ProcessDefinition definition : definitions) {
System.out.println("流程定義 id = " + definition.getId());
System.out.println("流程定義名稱 = " + definition.getName());
System.out.println("流程定義 key = " + definition.getKey());
System.out.println("流程定義版本 = " + definition.getVersion());
}
}
2. 流程定義刪除
public void deleteDeployment() {
// 1. 獲取流程引擎
ProcessEngine processEngine = ProcessEngines.getDefaultProcessEngine();
// 2. 獲取 RepositoryService
RepositoryService repositoryService = processEngine.getRepositoryService();
// 3. 通過部署 id 刪除流程部署資訊,如果該流程定義已有流程例項啟動則刪除時出錯
String deploymentId = "2501";
repositoryService.deleteDeployment(deploymentId);
// 設定 true 級聯刪除流程定義,即使該流程有流程例項啟動也可以刪除,設定 false 非級別刪除方式
// repositoryService.deleteDeployment(deploymentId, true);
}
3. 流程資源下載
我們把流程資原始檔上傳到資料庫,如果其他使用者想要檢視這些資原始檔,可以從資料庫下載資原始檔
/**
* 下載資原始檔,使用 Activiti 提供的 api 下載資原始檔,儲存到檔案目錄
*/
public void getDeployment() throws IOException {
// 1. 獲取流程引擎
ProcessEngine processEngine = ProcessEngines.getDefaultProcessEngine();
// 2. 獲取 RepositoryService
RepositoryService repositoryService = processEngine.getRepositoryService();
// 3. 獲取查詢物件 ProcessDefinitionQuery,查詢流程定義資訊
ProcessDefinition processDefinition = repositoryService.createProcessDefinitionQuery()
.processDefinitionKey("evection")
.singleResult();
// 4. 通過流程定義資訊,獲取部署 id
String deploymentId = processDefinition.getDeploymentId();
// 5. 通過 RepositoryService,傳遞部署 id 引數,讀取資源資訊
InputStream bpmnInput = repositoryService.getResourceAsStream(deploymentId, processDefinition.getResourceName());
// 6. 儲存資原始檔
File file = new File("g:/evectionFlow.bpmn");
FileOutputStream outputStream = new FileOutputStream(file);
IOUtils.copy(bpmnInput, outputStream);
bpmnInput.close();
outputStream.close();
}
4. 歷史記錄查詢
即使流程定義已經刪除了,流程執行的歷史資訊依然儲存在 activiti 的 act_hi_* 相關的表中,我們還是可以查詢流程執行的歷史資訊
public void findHistoryInfo() {
// 1. 獲取流程引擎
ProcessEngine processEngine = ProcessEngines.getDefaultProcessEngine();
// 2. 獲取 HistoryService
HistoryService historyService = processEngine.getHistoryService();
// 3. 獲取 actinst 表的查詢物件
HistoricActivityInstanceQuery instanceQuery = historyService.createHistoricActivityInstanceQuery();
// 4. 查詢 actinst 表
instanceQuery.processInstanceId("5001");
instanceQuery.orderByHistoricActivityInstanceStartTime();
// 5. 查詢所有內容
List<HistoricActivityInstance> activityInstanceList = instanceQuery.list();
// 6. 輸出
for (HistoricActivityInstance hi : activityInstanceList) {
System.out.println(hi.getActivityId());
System.out.println(hi.getActivityName());
System.out.println(hi.getProcessDefinitionId());
System.out.println(hi.getProcessInstanceId());
System.out.println("----------------------------");
}
}
5. 流程的掛起與啟用
某些情況可能由於流程變更需要將當前執行的流程暫停而不是直接刪除,流程暫停後將不會繼續執行。
/**
* 全部流程例項的掛起和啟用
*/
@Test
public void suspendAllProcessInstance() {
// 1. 獲取流程引擎
ProcessEngine processEngine = ProcessEngines.getDefaultProcessEngine();
// 2. 獲取 RepositoryService
RepositoryService repositoryService = processEngine.getRepositoryService();
// 3. 查詢流程定義
ProcessDefinition processDefinition = repositoryService.createProcessDefinitionQuery().processDefinitionKey("evection").singleResult();
// 4. 獲取當前流程定義的例項是否都是掛起狀態
boolean suspended = processDefinition.isSuspended();
// 5. 獲取流程定義的 id
String definitionId = processDefinition.getId();
// 6. 如果是掛起,改為啟用狀態,如果是啟用狀態,改為掛起狀態
if (suspended) {
repositoryService.activateProcessDefinitionById(definitionId, true, null);
} else {
repositoryService.suspendProcessDefinitionById(definitionId, true, null);
}
}
/**
* 掛起或啟用單個流程例項
*/
@Test
public void suspendSingleProcessInstance() {
// 1. 獲取流程引擎
ProcessEngine processEngine = ProcessEngines.getDefaultProcessEngine();
// 2. 獲取 RuntimeService
RuntimeService runtimeService = processEngine.getRuntimeService();
// 3. 得到當前流程例項的暫停狀態
ProcessInstance instance = runtimeService.createProcessInstanceQuery().processInstanceId("27501").singleResult();
boolean suspended = instance.isSuspended();
// 4. 獲取流程例項 id
String instanceId = instance.getId();
// 5. 如果是掛起,改為啟用狀態,如果是啟用狀態,改為掛起狀態
if (suspended) {
runtimeService.activateProcessInstanceById(instanceId);
} else {
runtimeService.suspendProcessInstanceById(instanceId);
}
}