基於springboot的flowable工作流實例實現
flowableUI 創建實例教程 https://www.cnblogs.com/nanstar/p/11959389.html
Flowable 中文官網 https://tkjohn.github.io/flowable-userguide/#_deploying_a_process_definition
1、首先創建一空白的個springboot的項目
2、這里是編輯項目名稱,我這里寫的是flowabledemo
3、這個位置是選擇配置的,因為是demo所以我沒有選擇任何配置
4、這里輸入的是輸出文件夾的名稱,我選擇了和項目文件名一致
5、創建完成之后打開項目:
在pomx里添加flowable和mysql依賴(生成數據庫要用到),我選擇的是MySQL數據庫,因為我電腦上有現成的mysql
<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>
6、這時候他會自動下載相應的文件,等待事件有點長,我們可以去新加一個數據庫,已備后用。
新建flowable數據庫(數據庫名字自己設定)
7、然后在主函數入口部分添加數據庫信息(用來自動生成所需要的表,原來的那句話需要注釋或刪除掉)
// 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();
8、接着右鍵運行,生成數據庫表信息。然后會在控制台輸出很長的內容,等到輸出停止,去數據庫查看,會發現flowable數據庫中新建了很多表,這樣操作就可以繼續了。
在運行實例的時候,關於數據庫新建的這部分代碼是不需要注釋掉的(若數據庫有更新的化會自動更新數據庫內容)。
9、接着書寫一個關於請假的實例:
我們需要再resource文件夾里新加配置文件 holiday-request.bpmn20.xml,內容是:
<?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>
10、接着在入口函數(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");
}
11、接着需要在主函數的同級目錄下新建一個類文件 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"));
}
}
目錄層級展示
13、運行截圖:
這時候是員工身份進行操作。
依次輸入:姓名 請假時長 請假理由
14、敲擊回車,這時候會進入到管理者的角色,會讓你選擇處理哪一個請假事務,顯示的是有16個任務,向上滾動可以查看具體的內容的編號,我們剛才新建的任務編號是14,所以這里輸入14,敲擊回車繼續
15、這時候會列出請假者的名字,請假時長,需要你輸入y來同意這個請假請求。
16、然后敲擊回車,程序完成,並輸出相關信息。
於是,一個簡單的flowable工作流實例就算是完成了!
點擊下載源文件
點我 Touch Me