繼續上一篇的事件的分享筆記,Start Event指明該處是流程開始,至於開始事件的類型(消息到達開始,指定的事件循環開始等),定義如何開始是在開始事件圓圈圖標裡面的小圖標表示,具體反映到xml中就是子元素的不同。
Start Event總是進行捕獲:在任何時候等待相應的觸發器觸發。
下面展示start event的xml,其中initiator指的是流程發起人,流程開始後他將會被保存起來:
<startEvent id="request" activiti:initiator="xxx" />
而用戶“xxx”在代碼中實現同樣的功能可以:
1 try { 2 identityService.setAuthenticatedUserId("bono"); 3 runtimeService.startProcessInstanceByKey("someProcessKey"); 4 } finally { 5 identityService.setAuthenticatedUserId(null); 6 }
使用在try-catch中使用IdentityService.setAuthenticatedUserId(String)方法。
一個none start event說的是在流程定義中沒有沒有定義觸發器。意味著流程引擎不會讓流程實例自動開始,需要由開發人員調用API實現(一般子流程就是這個樣子):
1 ProcessInstance processInstance = runtimeService.startProcessInstanceByXXX();
一個none start event在activiti可視化插件中的樣子:
而bpmn文件中則是
<startEvent id="start" name="my start event" />
可以配置formKey屬性:
<startEvent id="request" activiti:formKey="org/activiti/examples/taskforms/request.form" />
timer start event作用是在指定的時間啟動流程實例。它主要用在在流程只需要啟動一次或者流程循環啟動。注意:子流程是不能有timer start event。一般的在流程發布後就啟動流程,這時沒有必要調用startProcessInstanceByXXX方法了,盡管調用是沒有限制的,但是導致同一時刻有多個流程實例運行。同時如果流程有新的版本發布,timer start event只會啟動最新的版本的流程定義。
在activiti可視化插件中的樣子:
pbmn文件的xml格式中:
<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>
一個Message Start Event會使用命名的消息啟動流程實例,在有很多start event時候通過消息命名可以選擇正確的start event來啟動流程實例用到。
在發布流程定義一個或者多個的時候,需要注意一些問題:
每個message start event的名稱在流程定義中確保唯一的,在流程定義中沒有必要使得多個message start event的名字相同。在多個message start event引用的消息都相同的時候,工作流會拋出異常。
升級流程版本後,此前的message start event將會被新版本的message start event代替。
調用RunTimeService的API:
ProcessInstance startProcessInstanceByMessage(String messageName); ProcessInstance startProcessInstanceByMessage(String messageName, Map<String, Object> processVariables); ProcessInstance startProcessInstanceByMessage(String messageName, String businessKey, Map<String, Object< processVariables);
其中messageName是messageEventDefinition中messageRef引用message節點中name的值。message start event只支持頂層流程,不支持子流程。調用runtimeService.startProcessInstanceByMessage(…)可以選定message event。對於使用方法runtimeService.startProcessInstanceByKey(…) 和runtimeService.startProcessInstanceById(…)是使用了none start event,如果此時定義了多個message event會拋出異常。
例如在messageEventDefinition節點中配置:
<definitions id="definitions" xmlns="http://www.omg.org/spec/BPMN/20100524/MODEL" xmlns:activiti="http://activiti.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>
使用命名的信號進行啟動流程實例,信號在在流程中間信號拋出或者調用API(runtimeService.signalEventReceivedXXX方法)觸發,所有的流程定義如果有相同名稱的信號事件,都會被啟動。另外在這兩種情況下,都可以選擇同步或異步的方式啟動流程實例。
其中調用API的參數signalName來自流程定義中signalEventDefinition節點的signalRef的配置,而signalRef來自signal的屬性name。signal start event的可視化符號為下圖所示:
解析為xml:
1 <signal id="theSignal" name="The Signal" /> 2 3 <process id="processWithSignalStart1"> 4 <startEvent id="theStart"> 5 <signalEventDefinition id="theSignalEventDefinition" signalRef="theSignal" /> 6 </startEvent> 7 <sequenceFlow id="flow1" sourceRef="theStart" targetRef="theTask" /> 8 <userTask id="theTask" name="Task in process A" /> 9 <sequenceFlow id="flow2" sourceRef="theTask" targetRef="theEnd" /> 10 <endEvent id="theEnd" /> 11 </process>
一個error start event在子流程中常用,並且它並不能用在啟動一個流程實例。錯誤開始事件都是中斷事件。error start event的可視化符號為下圖所示:
解析為xml為:
1 <startEvent id="messageStart" > 2 <errorEventDefinition errorRef="someError" /> 3 </startEvent>
一個結束事件常常用在流程和子流程中,並且end event總是往外拋出信息,意味著流程執行到結束事件的時候會有結果拋出。
空的結束事件意味著並沒有指定的結果拋出,所以流程引擎在當前執行路徑下面並不會執行任何額外的事情。一個none end event的可視化效果。
<endEvent id="end" name="my end event" />
如果流程執行到error end event,當前路徑執行將會提前結束並拋出一個錯誤,這個錯誤會被匹配的邊界事件所捕獲,如果沒有找到對應的邊界事件,將會拋出異常,他具體的可視化效果下圖所示:
xml解析為:
<endEvent id="myErrorEndEvent"> <errorEventDefinition errorRef="myError" /> </endEvent>
errorRef引用的myError是在error中配置的:
<error id="myError" errorCode="123" /> ... <process id="myProcess"> ...
其中error的errorCode將會被匹配邊界事件,如果errorRef並沒有找到對於的error,errorRef將會作為errorCode的短名,這在Activiti中是特有的,比如:
<error id="myError" errorCode="error123" /> ... <process id="myProcess"> ... <endEvent id="myErrorEndEvent"> <errorEventDefinition errorRef="myError" /> </endEvent> ...
等效於:
<endEvent id="myErrorEndEvent"> <errorEventDefinition errorRef="error123" /> </endEvent>
當流程執行到terminate end event的時候,當前流程和子流程都將會終止結束。從概念上講,當執行到終止結束事件的時候,流程實例和子流程會結束,在BPMN2.0中,一個子流程會可以嵌入到子流程、含事務的子流程中,這適用於一般情況。當例如有多實例調用活動或嵌入的子流程,此時只有該實例將結束,其他實例和流程實例不受影響。流程設計器中設計可視化效果為:
解析為xml的話:
<endEvent id="myEndEvent > <terminateEventDefinition activiti:terminateAll="true"></terminateEventDefinition> </endEvent>