https://blog.coderstory.cn/bpmn2-xml/
<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"> ... </process> <definitions>
如上代碼是流程定義xml的基本代碼 definitions是根節點process 是每個流程的起點 必須有一個id和name 如果爲process元素定義了name,它會被用做流程的key 如果沒有指定name,id會被用做key。 注意key的規則與jPDL一樣: 空格和非字母數字的字符會被下劃線代替。
事件
?事件:空啓動事件
<startEvent id="start" name="myStart" />
空結束事件
<endEvent id="end" name="myEnd" /> 最簡單的流程定義
<process id="noneStartEndEvent" name="BPMN2 Example none start and end event"> <startEvent id="start" /> <sequenceFlow id="flow1" name="fromStartToEnd" sourceRef="start" targetRef="end" /> <endEvent id="end" name="End" /> </process>
終止結束事件
終止結束事件會結束整個流程實例,而空結束事件只會結束當前流程路徑。
<endEvent id="terminateEnd" name="myTerminateEnd"> <terminateEventDefinition/> </endEvent>
順序流
連接線
<sequenceFlow id="myFlow" name="My Flow" sourceRef="sourceId" targetRef="targetId" />
順序流條件
<sequenceFlow id=....>
<conditionExpression xsi:type="tFormalExpression">${amount >= 500}</conditionExpression>
</sequenceFlow>
默認順序流 認順序流只會在活動或網關的 所有其他外向順序流的condition條件爲false時纔會使用 默認順序流通過指定活動或網關的 'default' 屬性 來使用。
網關
網關是用來控制流程中的流向的
沒有定義條件的順序流會永遠被選擇
<parallelGateway id="myJoin" name="My synchronizing join" gatewayDirection="converging" /> gatewayDirection屬性:
- unspecificed (默認):網關可能擁有多個 進入和外出順序流。
- mixed:網關必須擁有多個 進入和外出順序流。
- converging:網關必須擁有多個進入順序流, 但是隻能有一個外出順序流。
- diverging:網關必須擁有一個進入順序流, 和多個外出順序流。
唯一網關(XOR 網關)
一個流程中的唯一決策。 會有一個外向順序流被使用?如果多個條件 執行爲true,第一個遇到的就會被使用
<process id="exclusiveGateway" name="BPMN2 Example exclusive gateway"> <startEvent id="start" /> <sequenceFlow id="flow1" name="fromStartToExclusiveGateway" sourceRef="start" targetRef="decideBasedOnAmountGateway" /> //定義網關 <exclusiveGateway id="decideBasedOnAmountGateway" name="decideBasedOnAmount" /> //第一個分支 <sequenceFlow id="flow2" name="fromGatewayToEndNotEnough" sourceRef="decideBasedOnAmountGateway" targetRef="endNotEnough"> <conditionExpression xsi:type="tFormalExpression"> ${amount < 100} </conditionExpression> </sequenceFlow> //第二個分支 <sequenceFlow id="flow3" name="fromGatewayToEnEnough" sourceRef="decideBasedOnAmountGateway" targetRef="endEnough"> <conditionExpression xsi:type="tFormalExpression"> ${amount <= 500 && amount >= 100} </conditionExpression> </sequenceFlow> //第三個分支 <sequenceFlow id="flow4" name="fromGatewayToMoreThanEnough" sourceRef="decideBasedOnAmountGateway" targetRef="endMoreThanEnough"> <conditionExpression xsi:type="tFormalExpression"> ${amount > 500} </conditionExpression> </sequenceFlow> <endEvent id="endNotEnough" name="not enough" /> <endEvent id="endEnough" name="enough" /> <endEvent id="endMoreThanEnough" name="more than enough" /> </process>
網關所需變量的提供
Map<String, Object> vars = new HashMap<String, Object>(); vars.put("amount", amount); ProcessInstance processInstance = executionService.startProcessInstanceByKey("exclusiveGateway", vars);
xor網關的默認走向 (如果所有條件都是false)
<exclusiveGateway id="decision" name="decideBasedOnAmountAndBankType" default="myFlow"/> <sequenceFlow id="myFlow" name="fromGatewayToStandard" sourceRef="decision" targetRef="standard"> </sequenceFlow>
並行網關 (不帶條件)
並行網關用來切分或同步相關的進入或外出 順序流。
一進多出的流程設計:並行切分
多進一處的流程設計:並行歸併
基本定義
<process id="parallelGateway" name="BPMN2 example parallel gatewar"> //空啓動事件 <startEvent id="Start" /> //連接空啓動時間和並行網關 <sequenceFlow id="flow1" name="fromStartToSplit" sourceRef="Start" targetRef="parallelGatewaySplit" /> //並行網關1 <parallelGateway id="parallelGatewaySplit" name="Split" gatewayDirection="diverging"/> //並行網關1連接節點1 <sequenceFlow id="flow2a" name="Leg 1" sourceRef="parallelGatewaySplit" targetRef="prepareShipment" /> //定義節點1 <userTask id="prepareShipment" name="Prepare shipment" implementation="other" /> //節點1連接並行網關2 <sequenceFlow id="flow2b" name="fromPrepareShipmentToJoin" sourceRef="prepareShipment" targetRef="parallelGatewayJoin" /> //節點2連接並行網關1 <sequenceFlow id="flow3a" name="Leg 2" sourceRef="parallelGatewaySplit" targetRef="billCustomer" /> //定義節點2 <userTask id="billCustomer" name="Bill customer" implementation="other" /> //節點2連接並行網關2 <sequenceFlow id="flow3b" name="fromLeg2ToJoin" sourceRef="billCustomer" targetRef="parallelGatewayJoin" /> //定義並行網關2 <parallelGateway id="parallelGatewayJoin" name="Join" gatewayDirection="converging"/> //並行網關2連接空結束事件 <sequenceFlow id="flow4" sourceRef="parallelGatewayJoin" targetRef="End"> </sequenceFlow> <endEvent id="End" name="End" /> </process>
包含網關?OR-gatewa (帶條件)
進行“條件性”切分或匯聚順序流。
<process id="inclusiveGateway" name="BPMN2 Example inclusive gateway"> <startEvent id="start" /> <sequenceFlow id="flow1" sourceRef="start" targetRef="inclusiveGatewaySplit" /> <inclusiveGateway id="inclusiveGatewaySplit" default="flow3"/> <sequenceFlow id="flow2" sourceRef="inclusiveGatewaySplit" targetRef="largeDeposit"> <conditionExpression xsi:type="tFormalExpression">${cash > 10000}</conditionExpression> </sequenceFlow> <sequenceFlow id="flow3" sourceRef="inclusiveGatewaySplit" targetRef="standardDeposit" /> <sequenceFlow id="flow4" sourceRef="inclusiveGatewaySplit" targetRef="foreignDeposit"> <conditionExpression xsi:type="tFormalExpression">${bank == 'foreign'}</conditionExpression> </sequenceFlow> <userTask id="largeDeposit" name="Large deposit" /> <sequenceFlow id="flow5" sourceRef="largeDeposit" targetRef="inclusiveGatewayMerge" /> <userTask id="standardDeposit" name="Standard deposit" /> <sequenceFlow id="flow6" sourceRef="standardDeposit" targetRef="inclusiveGatewayMerge" /> <userTask id="foreignDeposit" name="Foreign deposit" /> <sequenceFlow id="flow7" sourceRef="foreignDeposit" targetRef="inclusiveGatewayMerge" /> <inclusiveGateway id="inclusiveGatewayMerge" /> <sequenceFlow id="flow8" sourceRef="inclusiveGatewayMerge" targetRef="theEnd" /> <endEvent id="theEnd" /> </process>
?任務
人工任務(用戶任務 user task)
一個新人工任務就會被創建,交給用戶的任務列表
<userTask id="myTask" name="My task" /> 使用多種實現(WebService, WS-humantask,等等)
<userTask id="myTask" name="My task"> <potentialOwner resourceRef="manager" jbpm:type="group"> <resourceAssignmentExpression> <formalExpression>management</formalExpression> </resourceAssignmentExpression> </potentialOwner> </userTask> resourceAssignmentExpression 分配任務 potentialOwner 候選人 jbpm:type="group" 定義這是一個用戶組的分配方式 如果刪除了這個屬性,就會默認使用用戶組的語法 jbpm:type="user" 分配方式是候選用戶
<userTask id="myTask" name="My User task"> <potentialOwner resourceRef="employee" jbpm:type="user"> <resourceAssignmentExpression> <formalExpression>peter</formalExpression> </resourceAssignmentExpression> </potentialOwner> </userTask>
Peter將可以看到任務,因爲他是這個任務的候選用戶。 List<Task> tasks = taskService.createTaskQuery().candidate("peter").list();
用戶組的定義
identityService.createGroup("management"); identityService.createUser("peter", "Peter", "Pan"); identityService.createMembership("peter", "management"); identityService.createUser("mary", "Mary", "Littlelamb"); identityService.createMembership("mary", "management"); 所在用戶組的人能看到這個任務
// Peter and Mary are both part of management, so they both should see the task List<Task> tasks = taskService.findGroupTasks("peter"); assertEquals(1, tasks.size()); tasks = taskService.findGroupTasks("mary"); assertEquals(1, tasks.size()); // Mary claims the task Task task = tasks.get(0); taskService.takeTask(task.getId(), "mary"); assertNull(taskService.createTaskQuery().candidate("peter").uniqueResult()); taskService.completeTask(task.getId()); assertProcessInstanceEnded(processInstance);
human performer 一個任務直接分配給一個人, 組,角色時
<userTask id="myTask" name="My User task"> <humanPerformer resourceRef="employee"> <resourceAssignmentExpression> <formalExpression>mary</formalExpression> </resourceAssignmentExpression> </humanPerformer> </userTask>
任務列表中看到這個任務:
List<Task> tasks = taskService.findPersonalTasks("mary");
因爲任務分配已經完成,通過使用 formalExpression,它也可以定義表達式 在運行期解析、 比如,如果流程變量'user'被定義了,然後,它可以用在表達式中。 <userTask id="myTask" name="My User task"> <humanPerformer resourceRef="employee"> <resourceAssignmentExpression> <formalExpression>${user}</formalExpression> </resourceAssignmentExpression> </humanPerformer> </userTask>
Java服務任務
Service Task是一個自動活動,它會調用一些服務, 比如web service,java service等等。
<serviceTask id="MyServiceTask" name="My service task" implementation="Other" operationRef="myOperation" /> implementation 服務的類型 ->WebService, Other或者Unspecified
<interface id="myInterface" name="org.jbpm.MyJavaServicek"> <operation id="myOperation2" name="myMethod"> <inMessageRef>inputMessage</inMessageRef> <outMessageRef>outputMessage</outMessageRef> </bpmn:operation> </interface>
備註:每個操作都至少有一個 輸入信息,並且 最多有一個輸出信息。
<message id="inputMessage" name="input message" structureRef="myItemDefinition1" />
腳本任務
腳本任務時一個自動活動,當到達這個任務的時候 流程引擎會執行一個腳本。
<scriptTask id="scriptTask" name="Script Task" scriptLanguage="bsh"> <script><![CDATA[ for(int i=0; i < input.length; i++){ System.out.println(input[i] + " x 2 = " + (input[i]*2)); }]]> </script> </scriptTask> 允許指定 scriptLanguage和script
手工任務
一個由外部人員執行的任務,但是沒有指定是 一個BPM系統或是一個服務會被調用
<manualTask id="myManualTask" name="Call customer" />
java接收任務
receive task是一個任務會等到外部消息的到來。
<receiveTask id="receiveTask" name="wait" />
內嵌子流程
<process id="embeddedSubprocess"> <startEvent id="theStart" /> <sequenceFlow id="flow1" sourceRef="theStart" targetRef="receiveOrder" /> <receiveTask name="Receive order" id="receiveOrder" /> <sequenceFlow id="flow2" sourceRef="receiveOrder" targetRef="checkCreditSubProcess" /> <subProcess id="checkCreditSubProcess" name="Credit check"> ... </subProcess> <sequenceFlow id="flow9" sourceRef="checkCreditSubProcess" targetRef="theEnd" /> <endEvent id="theEnd" /> </process>
定時啓動事件
<startEvent name="Every Monday morning" id="myStart"> <timerEventDefinition/> </startEvent> 定義方法: 1.timeDate
<startEvent id="myStartEvent" > <timerEventDefinition> <timeDate>10/10/2099 00:00:00</timeDate> </timerEventDefinition> </startEvent> 2.timeCycle (延遲)
<startEvent id="myStartEvent" > <timerEventDefinition> <timeCycle>5 hours</timeCycle> </timerEventDefinition> </startEvent>
3.表達式 (每週五23點)
<startEvent id="myStartEvent" > <timerEventDefinition> <timeCycle>0 0 23 ? * FRI</timeCycle> </timerEventDefinition> </startEvent>
中間事件
間事件用來表示在流程執行過程中發生的事件(比如, 在流程啓動之後,在它完成之前)。
定時器事件,觸發事件,傳播事件
?中間事件既可以拋出也可以捕獲:
- 拋出:當一個流程到達事件中, 它會立刻觸發一個對應的觸發器(一個激活,一個錯誤,等等)。
- 捕獲:當一個流程到達事件中, 它會等待一個對應的觸發器發生(一個錯誤,一個定時器,等等)。
定時器
內部定時器事件用來表示一個流程的延遲。 直接的用例是收集數據, 只在沒有人工作的晚上執行大量的邏輯,等等。
原文:http://www.mossle.com/docs/jbpm4devguide/html/bpmn2.html