Activiti 學習(二)—— Activiti 流程定義和部署
概述
在這一節,我們將創建一個 Activit 工作流,並啟動這個流程,主要包含以下幾個步驟:
-
定義流程,按照 BPMN 的規範,使用流程定義工具,用流程符號把整個流程描述出來
-
部署流程,把畫好的流程定義文件,加載到數據庫中,生成表的數據
流程設計器的使用
在 resources 目錄下創建一個 bpmn 目錄,用來存放流程定義文件。選中 bpmn 目錄,點擊菜單 New -> New Activity 6.x BPMN 2.x file,創建一個 *.bpmn20.xml。選中該文件,右鍵 view BPMN(Activity ) Diagram,可以看到 BPMN-Activiti-Diagram 流程設計頁面。在該頁面右鍵,可以在菜單選擇圖形,拖拽圖形,連線,即可完成流程設計圖
連線的時候,要選中圖形,這時在圖形的右上角會出現一個箭頭符號。雙擊選中箭頭符號,右鍵按住不放即可拉長完成連線
選中一個圖形,下方會出現一個屬性欄,以創建出差申請為例,這裡只填任務名稱和負責人
流程部署
流程部署就是將在設計器中定義的流程部署到 activiti 數據庫中,Activiti 提供了多種部署流程的方式,包括自動部署、classpath 部署、輸入流部署、zip/bar 部署和上傳部署等方式,下面分別進行介紹:
1. 自動部署
Activiti7 可以自動部署流程,前提是在 resources 目錄下,創建一個新的目錄 processes,用來放置 bpmn 文件
2. classpath 部署
classpath 部署方式為採用代碼進行部署,使用 Java 代碼實現如下:
public class ActivitDemo {
@Test
public void testDeployment() {
// 1. 創建 ProcessEngine
ProcessEngine processEngine = ProcessEngines.getDefaultProcessEngine();
// 2. 獲取 RepositoryService
RepositoryService repositoryService = processEngine.getRepositoryService();
// 3. 使用 service 進行流程部署,即把 bpmn 部署到數據庫,並定義流程的名稱
Deployment deploy = repositoryService.createDeployment()
// 定義流程資源名稱
.name("出差申請流程")
// 加載待部署的資源,可以多次引用
.addClasspathResource("bpmn/evection.bpmn20.xml")
// 完成部署
.deploy();
}
}
3. 輸入流部署
Activiti 提供了按輸入流(InputStream)方式部署資源,輸入流的來源可以有多種,例如本地計算機、classpath 讀取、網絡讀取方式等,下面是讀取本地計算機方式進行部署方式的示例代碼
public class ActivitDemo {
@Test
public void testDeployment() {
// 1. 創建 ProcessEngine
ProcessEngine processEngine = ProcessEngines.getDefaultProcessEngine();
// 2. 獲取 RepositoryService
RepositoryService repositoryService = processEngine.getRepositoryService();
// 3. 獲取輸入流
String filePath = "D:/workflow/bpmn/evection.bpmn20.xml";
FileInputStream fileIns = new FileInputStream(filePath);
// 4. 使用 service 進行流程部署
Deployment deploy = repositoryService.createDeployment()
.name("出差申請流程")
.addInputStream("bpmn/evection.bpmn20.xml", fileIns)
.deploy();
}
}
4. zip/bar 部署
將流程資源文件壓縮成 zip 包進行部署,同樣採用流的方式
public void deployProcessByZip() {
// 1. 獲取流程引擎
ProcessEngine processEngine = ProcessEngines.getDefaultProcessEngine();
// 2. 獲取 RepositoryService
RepositoryService repositoryService = processEngine.getRepositoryService();
// 3. 流程部署
InputStream inputStream = this.getClass()
.getClassLoader()
.getResourceAsStream("bpmn/evection.zip");
ZipInputStream zipInputStream = new ZipInputStream(inputStream);
repositoryService.createDeployment()
.addZipInputStream(zipInputStream)
.deploy();
}
5. 按字符串方式部署
採用字符串方式進行部署,實際是把一個字符串轉換為位元組流後進行部署,也為開發人員提供了多一種部署方式
public void deployProcessByStr() {
// 1. 獲取流程引擎
ProcessEngine processEngine = ProcessEngines.getDefaultProcessEngine();
// 2. 獲取 RepositoryService
RepositoryService repositoryService = processEngine.getRepositoryService();
// 3. 構建字符串
String str = "<?xml version=\"1.0\" encoding=\"UTF-8\"?><definitions>...</definitions>"
// 4. 流程部署
repositoryService.createDeployment()
.name("出差申請流程")
.addStr("bpmn/evection.bpmn20.xml", str)
.deploy();
}
採用字符串進行部署的優點是可以通過用戶界面定義一個流程,然後進行部署,或者在測試時,直接將流程代碼寫入程序,進行流程部署
6. 動態 BPMN 模型部署
通過在程序中動態生成流程模型方式進行部署,動態創建 BPMN,需要在程序中指定每一個元素,並給出元素間的關係,最後將這些元素整合為一個完整的 BPMN
public void testDeploymentByBPMN() {
// 1. 創建 BPMN 模型實例
BpmnModel bpmnModel = new BpmnModel();
// 2. 創建開始事件
StartEvent startEvent = new StartEvent();
startEvent.setId("startEvent");
startEvent.setName("動態創建開始節點");
// 3. 創建用戶任務
UserTask userTask = new UserTask();
userTask.setId("userTask1");
userTask.setName("用戶任務節點1");
// 4. 創建結束事件
EndEvent endEvent = new EndEvent();
endEvent.setId("endEvent");
endEvent.setName("動態創建結束節點");
// 5. 定義連接
ArrayList<SequenceFlow> sequenceFlows = new ArrayList<>();
ArrayList<SequenceFlow> toEnd = new ArrayList<>();
SequenceFlow s1 = new SequenceFlow();
s1.setId("sequenceFlow1");
s1.setName("開始節點指向用戶任務節點");
s1.setSourceRef("startEvent");
s1.setTargetRef("userTask1");
sequenceFlows.add(s1);
SequenceFlow s2 = new SequenceFlow();
s2.setId("sequenceFlow2");
s2.setName("用戶任務節點指向結束節點");
s2.setSourceRef("userTask1");
s2.setTargetRef("endEvent");
toEnd.add(s2);
startEvent.setOutgoingFlows(sequenceFlows);
userTask.setOutgoingFlows(toEnd);
userTask.setIncomingFlows(sequenceFlows);
endEvent.setIncomingFlows(toEnd);
Process process = new Process();
process.setId("process1");
process.setName("test");
process.addFlowElement(startEvent);
process.addFlowElement(s1);
process.addFlowElement(userTask);
process.addFlowElement(s2);
process.addFlowElement(endEvent);
bpmnModel.addProcess(process);
new BpmnAutoLayout(bpmnModel).execute();
// 6. 部署
ProcessEngine processEngine = ProcessEngines.getDefaultProcessEngine();
RepositoryService repositoryService = processEngine.getRepositoryService();
Deployment deploy = repositoryService.createDeployment()
.name("出差申請流程")
.addBpmnModel("evection.bpmn20.xml", bpmnModel)
.deploy();
}
7. 相關數據表分析
流程部署後,流程相關的資源全部以數據流的形式存儲到數據表中,實際運行中,流程的處理都是通過調用數據表中的相關資源進行處理,下面介紹流程相關的數據表:
-
act_re_deployment
流程部署表,用於存放流程定義的部署信息,部署一個流程就會增加一條記錄
-
act_re_procdef
流程定義表,用於存放流程定義的屬性信息,和 act_re_deployment 是一對多的關係,act_re_procdef 表可以有多條記錄,每條記錄對應 act_re_deployment 中的一條記錄
-
act_ge_bytearray
資源文件表,部署流程時,會將 BPMN 流程定義文件保存為一條記錄,如果部署的流程還包括其他資源,也會增加相應的記錄,例如 png 圖片文件