學習來源
https://www.bilibili.com/video/BV1Pb4y1p7Ku?p=1
很重要的東西
一. 關於 Flowable 的介紹就不寫了,自己去看上面的視頻
二. 首先腦海中必須有一幅圖
這里是整工作流引擎的使用窗口工具。
1.PeocessEngine
這個類是 flowable 工作流的執行引擎,后續所有的子工具使用都是從這個類出發構建的。
2.RepositoryService
可以想象成所有的執行流程圖都是存放在這個類的倉庫里的。
只有一張圖在那里工作流是肯定不能開始扭轉的,你必須把這張圖從倉庫中拿出來,告知給引擎,也就是部署。
這張圖是在Repository 這個倉庫里的 那么 Repository 也有能力讓這張圖消失,也就是刪除。
3.RuntimeService
這個類顧名思義,運行時服務,負責將部署進引擎的圖跑起來,並且填充這張圖里基本參數,也就時流程變量,圖一定是憑借類似於 if else 這種分支跳轉運行的
4.TaskService
圖運轉起來了,每個節點都是對應的處理人,對於人來將這就是個任務,那么就可以通過TaskService 來拉取任務,執行任務,完成任務。
5.HistoryService
任務執行完了,理所當然的可以得到執行任務的歷史信息,這些信息可以用來做數據分析等諸如此類的事情
三.對於數據庫
個人認為,flowable 的數據庫表是非常多的,雖然有一定的規律,但是如果是初次入門,可以先放一放,但是對於被部署的圖必須是十分清楚的
就比如說視頻中當教材的這張圖
https://tkjohn.github.io/flowable-userguide/
這個網址去找對應的圖的 xml 文件
實操正文
先搭建環境 ,建議先搭建 maven 環境 ,先不要搭建 spring 環境 ,先熟悉基本操作 ,並且不要糾結使用到的 API 基本見名知意,而且是鏈式編程,按照常理的邏輯想就可以了。
`
<dependency>
<groupId>org.flowable</groupId>
<artifactId>flowable-engine</artifactId>
<version>6.3.0</version>
</dependency>
<dependency>
<groupId>mysql</groupId>
<artifactId>mysql-connector-java</artifactId>
<version>8.0.21</version>
</dependency>
<dependency>
<groupId>junit</groupId>
<artifactId>junit</artifactId>
<version>4.13.2</version>
<scope>test</scope>
</dependency>
<dependency>
<groupId>junit</groupId>
<artifactId>junit</artifactId>
<version>4.12</version>
<scope>test</scope>
</dependency>
<dependency>
<groupId>org.slf4j</groupId>
<artifactId>slf4j-api</artifactId>
<version>1.7.21</version>
</dependency>
<dependency>
<groupId>org.slf4j</groupId>
<artifactId>slf4j-log4j12</artifactId>
<version>1.7.21</version>
</dependency>
`
創建 xml 文件 (就是那個流程圖文件)
在xml的第一個 userTask 中指定 負責人
創建日志文件(這個可有可無)
一. 獲取流程引擎
`
// 全局引擎
private ProcessEngine processEngine;
@Before
public void testProcessEngine() {
// 引擎全局配置對象 ,這里配置了數據庫
ProcessEngineConfiguration configuration = new StandaloneInMemProcessEngineConfiguration();
// 數據庫
configuration.setJdbcDriver("com.mysql.cj.jdbc.Driver");
configuration.setJdbcUsername("root");
configuration.setJdbcPassword("100544");
configuration.setJdbcUrl("jdbc:mysql://42.192.121.155:3306/flowable?serverTimezone=UTC&nullCatelogMeansCurrent=true");
// 創建表 默認的 35 張 參數是創建的表策略
configuration.setDatabaseSchemaUpdate(ProcessEngineConfiguration.DB_SCHEMA_UPDATE_TRUE);
// 獲取流程引擎
processEngine = configuration.buildProcessEngine();
}
`
獲取到流程引擎后 ,去打開你的數據庫 ,你會驚喜的發現出現了 34 張表 ,而且大有規律
二. 部署流程實例
`
// 部署流程實例
@Test
public void processDeployment() {
// 注意到這里 ,是引擎獲取的 RepositoryService 對象干活的
RepositoryService repository = processEngine.getRepositoryService();
// 這里部署也是 RepositoryService 對象部署的
Deployment deploy = repository.createDeployment()
.addClasspathResource("holiday-request.bpmn20.xml")
.name("請求流程").deploy();
String id = deploy.getId();
System.out.println(" id = " + id);
String name = deploy.getName();
System.out.println(" name = " + name);
}
`
部署完成后去查看你的 act_re_deployment act_re_procdef act_ge_bytearray 表
三. 查詢流程實例
`
// 查詢流程實例
@Test
public void processDeploymentQuery() {
// 這里也是 RepositoryService對象干活
RepositoryService repository = processEngine.getRepositoryService();
ProcessDefinitionQuery processDefinitionQuery = repository.createProcessDefinitionQuery();
// 這里注意 ,如果確定就一個 可以返回 singleResult 否則就返回 list ,不然會報錯
ProcessDefinition result = processDefinitionQuery.deploymentId("2501").singleResult();
String deploymentId = result.getDeploymentId();
String name = result.getName();
String description = result.getDescription();
System.out.println(deploymentId);
System.out.println(name);
System.out.println(description);
}
`
四.刪除部署的流程
`
// 刪除部署的流程
@Test
public void processDeploymentDelete() {
RepositoryService repository = processEngine.getRepositoryService();
// 根據流程id 刪除流程 ,可以設置級聯刪除,這個方法后面有個參數 true 就是級聯刪除 ,相關的任務一定會被刪除掉
repository.deleteDeployment("7501", true);
}
`
五.啟動流程實例
`
// 啟動流程實例
@Test
public void processDeploymentStart() {
// 運行時服務 注意看 此時的 對象已經變了 ,是 RuntimeService
RuntimeService runtimeService = processEngine.getRuntimeService();
// 構建流程變量
Map<String, Object> variables = new HashMap<>();
variables.put("employee", "張三");
variables.put("nroOfHolidays", 3);
variables.put("descrition", "老子累了");
// 根據主鍵啟動流程實例
ProcessInstance holidayRequest = runtimeService.startProcessInstanceByKey("holidayRequest", variables);
String processDefinitionId = holidayRequest.getProcessDefinitionId();
System.out.println(processDefinitionId);
String activityId = holidayRequest.getActivityId();
System.out.println(activityId);
}
`
啟動流程實例
引擎已經走到這里了
啟動實例涉及到的表結構
六. 查詢任務
`
@Test
public void queryTask() {
// 此時實例已經啟動了,啟動就是一個任務,那么相應的調用的也就是任務的服務
// 注意看這里 TaskService
TaskService service = processEngine.getTaskService();
List<Task> list = service.createTaskQuery()
.processDefinitionKey("holidayRequest")
.taskAssignee("zhangsan")
.list();
System.out.println(list.size());
for (Task task : list) {
System.out.println("任務鏈表");
System.out.println(task.getAssignee());
System.out.println(task.getDescription());
System.out.println(task.getId());
System.out.println(task.getName());
}
}
`
七.完成任務
`
@Test
public void completeTask() {
// TaskService
TaskService service = processEngine.getTaskService();
List
.processDefinitionKey("holidayRequest")
.taskAssignee("zhangsan")
.list();
// 流程變量 ,就那個網關里需要的值
HashMap<String, Object> map = new HashMap<>();
map.put("approved", false);
task.forEach((t) -> {
service.complete(t.getId(), map);
});
}
`
流程圖跳轉
完成任務就跑到這里來了
注意 : 流程圖中的完成任務 本例中走的是不同意 ,咱們需要實現不同意方向的實現類
代碼示例
`
// 注意實現的接口 這是一個類似出發器的東西
public class SendRejectionMail implements JavaDelegate {
@Override
public void execute(DelegateExecution delegateExecution) {
System.out.println(" 這里模擬發一封郵件 --------------------- ");
System.out.println(" 請求被拒接了 , 資本家是吸血的 ");
}
}
`
八.查看歷史任務
`
@Test
public void historyTaskQuery() {
// 注意看這里
HistoryService service = processEngine.getHistoryService();
List
.processDefinitionId("holidayRequest:1:12503")
.finished()
.list();
list.forEach((o)->{
System.out.println(o.getActivityName());
System.out.println(o.getActivityId());
System.out.println(o.getAssignee());
});
}
`
關於畫流程圖
視頻中的波哥使用的是 Eclipse
如果你會使用 docker 的話
去dockerhub 拉一個鏡像
https://hub.docker.com/r/flowable/flowable-ui
啟動后訪問 ip:8080/flowable-ui/modeler/
user:admin
password : test