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

歡迎訪問 生活随笔!

生活随笔

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

编程问答

Flowable学习笔记(二、BPMN 2.0-基础 )

發布時間:2023/12/3 编程问答 38 豆豆
生活随笔 收集整理的這篇文章主要介紹了 Flowable学习笔记(二、BPMN 2.0-基础 ) 小編覺得挺不錯的,現在分享給大家,幫大家做個參考.

轉載自??Flowable學習筆記(二、BPMN 2.0-基礎 )

1、BPMN簡介

業務流程模型和標記法(BPMN, Business Process Model and Notation)是一套圖形化表示法,用于以業務流程模型詳細說明各種業務流程。

它最初由業務流程管理倡議組織(BPMI, Business Process Management Initiative)開發,名稱為"Business Process Modeling Notation",即“業務流程建模標記法”。BPMI于2005年與對象管理組織(OMG, Object Management Group)合并。2011年1月OMG發布2.0版本,同時改為現在的名稱。

?

2、BPMN基本要素

BPMN包含四種要素:

流對象(Flow Object):

  • 事件(Events)
  • 活動(Activities)
  • 網關(Gateways)

連接對象(Connecting Objects):

  • 順序流(Sequence Flow)
  • 消息流(Message Flow)
  • 關聯(Association)

泳道(Swimlanes):

  • 池(Pool)
  • 道(Lane)

附加工件(Artifacts/Artefacts):

  • 數據對象(Data Object)
  • 組(Group)
  • 注釋(Annotation)

在這里需要重要關注4個基本對象,

  • 事件(Event):用來表明流程的生命周期中發生了什么。
  • 活動(Activity):活動(Activities)是業務流程定義的核心元素,中文稱為“活動”、“節點”、“步驟”。一個活動可以是流程的基本處理單元(如人工任務、服務任務),也可以是一個組合單元(如外部子流程、嵌套子流程)。
  • 網關(Gateway):用來控制流程的流向。
  • 流向/順序流(Flow):是連接兩個流程節點的連線。

?

3、流程根元素

一個BPMN 2.0 XML流程的根是definitions元素。 在命名狀態,子元素會包含真正的業務流程定義。 每個process子元素 可以擁有一個id(必填)和 name(可選)。下面是一個空的BPMN 2.0業務流程 。

<definitions id="myProcesses"xmlns:xsi="http://www.w3.org/2001/XMLSchema-instance"xsi:schemaLocation="http://schema.omg.org/spec/BPMN/2.0 BPMN20.xsd"xmlns="http://schema.omg.org/spec/BPMN/2.0"typeLanguage="http://www.w3.org/2001/XMLSchema"expressionLanguage="http://www.w3.org/1999/XPath"targetNamespace="http://jbpm.org/example/bpmn2"><process id="My business processs" name="myBusinessProcess">

?

4、BPMN結構

在BPMN中,流對象是用于定義業務流程行為的主要圖形元素。需要重點理解三個流對象。


?

4.1、事件

事件包含啟動事件、結束事件、中間事件,還有一類邊界事件,屬于中間中間事件的一種。

?

4.1.1、啟動事件(startEvent)

啟動事件(start event)(有的譯為開始時間)是流程的起點。啟動事件的類型(例如流程在消息到達時啟動,在指定的時間間隔后啟動,等等),定義了流程如何啟動,并顯示為啟動事件中的小圖標。在XML中,類型由子元素聲明來定義。

啟動事件隨時捕獲:啟動事件(保持)等候,直到特定的觸發器被觸發。

4.1.1.1、空啟動事件

  • 描述:空”啟動事件(none Start Event),指的是未指定啟動流程實例觸發器的啟動事件。引擎將無法預知何時啟動流程實例。空啟動事件用于流程實例通過調用下列startProcessInstanceByXXX API方法啟動的情況。
ProcessInstance processInstance = runtimeService.startProcessInstanceByXXX();
  • 圖示:空啟動事件用空心圓圈表示,中間沒有圖標(也就是說,沒有觸發器):

  • xml表示:
<startEvent id="start" name="my start event" />

?

4.1.1.2、定時器啟動事件

  • 描述:定時器啟動事件(timer start event)在指定時間創建流程實例。在流程只需要啟動一次,或者流程需要在特定的時間間隔重復啟動時,可以使用定時器啟動事件。

請注意:子流程不能有定時器啟動事件。
請注意:定時器啟動事件,在流程部署的同時就開始計時。不需要調用startProcessInstanceByXXX就會在時間啟動。調用startProcessInstanceByXXX時會在定時啟動之外額外啟動一個流程。
請注意:當部署帶有定時器啟動事件的流程的更新版本時,上一版本的定時器作業會被移除。這是因為通常并不希望舊版本的流程仍然自動啟動新的流程實例。

  • 圖示:定時器啟動事件,用其中有一個鐘表圖標的圓圈來表示。

  • XML表示:定時器啟動事件的XML表示格式,是普通的啟動事件聲明加上定時器定義子元素。

示例:流程會啟動4次,間隔5分鐘,從2011年3月11日,12:13開始

<startEvent id="theStart"><timerEventDefinition><timeCycle>R4/2011-03-11T12:13/PT5M</timeCycle></timerEventDefinition> </startEvent>

示例:流程會在設定的時間啟動一次

<startEvent id="theStart"><timerEventDefinition><timeDate>2011-03-11T12:13:14</timeDate></timerEventDefinition> </startEvent>

?

4.1.1.3、消息啟動事件

  • 描述:
    消息啟動事件(message start event)使用具名消息啟動流程實例。消息名用于選擇正確的啟動事件。

當部署具有一個或多個消息啟動事件的流程定義時,會做如下判斷:

>> 給定流程定義中,消息啟動事件的名字必須是唯一的。一個流程定義不得包含多個同名的消息啟動事件。如果流程定義中有兩個或多個消息啟動事件引用同一個消息,或者兩個或多個消息啟動事件引用了具有相同消息名字的消息,則Flowable會在部署這個流程定義時拋出異常。

>> 在所有已部署的流程定義中,消息啟動事件的名字必須是唯一的。如果在流程定義中,一個或多個消息啟動事件引用了已經部署的另一流程定義中消息啟動事件的消息名,則Flowable會在部署這個流程定義時拋出異常。

>> 流程版本:在部署流程定義的新版本時,會取消上一版本的消息訂閱,即使新版本中并沒有這個消息事件)。

  • 圖示:消息啟動事件用其中有一個消息事件標志的圓圈表示。這個標志并未填充,用以表示捕獲(接收)行為。

  • XML表示:
    消息啟動事件的XML表示格式,為普通啟動事件聲明加上messageEventDefinition子元素:

<definitions id="definitions"xmlns="http://www.omg.org/spec/BPMN/20100524/MODEL"xmlns:flowable="http://flowable.org/bpmn"targetNamespace="Examples"xmlns:tns="Examples"><message id="newInvoice" name="newInvoiceMessage" /><process id="invoiceProcess"><startEvent id="messageStart" ><messageEventDefinition messageRef="tns:newInvoice" /></startEvent>...</process></definitions>

?

4.1.1.4、信號啟動事件

  • 描述:
    信號啟動事件(signal start event),使用具名信號啟動流程實例。這個信號可以由流程實例中的信號拋出中間事件(intermediary signal throw event),或者API(runtimeService.signalEventReceivedXXX方法)觸發。兩種方式都會啟動所有擁有相同名字信號啟動事件的流程定義。

請注意可以選擇異步還是同步啟動流程實例。

需要為API傳遞的signalName,是由signal元素的name屬性決定的名字。signal元素由signalEventDefinition的signalRef屬性引用。

  • 圖示:
    信號啟動事件用其中有一個信號事件標志的圓圈表示。這個標志并未填充,用以表示捕獲(接收)行為。

?

  • XML表示:
    信號啟動事件的XML表示格式,為普通啟動事件聲明,加上signalEventDefinition子元素:
<signal id="theSignal" name="The Signal" /><process id="processWithSignalStart1"><startEvent id="theStart"><signalEventDefinition id="theSignalEventDefinition" signalRef="theSignal" /></startEvent><sequenceFlow id="flow1" sourceRef="theStart" targetRef="theTask" /><userTask id="theTask" name="Task in process A" /><sequenceFlow id="flow2" sourceRef="theTask" targetRef="theEnd" /><endEvent id="theEnd" /> </process>

?

4.1.1.5、錯誤啟動事件

  • 描述:
    錯誤啟動事件(error start event),可用于觸發事件子流程(Event Sub-Process)。錯誤啟動事件不能用于啟動流程實例。
    錯誤啟動事件總是中斷。

  • 圖示:
    錯誤啟動事件用其中有一個錯誤事件標志的圓圈表示。這個標志并未填充,用以表示捕獲(接收)行為。

  • XML表示:
    錯誤啟動事件的XML表示格式,為普通啟動事件聲明加上errorEventDefinition子元素:
<startEvent id="messageStart" ><errorEventDefinition errorRef="someError" /> </startEvent>

?

4.1.2、結束事件

結束事件(end event)標志著流程或子流程中一個分支的結束。結束事件總是拋出(型)事件。這意味著當流程執行到達結束事件時,會拋出一個結果。結果的類型由事件內部的黑色圖標表示。在XML表示中,類型由子元素聲明給出。

?

4.1.2.1、空結束事件

  • 描述:
    “空”結束事件(none end event),意味著當到達這個事件時,沒有特別指定拋出的結果。因此,引擎除了結束當前執行分支之外,不會多做任何事情。

  • 圖示:
    空結束事件,用其中沒有圖標(沒有結果類型)的粗圓圈表示。

  • xml表示:
    空事件的XML表示格式為普通結束事件聲明,沒有任何子元素(其它種類的結束事件都有子元素,用于聲明其類型)。
<endEvent id="end" name="my end event" />

?

4.1.2.2、錯誤結束事件

  • 描述:
    當流程執行到達錯誤結束事件(error end event)時,結束執行的當前分支,并拋出錯誤。這個錯誤可以由匹配的錯誤邊界中間事件捕獲。如果找不到匹配的錯誤邊界事件,將會拋出異常。

  • 圖示:
    錯誤結束事件事件用內部有一個錯誤圖標的標準結束事件(粗圓圈)表示。錯誤圖標是全黑的,代表拋出的含義。

  • XML表示:
    錯誤結束事件表示為結束事件,加上errorEventDefinition子元素:
<endEvent id="myErrorEndEvent"><errorEventDefinition errorRef="myError" /> </endEvent>

errorRef屬性可以引用在流程外定義的error元素:

<error id="myError" errorCode="123" /> ... <process id="myProcess"> ...

?

4.1.2.3、終止結束事件

  • 描述:
    當到達終止結束事件(terminate end event)時,當前的流程實例或子流程會被終止。也就是說,當執行到達終止結束事件時,會判斷第一個范圍 scope(流程或子流程)并終止它。在BPMN 2.0中,子流程可以是嵌入式子流程,調用活動,事件子流程,或事務子流程。有一條通用規則:當存在多實例的調用過程或嵌入式子流程時,只會終止一個實例,其他的實例與流程實例不會受影響。
    可以添加一個可選屬性terminateAll。當其為true時,無論該終止結束事件在流程定義中的位置,也無論它是否在子流程(甚至是嵌套子流程)中,都會終止(根)流程實例。

  • 圖示:
    終止結束事件用內部有一個全黑圓的標準結束事件(粗圓圈)表示。

  • xml表示:
    終止結束事件,表示為結束事件,加上terminateEventDefinition子元素。
    terminateAll屬性是可選的(默認為false)。

<endEvent id="myEndEvent ><terminateEventDefinition flowable:terminateAll="true"></terminateEventDefinition> </endEvent>

?

4.1.2.4、取消結束事件

  • 描述:
    取消結束事件(cancel end event)只能與BPMN事務子流程(BPMN transaction subprocess)一起使用。當到達取消結束事件時,會拋出取消事件,且必須由取消邊界事件(cancel boundary event)捕獲。取消邊界事件將取消事務,并觸發補償(compensation)。

  • 圖示:
    取消結束事件用內部有一個取消圖標的標準結束事件(粗圓圈)表示。取消圖標是全黑的,代表拋出的含義。

  • xml表示:
    取消結束事件,表示為結束事件,加上cancelEventDefinition子元素。

<endEvent id="myCancelEndEvent"><cancelEventDefinition /> </endEvent>

?

4.1.3、邊界事件

邊界事件(boundary event)是捕獲型事件,依附在活動(activity)上。邊界事件永遠不會拋出。這意味著當活動運行時,事件將監聽特定類型的觸發器。當捕獲到事件時,會終止活動,并沿該事件的出口順序流繼續。

所有的邊界事件都用相同的方式定義:

<boundaryEvent id="myBoundaryEvent" attachedToRef="theActivity"><XXXEventDefinition/> </boundaryEvent>

邊界事件由下列元素定義:

  • (流程范圍內)唯一的標識符
* 由attachedToRef屬性定義的,對該事件所依附的活動的引用。邊界事件及其所依附的活動,應定義在相同級別(也就是說,邊界事件并不包含在活動內)。* 定義了邊界事件的類型的,形如XXXEventDefinition的XML子元素(例如TimerEventDefinition,ErrorEventDefinition,等等)。查閱特定的邊界事件類型,以了解更多細節。

?

4.1.3.1、定時器邊界事件

  • 描述:
    定時器邊界事件(timer boundary event)的行為像是跑表與鬧鐘。當執行到達邊界事件所依附的活動時,將啟動定時器。當定時器觸發時(例如在特定時間間隔后),可以中斷活動,并沿著邊界事件的出口順序流繼續執行。

  • 圖示:
    定時器邊界事件用內部有一個定時器圖標的標準邊界事件(圓圈)表示。

  • XML表示:
    定時器邊界事件與一般邊界事件一樣定義。其中類型子元素為timerEventDefinition元素。
<boundaryEvent id="escalationTimer" cancelActivity="true" attachedToRef="firstLineSupport"><timerEventDefinition><timeDuration>PT4H</timeDuration></timerEventDefinition> </boundaryEvent>

?

4.1.3.2、錯誤邊界事件

  • 描述
    在活動邊界上的錯誤捕獲中間(事件),或簡稱錯誤邊界事件(error boundary event),捕獲其所依附的活動范圍內拋出的錯誤。
    在嵌入式子流程或者調用活動上定義錯誤邊界事件最有意義,因為子流程的范圍會包括其中的所有活動。錯誤可以由錯誤結束事件拋出。這樣的錯誤會逐層向其上級父范圍傳播,直到在范圍內找到一個匹配錯誤事件定義的錯誤邊界事件。
    當捕獲錯誤事件時,會銷毀邊界事件定義所在的活動,同時銷毀其中所有的當前執行(例如,并行活動,嵌套子流程,等等)。流程執行將沿著邊界事件的出口順序流繼續。

  • 圖示:
    錯誤邊界事件用內部有一個錯誤圖標的標準中間事件(兩層圓圈)表示。錯誤圖標是白色的,代表捕獲的含義。

  • xml表示:
    錯誤邊界事件與標準邊界事件一樣定義:

<boundaryEvent id="catchError" attachedToRef="mySubProcess"><errorEventDefinition errorRef="myError"/> </boundaryEvent>

?

4.1.3.3、信號邊界事件

  • 描述:
    依附在活動邊界上的信號捕獲中間(事件),或簡稱信號邊界事件(signal boundary event),捕獲與其信號定義具有相同名稱的信號。

與其他事件例如錯誤邊界事件不同的是,信號邊界事件不只是捕獲其所依附范圍拋出的信號。信號邊界事件為全局范圍(廣播)的,意味著信號可以從任何地方拋出,甚至可以是不同的流程實例。

  • 圖示:
    信號邊界事件,用內部有一個信號圖標的標準中間事件(兩層圓圈)表示。信號圖標是白色的,代表捕獲的含義。

  • xml表示:
    信號邊界事件與標準邊界事件一樣定義:
<boundaryEvent id="boundary" attachedToRef="task" cancelActivity="true"><signalEventDefinition signalRef="alertSignal"/> </boundaryEvent>

?

4.1.3.4、消息邊界事件

  • 描述:
    在活動邊界上的消息捕獲中間(事件),或簡稱消息邊界事件(message boundary event),捕獲與其消息定義具有相同消息名的消息。

  • 圖示:
    消息邊界事件,用內部有一個消息圖標的標準中間事件(兩層圓圈)表示。信號圖標是白色的,代表捕獲的含義。

    息邊界事件既可以是中斷型的(右圖),也可以是非中斷型的(左圖)。

  • XML表示:
    消息邊界事件與標準邊界事件一樣定義:

<boundaryEvent id="boundary" attachedToRef="task" cancelActivity="true"><messageEventDefinition messageRef="newCustomerMessage"/> </boundaryEvent>

?

4.1.3.5、取消邊界事件

  • 描述
    依附在事務子流程邊界上的取消捕獲中間事件,或簡稱取消邊界事件(cancel boundary event),在事務取消時觸發。當取消邊界事件觸發時,首先會中斷當前范圍的所有活動執行。接下來,啟動事務范圍內所有有效的的補償邊界事件(compensation boundary event)。補償會同步執行,也就是說在離開事務前,邊界事件會等待補償完成。當補償完成時,沿取消邊界事件的任何出口順序流離開事務子流程。

>>> 一個事務子流程只允許使用一個取消邊界事件。
>>> 如果事務子流程中有嵌套的子流程,只會對成功完成的子流程觸發補償。
>>> 如果取消邊界事件放置在具有多實例特性的事務子流程上,如果一個實例觸發了取消,則邊界事件將取消所有實例。

  • 圖示:
    取消邊界事件,用內部有一個取消圖標的標準中間事件(兩層圓圈)表示。取消圖標是白色的(未填充),代表捕獲的含義。

  • xml表示:
    取消邊界事件與標準邊界事件一樣定義:
<boundaryEvent id="boundary" attachedToRef="transaction" ><cancelEventDefinition /> </boundaryEvent>

?

4.1.3.6、補償邊界事件

  • 描述:
    依附在活動邊界上的補償捕獲中間(事件),或簡稱補償邊界事件(compensation boundary event),可以為活動附加補償處理器。
    補償邊界事件必須使用直接關聯的方式引用單個的補償處理器。
    補償邊界事件與其它邊界事件的活動策略不同。其它邊界事件,例如信號邊界事件,在其依附的活動啟動時激活;當該活動結束時會被解除,并取消相應的事件訂閱。而補償邊界事件不是這樣。補償邊界事件在其依附的活動成功完成時激活,同時創建補償事件的相應訂閱。當補償事件被觸發,或者相應的流程實例結束時,才會移除訂閱。請考慮下列因素:

    >>> 當補償被觸發時,會調用補償邊界事件關聯的補償處理器。調用次數與其依附的活動成功完成的次數相同。

    >>>如果補償邊界事件依附在具有多實例特性的活動上,則會為每一個實例創建補償事件訂閱。

    >>> 如果補償邊界事件依附在位于循環內部的活動上,則每次該活動執行時,都會創建一個補償事件訂閱。

    >>> 如果流程實例結束,則取消補償事件的訂閱。

  • 圖示:
    補償邊界事件,用內部有一個補償圖標的標準中間事件(兩層圓圈)表示。補償圖標是白色的(未填充),代表捕獲的含義。另外,補償邊界事件使用單向連接關聯補償處理器,如下圖所示:

  • xml表示:
    補償邊界事件與標準邊界事件一樣定義:

<boundaryEvent id="compensateBookHotelEvt" attachedToRef="bookHotel" ><compensateEventDefinition /> </boundaryEvent><association associationDirection="One" id="a1"sourceRef="compensateBookHotelEvt" targetRef="undoBookHotel" /><serviceTask id="undoBookHotel" isForCompensation="true" flowable:class="..." />

?

4.1.4、中間事件

在開始事件和結束事件之間發生的事件都稱為中間事件。中間事件會影響流程的流轉路線,但不會啟動或直接終止流程的執行。

中間事件按照其特性可以分為兩類:中間Catching(捕獲)事件和中間Throwing(拋出)事件,當流程到達中間Catching事件時,它會一直在等待被觸發,直接接收到的信息,才會被觸發,而當流程到達中間Throwing事件時,該事件會自動被觸發并拋出相應的結果或者信息。

?

4.1.4.1、捕獲中間事件

所有的捕獲中間事件(intermediate catching events)都使用相同方式定義:

<intermediateCatchEvent id="myIntermediateCatchEvent" ><XXXEventDefinition/> </intermediateCatchEvent>

捕獲中間事件由下列元素定義:

  • (流程范圍內)唯一的標識符

  • 定義了捕獲中間事件類型的,形如XXXEventDefinition的XML子元素(例如TimerEventDefinition等)。查閱特定中間捕獲事件類型,以了解更多細節。

?

4.1.4.1.1、定時器捕獲中間事件

  • 描述:
    定時器捕獲中間事件(timer intermediate catching event)的行為像是跑表。當執行到達捕獲事件時,啟動定時器;當定時器觸發時(例如在一段時間間隔后),沿定時器中間事件的出口順序流繼續執行。

  • 圖示:
    定時器中間事件用內部有定時器圖標的中間捕獲事件表示。

  • XML表示:
    定時器中間事件與捕獲中間事件一樣定義。子元素為timerEventDefinition。

<intermediateCatchEvent id="timer"><timerEventDefinition><timeDuration>PT5M</timeDuration></timerEventDefinition> </intermediateCatchEvent>

?

4.1.4.1.2、信號捕獲中間事件

  • 描述:
    信號捕獲中間事件(signal intermediate catching event),捕獲與其引用的信號定義具有相同信號名稱的信號。

>>> 與其他事件如錯誤事件不同,信號在被捕獲后不會被消耗。如果有兩個激活的信號中間事件,捕獲相同的信號事件,則兩個中間事件都會被觸發,哪怕它們不在同一個流程實例里。

  • 圖示:
    信號捕獲中間事件用內部有信號圖標的標準中間事件(兩層圓圈)表示。信號圖標是白色的(未填充),代表捕獲的含義。

  • xml表示:
    信號中間事件與捕獲中間事件一樣定義。子元素為signalEventDefinition。
<intermediateCatchEvent id="signal"><signalEventDefinition signalRef="newCustomerSignal" /> </intermediateCatchEvent>

?

4.1.4.1.3、信號捕獲中間事件

  • 描述:
    消息捕獲中間事件(message intermediate catching event),捕獲特定名字的消息。

  • 圖示:
    消息捕獲中間事件用內部有消息圖標的標準中間事件(兩層圓圈)表示。消息圖標是白色的(未填充),代表捕獲的含義。

  • xml表示:
    消息中間事件與捕獲中間事件一樣定義。子元素為messageEventDefinition。
<intermediateCatchEvent id="message"><messageEventDefinition signalRef="newCustomerMessage" /> </intermediateCatchEvent>

?

4.1.4.2、拋出中間事件

所有的拋出中間事件(intermediate throwing evnet)都使用相同方式定義:

<intermediateThrowEvent id="myIntermediateThrowEvent" ><XXXEventDefinition/> </intermediateThrowEvent>

拋出中間事件由下列元素定義:

  • (流程范圍內)唯一的標識符
* 定義了拋出中間事件類型的,形如XXXEventDefinition的XML子元素(例如signalEventDefinition等)。查閱特定中間拋出事件類型,以了解更多細節。

?

4.1.4.2.1、空拋出中間事件

下面的流程圖展示了空拋出中間事件(intermediate throwing none event)的簡單例子。其用于指示流程已經到達了某種狀態。

添加一個執行監聽器后,空中間事件就可以成為很好的監視某些KPI(Key Performance Indicators 關鍵績效指標)的鉤子。

<intermediateThrowEvent id="noneEvent"><extensionElements><flowable:executionListener class="org.flowable.engine.test.bpmn.event.IntermediateNoneEventTest$MyExecutionListener" event="start" /></extensionElements> </intermediateThrowEvent>

?

4.1.4.2.2、信號拋出中間事件

  • 描述:
    信號拋出中間事件(signal intermediate throwing event),拋出所定義信號的信號事件。

在Flowable中,信號會廣播至所有的激活的處理器(也就是說,所有的信號捕獲事件)。可以同步或異步地發布信號。

  • 在默認配置中,信號同步地傳遞。這意味著拋出信號的流程實例會等待,直到信號傳遞至所有的捕獲信號的流程實例。所有的捕獲流程實例也會在與拋出流程實例相同的事務中,也就是說如果收到通知的流程實例中,有一個實例產生了技術錯誤(拋出異常),則所有相關的實例都會失敗。
  • 信號也可以異步地傳遞。這是由到達拋出信號事件時的發送處理器來決定的。對于每個激活的處理器,JobExecutor會為其存儲并傳遞一個異步通知消息(asynchronous notification message),即作業(Job)。
  • 圖示:
    消息拋出中間事件用內部有信號圖標的標準中間事件(兩層圓圈)表示。信號圖標是黑色的(已填充),代表拋出的含義。

  • xml表示:
    信號中間事件與拋出中間事件一樣定義。子元素為signalEventDefinition。

<intermediateThrowEvent id="signal"><signalEventDefinition signalRef="newCustomerSignal" /> </intermediateThrowEvent>

異步信號事件這樣定義:

<intermediateThrowEvent id="signal"><signalEventDefinition signalRef="newCustomerSignal" flowable:async="true" /> </intermediateThrowEvent>

?

4.1.4.2.3、補償拋出中間事件

  • 描述:
    補償拋出中間事件(compensation intermediate throwing event)用于觸發補償。

觸發補償:既可以為設計的活動觸發補償,也可以為補償事件所在的范圍觸發補償。補償由活動所關聯的補償處理器執行。

  • 活動拋出補償時,活動關聯的補償處理器將執行的次數,為活動成功完成的次數。
  • 拋出補償時,當前范圍中所有的活動,包括并行分支上的活動都會被補償。
* * 補償分層觸發:如果將要被補償的活動是一個子流程,則該子流程中所有的活動都會觸發補償。如果該子流程有嵌套的活動,則會遞歸地拋出補償。然而,補償不會傳播至流程的上層:如果子流程中觸發了補償,該補償不會傳播至子流程范圍外的活動。BPMN規范指出,對“與子流程在相同級別”的活動觸發補償。* * 在Flowable中,補償按照執行的相反順序運行。這意味著最后完成的活動會第一個補償。
  • 可以使用補償拋出中間事件補償已經成功完成的事務子流程。

>>> 如果拋出補償的范圍中有一個子流程,而該子流程包含有關聯了補償處理器的活動,則當拋出補償時,只有該子流程成功完成時,補償才會傳播至該子流程。如果子流程內嵌套的部分活動已經完成,并附加了補償處理器,但包含這些活動的子流程還沒有完成,則這些補償處理器仍不會執行。參考下面的例子:

在這個流程中,有兩個并行的執行:一個執行嵌入子流程,另一個執行“charge credit card(信用卡付款)”活動。假定兩個執行都已開始,且第一個執行正等待用戶完成“review bookings(檢查預定)”任務。第二個執行進行了“charge credit card(信用卡付款)”活動的操作,拋出了錯誤,導致“cancel reservations(取消預訂)”事件觸發補償。這時并行子流程還未完成,意味著補償不會傳播至該子流程,因此不會執行“cancel hotel reservation(取消酒店預訂)”補償處理器。而如果“cancel reservations(取消預訂)”運行前,這個用戶任務(因此該嵌入式子流程也)已經完成,則補償會傳播至該嵌入式子流程。

流程變量:當補償嵌入式子流程時,用于執行補償處理器的執行,可以訪問子流程的局部流程變量在子流程完成時的值。為此,會對范圍執行(為執行子流程所創建的執行)所關聯的流程變量進行快照。意味著:

  • 補償執行器無法訪問子流程范圍內并行執行所添加的變量。
* * 上層執行所關聯的流程變量(例如流程實例關聯的流程變量)不在該快照中。因為補償處理器可以直接訪問這些流程變量在拋出補償時的值。* * 只會為嵌入式子流程進行變量快照。其他活動不會進行變量快照。

目前的限制:

  • 目前不支持waitForCompletion="false"。當補償拋出中間事件觸發補償時,只有在補償成功完成時,才會離開該事件。
* * 補償由并行執行運行。并行執行會按照補償活動完成的逆序啟動。
  • 補償不會傳播至調用活動(call activity)生成的子流程。
  • 圖示:
    補償拋出中間事件用內部有補償圖標的標準中間事件(兩層圓圈)表示。補償圖標是黑色的(已填充),代表拋出的含義。

  • xml表示:
    補償中間事件與拋出中間事件一樣定義。子元素為compensateEventDefinition。
<intermediateThrowEvent id="throwCompensation"><compensateEventDefinition /> </intermediateThrowEvent>

另外,activityRef可選項用于為指定的范圍或活動觸發補償:

<intermediateThrowEvent id="throwCompensation"><compensateEventDefinition activityRef="bookHotel" /> </intermediateThrowEvent>

?

4.2、順序流

  • 描述:
    順序流(sequence flow)是流程中兩個元素間的連接器。在流程執行過程中,一個元素被訪問后,會沿著其所有出口順序流繼續執行。這意味著BPMN 2.0的默認是并行執行的:兩個出口順序流就會創建兩個獨立的、并行的執行路徑。

  • 圖示:
    順序流,用從源元素指向目標元素的箭頭表示。箭頭總是指向目標元素。

  • xml表示:
    順序流需要有流程唯一的id,并引用存在的源與目標元素。

<sequenceFlow id="flow1" sourceRef="theStart" targetRef="theTask" />

?

4.2.1、條件順序流

  • 描述:
    在順序流上可以定義條件(conditional sequence flow)。當離開BPMN 2.0活動時,默認行為是計算其每個出口順序流上的條件。當條件計算為true時,選擇該出口順序流。如果該方法選擇了多條順序流,則會生成多個執行,流程會以并行方式繼續。

>>> 上面的介紹針對BPMN 2.0活動(與事件),但不適用于網關(gateway)。不同類型的網關,會用不同的方式處理帶有條件的順序流。

  • 圖示:
    條件順序流用起點帶有小菱形的順序流表示。在順序流旁顯示條件表達式。

  • xml表示:
    條件順序流的XML表示格式為含有conditionExpression(條件表達式)子元素的普通順序流。請注意目前只支持tFormalExpressions。可以省略xsi:type=""定義,默認為唯一支持的表達式類型。
<sequenceFlow id="flow" sourceRef="theStart" targetRef="theTask"><conditionExpression xsi:type="tFormalExpression"><![CDATA[${order.price > 100 && order.price < 250}]]></conditionExpression> </sequenceFlow>

>>> 目前conditionalExpressions只能使用UEL。使用的表達式需要能解析為boolean值,否則當計算條件時會拋出異常。

  • 下面的例子,通過典型的JavaBean的方式,使用getter引用流程變量的數據。
<conditionExpression xsi:type="tFormalExpression"><![CDATA[${order.price > 100 && order.price < 250}]]> </conditionExpression>
  • 這個例子調用了一個解析為boolean值的方法。
<conditionExpression xsi:type="tFormalExpression"><![CDATA[${order.isStandardOrder()}]]> </conditionExpression>

Flowable發行版中包含了下列示例流程,用于展示值表達式與方法表達式的使用。

?

4.2.2、默認順序流

  • 描述:
    所有的BPMN 2.0任務與網關都可以使用默認順序流(default sequence flow)。只有當沒有其他順序流可以選擇時,才會選擇默認順序流作為活動的出口順序流。流程會忽略默認順序流上的條件。

  • 圖示:
    默認順序流用起點帶有“斜線”標記的一般順序流表示。

  • XML表示:
    活動的默認順序流由該活動的default屬性定義。下面的XML片段展示了一個排他網關(exclusive gateway),帶有默認順序流flow 2。只有當conditionA與conditionB都計算為false時,才會選擇默認順序流作為網關的出口順序流。
<exclusiveGateway id="exclusiveGw" name="Exclusive Gateway" default="flow2" /><sequenceFlow id="flow1" sourceRef="exclusiveGw" targetRef="task1"><conditionExpression xsi:type="tFormalExpression">${conditionA}</conditionExpression> </sequenceFlow><sequenceFlow id="flow2" sourceRef="exclusiveGw" targetRef="task2"/><sequenceFlow id="flow3" sourceRef="exclusiveGw" targetRef="task3"><conditionExpression xsi:type="tFormalExpression">${conditionB}</conditionExpression> </sequenceFlow>

對應下面的圖示:

?

4.3、網關

網關(gateway)用于控制執行的流向(或者按BPMN 2.0的用詞:執行的“標志(token)”)。網關可以消費(consuming)與生成(generating)標志。

網關用其中帶有圖標的菱形表示。該圖標顯示了網關的類型。

這里出口順序流的含義與BPMN 2.0中的一般情況不一樣。一般情況下,會選擇所有條件計算為true的順序流,并行執行。而使用排他網關時,只會選擇一條順序流。當多條順序流的條件都計算為true時,會且僅會選擇在XML中最先定義的順序流繼續流程。如果沒有可選的順序流,會拋出異常。

?

4.3.1、排他網關

  • 描述:
    排他網關(exclusive gateway)(也叫異或網關 XOR gateway,或者更專業的,基于數據的排他網關 exclusive data-based gateway),用于對流程中的決策建模。當執行到達這個網關時,會按照所有出口順序流定義的順序對它們進行計算。選擇第一個條件計算為true的順序流(當沒有設置條件時,認為順序流為true)繼續流程。

  • 圖示:
    排他網關用內部帶有’X’圖標的標準網關(菱形)表示,'X’圖標代表異或的含義。請注意內部沒有圖標的網關默認為排他網關。BPMN 2.0規范不允許在同一個流程中混合使用有及沒有X的菱形標志。

  • xml表示:
    排他網關的XML表示格式很簡潔:一行定義網關的XML。條件表達式定義在其出口順序流上。

以下面的模型為例:

其xml表示如下:

<exclusiveGateway id="exclusiveGw" name="Exclusive Gateway" /><sequenceFlow id="flow2" sourceRef="exclusiveGw" targetRef="theTask1"><conditionExpression xsi:type="tFormalExpression">${input == 1}</conditionExpression> </sequenceFlow><sequenceFlow id="flow3" sourceRef="exclusiveGw" targetRef="theTask2"><conditionExpression xsi:type="tFormalExpression">${input == 2}</conditionExpression> </sequenceFlow><sequenceFlow id="flow4" sourceRef="exclusiveGw" targetRef="theTask3"><conditionExpression xsi:type="tFormalExpression">${input == 3}</conditionExpression> </sequenceFlow>

?

4.3.2、并行網關

  • 描述:
    網關也可以建模流程中的并行執行。在流程模型中引入并行的最簡單的網關,就是并行網關(parallel gateway)。它可以將執行分支(fork)為多條路徑,也可以合并(join)多條入口路徑的執行。

并行網關的功能取決于其入口與出口順序流:

  • 分支:所有的出口順序流都并行執行,為每一條順序流創建一個并行執行。
  • 合并:所有到達并行網關的并行執行都會在網關處等待,直到每一條入口順序流都到達了有個執行。然后流程經過該合并網關繼續。

>>> 如果并行網關同時具有多條入口與出口順序流,可以同時具有分支與合并的行為。在這種情況下,網關首先合并所有入口順序流,然后分裂為多條并行執行路徑。

與其他網關類型有一個重要區別:并行網關不計算條件。如果連接到并行網關的順序流上定義了條件,會直接忽略該條件。

  • 圖示:
    并行網關,用內部帶有’加號’圖標的網關(菱形)表示,代表與(AND)的含義。

  • xml表示:
    定義并行網關只需要一行XML:
<parallelGateway id="myParallelGateway" />

實際行為(分支,合并或兩者皆有),由連接到該并行網關的順序流定義。

例如,上面的模型表示為下面的XML:

<startEvent id="theStart" /> <sequenceFlow id="flow1" sourceRef="theStart" targetRef="fork" /><parallelGateway id="fork" /> <sequenceFlow sourceRef="fork" targetRef="receivePayment" /> <sequenceFlow sourceRef="fork" targetRef="shipOrder" /><userTask id="receivePayment" name="Receive Payment" /> <sequenceFlow sourceRef="receivePayment" targetRef="join" /><userTask id="shipOrder" name="Ship Order" /> <sequenceFlow sourceRef="shipOrder" targetRef="join" /><parallelGateway id="join" /> <sequenceFlow sourceRef="join" targetRef="archiveOrder" /><userTask id="archiveOrder" name="Archive Order" /> <sequenceFlow sourceRef="archiveOrder" targetRef="theEnd" /><endEvent id="theEnd" />

在上面的例子中,當流程啟動后會創建兩個任務:

ProcessInstance pi = runtimeService.startProcessInstanceByKey("forkJoin"); TaskQuery query = taskService.createTaskQuery().processInstanceId(pi.getId()).orderByTaskName().asc();List<Task> tasks = query.list(); assertEquals(2, tasks.size());Task task1 = tasks.get(0); assertEquals("Receive Payment", task1.getName()); Task task2 = tasks.get(1); assertEquals("Ship Order", task2.getName());

當這兩個任務完成后,第二個并行網關會合并這兩個執行。由于它只有一條出口順序流,因此就不會再創建并行執行路徑,而只是激活Archive Order(存檔訂單)任務。

并行網關不需要“平衡”(也就是說,前后對應的兩個并行網關,其入口/出口順序流的數量不需要一致)。每個并行網關都會簡單地等待所有入口順序流,并為每一條出口順序流創建并行執行,而不受流程模型中的其他結構影響。因此,下面的流程在BPMN 2.0中是合法的:

4.3.3、包容網關

  • 描述:
    可以把包容網關(inclusive gateway)看做排他網關與并行網關的組合。與排他網關一樣,可以在包容網關的出口順序流上定義條件,包容網關會計算條件。然而主要的區別是,包容網關與并行網關一樣,可以同時選擇多于一條出口順序流。

包容網關的功能取決于其入口與出口順序流:

  • 分支:流程會計算所有出口順序流的條件。對于每一條計算為true的順序流,流程都會創建一個并行執行。
  • 合并:所有到達包容網關的并行執行,都會在網關處等待。直到每一條具有流程標志(process token)的入口順序流,都有一個執行到達。這是與并行網關的重要區別。換句話說,包容網關只會等待可以被執行的入口順序流。在合并后,流程穿過合并并行網關繼續。

>>> 如果包容網關同時具有多條入口與出口順序流,可以同時具有分支與合并的行為。在這種情況下,網關首先合并所有具有流程標志的入口順序流,然后為每一個條件計算為true的出口順序流分裂出并行執行路徑。

包容網關的匯聚行為比并行網關更復雜。所有到達包容網關的并行執行,都會在網關等待,直到所有“可以到達”包容網關的執行都“到達”包容網關。 判斷方法為:計算當前流程實例中的所有執行,檢查從其位置是否有一條到達包容網關的路徑(忽略順序流上的任何條件)。如果存在這樣的執行(可到達但尚未到達),則不會觸發包容網關的匯聚行為。

  • xml表示:
    定義包容網關需要一行XML:
<inclusiveGateway id="myInclusiveGateway" />

實際行為(分支,合并或兩者皆有),由連接到該包容網關的順序流定義。

例如,上面的模型表現為下面的XML:

<startEvent id="theStart" /> <sequenceFlow id="flow1" sourceRef="theStart" targetRef="fork" /><inclusiveGateway id="fork" /> <sequenceFlow sourceRef="fork" targetRef="receivePayment" ><conditionExpression xsi:type="tFormalExpression">${paymentReceived == false}</conditionExpression> </sequenceFlow> <sequenceFlow sourceRef="fork" targetRef="shipOrder" ><conditionExpression xsi:type="tFormalExpression">${shipOrder == true}</conditionExpression> </sequenceFlow><userTask id="receivePayment" name="Receive Payment" /> <sequenceFlow sourceRef="receivePayment" targetRef="join" /><userTask id="shipOrder" name="Ship Order" /> <sequenceFlow sourceRef="shipOrder" targetRef="join" /><inclusiveGateway id="join" /> <sequenceFlow sourceRef="join" targetRef="archiveOrder" /><userTask id="archiveOrder" name="Archive Order" /> <sequenceFlow sourceRef="archiveOrder" targetRef="theEnd" /><endEvent id="theEnd" />

在上面的例子中,當流程啟動后,如果流程變量paymentReceived == false且shipOrder == true,會創建兩個任務。如果只有一個流程變量等于true,則只會創建一個任務。如果沒有條件計算為true,會拋出異常(可通過指定默出口順序流避免)。在下面的例子中,只會創建ship order(傳遞訂單)一個任務:

HashMap<String, Object> variableMap = new HashMap<String, Object>(); variableMap.put("receivedPayment", true); variableMap.put("shipOrder", true);ProcessInstance pi = runtimeService.startProcessInstanceByKey("forkJoin");TaskQuery query = taskService.createTaskQuery().processInstanceId(pi.getId()).orderByTaskName().asc();List<Task> tasks = query.list(); assertEquals(1, tasks.size());Task task = tasks.get(0); assertEquals("Ship Order", task.getName());

當這個任務完成后,第二個包容網關會合并這兩個執行。并且由于它只有一條出口順序流,所有不會再創建并行執行路徑,而只會激活Archive Order(存檔訂單)任務。

>>> 包容網關不需要“平衡”(也就是說,對應的包容網關,其入口/出口順序流的數量不需要匹配)。包容網關會簡單地等待所有入口順序流,并為每一條出口順序流創建并行執行,不受流程模型中的其他結構影響。

>>> 包容網關不需要“平衡”(也就是說,前后對應的兩個包容網關,其入口/出口順序流的數量不需要一致)。每個包容網關都會簡單地等待所有入口順序流,并為每一條出口順序流創建并行執行,不受流程模型中的其他結構影響。

?

4.3.4、 基于事件的網關

  • 描述:
    基于事件的網關(event-based gateway)提供了根據事件做選擇的方式。網關的每一條出口順序流都需要連接至一個捕獲中間事件。當流程執行到達基于事件的網關時,與等待狀態類似,網關會暫停執行,并且為每一條出口順序流創建一個事件訂閱。

>>> 基于事件的網關的出口順序流與一般的順序流不同。這些順序流從不實際執行。相反,它們用于告知流程引擎:當執行到達一個基于事件的網關時,需要訂閱什么事件。有以下限制:

  • 一個基于事件的網關,必須有兩條或更多的出口順序流。
  • 基于事件的網關,只能連接至intermediateCatchEvent(捕獲中間事件)類型的元素(Flowable不支持在基于事件的網關之后連接“接收任務 Receive Task”)。
  • 連接至基于事件的網關的intermediateCatchEvent,必須只有一個入口順序流。
  • 圖示:
    基于事件的網關,用內部帶有特殊圖標的網關(菱形)表示。

  • xml表示:
    用于定義基于事件的網關的XML元素為eventBasedGateway。

  • 示例:
    下面是一個帶有基于事件的網關的示例流程。當執行到達基于事件的網關時,流程執行暫停。流程實例訂閱alert信號事件,并創建一個10分鐘后觸發的定時器。流程引擎會等待10分鐘,并同時等待信號事件。如果信號在10分鐘內觸發,則會取消定時器,流程沿著信號繼續執行,激活Handle alert用戶任務。如果10分鐘內沒有觸發信號,則會繼續執行,并取消信號訂閱。

<definitions id="definitions"xmlns="http://www.omg.org/spec/BPMN/20100524/MODEL"xmlns:flowable="http://flowable.org/bpmn"targetNamespace="Examples"><signal id="alertSignal" name="alert" /><process id="catchSignal"><startEvent id="start" /><sequenceFlow sourceRef="start" targetRef="gw1" /><eventBasedGateway id="gw1" /><sequenceFlow sourceRef="gw1" targetRef="signalEvent" /><sequenceFlow sourceRef="gw1" targetRef="timerEvent" /><intermediateCatchEvent id="signalEvent" name="Alert"><signalEventDefinition signalRef="alertSignal" /></intermediateCatchEvent><intermediateCatchEvent id="timerEvent" name="Alert"><timerEventDefinition><timeDuration>PT10M</timeDuration></timerEventDefinition></intermediateCatchEvent><sequenceFlow sourceRef="timerEvent" targetRef="exGw1" /><sequenceFlow sourceRef="signalEvent" targetRef="task" /><userTask id="task" name="Handle alert"/><exclusiveGateway id="exGw1" /><sequenceFlow sourceRef="task" targetRef="exGw1" /><sequenceFlow sourceRef="exGw1" targetRef="end" /><endEvent id="end" /></process> </definitions>

?

4.4、任務

一個任務表示工作需要被外部實體完成, 比如人工或自動服務。

任務被描繪成一個圓角矩形,一般內部包含文字。 任務的類型(用戶任務,服務任務,腳本任務,等等)顯示在矩形的左上角,用小圖標區別。 根據任務的類型, 引擎會執行不同的功能。

?

4.4.1、用戶任務

  • 描述:
    “用戶任務(user task)”,也叫人工任務,見名知意,是用于對需要人工執行的任務進行建模。當流程執行到達用戶任務時,會為指派至該任務的用戶或組的任務列表創建一個新任務。

  • 圖示:
    用戶任務用左上角有一個小用戶圖標的標準任務(圓角矩形)表示。

  • xml表示:
    用戶任務在XML中如下定義。其中id是必須屬性,name是可選屬性。

<userTask id="theTask" name="Important task" />

也可以為用戶任務添加描述(description)。事實上任何BPMN 2.0元素都可以有描述。描述由documentation元素定義。

<userTask id="theTask" name="Schedule meeting" ><documentation>Schedule an engineering meeting for next week with the new hire.</documentation>
  • 到期日期
    每個任務都可以使用一個字段標志該任務的到期日期(due date)。可以使用查詢API,查詢在給定日期前或后到期的任務。
    可以在任務定義中使用擴展指定表達式,以在任務創建時設定到期日期。該表達式必須解析為java.util.Date,java.util.String (ISO8601格式),ISO8601時間長度(例如PT50M),或者null。例如,可以使用在流程里前一個表單中輸入的日期,或者由前一個服務任務計算出的日期。如果使用的是時間長度,則到期日期基于當前時間加上給定長度計算。例如當dueDate使用“PT30M”時,任務在從現在起30分鐘后到期。
<userTask id="theTask" name="Important task" flowable:dueDate="${dateVariable}"/>

任務的到期日期也可以使用TaskService,或者在TaskListener中使用傳遞的DelegateTask修改。

  • 用戶指派:
    用戶任務可以直接指派(assign)給用戶。可以定義humanPerformer子元素來實現。humanPerformer需要resourceAssignmentExpression來實際定義用戶。目前,只支持formalExpressions。
<process >...<userTask id='theTask' name='important task' ><humanPerformer><resourceAssignmentExpression><formalExpression>kermit</formalExpression></resourceAssignmentExpression></humanPerformer></userTask>

只能指定一個用戶作為任務的humanPerformer。在Flowable術語中,這個用戶被稱作辦理人(assignee)。擁有辦理人的任務,在其他人的任務列表中不可見,而只能在該辦理人的個人任務列表中看到。

可以通過TaskService獲取特定用戶辦理的任務:

List<Task> tasks = taskService.createTaskQuery().taskAssignee("kermit").list();

任務也可以放在用戶的候選任務列表中。在這個情況下,需要使用potentialOwner(潛在用戶)結構。用法與humanPerformer結構類似。請注意需要指定表達式中的每一個元素為用戶還是組(引擎無法自行判斷)。

<process >...<userTask id='theTask' name='important task' ><potentialOwner><resourceAssignmentExpression><formalExpression>user(kermit), group(management)</formalExpression></resourceAssignmentExpression></potentialOwner></userTask>

可用如下方法獲取定義了potentialOwner結構的任務:

List<Task> tasks = taskService.createTaskQuery().taskCandidateUser("kermit");

將獲取所有kermit作為候選用戶的任務,也就是說,表達式含有user(kermit)的任務。同時也將獲取所有指派給kermit為其成員的組的任務(例如,kermit時management組的成員,且任務指派給management組)。組在運行時解析,并可通過身份服務管理。

如果并未指定給定字符串是用戶還是組,引擎默認其為組。下列代碼與聲明group(accountancy)效果一樣。

<formalExpression>accountancy</formalExpression>
  • 用于任務指派的Flowable擴展
    很明顯,當指派關系不復雜時,這種用戶與組的指派方式十分笨重。為避免這種復雜性,可以在用戶任務上使用自定義擴展。

  • assignee(辦理人)屬性:這個自定義擴展用于直接將用戶指派至用戶任務。
<userTask id="theTask" name="my task" flowable:assignee="kermit" />

與上面定義的humanPerformer結構效果完全相同。

  • candidateUsers(候選用戶)屬性:這個自定義擴展用于為任務指定候選用戶。
<userTask id="theTask" name="my task" flowable:candidateUsers="kermit, gonzo" />

與使用上面定義的potentialOwner結構效果完全相同。請注意不需要像在potentialOwner中一樣,使用user(kermit)的聲明,因為這個屬性只能用于用戶。

  • candidateGroups(候選組)attribute:這個自定義擴展用于為任務指定候選組。
<userTask id="theTask" name="my task" flowable:candidateGroups="management, accountancy" />

與使用上面定義的potentialOwner結構效果完全相同。請注意不需要像在potentialOwner中一樣,使用group(management)的聲明,因為這個屬性只能用于組。

  • 可以定義在一個用戶任務上同時定義candidateUsers與candidateGroups。

?

4.4.2、腳本任務

  • 描述:
    腳本任務(Script Task)是一個自動化任務。當流程到達腳本任務時,自動執行編寫的腳本,完畢后繼續執行后繼路線。

  • 圖示:
    腳本任務用左上角有一個小“腳本”圖標的標準BPMN 2.0任務(圓角矩形)表示。

  • xml表示:
    腳本任務使用script與scriptFormat元素定義。

<scriptTask id="theScriptTask" name="Execute script" scriptFormat="groovy"><script>sum = 0for ( i in inputArray ) {sum += i}</script> </scriptTask>

scriptFormat屬性的值,必須是兼容JSR-223(Java平臺腳本)的名字。默認情況下,JavaScript包含在每一個JDK中,因此不需要添加任何JAR文件。如果想使用其它(兼容JSR-223的)腳本引擎,則需要在classpath中添加相應的jar,并使用適當的名字。例如,Flowable單元測試經常使用Groovy,因為其語法與Java十分相似。

請注意Groovy腳本引擎與groovy-all JAR捆綁在一起。在Groovy 2.0版本以前,腳本引擎是Groovy JAR的一部分。因此,必須添加如下依賴:

<dependency><groupId>org.codehaus.groovy</groupId><artifactId>groovy-all</artifactId><version>2.x.x<version> </dependency>
  • 腳本中的變量:
    到達腳本引擎的執行中,所有的流程變量都可以在腳本中使用。在這個例子里,腳本變量'inputArray'實際上就是一個流程變量(一個integer的數組)。
<script>sum = 0for ( i in inputArray ) {sum += i} </script>

也可以簡單地調用execution.setVariable("variableName", variableValue),在腳本中設置流程變量。默認情況下,變量不會自動儲存(請注意,在一些早期版本中是會儲存的!)。可以將scriptTask的autoStoreVariables參數設置為true,以自動保存任何在腳本中定義的變量(例如上例中的sum)。

<scriptTask id="script" scriptFormat="JavaScript" flowable:autoStoreVariables="false">

這個參數的默認值為false。也就是說如果在腳本任務定義中忽略這個參數,則腳本聲明的所有變量將只在腳本執行期間有效。

在腳本中設置變量的例子:

<script>def scriptVar = "test123"execution.setVariable("myVar", scriptVar) </script>

>>> 下列名字是保留字,不能用于變量名:out,out:print,lang:import,context,elcontext。

  • 腳本任務的結果:
    腳本任務的返回值,可以通過為腳本任務定義的'flowable:resultVariable'屬性設置為流程變量。可以是已經存在的,或者新的流程變量。如果指定為已存在的流程變量,則流程變量的值會被腳本執行的結果值覆蓋。如果不指定結果變量名,則腳本結果值將被忽略。
<scriptTask id="theScriptTask" name="Execute script" scriptFormat="juel" flowable:resultVariable="myVar"><script>#{echo}</script> </scriptTask>

在上面的例子中,腳本執行的結果(解析表達式'#{echo}'的值),將在腳本完成后,設置為名為'myVar'的流程變量。

?

4.4.3、服務任務

服務任務(Service Task)是一個自動化任務。當流程到達系統任務時,它會調用一些服務(例如web service,java service等等),完畢后繼續執行后繼路線。

?

4.4.3.1、Java服務任務

  • 描述:
    Java服務任務(Java service task)用于調用Java類。

  • 圖示:
    服務任務用左上角有一個小齒輪圖標的圓角矩形表示。

  • xml表示:

有四種方法聲明如何調用Java邏輯:

  • 指定實現了JavaDelegate或ActivityBehavior的類
  • 調用解析為委托對象(delegation object)的表達式
  • 調用方法表達式(method expression)
  • 對值表達式(value expression)求值

使用flowable:class屬性提供全限定類名(fully qualified classname),指定流程執行時調用的類。

<serviceTask id="javaService"name="My Java Service Task"flowable:class="org.flowable.MyJavaDelegate" />

也可以使用解析為對象的表達式。該對象必須遵循的規則,與使用flowable:class創建的對象規則相同。

<serviceTask id="serviceTask" flowable:delegateExpression="${delegateExpressionBean}" />

delegateExpressionBean是一個實現了JavaDelegate接口的bean,定義在Spring容器中。

使用flowable:expression屬性指定需要計算的UEL方法表達式。

<serviceTask id="javaService"name="My Java Service Task"flowable:expression="#{printer.printMessage()}" />

將在名為printer的對象上調用printMessage方法(不帶參數)。

也可以為表達式中使用的方法傳遞變量。

<serviceTask id="javaService"name="My Java Service Task"flowable:expression="#{printer.printMessage(execution, myVar)}" />

將在名為printer的對象上調用printMessage方法。傳遞的第一個參數為DelegateExecution,名為execution,在表達式上下文中默認可用。傳遞的第二個參數,是當前執行中,名為myVar變量的值。

可以使用flowable:expression屬性指定需要計算的UEL值表達式。

<serviceTask id="javaService"name="My Java Service Task"flowable:expression="#{split.ready}" />

會調用名為split的bean的ready參數的getter方法,getReady(不帶參數)。該對象會被解析為執行的流程變量或(如果可用的話)Spring上下文中的bean。

  • 實現:

要實現可以在流程執行中調用的類,需要實現org.flowable.engine.delegate.JavaDelegate接口,并在execute方法中提供所需邏輯。當流程執行到達該活動時,會執行方法中定義的邏輯,并按照BPMN 2.0的默認方法離開活動。

下面是一個Java類的示例,用于將流程變量String改為大寫。這個類需要實現org.flowable.engine.delegate.JavaDelegate接口,因此需要實現execute(DelegateExecution)方法。這個方法就是引擎將調用的方法,需要實現業務邏輯。可以通過DelegateExecution接口(點擊鏈接獲取該接口操作的詳細Javadoc)訪問流程實例信息,如流程變量等。

public class ToUppercase implements JavaDelegate {public void execute(DelegateExecution execution) {String var = (String) execution.getVariable("input");var = var.toUpperCase();execution.setVariable("input", var);}}
  • 服務任務的結果:
    服務執行的返回值(僅對使用表達式的服務任務),可以通過為服務任務定義的'flowable:resultVariable'屬性設置為流程變量。可以是已經存在的,或者新的流程變量。 如果指定為已存在的流程變量,則流程變量的值會被服務執行的結果值覆蓋。 如果使用'flowable:useLocalScopeForResultVariable',則會將結果值設置為局部變量。 如果不指定結果變量名,則服務任務的結果值將被忽略。
<serviceTask id="aMethodExpressionServiceTask"flowable:expression="#{myService.doSomething()}"flowable:resultVariable="myVar" />

?

4.4.3.2、Web服務任務

  • 描述:
    Web服務任務(Web service task)用于同步地調用外部的Web服務。

  • 圖示:
    Web服務任務與Java服務任務圖標一樣。

  • xml表示:
    使用Web服務之前,需要導入其操作及復雜的類型。可以使用導入標簽(import tag)指向Web服務的WSDL,自動處理:
<import importType="http://schemas.xmlsoap.org/wsdl/"location="http://localhost:63081/counter?wsdl"namespace="http://webservice.flowable.org/" />

按照上面的聲明,Flowable會導入定義,但不會創建條目定義(item definition)與消息。如果需要調用一個名為’prettyPrint’的方法,則需要先為請求及回復消息創建對應的消息與條目定義:

<message id="prettyPrintCountRequestMessage" itemRef="tns:prettyPrintCountRequestItem" /> <message id="prettyPrintCountResponseMessage" itemRef="tns:prettyPrintCountResponseItem" /><itemDefinition id="prettyPrintCountRequestItem" structureRef="counter:prettyPrintCount" /> <itemDefinition id="prettyPrintCountResponseItem" structureRef="counter:prettyPrintCountResponse" />

在聲明服務任務前,需要定義實際引用Web服務的BPMN接口與操作。基本上,是定義“接口”與所需的“操作”。對每一個操作都可以重復使用之前定義的“傳入”與“傳出”消息。例如,下面的聲明定義了“counter”接口及“prettyPrintCountOperation”操作:

<interface name="Counter Interface" implementationRef="counter:Counter"><operation id="prettyPrintCountOperation" name="prettyPrintCount Operation"implementationRef="counter:prettyPrintCount"><inMessageRef>tns:prettyPrintCountRequestMessage</inMessageRef><outMessageRef>tns:prettyPrintCountResponseMessage</outMessageRef></operation> </interface>

這樣就可以使用##WebService實現,聲明Web服務任務,并引用Web服務操作。

<serviceTask id="webService"name="Web service invocation"implementation="##WebService"operationRef="tns:prettyPrintCountOperation">

參考:

【1】:Flowable BPMN 用戶手冊 (v 6.3.0)
【2】:第 3 章 BPMN 2.0
【3】:BPMN 2.0 / Flowable
【4】:業務流程模型和標記法
【5】:BPMN2.0十分鐘就夠了
【6】:基于BPMN2.0的工作流(Workflow)
【7】:?AWS BPMN2 Event參考指南
【8】:【activiti 入門】activiti6.0的中間事件,包含信號事件(捕獲與拋出)
【9】:AWS BPMN2 Activity參考指南
【10】:AWS BPMN2 Gateway參考指南

總結

以上是生活随笔為你收集整理的Flowable学习笔记(二、BPMN 2.0-基础 )的全部內容,希望文章能夠幫你解決所遇到的問題。

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

主站蜘蛛池模板: 婷婷色小说 | 亚洲女人天堂色在线7777 | 国产青青青| 亚洲九九九九 | caoporen在线 | 日韩免费视频一区二区视频在线观看 | 午夜美女网站 | 欧美日韩激情视频在线观看 | 成人调教视频 | 国内精品久久久久久久 | 国精产品99永久一区一区 | 依人成人网 | 亚洲综合在线播放 | 激情欧美一区二区免费视频 | 亚洲aa在线 | 国产免费视频一区二区三区 | 毛片网络| 美女扒开粉嫩的尿囗给男生桶 | 在线观看不卡av | 国产在线精品一区二区 | 不许穿内裤随时挨c调教h苏绵 | a级片在线免费看 | 亚洲AV成人无码精品久久盆瓶 | 色爱成人综合 | 欧美视频一区二区 | av中文字幕网址 | 日本国产在线观看 | 国产视频一二 | 日本精品在线观看 | 国产精品免费av一区二区三区 | 亚洲国产精品va在线看黑人 | 99综合久久| 国产区视频| 成人国产精品蜜柚视频 | 日韩av动漫| 日韩精品一区在线 | av免费天堂 | www插插插无码免费视频网站 | 中文字幕一区二区三区日韩精品 | 欧美精品一区三区 | 亚洲成人网在线观看 | 国产精品99久久久久久久久 | 无码人妻精品一区二区三区66 | 懂色av蜜臀av粉嫩av分享吧最新章节 | 夏晴子在线| 啪啪免费网站 | 日本中文字幕在线免费观看 | 女王脚交玉足榨精调教 | heyzo亚洲| 亚洲社区一区二区 | 国产女人高潮的av毛片 | 99re这里有精品 | free性欧美hd另类 | 永久免费看片在线观看 | 聚色屋 | 秘密的基地 | 亚洲在线免费观看 | 男女插插插网站 | 男人肌肌桶女人肌肌 | 国产在线一区二区三区四区 | 国产精品久久99 | 在线少妇| 国产成人亚洲一区二区 | 毛片库| 久久婷五月天 | 成人国产片 | 国产夫妻在线视频 | 日本熟伦人妇xxxx | 日韩精品人妻一区 | 精品无码av一区二区三区 | 欧美粗暴jizz性欧美20 | 青草热视频 | 国产美女在线精品 | 成年人免费大片 | 国产日本精品视频 | 一本一道久久综合狠狠老精东影业 | 中文字幕人妻一区二区三区视频 | 成人网在线| 国产精品一区二区三区四区五区 | 野外吮她的花蒂高h在线观看 | videos亚洲 | 国产精品成人无码免费 | 精品丰满少妇一区二区三区 | 男男做爰猛烈叫床爽爽小说 | 天天干天天舔天天操 | 国产成人av一区二区三区在线观看 | 91玉足脚交白嫩脚丫 | www.自拍| 亚洲一区二区图片 | 日本午夜免费福利视频 | 激情拍拍拍 | 日韩一区二区三区在线免费观看 | 欧美精品一区二区在线观看 | youjizz亚洲| 青青草视频成人 | 日韩一区二区免费播放 | 国产一二三在线观看 | 色桃网 | 少妇无码av无码专区在线观看 |