Flowable實戰(四)BPMN2.0 啟動與結束事件

金楊傑發表於2022-01-11

一、BPMN2.0

  BPMN2.0規範是一個標準,開源框架和不同供應商都遵循這份標準,使得終端使用者不會因為依賴專有解決方案,而被供應商“綁架”。有了BPMN2.0標準,不同解決方案之間的遷移,變得十分簡單平滑。

  缺點則是標準通常是不同觀點大量討論與妥協的結果,有些結構或方法會十分笨重。Flowable在實現規範的基礎上進行了功能和使用性擴充套件。

  • 自定義擴充套件是在標準方式的基礎上進行簡化。因此當你決定使用自定義擴充套件時,仍然可以用標準方式。
  • 使用自定義擴充套件時,總是通過flowable:名稱空間字首,明確標識出XML元素、屬性等。
  • Flowable引擎也支援activiti:名稱空間字首。

  注:在官方文件中,啟動和結束事件已有較詳細的介紹,是英文版。啟動和結束事件是流程裡重要的內容,現在做個彙總整理。

二、啟動事件

  啟動事件(start event)是流程的起點。

  • 啟動事件在XML中,型別由子元素宣告來定義。
  • 啟動事件保持等候狀態,直到特定的觸發器被觸發。
  • 啟動事件是細線圖形。

2.1 空啟動事件

2.1.1 描述

  空啟動事件(none Start Event),指的是未指定觸發器,由使用者呼叫的啟動事件。

2.1.2 圖示

  空啟動事件用空心圓圈表示,中間沒有圖示(也就是說,沒有觸發器)。

2.1.3 XML表示

  空啟動事件的XML表示格式,就是普通的啟動事件宣告,而沒有任何子元素(其他種類的啟動事件都有用於宣告其型別的子元素)。

	<startEvent id="start" name="my start event" />

2.1.4 使用方法:

	ProcessInstance processInstance = runtimeService.startProcessInstanceByXXX();

2.1.5 自定義擴充套件

  formKey: 引用表單定義,使用者需要在啟動時填寫的表單。(目前只需瞭解到啟動事件可以繫結表單即可,詳細內容在表單章節中講解。)

	<startEvent id="request" flowable:formKey="simpleForm" />

2.2 定時器啟動事件

2.2.1 描述

  定時器啟動事件(timer start event)在指定時間內建立一次或多次的流程例項。

  • 定時器啟動事件,在流程部署的同時就開始計時。不需要呼叫startProcessInstanceByXXX就會在時間啟動。呼叫startProcessInstanceByXXX時會在定時啟動之外額外啟動一個流程。

  • 當部署帶有定時器啟動事件的流程的更新版本時,上一版本的定時器作業會被移除。這是因為通常並不希望舊版本的流程仍然自動啟動新的流程例項。

2.2.2 圖示

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

2.2.3 XML表示

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

定時器定義必須且只能包含下列的一種元素:

  • timeDate。這個元素指定了ISO 8601格式的固定時間。在這個時間就會觸發觸發器。例如:
    <timerEventDefinition>
        <timeDate>2022-01-11T12:13:14</timeDate>
    </timerEventDefinition>
  • timeDuration。要定義定時器需要等待多長時間再觸發,同樣使用ISO 8601格式(BPMN 2.0規範要求)。例如(等待10天):
    <timerEventDefinition>
        <timeDuration>P10D</timeDuration>
    </timerEventDefinition>
  • timeCycle。指定重複週期,可用於週期性啟動流程。例如(重複三次啟動,每次間隔為10小時,到指定時間時結束重複):

        <timerEventDefinition>
            <timeCycle>R3/PT10H/2022-01-12T23:59:59+00:00</timeCycle>
        </timerEventDefinition>
    

    也可以使用變數,如${EndDate}

        <timerEventDefinition>
            <timeCycle>R3/PT10H/${EndDate}</timeCycle>
        </timerEventDefinition>
    

2.3 訊息啟動事件

2.3.1 描述

  訊息啟動事件(message start event)使用具名訊息啟動流程例項。訊息名用於定位指定的啟動事件。

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

  • 一個流程定義不得包含多個同名的訊息啟動事件。
  • 在流程定義中,一個或多個訊息啟動事件引用了已經部署的另一流程定義中訊息啟動事件的訊息名,則會丟擲異常。
  • 流程版本:在部署流程定義的新版本時,會取消上一版本的訊息訂閱,即使新版本中並沒有這個訊息事件。

2.3.2 圖示

  訊息啟動事件用其中有一個訊息事件標誌的圓圈表示。這個標誌並未填充,用以表示捕獲(接收)行為。

2.3.3 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>

2.3.4 使用方法

  在啟動流程例項時,可以使用下列RuntimeService中的方法,觸發訊息啟動事件:

    ProcessInstance startProcessInstanceByMessage(String messageName);
    ProcessInstance startProcessInstanceByMessage(String messageName, Map<String, Object> processVariables);
    ProcessInstance startProcessInstanceByMessage(String messageName, String businessKey,
        Map<String, Object< processVariables);

  messageName是由message元素的name屬性給定的名字。messageEventDefinition的messageRef屬性會引用message元素。

2.4 訊號啟動事件

2.4.1 描述

  訊號啟動事件(signal start event),使用具名訊號啟動流程例項。

2.4.2 圖示

  訊號啟動事件用其中有一個訊號事件標誌的圓圈表示。這個標誌並未填充,用以表示捕獲(接收)行為。

2.4.3 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>

2.4.4 使用方法

  訊號可以由流程例項中的訊號丟擲中間事件(intermediary signal throw event),或者API(runtimeService.signalEventReceivedXXX方法)觸發。

  兩種方式都會啟動所有擁有相同名字訊號啟動事件的流程定義。

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

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

注意:訊息與訊號的區別:訊息是一對一的,一個訊息只能啟動一個流程事件。訊號是全域性的,廣播式的,一個訊號可以啟動多個流程事件。

2.5 異常啟動事件

2.5.1 描述

  異常啟動事件(error start event),可用於觸發事件子流程(Event Sub-Process)。錯誤啟動事件不能用於啟動流程例項

2.5.2 圖示

  異常啟動事件用其中有一個異常事件標誌的圓圈表示。這個標誌並未填充,用以表示捕獲(接收)行為。

2.5.3 XML表示

  異常啟動事件的XML表示格式,為普通啟動事件宣告加上errorEventDefinition子元素:

    <startEvent id="messageStart" >
            <errorEventDefinition errorRef="someError" />
    </startEvent>

三、結束事件

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

3.1 空結束事件

3.1.1 描述

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

3.1.2 圖示

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

3.1.3 XML表示

  空事件的XML表示格式為普通結束事件宣告,沒有任何子元素(其它種類的結束事件都有子元素,用於宣告其型別)。

	<endEvent id="end" name="my end event" />

3.2 異常結束事件

3.2.1 描述

  當流程執行到達異常結束事件(error end event)時,結束執行的當前分支,並丟擲錯誤。

3.2.2 圖示

  異常結束事件事件用內部有一個異常圖示的標準結束事件(粗圓圈)表示。異常圖示是全黑的,代表丟擲的含義。

3.2.3 XML表示

  異常結束事件表示為結束事件,加上errorEventDefinition子元素:

    <endEvent id="myErrorEndEvent">
      <errorEventDefinition errorRef="myError" />
    </endEvent>

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

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

  errorerrorCode用於查詢匹配的異常捕獲邊界事件。如果errorRef不匹配任何已定義的error,則該errorRef會用做errorCode的快捷方式。這個快捷方式是Flowable特有的。下面的程式碼片段在功能上是相同的。

	<error id="myError" errorCode="error123" />
    ...
    <process id="myProcess">
    ...
      <endEvent id="myErrorEndEvent">
        <errorEventDefinition errorRef="myError" />
      </endEvent>
    ...

  與下面的程式碼功能相同

    <endEvent id="myErrorEndEvent">
      <errorEventDefinition errorRef="error123" />
    </endEvent>

  請注意errorRef必須遵從BPMN 2.0規範。

3.3 終止結束事件

3.3.1 描述

  當到達終止結束事件(terminate end event)時,當前的流程例項或子流程會被終止。也就是說,當執行到達終止結束事件時,會判斷第一個範圍 scope(流程或子流程)並終止它。請注意在BPMN 2.0中,子流程可以是嵌入式子流程,呼叫活動,事件子流程,或事務子流程。有一條通用規則:當存在多例項的呼叫過程或嵌入式子流程時,只會終止一個例項,其他的例項與流程例項不會受影響。

  可以新增一個可選屬性terminateAll。當其為true時,無論該終止結束事件在流程定義中的位置,也無論它是否在子流程(甚至是巢狀子流程)中,都會終止(根)流程例項。

3.3.2 圖示

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

3.3.4 XML表示

  終止結束事件,表示為結束事件,加上terminateEventDefinition子元素。

  請注意terminateAll屬性是可選的(預設為false)。

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

3.4 取消結束事件

3.4.1 描述

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

3.4.2 圖示

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

3.4.3 XML表示

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

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

四、小結

  理論是實踐的基礎,本篇彙總BPMN2.0 規範和Flowable擴充套件下的啟動和結束事件,為後面的實戰做準備。

相關文章