前言
在用 RuntimeService 接口啟動流程實例時,總是分不清楚不同 startProcessInstanceXXX 接口之間的區別,這篇文章基于 Activiti 7.0.0.GA 版本,對這一類接口進行一個梳理和歸類。
詳解
接口列表
RuntimeService 接口中以 startProcessInstance 開頭的所有方法如下,共計 20 個。
ProcessInstance startProcessInstanceByKey(String processDefinitionKey);ProcessInstance startProcessInstanceByKey(String processDefinitionKey, String businessKey);ProcessInstance startProcessInstanceByKey(String processDefinitionKey, Map<String, Object> variables);ProcessInstance startProcessInstanceByKey(String processDefinitionKey, String businessKey, Map<String, Object> variables);ProcessInstance startProcessInstanceByKeyAndTenantId(String processDefinitionKey, String tenantId);ProcessInstance startProcessInstanceByKeyAndTenantId(String processDefinitionKey, String businessKey, String tenantId);ProcessInstance startProcessInstanceByKeyAndTenantId(String processDefinitionKey, Map<String, Object> variables, String tenantId);ProcessInstance startProcessInstanceByKeyAndTenantId(String processDefinitionKey, String businessKey, Map<String, Object> variables, String tenantId);ProcessInstance startProcessInstanceById(String processDefinitionId);ProcessInstance startProcessInstanceById(String processDefinitionId, String businessKey);ProcessInstance startProcessInstanceById(String processDefinitionId, Map<String, Object> variables);ProcessInstance startProcessInstanceById(String processDefinitionId, String businessKey, Map<String, Object> variables);ProcessInstance startProcessInstanceByMessage(String messageName);ProcessInstance startProcessInstanceByMessageAndTenantId(String messageName, String tenantId);ProcessInstance startProcessInstanceByMessage(String messageName, String businessKey);ProcessInstance startProcessInstanceByMessageAndTenantId(String messageName, String businessKey, String tenantId);ProcessInstance startProcessInstanceByMessage(String messageName, Map<String, Object> processVariables);ProcessInstance startProcessInstanceByMessageAndTenantId(String messageName, Map<String, Object> processVariables, String tenantId);ProcessInstance startProcessInstanceByMessage(String messageName, String businessKey, Map<String, Object> processVariables);ProcessInstance startProcessInstanceByMessageAndTenantId(String messageName, String businessKey, Map<String, Object> processVariables, String tenantId);
分類
分析以上接口,雖接口種類繁多,但總體可按以下幾種方式劃分歸類。
按啟動類型分類
按啟動類型分類,可分為三類,分別是:

按可傳變量
按接口是否可傳變量劃分,可分為兩類,分別是:

按接口名稱
按相同接口名稱分類(含重載),可分為 5 類 ,分別是:

按內外業務鍵
按內外業務鍵劃分,可分為兩類,分別是:

按租戶類型
按租戶類型劃分,分為單租戶和多租戶兩類,分別是:

知識點
processDefinitionKey 和 processDefinitionId 有什么區別?
processDefinitionKey 是我們在創建流程模型時定義的,而 processDefinitionId 是在流程后得到的。
假設定義一個 multi-product-manage.bpmn20.xml 流程模型文件,processDefinitionKey 是 multi-product-manage-k, 對這個流程模型文件部署三次,得到的 processDefinitionId 分別是:
- multi-product-manage-k:1:805003
- multi-product-manage-k:2:815003
- multi-product-manage-k:3:825003
在同一個 bpmn20.xml 文件被部署多個版本的情況下,如果以 processDefinitionKey(在這里取值 multi-product-manage-k)啟動流程實例,Activiti 會選擇最新部署的版本來啟動流程實例,也就是會以 product-manage-k:3:825003 的這個版本來啟動流程實例,不會去采用 multi-product-manage-k:1:805003 或者 multi-product-manage-k:2:815003 啟動流程。如果以 processDefinitionId 來啟動,傳入 multi-product-manage-k:1:805003,Activiti 就會按照我們指定的版本來啟動流程實例。
這個就是 processDefinitionKey 和 processDefinitionId 的最大區別。
舉例
processDefinitionKey 舉例。打開 Activiti Editor 流程模型編輯頁面,創建一個流程模型,需要我們輸入 model name 和 model key,以及 description。其中的 model key 就是 processDefinitionKey。

processDefinitionId 舉例。processDefinitionId 由 processDefinitionKey + 部署次數 + 數字組成,格式為:
processDefinitionKey:部署次數:數字
對生成的 multi-product-manage.bpmn20.xml 流程模型文件進行部署。
第一次部署,得到的 processDefinitionId 如下

第二次部署,得到的 processDefinitionId 如下

仔細觀察可發現,部署次數會隨著同一個 bpmn20.xml 文件的部署而遞增。由此 部署次數 數字就可以看出某個 bpmn20.xml 文件被部署了多少次。
startProcessInstance 中 bussinessKey 的應用場景
提示:應用場景由 deepseek 生成
businessKey在Activiti工作流引擎中是一個重要的概念,它用于將業務流程實例與業務數據關聯起來。以下是兩個典型的應用示例:
示例1:訂單審批流程
假設我們有一個訂單審批流程,需要將工作流與具體的訂單關聯:
// 啟動流程時關聯業務鍵
Order order = orderService.createOrder(); // 創建訂單業務對象
String businessKey = "ORDER_" + order.getId(); // 構建業務鍵// 啟動流程實例并關聯業務鍵
ProcessInstance processInstance = runtimeService.startProcessInstanceByKey("orderApprovalProcess", businessKey,variables
);// 通過業務鍵查詢流程實例
ProcessInstance instance = runtimeService.createProcessInstanceQuery().processInstanceBusinessKey(businessKey).singleResult();// 在用戶任務中獲取業務鍵
Task task = taskService.createTaskQuery().processInstanceBusinessKey(businessKey).singleResult();
這樣,在流程的任何環節,我們都能通過訂單ID(業務鍵)快速找到對應的流程實例,實現業務數據與流程的關聯。
示例2:請假申請流程
另一個常見場景是員工請假申請流程:
// 員工提交請假申請
LeaveApplication leave = new LeaveApplication();
leave.setEmployeeId("EMP1001");
leave.setDays(3);
leave.setReason("家庭事務");
leaveApplicationService.save(leave);// 使用請假單ID作為業務鍵啟動流程
String businessKey = "LEAVE_" + leave.getId();
Map<String, Object> variables = new HashMap<>();
variables.put("applicant", leave.getEmployeeId());
variables.put("days", leave.getDays());runtimeService.startProcessInstanceByKey("leaveApprovalProcess", businessKey, variables
);// 經理審批時通過業務鍵獲取請假單信息
List<Task> tasks = taskService.createTaskQuery().taskAssignee("manager1").list();for (Task task : tasks) {String bk = task.getBusinessKey();String leaveId = bk.replace("LEAVE_", "");LeaveApplication application = leaveApplicationService.findById(leaveId);// 顯示審批頁面...
}
通過businessKey,審批人可以快速獲取關聯的請假單詳細信息,審批完成后也能方便地更新業務數據狀態。
businessKey的主要作用:
- 建立業務流程與業務數據的關聯
- 方便通過業務ID查詢流程狀態
- 在流程處理中快速定位業務數據
- 實現業務數據和流程數據的松耦合關聯
在實際應用中,businessKey通常采用"業務類型_業務ID"的格式,如"ORDER_123"、"LEAVE_456"等,以確保唯一性和可讀性。