程序流
形容
- 程序流是连贯两个流程节点的连线
- 流程执行完一个节点后,会沿着节点的所有外出程序流继续执行
BPMN 2.0默认的行为就是并发的:两个外出程序流会发明两个独自的,并发流程分支
图形标记
程序流显示为从终点到起点的箭头.箭头总是指向起点
XML内容
程序流须要流程范畴内惟一的id, 以及对终点与起点元素的援用
<sequenceFlow id="flow1" sourceRef="theStart" targetRef="theTask" />
条件程序流
形容
- 为程序流定义一个条件
来到一个BPMN 2.0节点时,默认会计算外出程序流的条件
- 如果条件后果为true,就会抉择外出程序流继续执行
- 当多条程序流被选中时,就会创立多条分支,流程会持续以并行形式继续执行
==留神:== 不包含网关 ,网关会用特定的形式解决程序流中的条件, 这与网关类型相干
图形标记
条件程序流显示为一个失常的程序流,在终点有一个菱形. 条件表达式也会显示在程序流上
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>
以后条件表达式只能应用UEL, 应用的表达式须要返回boolean值,否则会在解析表达式时抛出异样
援用了流程变量的数据,通过getter调用JavaBean
<conditionExpression xsi:type="tFormalExpression"><![CDATA[${order.price > 100 && order.price < 250}]]></conditionExpression>
通过调用办法返回一个boolean值
<conditionExpression xsi:type="tFormalExpression"><![CDATA[${order.isStandardOrder()}]]></conditionExpression>
在activiti公布包中,蕴含以下流程实例,应用了值和办法表达式
默认程序流
形容
- 所有的BPMN 2.0工作和网关都能够设置一个默认程序流
- 只有在节点的其它外出程序流不能被选中时,才会应用作为外出程序流继续执行
默认程序流的条件设置不会失效
图形标记
默认程序流显示为一般程序流, 终点有一个斜线标记
XML内容
- 默认程序流通过对应节点的default属性定义
上面的XML代码演示了排他网关设置了默认程序流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>
对应图形:
网关
- 网关用来管制流程的流向(流程的tokens),网关能够生产也能够生成token
网关显示成菱形图形,外部有有一个小图标.图标示意网关的类型:
排他网关
形容
- 排他网关: 异或XOR网关,用来在流程中实现决策
- 当流程执行到这个网关,所有外出程序流都会被解决一遍.其中条件解析为true的程序流(或者没有设置条件,概念上在程序流上定义了一个[true])会被选中,让流程持续运行
==留神:== 通常状况下,所有条件后果为true的程序流都会被选中,以并行形式执行,但排他网关只会抉择一条程序流执行. 就是说,尽管多个程序流的条件后果为true,那么XML中的第一个程序流(也只有这一条)会被选中,并用来持续运行流程.如果没有选中任何程序流,会抛出一个异样
图形标记
- 排他网关显示成一个一般网关(比方,菱形图形),外部是一个X图标,示意异或(XOR)语义.
- 没有外部图标的网关,默认为排他网关
BPMN 2.0标准不容许在同一个流程定义中同时应用没有X和有X的菱形图形
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>
并行网关
形容
- 网关也能够示意流程中的并行状况
- 容许将流程分成多条分支,也能够把多条分支汇聚到一起
并行网关的性能是基于进入和外出的程序流的:
- 分支: 并行后的所有外出程序流,为每个程序流都创立一个并发分支
- 汇聚: 所有达到并行网关,在此期待的进入分支 ,直到所有进入程序流的分支都达到当前, 流程就会通过汇聚网关
- 同一个并行网关有多个进入和多个外出程序流,同时具备分支和汇聚性能
- 网关会先汇聚所有进入的程序流,而后再切分成多个并行分支
并行网关不会解析条件: 与其余网关不同,即便程序流中定义了条件,也会疏忽
图形标记
并行网关显示成一个一般网关(菱形)外部是一个 + 图标,示意与(AND) 语义
XML内容
定义并行网关只须要一行XML
<parallelGateway id="myParallelGateway" />
理论产生的行为(分支,聚合,同时分支聚合),要依据并行网关的程序流来决定
<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());
当两个工作都实现时,第二个并行网关会汇聚两个分支.因为它只有一条外出连线,不会创立并行分支,只会创立归档订单工作
留神并行网关不须要是"均衡的"(对应并行网关的进入和外出节点数目相等).并行网关只是期待所有进入程序流,并为每个外出程序流创立并发分支,不会受到其余流程节点的影响
蕴含网关
形容
排他网关和并行网关的结合体:
- 和排他网关一样,能够在外出程序流上定义条件,蕴含网关会解析条件
- 和并行网关一样,蕴含网关能够抉择多于一条程序流
蕴含网关的性能是基于进入和外出程序流的:
- 分支: 所有外出程序流的条件都会被解析,后果为true的程序流会以并行形式继续执行,会为每个程序流创立一个分支
- 汇聚: 所有并行分支达到蕴含网关,会进入期待状态,直到每个蕴含流程token的进入程序流的分支都达到.这是与并行网关的最大不同.蕴含网关只会期待被选中执行了的进入程序流. 在汇聚之后,流程会穿过蕴含网关继续执行
- 如果同一个蕴含节点领有多个进入和外出程序流,它就会同时含有分支和汇聚性能
网关会先汇聚所有领有流程token的进入程序流,再依据条件判断后果为true的外出程序流,为它们生成多条并行分支
图形标记
并行网关显示为一个一般网关(菱形),外部蕴含一个圆圈图标
XML内容
定义一个蕴含网关须要一行XML
<inclusiveGateway id="myInclusiveGateway" />
理论的行为(分支,汇聚,同时分支汇聚),是由连贯在蕴含网关的程序流决定的
<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,就会抛出一个异样
- 如果想防止异样,能够定义一个默认程序流
蕴含网关示例: 创立一个发货工作
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());
- 当工作实现后,第二个蕴含网关会汇聚两个分支,因为只有一个外出程序流,所以不会创立并行分支,只有归档订单工作会被激活
蕴含网关不须要均衡(对应蕴含网关的进入和外出数目须要相等).蕴含网关会期待所有进入程序流实现,并为每个外出程序流创立并行分支,不会受到流程中其余元素的影响
基于事件网关
形容
基于事件网关容许依据事件判断流向
- 网关的每个外出程序流都要连贯到一个两头捕捉事件
- 当流程达到一个基于事件网关 ,网关会进入期待状态:会暂停执行
- 为每个外出程序流创立相应的事件订阅
基于事件网关的外出程序流和一般程序流不同:这些程序流不会真的"执行", 让流程引擎去决定执行到基于事件网关的流程须要订阅哪些事件,要思考以下条件:
- 基于事件网关必须有两条或以上外出程序流
- 基于事件网关后,只能应用intermediateCatchEvent类型(activiti不反对基于事件网关后连贯ReceiveTask)
连贯到基于事件网关的intermediateCatchEvent只能有一条进入程序流
图形标记
基于事件网关和其余BPMN网关一样显示成一个菱形,外部蕴含指定图标
XML内容
用来定义基于事件网关的XML元素是eventBasedGateway
实例
基于事件网关示例:
- 当流程执行到基于事件网关时,流程会暂停执行
- 与此同时,流程实例会订阅正告信号事件,并创立一个10分钟后触发的定时器.产生流程引擎为一个信号事件期待10分钟的成果
- 如果10分钟内发出信号,定时器就会勾销,流程会沿着信号执行
如果信号没有呈现,流程会沿着定时器的方向后退,信号订阅会被勾销
<definitions id="definitions" xmlns="http://www.omg.org/spec/BPMN/20100524/MODEL" xmlns:activiti="http://activiti.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>