flowable工作流進階(二)
Flowable spring boot 進階(二)
資料庫表介紹
Flowable的資料庫名稱都以ACT_開頭。第二部分是表的用例的雙字元標識。此用例也將大致匹配服務API。
ACT_RE_ *:RE代表repository。具有此字首的表包含靜態資訊,例如流程定義和流程資源(影象,規則等)。
ACT_RU_ *:RU代表runtime。這些是包含流程例項,使用者任務,變數,作業等的執行時資料的執行時表。Flowable僅在流程例項執行期間儲存執行時資料,並在流程例項結束時刪除記錄。這使執行時表保持小而快。
ACT_HI_ *:HI代表history。這些是包含歷史資料的表,例如過去的流程例項,變數,任務等。
ACT_GE_ *:general資料,用於各種用例。
事件監聽器實現
事件監聽器的唯一要求是實現org.flowable.engine.delegate.event.FlowableEventListener。下面是一個偵聽器的示例實現,它將收到的所有事件輸出到標準輸出,但與作業執行相關的事件除外:
public class MyEventListener implements FlowableEventListener {
@Override public void onEvent(FlowableEvent event) { if (event.getType().equals(FlowableEngineEventType.JOB_EXECUTION_SUCCESS)) { System.out.println("一個任務執行成功"); } else if (event.getType().equals(FlowableEngineEventType.JOB_EXECUTION_FAILURE)) { System.out.println("一個任務執行失敗"); } else { System.out.println(event.getType()); } } //該isFailOnException()方法確定onEvent(..)方法在排程事件時丟擲異常時的行為。 // 當false返回,異常被忽略。當true返回,異常不會被忽略 @Override public boolean isFailOnException() { return false; }
//該isFireOnTransactionLifecycleEvent()方法確定此事件偵聽器是在事件發生時立即觸發還是由getOnTransaction()方法確定的事務生命週期事件觸發。支援的事務生命週期事件的值是:COMMITTED,ROLLED_BACK,COMMITTING,ROLLINGBACK。
@Override public boolean isFireOnTransactionLifecycleEvent() { return false; } @Override public String getOnTransaction() { return null; } }
基礎類的監聽
org.flowable.engine.delegate.event.BaseEntityEventListener
一個事件偵聽器基類,可用於偵聽特定型別的實體或所有實體的實體相關事件。它隱藏掉型別檢查,並提供4種方法應覆蓋:onCreate(..),onUpdate(..)並onDelete(..)建立實體時,更新或刪除。對於所有其他與實體相關的事件,onEntityEvent(..) 呼叫它
執行的監聽器
通過RuntimeService呼叫
新增監聽器
void addEventListener(FlowableEventListener listenerToAdd);
新增監聽器並指定型別
void addEventListener(FlowableEventListener listenerToAdd, FlowableEventType... types);
刪除監聽器
void removeEventListener(FlowableEventListener listenerToRemove);
下面列出了引擎中可能出現的所有事件型別。每種型別對應於中的列舉值org.flowable.engine.common.api.delegate.event.FlowableEventType
所有ENTITY_\*事件都與引擎內的實體相關
ENTITY_CREATED, ENTITY_INITIALIZED, ENTITY_DELETED:附件,註釋,部署,執行,組,IdentityLink,作業,模型,ProcessDefinition,ProcessInstance,任務,使用者。
ENTITY_UPDATED:附件,部署,執行,組,IdentityLink,作業,模型,ProcessDefinition,ProcessInstance,任務,使用者。
ENTITY_SUSPENDED, ENTITY_ACTIVATED:ProcessDefinition,ProcessInstance / Execution,Task。
Process engine API和服務
重點7大介面
RepositoryService
主要是關於靜態資訊(資料不會改變,或者至少不是很多)
查詢引擎已知的部署和流程定義。
暫停和啟用整個部署或特定流程定義。暫停意味著不能對它們執行進一步的操作,而啟用則相反並且再次啟用操作。
檢索各種資源,例如部署中包含的檔案或引擎自動生成的流程圖。
檢索流程定義的POJO版本,該版本可用於使用Java而不是XML來內省流程
RuntimeService
但RuntimeService恰恰相反。它涉及啟動流程定義的新流程例項。
TaskService
需要由系統的使用者執行的任務是BPM引擎(如Flowable)的核心。圍繞任務的所有內容都在TaskService中進行分組:
查詢分配給使用者或組的任務
建立新的獨立任務。這些是與流程例項無關的任務。
操作分配任務的使用者或以某種方式參與任務的使用者。
聲稱並完成任務。聲稱意味著某人決定成為該任務的受讓人,這意味著該使用者將完成該任務。完成意味著完成任務的工作。通常,這是填寫各種形式。
IdentityService
它支援組和使用者的管理(建立,更新,刪除,查詢......)。
formService
是一個可選的服務,將flowable裡的表單關聯到dpmn中(不使用)。
HistoryService:
暴露了可流動的引擎收集的所有歷史資料例如流程例項啟動時間,執行哪些任務,完成任務所需的時間,每個流程例項中遵循的路徑,等等。此服務主要公開查詢功能以訪問此資料。
ManagementService
該ManagementService編碼使用可流動的自定義應用程式時,通常是沒有必要的。它允許檢索有關資料庫表和表元資料的資訊。此外,它還公開了作業的查詢功能和管理操作。Flowable中的作業用於各種事物,例如計時器,非同步延續,延遲暫停/啟用等。稍後,將更詳細地討論這些主題。
DynamicBpmnService(多出來特殊的一個)
可以用來改變流程定義的一部分,而無需重新部署。例如,您可以更改流程定義中使用者任務的受理人定義,或更改服務任務的類名稱。
ProcessEngines.getDefaultProcessEngine()將在第一次呼叫時初始化並構建流程引擎,之後始終返回相同的流程引擎。可以使用ProcessEngines.init() 和完成所有流程引擎的正確建立和關閉ProcessEngines.destroy()
異常
org.flowable.engine.FlowableException
FlowableWrongDbException:當Flowable引擎發現數據庫架構版本與引擎版本不匹配時丟擲。
FlowableOptimisticLockingException:在由同一資料條目的併發訪問引起的資料儲存中發生樂觀鎖定時丟擲。
FlowableClassLoadingException:在未找到請求載入的類或載入時發生錯誤(例如JavaDelegates,TaskListeners,...)時丟擲。
FlowableObjectNotFoundException: Thrown when an object that is requested or actioned does not exist.
FlowableIllegalArgumentException:一個異常,指示在Flowable API呼叫中提供了非法引數,在引擎配置中配置了非法值,或者提供了非法值,或者在流程定義中使用了非法值。
FlowableTaskAlreadyClaimedException:當已經宣告任務時,在taskService.claim(…)被呼叫時丟擲。
查詢API
有兩種方法可以從引擎查詢資料:查詢API和本機查詢。
API查詢
List<Task> list = taskService.createTaskQuery().taskAssignee("")
.processVariableValueEquals("orderId", "0851")
.orderByTaskDueDate().asc().list();
本地查詢
List<Task> tasks = taskService.createNativeTaskQuery()
.sql("SELECT count(*) FROM " + managementService.getTableName(Task.class) +
" T WHERE T.NAME_ = #{taskName}")
.parameter("taskName", "gonzoTask")
.list();
long count = taskService.createNativeTaskQuery()
.sql("SELECT count(*) FROM " + managementService.getTableName(Task.class) + " T1, " +
managementService.getTableName(VariableInstanceEntity.class) + " V1 WHERE V1.TASK_ID_ = T1.ID_")
.count();
持久變數
每個流程例項都需要並使用資料來執行由它組成的步驟。在Flowable中,此資料稱為變數,儲存在資料庫中。變數可以在表示式中使用(例如,在獨佔閘道器中選擇正確的傳出順序流),在呼叫外部服務時的Java服務任務中(例如,提供輸入或儲存服務呼叫的結果),等等上。流程例項可以包含變數(稱為流程變數),但也可以包含執行(指向流程活動位置的特定指標),使用者任務可以包含變數。流程例項可以包含任意數量的變數。每個變數都儲存在ACT_RU_VARIABLE資料庫表的一行中。
所有startProcessInstanceXXX方法都有一個可選引數,用於在建立和啟動流程例項時提供變數。例如,從RuntimeService:
runtimeService.startProcessInstanceById("");
瞬時變數
瞬態變數是行為類似於常規變數的變數,但不是持久變數。通常,瞬態變數用於高階用例。
瞬態變數根本沒有儲存歷史記錄。
瞬態變數只能通過setTransientVariable(name,value)設定,但在呼叫getVariable(name)時也會返回瞬態變數(getTransientVariable(name)也存在,只檢查瞬態變數)。這樣做的原因是使表示式的編寫變得容易,並且使用變數的現有邏輯適用於這兩種型別。
瞬態變數會影響具有相同名稱的持久變數。這意味著當在流程例項上設定持久變數和瞬態變數並且呼叫getVariable(“someVariable”)時,將返回瞬態變數值。
例子:
假設Fetch Data服務任務呼叫一些遠端服務(例如,使用REST)。我們還假設需要一些配置引數,並且在啟動流程例項時需要提供這些引數。此外,這些配置引數對於歷史審計目的並不重要,因此我們將它們作為瞬態變數傳遞:
表示式
Flowable使用UEL進行表示式解析。UEL代表統一表達語言,是EE6規範的一部分
表示式可用於例如Java服務任務,執行監聽器,任務監聽器和條件序列流
值表示式:
解析為值
$ {myVar}
$ {myBean.myProperty}
方法表示式:
呼叫帶或不帶引數的方法。在呼叫不帶引數的方法時,請務必在方法名稱後面新增空括號(因為這會將表示式與值表示式區分開來)。傳遞的引數可以是文字值或自己解析的表示式。
$ {printer.print()}
$ {myBean.addNewOrder ('orderName')}
$ {myBean.doSomething (myVar,execution)}
表示式函式
變數:get(varName)
例如,如果myVariable不存在,$ {myVariable ==“hello”}將丟擲異常,但$ {var:get(myVariable)== hello }將起作用。
變數:getOrDefault(varName, defaultValue)
類似於get,但可以選擇提供預設值,該值在未設定變數或值為null時返回。
變數:exists(varName)
如果變數具有非null值,則返回true。
變數:isEmpty(varName)
檢查變數值是否為空。根據變數型別,行為如下
對於String變數,如果變數為空字串,則該變數被視為空。
對於java.util.Collection變數,如果集合沒有元素,則返回true。
對於ArrayNode變數,如果沒有元素,則返回true
如果變數為null,則始終返回true
變數:isNotEmpty(varName)
不為null返回true
變數:equals(varName,value)
檢查變數是否等於給定值。否則將寫為$ {execution.getVariable(“varName”)!= null && execution.getVariable(“varName”)== value}
變數:notEquals(varName,value)
equals的反向比較。
變數:contains(varName,value1,value2,...)
檢查提供的所有值是否包含在變數中
對於String變數,傳遞的值用作需要作為變數一部分的子字串
對於java.util.Collection變數,所有傳遞的值都需要是集合的元素(常規包含語義)。
對於ArrayNode變數:支援檢查arraynode是否包含作為變數型別支援的型別的JsonNode
當變數值為null時,在所有情況下都返回false。當變數值不為null,並且例項型別不是上述型別之一時,將返回false。
變數:containsAny(varName,value1,value2,...)
類似於contains函式,但如果傳遞的值中包含任何(而不是全部)傳遞值,則返回true。
比較器功能:
變數:lowerThan(varName,value)(別名:lessThan或 :lt):
${execution.getVariable("varName") != null && execution.getVariable("varName") < value}
變數:lowerThanOrEquals(varName,value)(別名:lessThanOrEquals或:lte):相似,但現在為<=
變數:greaterThan(varName,value)(別名:gt):類似,但現在為>
變數:greaterThanOrEquals(varName,value)(別名:gte):相似,但現在為> =