flowable.7z官方版下載丨最新版下載丨綠色版下載丨APP下載-123云盤
1、Flowable介紹
????????Flowable是BPMN的一個基于java的軟件實現,不過Flowable不僅僅包括BPMN,還有DMN決策表和CMMN Case管理引擎,并且有自己的用戶管理、微服務API等一系列功能,是一個服務平臺。
2、Flowable 基礎
官方手冊:Flowable BPMN 用戶手冊 (v 6.3.0)
1.創建ProcessEngine
????????創建一個基本的maven工程,可以是Eclipse也可以是其他IDEA。然后添加兩個依賴
- Flowable流程引擎。使我們可以創建一個ProcessEngine流程引擎對象,并訪問Flowable API。
- 一個是MySQL的數據庫驅動
在pom.xml文件中添加下列行:
<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>
????????然后創建一個普通的Java類,添加對應的main方法,首先要做的是初始化ProcessEngine流程引擎實例。這是一個線程安全的對象,因此通常只需要在一個應用中初始化一次。 ProcessEngine由ProcessEngineConfiguration實例創建。該實例可以配置與調整流程引擎的設置。 通常使用一個配置XML文件創建ProcessEngineConfiguration,但是(像在這里做的一樣)也可以編程方式創建它。 ProcessEngineConfiguration所需的最小配置,是數據庫JDBC連接:
public static void main(String[] args) {ProcessEngineConfiguration cfg = new StandaloneProcessEngineConfiguration().setJdbcUrl("jdbc:mysql://localhost:3306/flowable-learn?serverTimezone=UTC").setJdbcUsername("root").setJdbcPassword("123456").setJdbcDriver("com.mysql.cj.jdbc.Driver").setDatabaseSchemaUpdate(ProcessEngineConfiguration.DB_SCHEMA_UPDATE_TRUE);ProcessEngine processEngine = cfg.buildProcessEngine();
}
????????注意在mysql8.0中執行可能出現如下的錯誤:
????????出現這種情況只需要在mysql的連接字符串中添加上nullCatalogMeansCurrent=true,設置為只查當前連接的schema庫即可。
public static void main(String[] args) {ProcessEngineConfiguration cfg = new StandaloneProcessEngineConfiguration().setJdbcUrl("jdbc:mysql://localhost:3306/flowable-learn1?serverTimezone=UTC&nullCatalogMeansCurrent=true").setJdbcUsername("root").setJdbcPassword("123456").setJdbcDriver("com.mysql.cj.jdbc.Driver").setDatabaseSchemaUpdate(ProcessEngineConfiguration.DB_SCHEMA_UPDATE_TRUE);ProcessEngine processEngine = cfg.buildProcessEngine();}
????????然后應用運行沒有問題,但也沒有在控制臺提供有用的信息,只有一條消息提示日志沒有正確配置。Flowable使用SLF4J作為內部日志框架。在這個例子中,我們使用log4j作為SLF4J的實現。因此在pom.xml文件中添加下列依賴:
<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>
????????Log4j需要一個配置文件。在src/main/resources文件夾下添加log4j.properties文件,并寫入下列內容:
log4j.rootLogger=DEBUG, CAlog4j.appender.CA=org.apache.log4j.ConsoleAppender
log4j.appender.CA.layout=org.apache.log4j.PatternLayout
log4j.appender.CA.layout.ConversionPattern= %d{hh:mm:ss,SSS} [%t] %-5p %c %x - %m%n
????????重新運行應用。應該可以看到關于引擎啟動與創建數據庫表結構的提示日志:
????????同時可以看到創建了相關的表結構在數據庫中:
????????這樣就得到了一個啟動可用的流程引擎。接下來為它提供一個流程!
2.部署流程定義
??接下來我們構建一個非常簡單的請假流程,Flowable引擎需要流程定義為BPMN 2.0格式,這是一個業界廣泛接受的XML標準。 在Flowable術語中,我們將其稱為一個流程定義(process definition)。一個流程定義可以啟動多個流程實例(process instance)。流程定義可以看做是重復執行流程的藍圖。 在這個例子中,流程定義定義了請假的各個步驟,而一個流程實例對應某個雇員提出的一個請假申請。
??BPMN 2.0存儲為XML,并包含可視化的部分:使用標準方式定義了每個步驟類型(人工任務,自動服務調用,等等)如何呈現,以及如何互相連接。這樣BPMN 2.0標準使技術人員與業務人員能用雙方都能理解的方式交流業務流程。
??我們要使用的流程定義為:
流程定義說明:
-
我們假定啟動流程需要提供一些信息,例如雇員名字、請假時長以及說明。當然,這些可以單獨建模為流程中的第一步。 但是如果將它們作為流程的“輸入信息”,就能保證只有在實際請求時才會建立一個流程實例。否則(將提交作為流程的第一步),用戶可能在提交之前改變主意并取消,但流程實例已經創建了。 在某些場景中,就可能影響重要的指標(例如啟動了多少申請,但還未完成),取決于業務目標。
-
左側的圓圈叫做啟動事件(start event)。這是一個流程實例的起點。
-
第一個矩形是一個用戶任務(user task)。這是流程中用戶操作的步驟。在這個例子中,經理需要批準或駁回申請
-
取決于經理的決定,排他網關(exclusive gateway) (帶叉的菱形)會將流程實例路由至批準或駁回路徑
-
如果批準,則需要將申請注冊至某個外部系統,并跟著另一個用戶任務,將經理的決定通知給申請人。當然也可以改為發送郵件。
-
如果駁回,則為雇員發送一封郵件通知他。
????????一般來說,這樣的流程定義使用可視化建模工具建立,如Flowable Designer(Eclipse)或Flowable Web Modeler(Web應用)。但在這里我們直接撰寫XML,以熟悉BPMN 2.0及其概念。
??與上面展示的流程圖對應的BPMN 2.0 XML在下面顯示。請注意這只包含了“流程部分”。如果使用圖形化建模工具,實際的XML文件還將包含“可視化部分”,用于描述圖形信息,如流程定義中各個元素的坐標(所有的圖形化信息包含在XML的BPMNDiagram標簽中,作為definitions標簽的子元素)。
??將下面的XML保存在src/main/resources文件夾下名為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"/><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="org.flowable.CallExternalSystemDelegate"/><sequenceFlow sourceRef="externalSystemCall" targetRef="holidayApprovedTask"/><userTask id="holidayApprovedTask" name="Holiday approved"/><sequenceFlow sourceRef="holidayApprovedTask" targetRef="approveEnd"/><serviceTask id="sendRejectionMail" name="Send out rejection email"flowable:class="org.flowable.SendRejectionMail"/><sequenceFlow sourceRef="sendRejectionMail" targetRef="rejectEnd"/><endEvent id="approveEnd"/><endEvent id="rejectEnd"/></process></definitions>
????????現在我們已經有了流程BPMN 2.0 XML文件,下來需要將它部署(deploy)*到引擎中。部署*一個流程定義意味著:
-
流程引擎會將XML文件存儲在數據庫中,這樣可以在需要的時候獲取它
-
流程定義轉換為內部的、可執行的對象模型,這樣使用它就可以啟動流程實例。
????????將流程定義部署至Flowable引擎,需要使用RepositoryService,其可以從ProcessEngine對象獲取。使用RepositoryService,可以通過XML文件的路徑創建一個新的部署(Deployment),并調用deploy()方法實際執行:
/*** 部署流程*/@Testpublic void testDeploy(){// 配置數據庫相關信息 獲取 ProcessEngineConfigurationProcessEngineConfiguration cfg = new StandaloneProcessEngineConfiguration().setJdbcUrl("jdbc:mysql://localhost:3306/flowable-learn2?serverTimezone=UTC&nullCatalogMeansCurrent=true").setJdbcUsername("root").setJdbcPassword("123456").setJdbcDriver("com.mysql.cj.jdbc.Driver").setDatabaseSchemaUpdate(ProcessEngineConfiguration.DB_SCHEMA_UPDATE_TRUE);// 獲取流程引擎對象ProcessEngine processEngine = cfg.buildProcessEngine();// 部署流程 獲取RepositoryService對象RepositoryService repositoryService = processEngine.getRepositoryService();Deployment deployment = repositoryService.createDeployment()// 創建Deployment對象.addClasspathResource("holiday-request.bpmn20.xml") // 添加流程部署文件.name("請求流程") // 設置部署流程的名稱.deploy(); // 執行部署操作System.out.println("deployment.getId() = " + deployment.getId());System.out.println("deployment.getName() = " + deployment.getName());}
????????然后執行該方法日志操作成功:
????????在后臺表結構也可以看到相關的信息,act_re_deployment: 流程定義部署表,每部署一次就增加一條記錄。
????????act_re_procdef :流程定義表,部署每個新的流程定義都會在這張表中增加一條記錄
????????act_ge_bytearray :流程資源表,流程部署的 bpmn文件和png圖片會保存在該表中
????????我們現在可以通過API查詢驗證流程定義已經部署在引擎中(并學習一些API)。通過RepositoryService創建的ProcessDefinitionQuery對象實現。
/*** 查看流程定義*/@Testpublic void testDeployQuery(){// 配置數據庫相關信息 獲取 ProcessEngineConfigurationProcessEngineConfiguration cfg = new StandaloneProcessEngineConfiguration().setJdbcUrl("jdbc:mysql://localhost:3306/flowable-learn2?serverTimezone=UTC&nullCatalogMeansCurrent=true").setJdbcUsername("root").setJdbcPassword("123456").setJdbcDriver("com.mysql.cj.jdbc.Driver").setDatabaseSchemaUpdate(ProcessEngineConfiguration.DB_SCHEMA_UPDATE_TRUE);// 獲取流程引擎對象ProcessEngine processEngine = cfg.buildProcessEngine();// 部署流程 獲取RepositoryService對象RepositoryService repositoryService = processEngine.getRepositoryService();// 獲取流程定義對象ProcessDefinition processDefinition = repositoryService.createProcessDefinitionQuery().deploymentId("2501").singleResult();System.out.println("processDefinition.getId() = " + processDefinition.getId());System.out.println("processDefinition.getName() = " + processDefinition.getName());System.out.println("processDefinition.getDeploymentId() = " + processDefinition.getDeploymentId());System.out.println("processDefinition.getDescription() = " + processDefinition.getDescription());}
輸出結果為:
processDefinition.getId() = holidayRequest:2:2503
processDefinition.getName() = Holiday Request
processDefinition.getDeploymentId() = 2501
processDefinition.getDescription() = null
3.啟動流程實例
??現在已經在流程引擎中部署了流程定義,因此可以使用這個流程定義作為“模板”啟動流程實例。
????????要啟動流程實例,需要提供一些初始化流程變量。一般來說,可以通過呈現給用戶的表單,或者在流程由其他系統自動觸發時通過REST API,來獲取這些變量。在這個例子里,我們簡化直接在代碼中定義了,我們使用RuntimeService啟動一個流程實例。
/*** 啟動流程實例*/@Testpublic void testRunProcess(){// 配置數據庫相關信息 獲取 ProcessEngineConfigurationProcessEngineConfiguration cfg = new StandaloneProcessEngineConfiguration().setJdbcUrl("jdbc:mysql://localhost:3306/flowable-learn2?serverTimezone=UTC&nullCatalogMeansCurrent=true").setJdbcUsername("root").setJdbcPassword("123456").setJdbcDriver("com.mysql.cj.jdbc.Driver").setDatabaseSchemaUpdate(ProcessEngineConfiguration.DB_SCHEMA_UPDATE_TRUE);// 獲取流程引擎對象ProcessEngine processEngine = cfg.buildProcessEngine();// 啟動流程實例通過 RuntimeService 對象RuntimeService runtimeService = processEngine.getRuntimeService();// 構建流程變量Map<String,Object> variables = new HashMap<>();variables.put("employee","張三") ;// 誰申請請假variables.put("nrOfHolidays",3); // 請幾天假variables.put("description","工作累了,想出去玩玩"); // 請假的原因// 啟動流程實例,第一個參數是流程定義的idProcessInstance processInstance = runtimeService.startProcessInstanceByKey("holidayRequest", variables);// 啟動流程實例// 輸出相關的流程實例信息System.out.println("流程定義的ID:" + processInstance.getProcessDefinitionId());System.out.println("流程實例的ID:" + processInstance.getId());System.out.println("當前活動的ID:" + processInstance.getActivityId());}
啟動成功,輸出結果如下:
流程定義的ID:holidayRequest:2:2503
流程實例的ID:5001
當前活動的ID:null
對應的流程實例ID為:5001
啟動流程實例涉及到的表結構:
-
act_hi_actinst 流程實例執行歷史
-
act_hi_identitylink 流程的參與用戶的歷史信息
-
act_hi_procinst 流程實例歷史信息
-
act_hi_taskinst 流程任務歷史信息
-
act_ru_execution 流程執行信息
-
act_ru_identitylink 流程的參與用戶信息
-
act_ru_task 任務信息
4.查看任務
??上面員工發起了一個請假流程,接下來就會流轉到總經理這兒來處理,之前我們沒有指定經理這的處理人,我們可以加一個。
然后我們來查看下lisi的任務。
/*** 查看任務*/@Testpublic void testQueryTask(){// 配置數據庫相關信息 獲取 ProcessEngineConfigurationProcessEngineConfiguration cfg = new StandaloneProcessEngineConfiguration().setJdbcUrl("jdbc:mysql://localhost:3306/flowable-learn2?serverTimezone=UTC&nullCatalogMeansCurrent=true").setJdbcUsername("root").setJdbcPassword("123456").setJdbcDriver("com.mysql.cj.jdbc.Driver").setDatabaseSchemaUpdate(ProcessEngineConfiguration.DB_SCHEMA_UPDATE_TRUE);// 獲取流程引擎對象ProcessEngine processEngine = cfg.buildProcessEngine();TaskService taskService = processEngine.getTaskService();List<Task> list = taskService.createTaskQuery().processDefinitionKey("holidayRequestNew").taskAssignee("lisi").list();for (Task task : list) {System.out.println("task.getProcessDefinitionId() = " + task.getProcessDefinitionId());System.out.println("task.getId() = " + task.getId());System.out.println("task.getAssignee() = " + task.getAssignee());System.out.println("task.getName() = " + task.getName());}}
輸出結果為:
task.getProcessDefinitionId() = holidayRequestNew:1:10003
task.getId() = 12508
task.getAssignee() = lisi
task.getName() = Approve or reject request
5.完成任務
??現在李四這個角色可以來完成當前的任務了
????????在此處我們直接解決掉這個請假,然后會走發送拒絕郵件的流程,這塊我們需要用到JavaDelegate來觸發。
public class SendRejectionMail implements JavaDelegate {/*** 觸發發送郵件的操作* @param delegateExecution*/@Overridepublic void execute(DelegateExecution delegateExecution) {System.out.println("請假被拒絕,,,安心工作吧");}
}
然后來完成任務
/*** 完成任務*/@Testpublic void testCompleteTask(){// 配置數據庫相關信息 獲取 ProcessEngineConfigurationProcessEngineConfiguration cfg = new StandaloneProcessEngineConfiguration().setJdbcUrl("jdbc:mysql://localhost:3306/flowable-learn2?serverTimezone=UTC&nullCatalogMeansCurrent=true").setJdbcUsername("root").setJdbcPassword("123456").setJdbcDriver("com.mysql.cj.jdbc.Driver").setDatabaseSchemaUpdate(ProcessEngineConfiguration.DB_SCHEMA_UPDATE_TRUE);// 獲取流程引擎對象ProcessEngine processEngine = cfg.buildProcessEngine();TaskService taskService = processEngine.getTaskService();Task task = taskService.createTaskQuery().processDefinitionKey("holidayRequestNew").taskAssignee("lisi").singleResult();// 添加流程變量Map<String,Object> variables = new HashMap<>();variables.put("approved",false); // 拒絕請假// 完成任務taskService.complete(task.getId(),variables);}
????????然后可以看到JavaDelegate觸發了:
6.流程的刪除
??有些流程已經沒有用了,我們需要刪除掉,其實也非常簡單。
/*** 刪除流程*/@Testpublic void testDeleteProcess(){// 配置數據庫相關信息 獲取 ProcessEngineConfigurationProcessEngineConfiguration cfg = new StandaloneProcessEngineConfiguration().setJdbcUrl("jdbc:mysql://localhost:3306/flowable-learn2?serverTimezone=UTC&nullCatalogMeansCurrent=true").setJdbcUsername("root").setJdbcPassword("123456").setJdbcDriver("com.mysql.cj.jdbc.Driver").setDatabaseSchemaUpdate(ProcessEngineConfiguration.DB_SCHEMA_UPDATE_TRUE);// 獲取流程引擎對象ProcessEngine processEngine = cfg.buildProcessEngine();RepositoryService repositoryService = processEngine.getRepositoryService();// 刪除流程定義,如果該流程定義已經有了流程實例啟動則刪除時報錯// repositoryService.deleteDeployment("1");// 設置為TRUE 級聯刪除流程定義,及時流程有實例啟動,也可以刪除,設置為false 非級聯刪除操作。repositoryService.deleteDeployment("2501",true);}
7.查看歷史信息
??選擇使用Flowable這樣的流程引擎的原因之一,是它可以自動存儲所有流程實例的審計數據或歷史數據。這些數據可以用于創建報告,深入展現組織運行的情況,瓶頸在哪里,等等。
??例如,如果希望顯示流程實例已經執行的時間,就可以從ProcessEngine獲取HistoryService,并創建歷史活動(historical activities)的查詢。在下面的代碼片段中,可以看到我們添加了一些額外的過濾條件:
-
只選擇一個特定流程實例的活動
-
只選擇已完成的活動
??結果按照結束時間排序,代表其執行順序。
/*** 查看歷史*/@Testpublic void testQueryHistory(){// 配置數據庫相關信息 獲取 ProcessEngineConfigurationProcessEngineConfiguration cfg = new StandaloneProcessEngineConfiguration().setJdbcUrl("jdbc:mysql://localhost:3306/flowable-learn2?serverTimezone=UTC&nullCatalogMeansCurrent=true").setJdbcUsername("root").setJdbcPassword("123456").setJdbcDriver("com.mysql.cj.jdbc.Driver").setDatabaseSchemaUpdate(ProcessEngineConfiguration.DB_SCHEMA_UPDATE_TRUE);// 獲取流程引擎對象ProcessEngine processEngine = cfg.buildProcessEngine();HistoryService historyService = processEngine.getHistoryService();List<HistoricActivityInstance> list = historyService.createHistoricActivityInstanceQuery().processDefinitionId("holidayRequestNew:1:10003").finished().orderByHistoricActivityInstanceEndTime().asc().list();for (HistoricActivityInstance historicActivityInstance : list) {System.out.println(historicActivityInstance.getActivityId() + " took "+ historicActivityInstance.getDurationInMillis() + " milliseconds");}}
輸出結果:
startEvent took 1 milliseconds
approveTask took 837735 milliseconds
decision took 13 milliseconds
sendRejectionMail took 2 milliseconds
rejectEnd took 1 milliseconds
3、Flowable流程設計器
1.Eclipse Designer
??Flowable提供了名為Flowable Eclipse Designer的Eclipse插件,可以用于圖形化地建模、測試與部署BPMN 2.0流程。
1.1 下載安裝Eclipse
??去Eclipse官網下載即可:Eclipse Packaging Project (EPP) Releases | Eclipse Packages 注意2020-09后的版本不再支持jdk8
????????解壓縮就可以了,然后進入解壓縮的目錄:
直接啟動即可:
1.2 安裝Flowable插件
??然后我們再安裝下Flowable的插件,選擇Help → Install New Software。在下圖面板中,點擊Add按鈕,并填寫下列字段
-
Name: Flowable BPMN 2.0 designer
-
Location: http://www.flowable.org/designer/update/
????????這種在線更新的方式已經被官網移除了,操作不了。
????????這時我們就只能通過離線安裝的方式來實現了,下載對應的離線文件。
然后繼續:選擇Help → Install New Software
1.3 創建項目
??然后我們就可以創建一個Flowable Project了.
????????然后我們可以在src/mian/resources/ 的目錄下創建對應的流程圖了。
????????看到如下的界面說明插件安裝成功了。
1.4 創建流程圖
????????使用滑板來繪制流程,通過從右側把圖標拖拽到左側的面板,最終的效果
????????指定流程的主鍵:
????????指定任務的負責人,在Properties視圖中指定每個任務節點的負責人。
創建請假單:zhangsan
審批請假單:lisi
????????當我們設置完成后保存文件,會同時生成png圖片:
注意:生成圖片需要如下配置。
1.5 部署流程
??首先在Eclipse中生成bar文件,選中項目然后鼠標右擊。
????????然后會發現在項目的根目錄下多了一個deployment文件夾,里面多了一個MyProcess.bar文件。
????????然后我們就可以把這個bar文件拷貝到IDEA中,繼續部署的流程。
????????而部署的代碼和前面沒啥區別。
@Testpublic void testDeploy(){// 1.獲取 ProcessEngine 對象ProcessEngine processEngine = configuration.buildProcessEngine();// 2.獲取RepositoryServiceRepositoryService repositoryService = processEngine.getRepositoryService();InputStream in = this.getClass().getClassLoader().getResourceAsStream("MyHoliday.bar");ZipInputStream zipInputStream = new ZipInputStream(in);// 3.完成流程的部署操作 ZIP 或者 Bar文件Deployment deploy = repositoryService.createDeployment()// .addClasspathResource("MyHoliday.bar")// 關聯要部署的流程文件.addZipInputStream(zipInputStream).name("XXX公司請求流程").deploy() ;// 部署流程System.out.println("deploy.getId() = " + deploy.getId());System.out.println("deploy.getName() = " + deploy.getName());}
執行后查看表結構,相關的信息就進去了
import org.flowable.engine.*;
import org.flowable.engine.history.HistoricActivityInstance;
import org.flowable.engine.impl.cfg.StandaloneProcessEngineConfiguration;
import org.flowable.engine.repository.Deployment;
import org.flowable.engine.runtime.ProcessInstance;
import org.flowable.task.api.Task;
import org.junit.Before;
import org.junit.Test;import java.io.InputStream;
import java.util.HashMap;
import java.util.List;
import java.util.Map;
import java.util.zip.ZipInputStream;public class Test02 {ProcessEngineConfiguration configuration = null;@Beforepublic void before(){// 獲取 ProcessEngineConfiguration 對象configuration = new StandaloneProcessEngineConfiguration();// 配置 相關的數據庫的連接信息configuration.setJdbcDriver("com.mysql.cj.jdbc.Driver");configuration.setJdbcUsername("root");configuration.setJdbcPassword("123456");configuration.setJdbcUrl("jdbc:mysql://localhost:3306/flowable-learn?serverTimezone=UTC&nullCatalogMeansCurrent=true");// 如果數據庫中的表結構不存在就新建configuration.setDatabaseSchemaUpdate(ProcessEngineConfiguration.DB_SCHEMA_UPDATE_TRUE);}/*** 部署流程**/@Testpublic void testDeploy(){// 1.獲取 ProcessEngine 對象ProcessEngine processEngine = configuration.buildProcessEngine();// 2.獲取RepositoryServiceRepositoryService repositoryService = processEngine.getRepositoryService();InputStream in = this.getClass().getClassLoader().getResourceAsStream("MyHoliday.bar");ZipInputStream zipInputStream = new ZipInputStream(in);// 3.完成流程的部署操作 ZIP 或者 Bar文件Deployment deploy = repositoryService.createDeployment()// .addClasspathResource("MyHoliday.bar")// 關聯要部署的流程文件.addZipInputStream(zipInputStream).name("XXX公司請求流程").deploy() ;// 部署流程System.out.println("deploy.getId() = " + deploy.getId());System.out.println("deploy.getName() = " + deploy.getName());}/*** 啟動流程實例*/@Testpublic void testRunProcess(){ProcessEngine processEngine = configuration.buildProcessEngine();// 我們需要通過RuntimeService來啟動流程實例RuntimeService runtimeService = processEngine.getRuntimeService();// 啟動流程實例ProcessInstance holidayRequest = runtimeService.startProcessInstanceById("myProcess:1:25004");System.out.println("holidayRequest.getProcessDefinitionId() = " + holidayRequest.getProcessDefinitionId());System.out.println("holidayRequest.getActivityId() = " + holidayRequest.getActivityId());System.out.println("holidayRequest.getId() = " + holidayRequest.getId());}/*** 測試任務查詢*/@Testpublic void testQueryTask(){ProcessEngine processEngine = configuration.buildProcessEngine();TaskService taskService = processEngine.getTaskService();List<Task> list = taskService.createTaskQuery().processDefinitionKey("myProcess") // 指定查詢的流程編程.taskAssignee("zhangsan") // 查詢這個任務的處理人.list();for (Task task : list) {System.out.println("task.getProcessDefinitionId() = " + task.getProcessDefinitionId());System.out.println("task.getName() = " + task.getName());System.out.println("task.getAssignee() = " + task.getAssignee());System.out.println("task.getDescription() = " + task.getDescription());System.out.println("task.getId() = " + task.getId());}}/*** 完成當前任務*/@Testpublic void testCompleteTask(){ProcessEngine processEngine = configuration.buildProcessEngine();TaskService taskService = processEngine.getTaskService();Task task = taskService.createTaskQuery().processDefinitionKey("myProcess").taskAssignee("lisi").singleResult();// 創建流程變量if(task != null){// 完成任務taskService.complete(task.getId());}}/*** 獲取流程任務的歷史數據*/@Testpublic void testHistory(){ProcessEngine processEngine = configuration.buildProcessEngine();HistoryService historyService = processEngine.getHistoryService();List<HistoricActivityInstance> list = historyService.createHistoricActivityInstanceQuery().processDefinitionId("myProcess:1:25004").finished() // 查詢的歷史記錄的狀態是已經完成.orderByHistoricActivityInstanceEndTime().asc() // 指定排序的字段和順序.list();for (HistoricActivityInstance history : list) {System.out.println(history.getActivityName()+":"+history.getAssignee()+"--"+history.getActivityId()+":" + history.getDurationInMillis()+"毫秒");}}
}
2.Flowable UI應用
??Flowable提供了幾個web應用,用于演示及介紹Flowable項目提供的功能:
-
Flowable IDM: 身份管理應用。為所有Flowable UI應用提供單點登錄認證功能,并且為擁有IDM管理員權限的用戶提供了管理用戶、組與權限的功能。
-
Flowable Modeler: 讓具有建模權限的用戶可以創建流程模型、表單、選擇表與應用定義。
-
Flowable Task: 運行時任務應用。提供了啟動流程實例、編輯任務表單、完成任務,以及查詢流程實例與任務的功能。
-
Flowable Admin: 管理應用。讓具有管理員權限的用戶可以查詢BPMN、DMN、Form及Content引擎,并提供了許多選項用于修改流程實例、任務、作業等。管理應用通過REST API連接至引擎,并與Flowable Task應用及Flowable REST應用一同部署。
??所有其他的應用都需要Flowable IDM提供認證。每個應用的WAR文件可以部署在相同的servlet容器(如Apache Tomcat)中,也可以部署在不同的容器中。由于每個應用使用相同的cookie進行認證,因此應用需要運行在相同的域名下。
2.1 安裝部署
????????下載Tomcat:Apache Download Mirrors 官網下載后解壓縮到非中文目錄即可,然后是下載FlowableUI的文件,在Flowable6.6之后把FlowableUI中提供的四個功能合并到了一起。
????????然后把解壓縮后的兩個war包拷貝到Tomcat的解壓縮的webapps目錄下。
2.2 啟動服務
??啟動Tomcat服務,執行startup.bat文件
????????如果啟動中出現亂碼修改Tomcat的conf目錄下的 logging.properties 文件中的編碼。
????????如果一閃而過則檢查jdk的環境變量配置。啟動成功后,在瀏覽器中訪問 http://localhost:8080/flowable-ui, 默認的賬號密碼是 admin/test
2.3 用戶管理
??我們先在 身份管理應用程序
中創建用戶并授權。
2.4 繪制流程
????????創建新的流程:
創建流程,分配處理人:
繼續完成流程圖的創建:
2.5 部署流程
??繪制好的流程圖,我們只需要一鍵導出即可
????????下載下來后拷貝到項目的resource目錄下即可:
2.6 FlowableUI 演示
2.6.1 部署流程
??在FlowableUI中提供了演示程序:
????????創建一個新的應用程序,并指定相關的信息:
????????創建應用后需要指定對應的流程圖:
2.6.2 啟動流程
??發布了應用程序后我們就可以來啟動流程了
????????也就是可以看到當前是user1來處理,user1登錄后可以看到要處理的流程,user2登錄是看不到的。
????????點擊完成后流程就向下一步流轉了。
????????這時再通過user2登錄,就可以看到對應的代辦的信息。
4、Flowable基礎表結構
1.表結構講解
??工作流程的相關操作都是操作存儲在對應的表結構中,為了能更好的弄清楚Flowable的實現原理和細節,我們有必要先弄清楚Flowable的相關表結構及其作用。在Flowable中的表結構在初始化的時候會創建五類表結構,具體如下:
-
ACT_RE :'RE'表示 repository。 這個前綴的表包含了流程定義和流程靜態資源 (圖片,規則,等等)。
-
ACT_RU:'RU'表示 runtime。 這些運行時的表,包含流程實例,任務,變量,異步任務,等運行中的數據。 Flowable只在流程實例執行過程中保存這些數據, 在流程結束時就會刪除這些記錄。 這樣運行時表可以一直很小速度很快。
-
ACT_HI:'HI'表示 history。 這些表包含歷史數據,比如歷史流程實例, 變量,任務等等。
-
ACT_GE: GE 表示 general。 通用數據, 用于不同場景下
-
ACT_ID: ’ID’表示identity(組織機構)。這些表包含標識的信息,如用戶,用戶組,等等。
具體的表結構的含義:
表分類 | 表名 | 解釋 |
---|---|---|
一般數據 | ||
[ACT_GE_BYTEARRAY] | 通用的流程定義和流程資源 | |
[ACT_GE_PROPERTY] | 系統相關屬性 | |
流程歷史記錄 | ||
[ACT_HI_ACTINST] | 歷史的流程實例 | |
[ACT_HI_ATTACHMENT] | 歷史的流程附件 | |
[ACT_HI_COMMENT] | 歷史的說明性信息 | |
[ACT_HI_DETAIL] | 歷史的流程運行中的細節信息 | |
[ACT_HI_IDENTITYLINK] | 歷史的流程運行過程中用戶關系 | |
[ACT_HI_PROCINST] | 歷史的流程實例 | |
[ACT_HI_TASKINST] | 歷史的任務實例 | |
[ACT_HI_VARINST] | 歷史的流程運行中的變量信息 | |
流程定義表 | ||
[ACT_RE_DEPLOYMENT] | 部署單元信息 | |
[ACT_RE_MODEL] | 模型信息 | |
[ACT_RE_PROCDEF] | 已部署的流程定義 | |
運行實例表 | ||
[ACT_RU_EVENT_SUBSCR] | 運行時事件 | |
[ACT_RU_EXECUTION] | 運行時流程執行實例 | |
[ACT_RU_IDENTITYLINK] | 運行時用戶關系信息,存儲任務節點與參與者的相關信息 | |
[ACT_RU_JOB] | 運行時作業 | |
[ACT_RU_TASK] | 運行時任務 | |
[ACT_RU_VARIABLE] | 運行時變量表 | |
用戶用戶組表 | ||
[ACT_ID_BYTEARRAY] | 二進制數據表 | |
[ACT_ID_GROUP] | 用戶組信息表 | |
[ACT_ID_INFO] | 用戶信息詳情表 | |
[ACT_ID_MEMBERSHIP] | 人與組關系表 | |
[ACT_ID_PRIV] | 權限表 | |
[ACT_ID_PRIV_MAPPING] | 用戶或組權限關系表 | |
[ACT_ID_PROPERTY] | 屬性表 | |
[ACT_ID_TOKEN] | 記錄用戶的token信息 | |
[ACT_ID_USER] | 用戶表 |
2.ProcessEngine講解
2.1 硬編碼的方式
??我們前面講解案例的時候是通過ProcessEngineConfiguration這個配置類來加載的。
// 配置數據庫相關信息 獲取 ProcessEngineConfiguration
ProcessEngineConfiguration cfg = new StandaloneProcessEngineConfiguration().setJdbcUrl("jdbc:mysql://localhost:3306/flowable-learn2?serverTimezone=UTC&nullCatalogMeansCurrent=true").setJdbcUsername("root").setJdbcPassword("123456").setJdbcDriver("com.mysql.cj.jdbc.Driver").setDatabaseSchemaUpdate(ProcessEngineConfiguration.DB_SCHEMA_UPDATE_TRUE);
// 獲取流程引擎對象
ProcessEngine processEngine = cfg.buildProcessEngine();
2.2 配置文件
??除了上面的硬編碼的方式外,我們還可以在resources目錄下創建一個flowable.cfg.xml
文件,注意這個名稱是固定的哦。內容如下:
<beans xmlns="http://www.springframework.org/schema/beans"xmlns:xsi="http://www.w3.org/2001/XMLSchema-instance"xsi:schemaLocation="http://www.springframework.org/schema/beans http://www.springframework.org/schema/beans/spring-beans.xsd"><bean id="processEngineConfiguration"class="org.flowable.engine.impl.cfg.StandaloneProcessEngineConfiguration"><property name="jdbcUrl" value="jdbc:mysql://localhost:3306/flow1?allowMultiQueries=true&useUnicode=true&characterEncoding=UTF-8&useSSL=false&serverTimezone=UTC&nullCatalogMeansCurrent=true" /><property name="jdbcDriver" value="com.mysql.cj.jdbc.Driver" /><property name="jdbcUsername" value="root" /><property name="jdbcPassword" value="123456" /><property name="databaseSchemaUpdate" value="true" /><property name="asyncExecutorActivate" value="false" /></bean>
</beans>
????????在上面的配置文件中配置相關的信息。我們在Java代碼中就可以簡化為:
@Testpublic void test01(){// 獲取流程引擎對象ProcessEngine processEngine = ProcessEngines.getDefaultProcessEngine();System.out.println("processEngine = " + processEngine);}
????????可以看下getDefaultProcessEngine的源碼,在里面最終還是執行了和硬編碼一樣的代碼:
public static ProcessEngine getProcessEngine(String processEngineName) {if (!isInitialized()) {init(); // 完成初始化操作}return processEngines.get(processEngineName);}public static synchronized void init() {if (!isInitialized()) {if (processEngines == null) {// Create new map to store process-engines if current map is nullprocessEngines = new HashMap<>();}ClassLoader classLoader = ReflectUtil.getClassLoader();Enumeration<URL> resources = null;try {resources = classLoader.getResources("flowable.cfg.xml"); // 加載flowable.cfg.xml配置文件} catch (IOException e) {throw new FlowableIllegalArgumentException("problem retrieving flowable.cfg.xml resources on the classpath: " + System.getProperty("java.class.path"), e);}// Remove duplicated configuration URL's using set. Some// classloaders may return identical URL's twice, causing duplicate// startupsSet<URL> configUrls = new HashSet<>();while (resources.hasMoreElements()) {configUrls.add(resources.nextElement());}for (Iterator<URL> iterator = configUrls.iterator(); iterator.hasNext();) {URL resource = iterator.next();LOGGER.info("Initializing process engine using configuration '{}'", resource.toString());initProcessEngineFromResource(resource); // 初始化ProcessEngine}try {resources = classLoader.getResources("flowable-context.xml"); // 在整合Spring的情況下加載該文件} catch (IOException e) {throw new FlowableIllegalArgumentException("problem retrieving flowable-context.xml resources on the classpath: " + System.getProperty("java.class.path"), e);}while (resources.hasMoreElements()) {URL resource = resources.nextElement();LOGGER.info("Initializing process engine using Spring configuration '{}'", resource.toString());initProcessEngineFromSpringResource(resource); // 從Spring的資源文件中完成ProcessEngine的初始化}setInitialized(true);} else {LOGGER.info("Process engines already initialized");}}
????????在源碼中提供了單獨使用好整合Spring的配置加載方式。再進入到initProcessEngineFromResource(resource)方法中:
????????而且我們也可以看到ProcessEngine最終的實現是 ProcessEngineImpl對象。
2.3 自定義配置文件
??最后我們如果要加載自定義名稱的配置文件可以通過ProcessEngineConfiguration中的對應構造方法來實現。
@Testpublic void test2() throws Exception{ProcessEngineConfiguration configuration = ProcessEngineConfiguration.createProcessEngineConfigurationFromResource("flowable.cfg.xml");ProcessEngine processEngine = configuration.buildProcessEngine();System.out.println("processEngine = " + processEngine);}
3. Servcie服務接口
????????Service是工作流引擎提供用于進行工作流部署、執行、管理的服務接口,我們使用這些接口可以就是操作服務對應的數據表。
3.1 Service創建方式
????????通過ProcessEngine創建Service,方式如下:
RuntimeService runtimeService = processEngine.getRuntimeService();
RepositoryService repositoryService = processEngine.getRepositoryService();
TaskService taskService = processEngine.getTaskService();
// ...
3.2 Service總覽
service名稱 | service作用 |
---|---|
RepositoryService | Flowable的資源管理類 |
RuntimeService | Flowable的流程運行管理類 |
TaskService | Flowable的任務管理類 |
HistoryService | Flowable的歷史管理類 |
ManagerService | Flowable的引擎管理類 |
簡單介紹:
RepositoryService
????????是activiti的資源管理類,提供了管理和控制流程發布包和流程定義的操作。使用工作流建模工具設計的業務流程圖需要使用此service將流程定義文件的內容部署到計算機。
????????除了部署流程定義以外還可以:查詢引擎中的發布包和流程定義。
????????暫停或激活發布包,對應全部和特定流程定義。 暫停意味著它們不能再執行任何操作了,激活是對應的反向操作。獲得多種資源,像是包含在發布包里的文件, 或引擎自動生成的流程圖。獲得流程定義的pojo版本, 可以用來通過java解析流程,而不必通過xml。
RuntimeService
????????Activiti的流程運行管理類。可以從這個服務類中獲取很多關于流程執行相關的信息
TaskService
????????Activiti的任務管理類。可以從這個類中獲取任務的信息。
HistoryService
????????Flowable的歷史管理類,可以查詢歷史信息,執行流程時,引擎會保存很多數據(根據配置),比如流程實例啟動時間,任務的參與者, 完成任務的時間,每個流程實例的執行路徑,等等。 這個服務主要通過查詢功能來獲得這些數據。
ManagementService
????????Activiti的引擎管理類,提供了對Flowable 流程引擎的管理和維護功能,這些功能不在工作流驅動的應用程序中使用,主要用于 Flowable 系統的日常維護。
4.圖標介紹
??BPMN 2.0是業務流程建模符號2.0的縮寫。它由Business Process Management Initiative這個非營利協會創建并不斷發展。作為一種標識,BPMN 2.0是使用一些符號來明確業務流程設計流程圖的一整套符號規范,它能增進業務建模時的溝通效率。目前BPMN2.0是最新的版本,它用于在BPM上下文中進行布局和可視化的溝通。接下來我們先來了解在流程設計中常見的 符號。
BPMN2.0的基本符合主要包含:
4.1 事件圖標
??在Flowable中的事件圖標啟動事件,邊界事件,中間事件和結束事件.
4.2 活動(任務)圖標
??活動是工作或任務的一個通用術語。一個活動可以是一個任務,還可以是一個當前流程的子處理流程; 其次,你還可以為活動指定不同的類型。常見活動如下:
4.3 結構圖標
??結構圖標可以看做是整個流程活動的結構,一個流程中可以包括子流程。常見的結構有:
4.4 網關圖標
??網關用來處理決策,有幾種常用網關需要了解:
5.流程部署詳解
5.1 部署實現
??我們先來看下流程部署的具體過程。代碼實現
/*** 部署流程*/@Testpublic void test3(){ProcessEngine processEngine = ProcessEngines.getDefaultProcessEngine();RepositoryService repositoryService = processEngine.getRepositoryService();Deployment deploy = repositoryService.createDeployment().addClasspathResource("holiday-request-new.bpmn20.xml").name("請假流程...").category("請假") // 分類.tenantId("dpb") // 租戶id.deploy();System.out.println("deploy.getId() = " + deploy.getId());System.out.println("deploy.getName() = " + deploy.getName());System.out.println("deploy.getCategory() = " + deploy.getCategory());}
5.2 部署涉及表結構
涉及到的三張表:
部署資源表:act_ge_bytearray
字段 | 名稱 | 備注 |
---|---|---|
ID_ | 主鍵 | |
REV_ | 版本號 | |
NAME_ | 名稱 | 部署的文件名稱,如:holiday-request-new.bpmn20.xml、holiday-request-new.bpmn20.png |
DEPLOYMENT_ID_ | 部署ID | |
BYTES_ | 字節(二進制數據) | |
GENERATED_ | 是否系統生成 | 0為用戶上傳, 1為系統自動生成, 比如系統會 自動根據xml生 成png |
部署ID表:act_re_deployment
字段 | 名稱 | 備注 |
---|---|---|
ID_ | 主鍵 | |
NAME_ | 名稱 | |
CATEGORY_ | 分類 | |
TENANT_ID_ | 租戶ID | |
DEPLOY_TIME_ | 部署時間 | |
DERIVED_FROM_ | 來源于 | |
DERIVED_FROM_ROOT_ | 來源于 | |
ENGINE_VERSION_ | 流程引擎的版本 |
流程表:act_re_procdef
字段 | 名稱 | 備注 |
---|---|---|
ID_ | 主鍵 | |
REV_ | 版本號 | |
CATEGORY_ | 分類 | 流程定義的Namespace就是類別 |
NAME_ | 名稱 | |
KEY_ | 標識 | |
VERSION_ | 版本 | |
DEPLOYMENT_ID_ | 部署ID | |
RESOURCE_NAME_ | 資源名稱 | 流程bpmn文件名稱 |
DGRM_RESOURCE_NAME_ | 圖片資源名稱 | |
DESCRIPTION_ | 描述 | |
HAS_START_FORM_KEY_ | 擁有開始表單標識 | start節點是否存在formKey 0否 1是 |
HAS_GRAPHICAL_NOTATION_ | 擁有圖形信息 | |
SUSPENSION_STATE_ | 掛起狀態 | 暫停狀態 1激活 2暫停 |
TENANT_ID_ | 租戶ID | |
注意:
????????業務流程定義數據表,此表和ACT_RE_DEPLOYMENT是多對一的關系。即,一個部署的bar包里可能包含多個流程定義文件,每個流程定義文件都會有一條記錄在ACT_REPROCDEF表內,每個流程定義的數據,都會對于ACT_GE_BYTEARRAY表內的一個資源文件和PNG圖片文件。和ACT_GE_BYTEARRAY的關聯是通過程序用ACT_GE_BYTEARRAY.NAME與ACT_RE_PROCDEF.NAME_完成的。
5.3 掛起和激活
??部署的流程默認的狀態為激活,如果我們暫時不想使用該定義的流程,那么可以掛起該流程。當然該流程定義下邊所有的流程實例全部暫停。
????????流程定義為掛起狀態,該流程定義將不允許啟動新的流程實例,同時該流程定義下的所有的流程實例都將全部掛起暫停執行。
/*** 掛起流程*/@Testpublic void test05(){// 獲取流程引擎對象ProcessEngine processEngine = ProcessEngines.getDefaultProcessEngine();RepositoryService repositoryService = processEngine.getRepositoryService();ProcessDefinition processDefinition = repositoryService.createProcessDefinitionQuery().processDefinitionId("holiday:1:4").singleResult();// 獲取流程定義的狀態boolean suspended = processDefinition.isSuspended();System.out.println("suspended = " + suspended);if(suspended){// 表示被掛起System.out.println("激活流程定義");repositoryService.activateProcessDefinitionById("holiday:1:4",true,null);}else{// 表示激活狀態System.out.println("掛起流程");repositoryService.suspendProcessDefinitionById("holiday:1:4",true,null);}}
????????具體的實現其實就是更新了流程定義表中的字段:
????????而且通過REV_字段來控制數據安全,也是一種樂觀鎖的體現了,如果要啟動一個已經掛起的流程就會出現如下的錯誤:
6.啟動流程實例
??然后我們來看看啟動流程實例的過程。實現代碼如下:
/*** 啟動流程實例*/@Testpublic void testRunProcess(){// 獲取流程引擎對象ProcessEngine processEngine = ProcessEngines.getDefaultProcessEngine();// 啟動流程實例通過 RuntimeService 對象RuntimeService runtimeService = processEngine.getRuntimeService();// 構建流程變量Map<String,Object> variables = new HashMap<>();variables.put("employee","張三") ;// 誰申請請假variables.put("nrOfHolidays",3); // 請幾天假variables.put("description","工作累了,想出去玩玩"); // 請假的原因// 啟動流程實例,第一個參數是流程定義的idProcessInstance processInstance = runtimeService.startProcessInstanceById("holiday:1:4", variables);// 啟動流程實例// 輸出相關的流程實例信息System.out.println("流程定義的ID:" + processInstance.getProcessDefinitionId());System.out.println("流程實例的ID:" + processInstance.getId());System.out.println("當前活動的ID:" + processInstance.getActivityId());}
????????當我們啟動了一個流程實例后,會在ACT_RU_*對應的表結構中操作,運行時實例涉及的表結構共10張:
-
ACT_RU_DEADLETTER_JOB 正在運行的任務表
-
ACT_RU_EVENT_SUBSCR 運行時事件
-
ACT_RU_EXECUTION 運行時流程執行實例
-
ACT_RU_HISTORY_JOB 歷史作業表
-
ACT_RU_IDENTITYLINK 運行時用戶關系信息
-
ACT_RU_JOB 運行時作業表
-
ACT_RU_SUSPENDED_JOB 暫停作業表
-
ACT_RU_TASK 運行時任務表
-
ACT_RU_TIMER_JOB 定時作業表
-
ACT_RU_VARIABLE 運行時變量表
????????啟動一個流程實例的時候涉及到的表有
-
ACT_RU_EXECUTION 運行時流程執行實例
-
ACT_RU_IDENTITYLINK 運行時用戶關系信息
-
ACT_RU_TASK 運行時任務表
-
ACT_RU_VARIABLE 運行時變量表
ACT_RU_EXECUTION表結構
字段 | 名稱 | 備注 |
---|---|---|
ID_ | 主鍵 | |
REV_ | 版本號 | |
PROC_INST_ID_ | 流程實例ID | |
BUSINESS_KEY_ | 業務主鍵ID | |
PARENT_ID_ | 父執行流的ID | |
PROC_DEF_ID_ | 流程定義的數據ID | |
SUPER_EXEC_ | ||
ROOT_PROC_INST_ID_ | 流程實例的root流程id | |
ACT_ID_ | 節點實例ID | |
IS_ACTIVE_ | 是否存活 | |
IS_CONCURRENT_ | 執行流是否正在并行 | |
IS_SCOPE_ | ||
IS_EVENT_SCOPE_ | ||
IS_MI_ROOT_ | ||
SUSPENSION_STATE_ | 流程終端狀態 | |
CACHED_ENT_STATE_ | ||
TENANT_ID_ | 租戶編號 | |
NAME_ | ||
START_TIME_ | 開始時間 | |
START_USER_ID_ | 開始的用戶編號 | |
LOCK_TIME_ | 鎖定時間 | |
IS_COUNT_ENABLED_ | ||
EVT_SUBSCR_COUNT_ | ||
TASK_COUNT_ | ||
JOB_COUNT_ | ||
TIMER_JOB_COUNT_ | ||
SUSP_JOB_COUNT_ | ||
DEADLETTER_JOB_COUNT_ | ||
VAR_COUNT_ | ||
ID_LINK_COUNT_ |
????????創建流程實例后對應的表結構的數據:
ACT_RU_TASK 運行時任務表
字段 | 名稱 | 備注 |
---|---|---|
ID_ | 主鍵 | |
REV_ | 版本號 | |
EXECUTION_ID_ | 任務所在的執行流ID | |
PROC_INST_ID_ | 流程實例ID | |
PROC_DEF_ID_ | 流程定義數據ID | |
NAME_ | 任務名稱 | |
PARENT_TASK_ID_ | 父任務ID | |
DESCRIPTION_ | 說明 | |
TASK_DEF_KEY_ | 任務定義的ID值 | |
OWNER_ | 任務擁有人 | |
ASSIGNEE_ | 被指派執行該任務的人 | |
DELEGATION_ | 委托人 | |
PRIORITY_ | 優先級 | |
CREATE_TIME_ | 創建時間 | |
DUE_DATE_ | 耗時 | |
CATEGORY_ | 類別 | |
SUSPENSION_STATE_ | 是否掛起 | 1代表激活 2代表掛起 |
TENANT_ID_ | 租戶編號 | |
FORM_KEY_ | ||
CLAIM_TIME_ | 拾取時間 |
????????創建流程實例后對應的表結構的數據:
ACT_RU_VARIABLE 運行時變量表
字段 | 名稱 | 備注 |
---|---|---|
ID_ | 主鍵 | |
REV_ | 版本號 | |
TYPE_ | 參數類型 | 可以是基本的類型,也可以用戶自行擴展 |
NAME_ | 參數名稱 | |
EXECUTION_ID_ | 參數執行ID | |
PROC_INST_ID_ | 流程實例ID | |
TASK_ID_ | 任務ID | |
BYTEARRAY_ID_ | 資源ID | |
DOUBLE_ | 參數為double,則保存在該字段中 | |
LONG_ | 參數為long,則保存在該字段中 | |
TEXT_ | 用戶保存文本類型的參數值 | |
TEXT2_ | 用戶保存文本類型的參數值 |
????????創建流程實例后對應的表結構的數據:
ACT_RU_IDENTITYLINK 運行時用戶關系信息
字段 | 名稱 | 備注 |
---|---|---|
ID_ | 主鍵 | |
REV_ | 版本號 | |
GROUP_ID_ | 用戶組ID | |
TYPE_ | 關系數據類型 | assignee支配人(組)、candidate候選人(組)、owner擁有人,participant參與者 |
USER_ID_ | 用戶ID | |
TASK_ID_ | 任務ID | |
PROC_INST_ID_ | 流程定義ID | |
PROC_DEF_ID_ | 屬性ID |
????????創建流程實例后對應的表結構的數據:
7.處理流程
??上面的流程已經流轉到了zhangsan這個用戶這里,然后可以開始審批了
// 獲取流程引擎對象ProcessEngine processEngine = ProcessEngines.getDefaultProcessEngine();TaskService taskService = processEngine.getTaskService();Task task = taskService.createTaskQuery().processDefinitionId("holiday:1:4").taskAssignee("zhangsan").singleResult();// 添加流程變量Map<String,Object> variables = new HashMap<>();variables.put("approved",false); // 拒絕請假// 完成任務taskService.complete(task.getId(),variables);
在正常處理流程中涉及到的表結構
-
ACT_RU_EXECUTION 運行時流程執行實例
-
ACT_RU_IDENTITYLINK 運行時用戶關系信息
-
ACT_RU_TASK 運行時任務表
-
ACT_RU_VARIABLE 運行時變量表
ACT_RU_TASK 運行時任務表 :會新生成一條記錄
ACT_RU_VARIABLE 運行時變量表:會記錄新的流程變量
????????當然流程實例也可以掛起:
// 1.獲取ProcessEngine對象
ProcessEngine engine = ProcessEngines.getDefaultProcessEngine();
// 2.獲取RuntimeService
RuntimeService runtimeService = engine.getRuntimeService();
// 3.獲取流程實例對象
ProcessInstance processInstance = runtimeService.createProcessInstanceQuery().processInstanceId("25001").singleResult();
// 4.獲取相關的狀態操作
boolean suspended = processInstance.isSuspended();
String id = processInstance.getId();
if(suspended){// 掛起--》激活runtimeService.activateProcessInstanceById(id);System.out.println("流程定義:" + id + ",已激活");
}else{// 激活--》掛起runtimeService.suspendProcessInstanceById(id);System.out.println("流程定義:" + id + ",已掛起");
}
????????啟動第二個流程實例后再查看相關的表結構時,對他們的關系理解會更加的清楚一些;啟動一個新的流程實例對應的就會產生兩條記錄。
IDENTITYLINK中會記錄每次流程操作的信息:
????????流程變量數據,及時key 相同,但是屬于不同的流程實例相互間也是隔離的。
8.完成一個流程
??然后我們把第一個流程處理完成。
ProcessEngine processEngine = cfg.buildProcessEngine();
TaskService taskService = processEngine.getTaskService();
Task task = taskService.createTaskQuery().processDefinitionId("holiday:1:4").taskAssignee("lisi").singleResult();
// 添加流程變量
Map<String,Object> variables = new HashMap<>();
variables.put("approved",false); // 拒絕請假
// 完成任務
taskService.complete(task.getId(),variables);
????????處理完了一個工作流程后,我們來看看相關的表結構信息,首先我們會發現
-
ACT_RU_EXECUTION 運行時流程執行實例
-
ACT_RU_IDENTITYLINK 運行時用戶關系信息
-
ACT_RU_TASK 運行時任務表
-
ACT_RU_VARIABLE 運行時變量表
????????這四張表中對應的數據都沒有了,也就是這個流程已經不是運行中的流程了。然后在對應的歷史表中我們可以看到相關的信息
-
ACT_HI_ACTINST 歷史的流程實例
-
ACT_HI_ATTACHMENT 歷史的流程附件
-
ACT_HI_COMMENT 歷史的說明性信息
-
ACT_HI_DETAIL 歷史的流程運行中的細節信息
-
ACT_HI_IDENTITYLINK 歷史的流程運行過程中用戶關系
-
ACT_HI_PROCINST 歷史的流程實例
-
ACT_HI_TASKINST 歷史的任務實例
-
ACT_HI_VARINST 歷史的流程運行中的變量信息
在我們上面的處理流程的過程中設計到的歷史表有
ACT_HI_ACTINST 歷史的流程實例
字段 | 名稱 | 備注 |
---|---|---|
ID_ | 主鍵 | |
PROC_DEF_ID_ | 流程定義ID | |
PROC_INST_ID_ | 流程實例ID | |
EXECUTION_ID_ | 執行ID | |
ACT_ID_ | 節點實例ID | |
TASK_ID_ | 任務ID | |
CALL_PROC_INST_ID_ | 調用外部的流程實例ID | |
ACT_NAME_ | 節點名稱 | |
ACT_TYPE_ | 節點類型 | |
ASSIGNEE_ | 處理人 | |
START_TIME_ | 開始時間 | |
END_TIME_ | 結束時間 | |
DURATION_ | 耗時 | |
DELETE_REASON_ | 刪除原因 | |
TENANT_ID_ | 租戶編號 |
ACT_HI_IDENTITYLINK 歷史的流程運行過程中用戶關系
字段 | 名稱 | 備注 |
---|---|---|
ID_ | 主鍵 | |
GROUP_ID_ | 組編號 | |
TYPE_ | 類型 | |
USER_ID_ | 用戶編號 | |
TASK_ID_ | 任務編號 | |
CREATE_TIME_ | 創建時間 | |
PROC_INST_ID_ | 流程實例編號 | |
SCOPE_ID_ | ||
SCOPE_TYPE_ | ||
SCOPE_DEFINITION_ID_ | ||
ACT_HI_PROCINST 歷史的流程實例
字段 | 名稱 | 備注 |
---|---|---|
ID_ | 主鍵 | |
PROC_INST_ID_ | 流程實例ID | |
BUSINESS_KEY_ | 業務主鍵 | |
PROC_DEF_ID_ | 屬性ID | |
START_TIME_ | 開始時間 | |
END_TIME_ | 結束時間 | |
DURATION_ | 耗時 | |
START_USER_ID_ | 起始人 | |
START_ACT_ID_ | 起始節點 | |
END_ACT_ID_ | 結束節點 | |
SUPER_PROCESS_INSTANCE_ID_ | 父流程實例ID | |
DELETE_REASON_ | 刪除原因 | |
TENANT_ID_ | 租戶編號 | |
NAME_ | 名稱 |
ACT_HI_TASKINST 歷史的任務實例
字段 | 名稱 | 備注 |
---|---|---|
ID_ | 主鍵 | |
PROC_DEF_ID_ | 流程定義ID | |
TASK_DEF_KEY_ | 任務定義的ID值 | |
PROC_INST_ID_ | 流程實例ID | |
EXECUTION_ID_ | 執行ID | |
PARENT_TASK_ID_ | 父任務ID | |
NAME_ | 名稱 | |
DESCRIPTION_ | 說明 | |
OWNER_ | 實際簽收人 任務的擁有者 | 簽收人(默認為空,只有在委托時才有值) |
ASSIGNEE_ | 被指派執行該任務的人 | |
START_TIME_ | 開始時間 | |
CLAIM_TIME_ | 任務拾取時間 | |
END_TIME_ | 結束時間 | |
DURATION_ | 耗時 | |
DELETE_REASON_ | 刪除原因 | |
PRIORITY_ | 優先級別 | |
DUE_DATE_ | 過期時間 | |
FORM_KEY_ | 節點定義的formkey | |
CATEGORY_ | 類別 | |
TENANT_ID_ | 租戶 |
????????ACT_HI_VARINST 歷史的流程運行中的變量信息:流程變量雖然在任務完成后在流程實例表中會刪除,但是在歷史表中還是會記錄的
字段 | 名稱 | 備注 |
---|---|---|
ID_ | 主鍵 | |
PROC_INST_ID_ | 流程實例ID | |
EXECUTION_ID_ | 指定ID | |
TASK_ID_ | 任務ID | |
NAME_ | 名稱 | |
VAR_TYPE_ | 參數類型 | |
REV_ | 數據版本 | |
BYTEARRAY_ID_ | 字節表ID | |
DOUBLE_ | 存儲double類型數據 | |
LONG_ | 存儲long類型數據 | |
..... |