欧美bbbwbbbw肥妇,免费乱码人妻系列日韩,一级黄片

Flowable流程引擎API與服務

 更新時間:2023年10月01日 09:56:02   作者:吳聲子夜歌  
這篇文章主要介紹了Flowable流程引擎API與服務,引擎API是與Flowable交互的最常用手段,總?cè)肟邳c是ProcessEngine,使用ProcessEngine,可以獲得各種提供工作流或BPM方法的服務,下面我們來詳細了解

1、流程引擎API與服務

引擎API是與Flowable交互的最常用手段???cè)肟邳c是ProcessEngine。使用ProcessEngine,可以獲得各種提供工作流/BPM方法的服務。ProcessEngine與服務對象都是線程安全的,因此可以在服務器中保存并共用同一個引用。

ProcessEngine processEngine = ProcessEngines.getDefaultProcessEngine();
RuntimeService runtimeService = processEngine.getRuntimeService();
RepositoryService repositoryService = processEngine.getRepositoryService();
TaskService taskService = processEngine.getTaskService();
ManagementService managementService = processEngine.getManagementService();
IdentityService identityService = processEngine.getIdentityService();
HistoryService historyService = processEngine.getHistoryService();
FormService formService = processEngine.getFormService();
DynamicBpmnService dynamicBpmnService = processEngine.getDynamicBpmnService();

在ProcessEngines.getDefaultProcessEngine()第一次被調(diào)用時,將初始化并構(gòu)建流程引擎,之后的重復調(diào)用都會返回同一個流程引擎??梢酝ㄟ^ProcessEngines.init()創(chuàng)建流程引擎,并由ProcessEngines.destroy()關(guān)閉流程引擎。

ProcessEngines會掃描flowable.cfg.xml與flowable-context.xml文件。對于flowable.cfg.xml文件,流程引擎會以標準Flowable方式構(gòu)建引擎:ProcessEngineConfiguration.createProcessEngineConfigurationFromInputStream(inputStream).buildProcessEngine()。對于flowable-context.xml文件,流程引擎會以Spring的方式構(gòu)建:首先構(gòu)建Spring應用上下文,然后從該上下文中獲取流程引擎。

所有的服務都是無狀態(tài)的。這意味著你可以很容易的在集群環(huán)境的多個節(jié)點上運行Flowable,使用同一個數(shù)據(jù)庫,而不用擔心上一次調(diào)用實際在哪臺機器上執(zhí)行。不論在哪個節(jié)點執(zhí)行,對任何服務的任何調(diào)用都是冪等(idempotent)的。

1.1、RepositoryService

RepositoryService很可能是使用Flowable引擎要用的第一個服務。這個服務提供了管理與控制部署(deployments)與流程定義(process definitions)的操作。在這里簡單說明一下,流程定義是BPMN 2.0流程對應的Java對象,體現(xiàn)流程中每一步的結(jié)構(gòu)與行為。部署是Flowable引擎中的包裝單元,一個部署中可以包含多個BPMN 2.0 XML文件及其他資源。開發(fā)者可以決定在一個部署中包含的內(nèi)容,可以是單個流程的BPMN 2.0 XML文件,也可以包含多個流程及其相關(guān)資源(如’hr-processes’部署可以包含所有與人力資源流程相關(guān)的的東西)。RepositoryService可用于部署這樣的包。部署意味著將它上傳至引擎,引擎將在儲存至數(shù)據(jù)庫之前檢查與分析所有的流程。在部署操作后,可以在系統(tǒng)中使用這個部署包,部署包中的所有流程都可以啟動。

此外,這個服務還可以:

  • 查詢引擎現(xiàn)有的部署與流程定義。
  • 暫?;蚣せ畈渴鹬械哪承┝鞒?,或整個部署。暫停意味著不能再對它進行操作,激活剛好相反,重新使它可以操作。
  • 獲取各種資源,比如部署中保存的文件,或者引擎自動生成的流程圖。
  • 獲取POJO版本的流程定義。它可以用Java而不是XML的方式查看流程。

1.2、RuntimeService

RuntimeService用于啟動流程定義的新流程實例。前面介紹過,流程定義中定義了流程中不同步驟的結(jié)構(gòu)與行為。流程實例則是流程定義的實際執(zhí)行過程。同一時刻,一個流程定義通常有多個運行中的實例。RuntimeService也用于讀取與存儲流程變量。流程變量是流程實例中的數(shù)據(jù),可以在流程的許多地方使用(例如排他網(wǎng)關(guān)經(jīng)常使用流程變量判斷流程下一步要走的路徑)。RuntimeService還可以用于查詢流程實例與執(zhí)行(Execution)。執(zhí)行也就是BPMN 2.0中 ‘token’ 的概念。通常執(zhí)行是指向流程實例當前位置的指針。最后,還可以在流程實例等待外部觸發(fā)時使用RuntimeService,使流程可以繼續(xù)運行。流程有許多等待狀態(tài)(wait states),RuntimeService服務提供了許多操作用于“通知”流程實例:已經(jīng)接收到外部觸發(fā),流程實例可以繼續(xù)運行。

1.3、TaskService

所有任務相關(guān)的東西都組織在TaskService中,例如:

  • 查詢分派給用戶或組的任務
  • 創(chuàng)建獨立運行(standalone)任務。這是一種沒有關(guān)聯(lián)到流程實例的任務。
  • 決定任務的執(zhí)行用戶(assignee),或者將用戶通過某種方式與任務關(guān)聯(lián)。
  • 認領(claim)與完成(complete)任務。認領是指某人決定成為任務的執(zhí)行用戶,也即他將會完成這個任務。完成任務是指“做這個任務要求的工作”,通常是填寫某個表單。

1.4、IdentityService

它用于管理(創(chuàng)建,更新,刪除,查詢……)組與用戶。請注意,F(xiàn)lowable實際上在運行時并不做任何用戶檢查。例如任務可以分派給任何用戶,而引擎并不會驗證系統(tǒng)中是否存在該用戶。這是因為Flowable有時要與LDAP、Active Directory等服務結(jié)合使用。

1.5、FormService

FormService是可選服務。也就是說Flowable沒有它也能很好地運行,而不必犧牲任何功能。這個服務引入了開始表單(start form)與任務表單(task form)的概念。 開始表單是在流程實例啟動前顯示的表單,而任務表單是用戶完成任務時顯示的表單。Flowable可以在BPMN 2.0流程定義中定義這些表單。表單服務通過簡單的方式暴露這些數(shù)據(jù)。再次重申,表單不一定要嵌入流程定義,因此這個服務是可選的。

1.6、HistoryService

HistoryService暴露Flowable引擎收集的所有歷史數(shù)據(jù)。當執(zhí)行流程時,引擎會保存許多數(shù)據(jù)(可配置),例如流程實例啟動時間、誰在執(zhí)行哪個任務、完成任務花費的事件、每個流程實例的執(zhí)行路徑,等等。這個服務主要提供查詢這些數(shù)據(jù)的能力。

1.7、ManagementService

ManagementService通常在用Flowable編寫用戶應用時不需要使用。它可以讀取數(shù)據(jù)庫表與表原始數(shù)據(jù)的信息,也提供了對作業(yè)(job)的查詢與管理操作。Flowable中很多地方都使用作業(yè),例如定時器(timer),異步操作(asynchronous continuation),延時暫停/激活(delayed suspension/activation)等等。后續(xù)會詳細介紹這些內(nèi)容。

1.8、DynamicBpmnService

DynamicBpmnService可用于修改流程定義中的部分內(nèi)容,而不需要重新部署它。例如可以修改流程定義中一個用戶任務的辦理人設置,或者修改一個服務任務中的類名。

2、異常策略

Flowable的異?;愂莖rg.flowable.engine.FlowableException,這是一個非受檢異常(unchecked exception)。在任何API操作時都可能會拋出這個異常,javadoc提供了每個方法可能拋出的異常。例如,從TaskService中摘錄:

/**
 * 當任務成功執(zhí)行時調(diào)用。
 * @param taskId 需要完成的任務id,不能為null。
 * @throws FlowableObjectNotFoundException 若給定id找不到任務。
 */
 void complete(String taskId);

在上例中,如果所用的id找不到任務,就會拋出異常。并且,由于javadoc中明確要求taskId不能為null,因此如果傳遞了null值,會拋出FlowableIllegalArgumentException異常。

盡管我們想避免過大的異常層次結(jié)構(gòu),但在特定情況下仍然會拋出下述異常子類。所有流程執(zhí)行與API調(diào)用中發(fā)生的錯誤,如果不符合下面列出的異常,會統(tǒng)一拋出FlowableExceptions。

  • FlowableWrongDbException: 當Flowable引擎檢測到數(shù)據(jù)庫表結(jié)構(gòu)版本與引擎版本不匹配時拋出。
  • FlowableOptimisticLockingException: 當對同一數(shù)據(jù)實體的并發(fā)訪問導致數(shù)據(jù)存儲發(fā)生樂觀鎖異常時拋出。
  • FlowableClassLoadingException: 當需要載入的類(如JavaDelegate, TaskListener, …?)無法找到,或載入發(fā)生錯誤時拋出。
  • FlowableObjectNotFoundException: 當請求或要操作的對象不存在時拋出。
  • FlowableIllegalArgumentException: 當調(diào)用Flowable API時使用了不合法的參數(shù)時拋出??赡苁且媾渲弥械牟缓戏ㄖ担蛘呤茿PI調(diào)用傳遞的不合法參數(shù),也可能是流程定義中的不合法值。
  • FlowableTaskAlreadyClaimedException: 當對已被認領的任務調(diào)用taskService.claim(…?)時拋出。

3、查詢API

從引擎中查詢數(shù)據(jù)有兩種方式:查詢API與原生(native)查詢。查詢API可以使用鏈式API,通過編程方式進行類型安全的查詢。你可以在查詢中增加各種條件(所有條件都用做AND邏輯),也可以明確指定排序方式。下面是示例代碼:

List<Task> tasks = taskService.createTaskQuery()
    .taskAssignee("kermit")
    .processVariableValueEquals("orderId", "0815")
    .orderByDueDate().asc()
    .list();

有時需要更復雜的查詢,例如使用OR操作符查詢,或者使用查詢API不能滿足查詢條件要求。我們?yōu)檫@種需求提供了可以自己寫SQL查詢的原生查詢。返回類型由使用的查詢對象決定,數(shù)據(jù)會映射到正確的對象中(Task、ProcessInstance、Execution,等等)。查詢在數(shù)據(jù)庫中進行,因此需要使用數(shù)據(jù)庫中定義的表名與列名。這需要了解內(nèi)部數(shù)據(jù)結(jié)構(gòu),因此建議小心使用原生查詢。數(shù)據(jù)庫表名可以通過API讀取,這樣可以將依賴關(guān)系減到最小。

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();

4、變量

流程實例按步驟執(zhí)行時,需要使用一些數(shù)據(jù)。在Flowable中,這些數(shù)據(jù)稱作變量(variable),并會存儲在數(shù)據(jù)庫中。變量可以用在表達式中(例如在排他網(wǎng)關(guān)中用于選擇正確的出口路徑),也可以在Java服務任務(service task)中用于調(diào)用外部服務(例如為服務調(diào)用提供輸入或結(jié)果存儲),等等。

流程實例可以持有變量(稱作流程變量 process variables);用戶任務以及執(zhí)行(executions)——流程當前活動節(jié)點的指針——也可以持有變量。流程實例可以持有任意數(shù)量的變量,每個變量存儲為ACT_RU_VARIABLE數(shù)據(jù)庫表的一行。

所有的startProcessInstanceXXX方法都有一個可選參數(shù),用于在流程實例創(chuàng)建及啟動時設置變量。例如,在RuntimeService中:

ProcessInstance startProcessInstanceByKey(String processDefinitionKey, Map&amp;lt;String, Object&amp;gt; variables);

也可以在流程執(zhí)行中加入變量。例如,(RuntimeService):

void setVariable(String executionId, String variableName, Object value);
void setVariableLocal(String executionId, String variableName, Object value);
void setVariables(String executionId, Map<String, ? extends Object> variables);
void setVariablesLocal(String executionId, Map<String, ? extends Object> variables);

請注意可以為給定執(zhí)行(請記住,流程實例由一顆執(zhí)行的樹(tree of executions)組成)設置局部(local)變量。局部變量將只在該執(zhí)行中可見,對執(zhí)行樹的上層則不可見。這可以用于 數(shù)據(jù)不應該暴露給流程實例的其他執(zhí)行,或者變量在流程實例的不同路徑中有不同的值(例如使用并行路徑時)的情況。

可以用下列方法讀取變量。請注意TaskService中有類似的方法。這意味著任務與執(zhí)行一樣,可以持有局部變量,其生存期為任務持續(xù)的時間。

Map<String, Object> getVariables(String executionId);
Map<String, Object> getVariablesLocal(String executionId);
Map<String, Object> getVariables(String executionId, Collection<String> variableNames);
Map<String, Object> getVariablesLocal(String executionId, Collection<String> variableNames);
Object getVariable(String executionId, String variableName);
<T> T getVariable(String executionId, String variableName, Class<T> variableClass);

變量通常用于Java代理(Java delegates)、表達式(expressions)、執(zhí)行(execution)、任務監(jiān)聽器(tasklisteners)、腳本(scripts)等等。在這些結(jié)構(gòu)中,提供了當前的execution或task對象,可用于變量的設置、讀取。簡單示例如下:

execution.getVariables();
execution.getVariables(Collection<String> variableNames);
execution.getVariable(String variableName);
execution.setVariables(Map<String, object> variables);
execution.setVariable(String variableName, Object value);

請注意也可以使用上例中方法的局部變量版本。

由于歷史(與向后兼容)原因,當調(diào)用上述任何方法時,引擎會從數(shù)據(jù)庫中取出所有變量。也就是說,如果你有10個變量,使用getVariable(“myVariable”)獲取其中的一個,實際上其他9個變量也會從數(shù)據(jù)庫取出并緩存。這并不壞,因為后續(xù)的調(diào)用可以不必再讀取數(shù)據(jù)庫。比如,如果流程定義包含三個連續(xù)的服務任務(因此它們在同一個數(shù)據(jù)庫事務里),在第一個服務任務里通過一次調(diào)用獲取全部變量,也許比在每個服務任務里分別獲取需要的變量要好。請注意對讀取與設置變量都是這樣。

當然,如果使用大量變量,或者你希望精細控制數(shù)據(jù)庫查詢與流量,上述的做法就不合適了。我們引入了可以更精細控制的方法。這個方法有一個可選的參數(shù),告訴引擎是否需要讀取并緩存所有變量:

Map<String, Object> getVariables(Collection<String> variableNames, boolean fetchAllVariables);
Object getVariable(String variableName, boolean fetchAllVariables);
void setVariable(String variableName, Object value, boolean fetchAllVariables);

當fetchAllVariables參數(shù)為true時,行為與上面描述的完全一樣:讀取或設置一個變量時,所有的變量都將被讀取并緩存。

而當參數(shù)值為false時,會使用明確的查詢,其他變量不會被讀取或緩存。只有指定的變量的值會被緩存并用于后續(xù)使用。

5、瞬時變量

瞬時變量(Transient variable)類似普通變量,只是不會被持久化。通常來說,瞬時變量用于高級使用場景。如果不明確,還是使用普通流程變量為好。

  • 瞬時變量具有下列特性:
  • 瞬時變量完全不存儲歷史。
  • 與普通變量類似,設置瞬時變量時會存入最上層父中。這意味著在一個執(zhí)行中設置一個變量時,瞬時變量實際上會存儲在流程實例執(zhí)行中。與普通變量類似,可以使用局部(local)的對應方法,將變量設置為某個執(zhí)行或任務的局部變量。
  • 瞬時變量只能在下一個“等待狀態(tài)”之前訪問。之后該變量即消失。等待狀態(tài)意味著流程實例會持久化至數(shù)據(jù)存儲中。請注意在這個定義中,異步活動也是“等待狀態(tài)”!
  • 只能使用setTransientVariable(name, value)設置瞬時變量,但是調(diào)用getVariable(name)也會返回瞬時變量(也有g(shù)etTransientVariable(name)方法,它只會返回瞬時變量)。這是為了簡化表達式的撰寫,并保證已有邏輯可以使用這兩種類型的變量。
  • 瞬時變量屏蔽(shadow)同名的持久化變量。也就是說當一個流程實例中設置了同名的持久化變量與瞬時變量時,getVariable(“someVariable”)會返回瞬時變量的值。

在大多數(shù)可以使用普通變量的地方,都可以獲取、設置瞬時變量:

  • 在JavaDelegate實現(xiàn)中的DelegateExecution內(nèi)
  • 在ExecutionListener實現(xiàn)中的DelegateExecution內(nèi),以及在TaskListener實現(xiàn)中的DelegateTask內(nèi)
  • 通過execution對象在腳本任務內(nèi)
  • 通過RuntimeService啟動流程實例時
  • 完成任務時
  • 調(diào)用runtimeService.trigger方法時
  • 瞬時變量相關(guān)的方法遵循普通流程變量方法的命名約定:
void setTransientVariable(String variableName, Object variableValue);
void setTransientVariableLocal(String variableName, Object variableValue);
void setTransientVariables(Map<String, Object> transientVariables);
void setTransientVariablesLocal(Map<String, Object> transientVariables);
Object getTransientVariable(String variableName);
Object getTransientVariableLocal(String variableName);
Map<String, Object> getTransientVariables();
Map<String, Object> getTransientVariablesLocal();
void removeTransientVariable(String variableName);
void removeTransientVariableLocal(String variableName);

示例

假設’Fetch Data(獲取數(shù)據(jù))'服務任務調(diào)用某個遠程服務(例如使用REST)。也假設需要其需要一些配置參數(shù),并需要在啟動流程實例時提供。同時,這些配置參數(shù)對于歷史審計并不重要,因此我們將它們作為瞬時變量傳遞:

ProcessInstance processInstance = runtimeService.createProcessInstanceBuilder()
       .processDefinitionKey("someKey")
       .transientVariable("configParam01", "A")
       .transientVariable("configParam02", "B")
       .transientVariable("configParam03", "C")
       .start();

請注意在到達用戶任務并持久化之前,都可以使用這些瞬時變量。例如,在’Additional Work(額外工作)'用戶任務中它們就不再可用。也請注意如果’Fetch Data’是異步的,則瞬時變量在該步驟之后也不再可用。

Fetch Data(的簡化版本)可以像是:

public static class FetchDataServiceTask implements JavaDelegate {
  public void execute(DelegateExecution execution) {
    String configParam01 = (String) execution.getVariable(configParam01);
    // ...
    RestReponse restResponse = executeRestCall();
    execution.setTransientVariable("response", restResponse.getBody());
    execution.setTransientVariable("status", restResponse.getStatus());
  }
}

Process Data(處理數(shù)據(jù))'可以獲取response瞬時變量,解析并將其相關(guān)數(shù)據(jù)存儲在實際流程變量中,因為之后還需要使用它們。

離開排他網(wǎng)關(guān)的順序流上的條件表達式,不關(guān)注使用的是持久化還是瞬時變量(在這個例子中status是瞬時變量):

&amp;lt;conditionExpression xsi:type&amp;#61;&amp;#34;tFormalExpression&amp;#34;&amp;gt;${status &amp;#61;&amp;#61; 200}&amp;lt;/conditionExpression&amp;gt;

6、表達式

Flowable使用UEL進行表達式解析。UEL代表Unified Expression Language,是EE6規(guī)范的一部分(查看EE6規(guī)范了解更多信息)。

表達式可以用于Java服務任務(Java Service task)、執(zhí)行監(jiān)聽器(Execution Listener)、任務監(jiān)聽器(Task Listener) 與 條件順序流(Conditional sequence flow)等。盡管有值表達式與方法表達式這兩種不同的表達式,F(xiàn)lowable通過抽象,使它們都可以在需要表達式的地方使用。

值表達式 Value expression: 解析為一個值。默認情況下,所有流程變量都可以使用。(若使用Spring)所有的Spring bean也可以用在表達式里。例如:

${myVar}
${myBean.myProperty}

方法表達式 Method expression: 調(diào)用一個方法,可以帶或不帶參數(shù)。當調(diào)用不帶參數(shù)的方法時,要確保在方法名后添加空括號(以避免與值表達式混淆)。傳遞的參數(shù)可以是字面值(literal value),也可以是表達式,它們會被自動解析。例如:

${printer.print()}
${myBean.addNewOrder('orderName')}
${myBean.doSomething(myVar, execution)}

請注意,表達式支持解析(及比較)原始類型(primitive)、bean、list、array與map。 Note that these expressions support resolving primitives (including comparing them), beans, lists, arrays and maps.

除了所有流程變量外,還有一些默認對象可在表達式中使用:

  • execution: DelegateExecution+,持有正在運行的執(zhí)行的額外信息。
  • task: DelegateTask持有當前任務的額外信息。請注意:只在任務監(jiān)聽器的表達式中可用。
  • authenticatedUserId: 當前已驗證的用戶id。如果沒有已驗證的用戶,該變量不可用。

7、單元測試

業(yè)務流程是軟件項目的必要組成部分,也需要使用測試一般應用邏輯的方法——單元測試——測試它們。Flowable是嵌入式的Java引擎,因此為業(yè)務流程編寫單元測試就同編寫一般的單元測試一樣簡單。

Flowable支持JUnit 3及4的單元測試風格。按照JUnit 3的風格,必須擴展(extended)org.flowable.engine.test.FlowableTestCase。它通過保護(protected)成員變量提供對ProcessEngine與服務的訪問。在測試的setup()中,processEngine會默認使用classpath中的flowable.cfg.xml資源初始化。如果要指定不同的配置文件,請覆蓋getConfigurationResource()方法。當使用相同的配置資源時,流程引擎會靜態(tài)緩存,用于多個單元測試。

通過擴展FlowableTestCase,可以使用org.flowable.engine.test.Deployment注解測試方法。在測試運行前,會部署與測試類在同一個包下的格式為testClassName.testMethod.bpmn20.xml的資源文件。在測試結(jié)束時,會刪除這個部署,包括所有相關(guān)的流程實例、任務,等等。也可以使用Deployment注解顯式指定資源位置。查看該類以獲得更多信息。

綜上所述,JUnit 3風格的測試看起來類似:

public class MyBusinessProcessTest extends FlowableTestCase {
  @Deployment
  public void testSimpleProcess() {
    runtimeService.startProcessInstanceByKey("simpleProcess");
    Task task = taskService.createTaskQuery().singleResult();
    assertEquals("My Task", task.getName());
    taskService.complete(task.getId());
    assertEquals(0, runtimeService.createProcessInstanceQuery().count());
  }
}

要使用JUnit 4的風格書寫單元測試并達成同樣的功能,必須使用org.flowable.engine.test.FlowableRule Rule。這樣能夠通過它的getter獲得流程引擎與服務。對于FlowableTestCase(上例),包含@Rule就可以使用org.flowable.engine.test.Deployment注解(參見上例解釋其用途及配置),并且會自動在classpath中尋找默認配置文件。當使用相同的配置資源時,流程引擎會靜態(tài)緩存,以用于多個單元測試。

下面的代碼片段展示了JUnit 4風格的測試與FlowableRule的用法。

public class MyBusinessProcessTest {
  @Rule
  public FlowableRule FlowableRule = new FlowableRule();
  @Test
  @Deployment
  public void ruleUsageExample() {
    RuntimeService runtimeService = FlowableRule.getRuntimeService();
    runtimeService.startProcessInstanceByKey("ruleUsage");
    TaskService taskService = FlowableRule.getTaskService();
    Task task = taskService.createTaskQuery().singleResult();
    assertEquals("My Task", task.getName());
    taskService.complete(task.getId());
    assertEquals(0, runtimeService.createProcessInstanceQuery().count());
  }
}

8、Web應用中的流程引擎

ProcessEngine是線程安全的類,可以很容易地在多個線程間共享。在web應用中,這意味著可以在容器啟動時創(chuàng)建引擎,并在容器關(guān)閉時關(guān)閉引擎。

下面的代碼片段展示了如何在Servlet環(huán)境中,通過ServletContextListener初始化與銷毀流程引擎。

public class ProcessEnginesServletContextListener implements ServletContextListener {
  public void contextInitialized(ServletContextEvent servletContextEvent) {
    ProcessEngines.init();
  }
  public void contextDestroyed(ServletContextEvent servletContextEvent) {
    ProcessEngines.destroy();
  }
}

contextInitialized方法會調(diào)用ProcessEngines.init()。它會在classpath中查找flowable.cfg.xml資源文件,并為每個文件分別創(chuàng)建ProcessEngine(如果多個JAR都包含配置文件)。如果在classpath中有多個這樣的資源文件,請確保它們使用不同的引擎名。需要使用流程引擎時,可以這樣獲取:

ProcessEngines.getDefaultProcessEngine()

或者:

ProcessEngines.getProcessEngine(&amp;#34;myName&amp;#34;);

context-listener的contextDestroyed方法會調(diào)用ProcessEngines.destroy()。它會妥善關(guān)閉所有已初始化的流程引擎。

到此這篇關(guān)于Flowable流程引擎API與服務的文章就介紹到這了,更多相關(guān)Flowable API內(nèi)容請搜索腳本之家以前的文章或繼續(xù)瀏覽下面的相關(guān)文章希望大家以后多多支持腳本之家!

相關(guān)文章

  • ApplicationListenerDetector監(jiān)聽器判斷demo

    ApplicationListenerDetector監(jiān)聽器判斷demo

    這篇文章主要為大家介紹了ApplicationListenerDetector監(jiān)聽器判斷demo,有需要的朋友可以借鑒參考下,希望能夠有所幫助,祝大家多多進步,早日升職加薪
    2023-03-03
  • Java8新特性之Stream API詳解

    Java8新特性之Stream API詳解

    這篇文章主要介紹了Java8新特性之StreamAPI詳解,文中有非常詳細的代碼示例,對正在學習java的小伙伴們有非常好的幫助,需要的朋友可以參考下
    2021-04-04
  • hadoop之MapReduce框架原理

    hadoop之MapReduce框架原理

    這篇文章主要介紹了hadoop的MapReduce框架原理,MapReduce是分為兩個階段的,MapperTask階段,和ReduceTask階段。如果有感興趣的小伙伴可以借鑒參考
    2023-03-03
  • Java中的命名與目錄接口JNDI基本操作方法概覽

    Java中的命名與目錄接口JNDI基本操作方法概覽

    這篇文章主要介紹了Java中的命名與目錄接口JNDI基本操作方法概覽,JNDI提供統(tǒng)一的客戶端API使得Java應用程序可以和這些命名服務和目錄服務之間進行交互,需要的朋友可以參考下
    2016-03-03
  • java打印正弦曲線示例

    java打印正弦曲線示例

    這篇文章主要介紹了java數(shù)組排序示例,需要的朋友可以參考下
    2014-03-03
  • Java實現(xiàn)十秒向MySQL插入百萬條數(shù)據(jù)

    Java實現(xiàn)十秒向MySQL插入百萬條數(shù)據(jù)

    這篇文章主要為大家詳細介紹了Java如何實現(xiàn)十秒向MySQL插入百萬條數(shù)據(jù),文中的示例代碼講解詳細,對我們學習或工作有一定借鑒價值,需要的可以參考一下
    2022-11-11
  • SpringCloud OpenFeign基本介紹與實現(xiàn)示例

    SpringCloud OpenFeign基本介紹與實現(xiàn)示例

    OpenFeign源于Netflix的Feign,是http通信的客戶端。屏蔽了網(wǎng)絡通信的細節(jié),直接面向接口的方式開發(fā),讓開發(fā)者感知不到網(wǎng)絡通信細節(jié)。所有遠程調(diào)用,都像調(diào)用本地方法一樣完成
    2023-02-02
  • java實現(xiàn)字符串反轉(zhuǎn)案例

    java實現(xiàn)字符串反轉(zhuǎn)案例

    這篇文章主要為大家詳細介紹了java實現(xiàn)字符串反轉(zhuǎn),文中示例代碼介紹的非常詳細,具有一定的參考價值,感興趣的小伙伴們可以參考一下
    2020-09-09
  • JAVA mongodb 聚合幾種查詢方式詳解

    JAVA mongodb 聚合幾種查詢方式詳解

    這篇文章主要介紹了JAVA mongodb 聚合幾種查詢方式詳解,小編覺得挺不錯的,現(xiàn)在分享給大家,也給大家做個參考。一起跟隨小編過來看看吧
    2018-03-03
  • Mybatis-plus原生pages分頁未生效的解決方案

    Mybatis-plus原生pages分頁未生效的解決方案

    本文主要介紹了Mybatis-plus原生pages分頁未生效的解決方案,包含介紹了未生效的5種原因以及解決方法,具有一定的參考價值,感興趣的可以了解一下
    2024-07-07

最新評論