日韩性视频-久久久蜜桃-www中文字幕-在线中文字幕av-亚洲欧美一区二区三区四区-撸久久-香蕉视频一区-久久无码精品丰满人妻-国产高潮av-激情福利社-日韩av网址大全-国产精品久久999-日本五十路在线-性欧美在线-久久99精品波多结衣一区-男女午夜免费视频-黑人极品ⅴideos精品欧美棵-人人妻人人澡人人爽精品欧美一区-日韩一区在线看-欧美a级在线免费观看

歡迎訪問 生活随笔!

生活随笔

當前位置: 首頁 > 编程资源 > 编程问答 >内容正文

编程问答

《Flowable基础二 Flowable是什么》

發(fā)布時間:2025/3/21 编程问答 35 豆豆
生活随笔 收集整理的這篇文章主要介紹了 《Flowable基础二 Flowable是什么》 小編覺得挺不錯的,現(xiàn)在分享給大家,幫大家做個參考.

2.1. Flowable是什么??

Flowable是一個使用Java編寫的輕量級業(yè)務流程引擎。Flowable流程引擎讓你可以部署B(yǎng)PMN 2.0流程定義(用于定義流程的行業(yè)XML標準)、創(chuàng)建這些流程定義的流程實例、進行查詢、訪問運行中或歷史的流程實例與相關數(shù)據(jù),等等。這個章節(jié)將用一個可以在你自己的開發(fā)環(huán)境中使用的例子,逐步介紹各種概念與API。

Flowable可以十分靈活地加入你的應用/服務/構架。可以將JAR形式發(fā)布的Flowable庫加入應用或服務,來嵌入引擎。以JAR形式發(fā)布使Flowable可以輕易加入任何Java環(huán)境:Java SE;Tomcat、Jetty或Spring之類的servlet容器;JBoss或WebSphere之類的Java EE服務器,等等。另外,也可以使用Flowable REST API通過HTTP通信。也有許多Flowable應用(Flowable Modeler, Flowable Admin, Flowable IDM 與 Flowable Task),提供了直接可用的UI示例,可以使用流程與任務。

所有設置Flowable方法的共同點是核心引擎。核心引擎可被看做是一組服務的集合,并暴露了管理與執(zhí)行業(yè)務流程的API。下面的各種教程都以設置與使用核心引擎的介紹開始。后續(xù)章節(jié)都建立在之前章節(jié)中獲取的知識之上。

  • 第一節(jié)展示了以最簡單的方式運行Flowable的方法:只使用Java SE的標準Java main方法。這里也會介紹許多核心概念與API。

  • Flowable REST API章節(jié)展示了如何通過REST運行及使用相同的API。

  • Flowable APP章節(jié)將介紹直接可用的Flowable UI示例的基本方法。

2.2. Flowable與Activiti (Flowable and Activiti)

Flowable是Activiti(Alfresco的注冊商標)的分支。在下面的章節(jié)中,你會注意到包名,配置文件等等,都使用flowable。

2.3. 構建一個命令行程序 Building a command-line application

2.3.1. 創(chuàng)建一個流程引擎 Creating a process engine

在本教程中,將構建一個簡單的例子,以展示如何創(chuàng)建一個Flowable流程引擎,介紹一些核心概念,并展示如何使用API。截圖使用Eclipse,但實際上可以使用任何IDE。我們使用Maven獲取Flowable依賴及管理構建,但是類似的任何其它方法也都可以使用(Gradle,Ivy,等等)。

我們將構建的例子是一個簡單的請假(holiday request)流程:

  • 雇員(employee)申請幾天的假期

  • 經理(manager)批準或駁回申請

  • 模擬將申請注冊到某個外部系統(tǒng),并給雇員發(fā)送結果郵件

首先,通過File → New → Other → Maven Project創(chuàng)建一個新的Maven項目

在下一界面中,選中'create a simple project (skip archetype selection)'

填入'Group Id'與'Artifact id':

這樣就建立了空的Maven項目,然后添加兩個依賴:

  • Flowable流程引擎。使我們可以創(chuàng)建一個ProcessEngine流程引擎對象,并訪問Flowable API。

  • 一個內存數(shù)據(jù)庫。本例中為H2,因為Flowable引擎在運行流程實例時,需要使用數(shù)據(jù)庫來存儲執(zhí)行與歷史數(shù)據(jù)。請注意H2依賴包含了數(shù)據(jù)庫及驅動。如果使用其他數(shù)據(jù)庫(例如PostgreSQL,MySQL等),需要添加對應的數(shù)據(jù)庫驅動依賴。

在你的pom.xml文件中添加下列行:

<dependencies> <dependency> <groupId>org.flowable</groupId> <artifactId>flowable-engine</artifactId> <version>6.0.1</version> </dependency> <dependency> <groupId>com.h2database</groupId> <artifactId>h2</artifactId> <version>1.3.176</version> </dependency> </dependencies>

如果由于某些原因,依賴JAR無法自動獲取,可以右鍵點擊項目,并選擇'Maven → Update Project'以強制手動刷新(一般不會需要這么操作)。在這個項目中的'Maven Dependencies'下,可以看到flowable-engine與許多其他依賴。

創(chuàng)建一個新的Java類,并添加標準的Java main方法:

package org.flowable; public class HolidayRequest { public static void main(String[] args) { } }

?

首先要做的是初始化一個ProcessEngine流程引擎實例。這是一個線程安全的對象,因此通常只需要在一個應用中初始化一次。ProcessEngine由一個ProcessEngineConfiguration實例創(chuàng)建。該實例可以配置與調整流程引擎的設置。通常使用一個配置XML文件創(chuàng)建ProcessEngineConfiguration,但是(像在這里做的一樣)也可以編程方式創(chuàng)建它。ProcessEngineConfiguration最少需要配置一個數(shù)據(jù)庫的JDBC連接:

package org.flowable; import org.flowable.engine.ProcessEngine; import org.flowable.engine.ProcessEngineConfiguration; import org.flowable.engine.impl.cfg.StandaloneProcessEngineConfiguration; public class HolidayRequest { public static void main(String[] args) { ProcessEngineConfiguration cfg = new StandaloneProcessEngineConfiguration() .setJdbcUrl("jdbc:h2:mem:flowable;DB_CLOSE_DELAY=-1") .setJdbcUsername("sa") .setJdbcPassword("") .setJdbcDriver("org.h2.Driver") .setDatabaseSchemaUpdate(ProcessEngineConfiguration.DB_SCHEMA_UPDATE_TRUE); ProcessEngine processEngine = cfg.buildProcessEngine(); } }

?

在上面的代碼中,第10行創(chuàng)建了一個獨立(standalone)配置對象。這里的'獨立'指的是引擎是完全獨立創(chuàng)建及使用的(而不是在例如Spring環(huán)境中使用,這時需要使用SpringProcessEngineConfiguration類代替)。第11至14行中,傳遞了一個內存H2數(shù)據(jù)庫實例的JDBC連接參數(shù)。重要:請注意這樣的數(shù)據(jù)庫在JVM重啟后會消失。如果需要永久保存數(shù)據(jù),需要切換為持久化數(shù)據(jù)庫,并相應切換連接參數(shù)。第15行中,設置了一個true標志,確保在JDBC參數(shù)連接的數(shù)據(jù)庫中,數(shù)據(jù)庫表結構不存在時,會創(chuàng)建相應的表結構。另外,Flowable也提供了一組SQL文件,可用于手動創(chuàng)建所有表的數(shù)據(jù)庫表結構。

然后使用這個配置創(chuàng)建ProcessEngine對象(第17行)。

這樣就可以運行了。在Eclipse中最簡單的方法是右鍵點擊類文件,選擇Run As → Java Application

應用運行沒有問題,但也沒有在控制臺提供有用的信息,只有一條消息提示日志沒有正確配置:

Flowable使用SLF4J作為內部日志框架。在這個例子中,我們在SLF4J之上使用log4j。因此在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

回到應用。應該可以看到關于引擎啟動與創(chuàng)建數(shù)據(jù)庫表結構的提示日志:

這樣就得到了一個啟動可用的流程引擎。接下來為它提供一個流程!

2.3.2. 部署一個流程定義 Deploying a process definition

我們要構建的流程是一個非常簡單的請假流程。Flowable引擎需要流程定義為BPMN 2.0格式,這是一個業(yè)界廣泛接受的XML標準。在Flowable術語中,我們將其稱為一個流程定義(process definition)。一個流程定義可以啟動多個流程實例(process instance)。流程定義可以看做是重復執(zhí)行流程的藍圖。在這個例子中,流程定義定義了請假的各個步驟,而一個流程實例對應某個雇員提出的一個請假申請。

BPMN 2.0存儲為XML,包含可視化的部分:使用標準方式定義了每個步驟類型(人工任務,自動服務調用,等等)如何呈現(xiàn),以及如何互相連接。這樣BPMN 2.0標準使技術人員與業(yè)務人員能用雙方都能理解的方式交流業(yè)務流程。

我們要使用的流程定義為:

這個流程應該已經十分自我解釋了,但為了明確起見,描述一下不同的部分:

  • 我們假定啟動流程需要提供一些信息,例如雇員名字、請假時長以及描述。當然,這些可以單獨建模為流程中的第一步。但是如果將它們作為流程的“輸入信息”,就能保證只有在實際請求時才會建立一個流程實例。否則(將提交作為流程的第一步),用戶可能在提交之前改變主意并取消,但流程實例已經創(chuàng)建了。在某些場景中,就可能影響重要的指標(例如啟動了多少申請,但還未完成),取決于業(yè)務目標。

  • 左側的圓圈叫做啟動事件(start event)。這是一個流程實例的起點。

  • 第一個矩形是一個用戶任務(user task)。這是流程中人類用戶操作的步驟。在這個例子中,經理需要批準或駁回申請。

  • 取決于經理的決定,排他網關(exclusive gateway)?(帶叉的菱形)會將流程實例路由至批準或駁回路徑。

  • 如果批準,則需要將申請注冊至某個外部系統(tǒng),并跟著另一個用戶任務,將經理的決定通知給申請人。當然也可以替換為郵件。

  • 如果駁回,則為雇員發(fā)送一封郵件通知他。

一般來說,這樣的流程定義使用可視化建模工具建立,如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>

?

第2至11行看起來挺嚇人,但其實在大多數(shù)的流程定義中都是一樣的。這是一種樣板文件,需要與BPMN 2.0標準規(guī)范完全一致。

每一個步驟(在BPMN 2.0術語中稱作活動 activity)都有一個id屬性,為其提供一個在XML文件中唯一的標識符。所有的活動都可選有一個名字,以提高流程圖的可讀性。

活動之間通過順序流(sequence flow)連接,在流程圖中是一個有向箭頭。在執(zhí)行流程實例時,執(zhí)行(execution)會從啟動事件沿著順序流流向下一個活動。

離開排他網關(帶有X的菱形)的順序流很特別:都以表達式(expression)的形式定義了條件(condition)?(見第25至32行)。當流程實例的執(zhí)行到達這個網關時,會計算條件,并使用第一個計算為true的順序流。這就是排他的含義:只選擇一個。當然如果需要不同的路由策略,可以使用其他類型的網關。

這里用作條件的表達式格式為${approved},這是${approved == true}的簡寫。變量’approved’被稱作流程變量(process variable)。流程變量是一個持久化數(shù)據(jù),與流程實例存儲在一起,并可以在流程實例的生命周期中使用。在這個例子里,我們需要在特定的地方(當經理用戶任務提交時,或者以Flowable的術語來說,完成(complete)時)設置這個流程變量,因為這不是流程實例啟動時就能獲取的數(shù)據(jù)。

現(xiàn)在我們已經有了流程BPMN 2.0 XML文件,下來需要將它部署(deploy)到引擎中。部署一個流程定義意味著:

  • 流程引擎會將XML文件存儲在數(shù)據(jù)庫中,這樣可以在需要的時候獲取它。

  • 流程定義轉換為內部的、可執(zhí)行的對象模型,這樣使用它就可以啟動流程實例。

將流程定義部署至Flowable引擎,需要使用RepositoryService,其可以從ProcessEngine對象獲取。使用RepositoryService,可以通過傳遞XML文件的地址創(chuàng)建一個新的部署(Deployment),并調用deploy()方法實際執(zhí)行它:

RepositoryService repositoryService = processEngine.getRepositoryService(); Deployment deployment = repositoryService.createDeployment() .addClasspathResource("holiday-request.bpmn20.xml") .deploy();

?

我們現(xiàn)在可以通過API查詢驗證流程定義已經部署在引擎中(并學習一些API)。通過RepositoryService創(chuàng)建的ProcessDefinitionQuery對象實現(xiàn)。

ProcessDefinition processDefinition = repositoryService.createProcessDefinitionQuery() .deploymentId(deployment.getId()) .singleResult(); System.out.println("Found process definition : " + processDefinition.getName());

?

2.3.3. 啟動一個流程實例 Starting a process instance

現(xiàn)在已經在流程引擎中部署了流程定義,因此可以使用這個流程定義作為“藍圖”啟動流程實例。

要啟動流程實例,需要提供一些初始化流程變量。一般來說,可以通過呈現(xiàn)給用戶的表單,或者在流程由其他系統(tǒng)自動觸發(fā)時通過REST API,來獲取這些變量。在這個例子里,我們簡化為使用java.util.Scanner類在命令行輸入一些數(shù)據(jù):

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啟動一個流程實例。收集的數(shù)據(jù)作為一個java.util.Map實例傳遞,其中的鍵就是之后用于獲取變量的標識符。這個流程實例使用key啟動。這個key就是BPMN 2.0 XML文件中設置的id屬性,在這個例子里是holidayRequest。

(請注意:除了使用key之外,在后面你還會看到有很多其他方式啟動一個流程實例)

<process id="holidayRequest" name="Holiday Request" isExecutable="true"> 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);

?

在流程實例啟動后,會創(chuàng)建一個執(zhí)行(execution),并將其放在啟動事件上。從這里開始,這個執(zhí)行沿著順序流移動到經理審批的用戶任務,并執(zhí)行用戶任務行為。這個行為將在數(shù)據(jù)庫中創(chuàng)建一個任務,該任務可以之后使用查詢找到。用戶任務是一個等待狀態(tài)(wait state),引擎會停止繼續(xù)執(zhí)行,返回API調用。

2.3.4. 另一個話題:事務性 Sidetrack: transactionality

在Flowable中,數(shù)據(jù)庫事務扮演了關鍵角色,保證了數(shù)據(jù)一致性,并解決并發(fā)問題。當調用Flowable API時,默認情況下,所有操作都是同步的,并處于同一個事務下。這意味著,當方法調用返回時,會啟動并提交一個事務。

流程啟動后,會有一個數(shù)據(jù)庫事務從流程實例啟動時持續(xù)到下一個等待狀態(tài)。在這個例子里,指的是第一個用戶任務。當引擎到達這個用戶任務時,狀態(tài)會持久化至數(shù)據(jù)庫,提交事務,并返回API調用。

在Flowable中,當一個流程實例運行時,總會有一個數(shù)據(jù)庫事務從前一個等待狀態(tài)持續(xù)到下一個等待狀態(tài)。數(shù)據(jù)持久化之后,可能在數(shù)據(jù)庫中保存很長時間,甚至幾年,直到某個API調用使流程實例繼續(xù)執(zhí)行。請注意當流程處在等待狀態(tài)時,不會消耗任何計算或內存資源。

在這個例子中,當?shù)谝粋€用戶任務完成時,會啟動一個數(shù)據(jù)庫事務,從用戶任務開始,經過排他網關(自動邏輯),直到第二個用戶任務。或通過另一條路徑直接到達結束。

2.3.5. 查詢與完成任務 Querying and completing tasks

在更實際的應用中,會為雇員及經理提供用戶界面,讓他們可以登入并查看任務列表。其中可以看到作為流程變量存儲的流程實例數(shù)據(jù),并決定如何操作任務。在這個例子中,我們通過執(zhí)行API調用模擬任務列表,通常這些API都是由UI驅動的服務在后臺調用的。

我們還沒有為用戶任務配置辦理人。我們想將第一個任務指派給"經理(managers)"組,而第二個用戶任務指派給請假申請的提交人。這需要為第一個任務添加candidateGroups屬性:

<userTask id="approveTask" name="Approve or reject request" flowable:candidateGroups="managers"/>

并如下所示為第二個任務添加assignee屬性。請注意我們沒有像上面的’managers’一樣使用靜態(tài)值,而是使用一個流程變量動態(tài)指派。這個流程變量是在流程實例啟動時傳遞的:

<userTask id="holidayApprovedTask" name="Holiday approved" flowable:assignee="${employee}"/>

要獲得實際的任務列表,需要通過TaskService創(chuàng)建一個TaskQuery。我們配置這個查詢只返回’managers’組的任務:

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

?

可以使用任務Id獲取特定流程實例的變量,并在屏幕上顯示實際的申請:

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?");

?

運行結果像下面這樣:

經理現(xiàn)在就可以完成任務了。在現(xiàn)實中,這通常意味著由用戶提交一個表單。表單中的數(shù)據(jù)作為流程變量傳遞。在這里,我們在完成任務時傳遞帶有’approved’變量(這個名字很重要,因為之后會在順序流的條件中使用!)的map來模擬:

boolean approved = scanner.nextLine().toLowerCase().equals("y"); variables = new HashMap<String, Object>(); variables.put("approved", approved); taskService.complete(task.getId(), variables);

現(xiàn)在任務完成,并會在離開排他網關的兩條路徑中,基于’approved’流程變量選擇一條。

2.3.6. 撰寫一個JavaDelegate (Writing a JavaDelegate)

拼圖還缺了一塊:我們還沒有實現(xiàn)在申請通過后執(zhí)行的自動邏輯。在BPMN 2.0 XML中,這是一個服務任務(service task),長這樣:

<serviceTask id="externalSystemCall" name="Enter holidays in external system"flowable:class="org.flowable.CallExternalSystemDelegate"/>

在現(xiàn)實中,這個邏輯可以做任何事情:向某個系統(tǒng)發(fā)起一個HTTP REST服務調用,或調用某個使用了好幾十年的系統(tǒng)中的遺留代碼。我們不會在這里實現(xiàn)實際的邏輯,而只是簡單的日志記錄流程。

創(chuàng)建一個新的類(在Eclipse里File → New → Class),填入org.flowable作為包名,CallExternalSystemDelegate作為類名。讓這個類實現(xiàn)org.flowable.engine.delegate.JavaDelegate接口,并實現(xiàn)execute方法:

package org.flowable; 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")); } }

?

當執(zhí)行到達服務任務時,會初始化并調用BPMN 2.0 XML中引用的類。

現(xiàn)在執(zhí)行這個例子的時候,日志信息就會顯示出,已經執(zhí)行了自定義邏輯:

2.3.7. 使用歷史數(shù)據(jù) Working with historical data

選擇使用Flowable這樣的流程引擎的原因之一,是它可以自動存儲所有流程實例的審計數(shù)據(jù)或歷史數(shù)據(jù)。這些數(shù)據(jù)可以用于創(chuàng)建報告,深入展現(xiàn)組織運行的情況,瓶頸在哪里,等等。

例如,如果希望顯示流程實例已經執(zhí)行的時間,就可以從ProcessEngine獲取HistoryService,并創(chuàng)建歷史活動(historical activities)的查詢。在下面的代碼片段中,可以看到我們添加了一些額外的過濾:

  • 只選擇一個特定流程實例的活動

  • 只選擇已完成的活動

結果也已按照結束時間排序,意味著我們可以獲取其執(zhí)行順序。

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"); }

?

再次運行例子,可以看到控制臺中顯示:

startEvent took 1 milliseconds approveTask took 2638 milliseconds decision took 3 milliseconds externalSystemCall took 1 milliseconds

2.3.8. 小結 Conclusion

這個教程介紹了各種Flowable與BPMN 2.0的概念與術語,也展示了如何編程使用Flowable API。

當然,這只是旅程的開始。下面的章節(jié)會更深入介紹許多Flowable引擎支持的選項與特性。其他章節(jié)介紹安裝與使用Flowable引擎的不同方法,并詳細介紹了可用的所有BPMN 2.0結構。

總結

以上是生活随笔為你收集整理的《Flowable基础二 Flowable是什么》的全部內容,希望文章能夠幫你解決所遇到的問題。

如果覺得生活随笔網站內容還不錯,歡迎將生活随笔推薦給好友。