基於springboot的flowable工做流實例實現
flowableUI 建立實例教程 https://www.cnblogs.com/nanstar/p/11959389.htmlhtml
Flowable 中文官網 https://tkjohn.github.io/flowable-userguide/#_deploying_a_process_definition
一、首先建立一空白的個springboot的項目
二、這裏是編輯項目名稱,我這裏寫的是flowabledemo
三、這個位置是選擇配置的,由於是demo因此我沒有選擇任何配置
四、這裏輸入的是輸出文件夾的名稱,我選擇了和項目文件名一致
五、建立完成以後打開項目:
在pomx裏添加flowable和mysql依賴(生成數據庫要用到),我選擇的是MySQL數據庫,由於我電腦上有現成的mysqljava
<dependency> <groupId>org.flowable</groupId> <artifactId>flowable-engine</artifactId> <version>6.5.0-SNAPSHOT</version> </dependency> <dependency> <groupId>mysql</groupId> <artifactId>mysql-connector-java</artifactId> <version>5.1.45</version> </dependency>
六、這時候他會自動下載相應的文件,等待事件有點長,咱們能夠去新加一個數據庫,已備後用。
新建flowable數據庫(數據庫名字本身設定)mysql
七、而後在主函數入口部分添加數據庫信息(用來自動生成所須要的表,原來的那句話須要註釋或刪除掉)
// SpringApplication.run(FlowabledemoApplication.class, args); ProcessEngineConfiguration cfg = new StandaloneProcessEngineConfiguration() .setJdbcUrl("jdbc:mysql://localhost:3306/flowable") .setJdbcUsername("root") .setJdbcPassword("123456") .setJdbcDriver("com.mysql.jdbc.Driver") .setDatabaseSchemaUpdate(ProcessEngineConfiguration.DB_SCHEMA_UPDATE_TRUE); ProcessEngine processEngine = cfg.buildProcessEngine();
八、接着右鍵運行,生成數據庫表信息。而後會在控制檯輸出很長的內容,等到輸出中止,去數據庫查看,會發現flowable數據庫中新建了不少表,這樣操做就能夠繼續了。
在運行實例的時候,關於數據庫新建的這部分代碼是不須要註釋掉的(若數據庫有更新的化會自動更新數據庫內容)。git
九、接着書寫一個關於請假的實例:
咱們須要再resource文件夾裏新加配置文件 holiday-request.bpmn20.xml,內容是:github
<?xml version="1.0" encoding="UTF-8"?> <definitions xmlns="http://www.omg.org/spec/BPMN/20100524/MODEL" xmlns:xsi="http://www.w3.org/2001/XMLSchema-instance" xmlns:xsd="http://www.w3.org/2001/XMLSchema" xmlns:bpmndi="http://www.omg.org/spec/BPMN/20100524/DI" xmlns:omgdc="http://www.omg.org/spec/DD/20100524/DC" xmlns:omgdi="http://www.omg.org/spec/DD/20100524/DI" xmlns:flowable="http://flowable.org/bpmn" typeLanguage="http://www.w3.org/2001/XMLSchema" expressionLanguage="http://www.w3.org/1999/XPath" targetNamespace="http://www.flowable.org/processdef"> <process id="holidayRequest" name="Holiday Request" isExecutable="true"> <startEvent id="startEvent"/> <sequenceFlow sourceRef="startEvent" targetRef="approveTask"/> <userTask id="approveTask" name="Approve or reject request" flowable:candidateGroups="managers"/> <sequenceFlow sourceRef="approveTask" targetRef="decision"/> <exclusiveGateway id="decision"/> <sequenceFlow sourceRef="decision" targetRef="externalSystemCall"> <conditionExpression xsi:type="tFormalExpression"> <![CDATA[ ${approved} ]]> </conditionExpression> </sequenceFlow> <sequenceFlow sourceRef="decision" targetRef="sendRejectionMail"> <conditionExpression xsi:type="tFormalExpression"> <![CDATA[ ${!approved} ]]> </conditionExpression> </sequenceFlow> <serviceTask id="externalSystemCall" name="Enter holidays in external system" flowable:class="com.flowable.flowabledemo.CallExternalSystemDelegate"/> <sequenceFlow sourceRef="externalSystemCall" targetRef="holidayApprovedTask"/> <userTask id="holidayApprovedTask" name="Holiday approved" flowable:assignee="${employee}"/> <sequenceFlow sourceRef="holidayApprovedTask" targetRef="approveEnd"/> <serviceTask id="sendRejectionMail" name="Send out rejection email" flowable:class="com.flowable.flowabledemo.SendRejectionMail"/> <!--這裏的class須要注意,後邊跟的路徑是你項目類問價所在的相對位置,若運行的時候報錯,須要來修改這裏的位置代碼--> <sequenceFlow sourceRef="sendRejectionMail" targetRef="rejectEnd"/> <endEvent id="approveEnd"/> <endEvent id="rejectEnd"/> </process> </definitions>
十、接着在入口函數(main)下追加如下內容
/** * 部署工做流文件到流程引擎,其實就是將xml文件解析成Java對象,從而能夠在程序裏使用. */ RepositoryService repositoryService = processEngine.getRepositoryService(); Deployment deployment = repositoryService.createDeployment() .addClasspathResource("holiday-request.bpmn20.xml") .deploy(); /** * API使用 */ ProcessDefinition processDefinition = repositoryService.createProcessDefinitionQuery() .deploymentId(deployment.getId()) .singleResult(); System.out.println("Found process definition : " + processDefinition.getName()); /** * 初始化流程變量 */ Scanner scanner= new Scanner(System.in); System.out.println("Who are you?"); String employee = scanner.nextLine(); System.out.println("How many holidays do you want to request?"); Integer nrOfHolidays = Integer.valueOf(scanner.nextLine()); System.out.println("Why do you need them?"); String description = scanner.nextLine(); /** * 經過RuntimeService啓動一個流程實例,簡稱「啓動流程」,這裏就是啓動請假流程 */ RuntimeService runtimeService = processEngine.getRuntimeService(); Map<String, Object> variables = new HashMap<String, Object>(); variables.put("employee", employee); variables.put("nrOfHolidays", nrOfHolidays); variables.put("description", description); ProcessInstance processInstance = runtimeService.startProcessInstanceByKey("holidayRequest", variables); /** * 查詢某個用戶的任務 */ TaskService taskService = processEngine.getTaskService(); List<Task> tasks = taskService.createTaskQuery().taskCandidateGroup("managers").list(); System.out.println("You have " + tasks.size() + " tasks:"); for (int i=0; i<tasks.size(); i++) { System.out.println((i+1) + ") " + tasks.get(i).getName() + " created by [" + taskService.getVariables(tasks.get(i).getId()).get("employee") + "]"); } /** * 根據任務獲取到這個任務涉及的流程變量 */ System.out.println("Which task would you like to complete?"); int taskIndex = Integer.valueOf(scanner.nextLine()); Task task = tasks.get(taskIndex - 1); Map<String, Object> processVariables = taskService.getVariables(task.getId()); System.out.println(processVariables.get("employee") + " wants " + processVariables.get("nrOfHolidays") + " of holidays. Do you approve this?"); /** * 若是是y,則流程結束 */ boolean approved = scanner.nextLine().toLowerCase().equals("y"); variables = new HashMap<String, Object>(); variables.put("approved", approved); taskService.complete(task.getId(), variables); /** * 查詢歷史數據,每一個步驟的花費的時間 */ HistoryService historyService = processEngine.getHistoryService(); List<HistoricActivityInstance> activities = historyService.createHistoricActivityInstanceQuery() .processInstanceId(processInstance.getId()) .finished() .orderByHistoricActivityInstanceEndTime().asc() .list(); for (HistoricActivityInstance activity : activities) { System.out.println(activity.getActivityId() + " took " + activity.getDurationInMillis() + " milliseconds"); }
十一、接着須要在主函數的同級目錄下新建一個類文件 CallExternalSystemDelegate 內容是:
package com.flowable.flowabledemo; import org.flowable.engine.delegate.DelegateExecution; import org.flowable.engine.delegate.JavaDelegate; public class CallExternalSystemDelegate implements JavaDelegate { public void execute(DelegateExecution execution) { System.out.println("Calling the external system for employee " + execution.getVariable("employee")); } }
目錄層級展現
1三、運行截圖:
這時候是員工身份進行操做。 依次輸入:姓名 請假時長 請假理由spring
1四、敲擊回車,這時候會進入到管理者的角色,會讓你選擇處理哪個請假事務,顯示的是有16個任務,向上滾動能夠查看具體的內容的編號,咱們剛纔新建的任務編號是14,因此這裏輸入14,敲擊回車繼續
1五、這時候會列出請假者的名字,請假時長,須要你輸入y來贊成這個請假請求。
1六、而後敲擊回車,程序完成,並輸出相關信息。
因而,一個簡單的flowable工做流實例就算是完成了!
點擊下載源文件 點我 Touch Mesql