BPMN2.0
BPMN2.0介绍
BPMN2.0规范定义了标准的图形和符号,绘制流程文档时,定义的元素需要遵循BPMN2.0规范。BPMN文件本质上是一个XML文件
BPMN(Business Process Model And Notation, BPMN):“业务流程模型和符号”。BPMN规范的发布是为了让业务流程的全部参与人员可以对流程进行可视化管理,提供一套让所有参与人员都易于理解的语言和标记。
BPMI:业务流程管理倡议组织(BPMI),2005年并入到OMG组织,当前BPMN规范由OMG组织进行维护。
BPMN1.0规范:NPMI组织2004年发布。
BPMN2.0规范:OMG组织2011年1月正式发布。定义了业务流程的符号以及模型,并且为流程定义设定了转换格式,目的是为了让流程的定义实现可移植性
1. BPMN2.0三大要素
- Event(事件):流程的创建、流转、结束均需要事件支持
- Gateways(网关):辅助决定流程实例最终流转的目的地,排他并行包容
- Activitis(活动):有生命周期的元素或者节点

2. BPMN2.0的XML结构
BPMN2.0的文件以.bpmn结尾,但是它也是一个XML文件,将.bmpn修改成.xml,我们可以看到它是由各种标签组成的。xml文件和bpmn文件可以相互转化(前提是xml中的标签书写正确)。
1. 事件
事件分类:
- 启动事件
- 结束事件
- 边界事件
- 中间事件

1.1 启动事件
作用:负责一个流程的开始,都是捕获型
启动事件分类
- 空启动事件
- 定时启动事件
- 异常启动事件
- 消息启动事件
空启动事件
图形化表示

空启动事件XML标签
<!-- startEvent:表示空开始事件-->
<startEvent id="startevert" name ="startEvent"></startEvent>
空启动事件属性
| 属性名称 | 属性说明 | 实例 |
|---|---|---|
| activiti:initiator | 可以用来记录启动流程的人的ID (也可以是用户的名称),启动流程之后此属性指定的变量就会自动设置当前人的名称 | <startEvent id=“startEvent” activiti:initiator=“startUserld” / >在流程流转中就可以通过获取变量startUserld得到启动时操作人ID |
| activiti:formKey | 可以用来指定空启动事件关联的表单文件。关于如何设置关联表单将在后续章节介绍 | < startEvent id=“startEvent” activiti:formKey=“apply.form” > |
定时启动事件
作用:一次性定时启动、特定时间间隔后启动、持续性启动
应用场景
- 指定日期开启流程实例
- 24小时任务未办理短信提醒
- 3天未审核则主管介入
- 公司每个月产生一次报表,可以设定每个月1号系统自动生成报表,并自动启动公司的业务处理流程
定时启动事件图形化表示

定时启动事件XML标签
<startEvent id="timerStartEvent" name="Timer start event for report process">
<!-- timerEventDefinition:表示定时事件-->
<timerEventDefinition>
<!-- timecycle:使用ISO 8601 标志定义一个循环定时器-->
<timeCycle>R1/2012-02-01T00:00/PM1M</timeCycle>
</timerEventDefinition>
</startEvent>
定时启动事件属性
| 属性名称 | 属性说明 | 示例 |
|---|---|---|
| timeDate | 一次性启动,具体到一个日期,用ISO 8601格式设定 | < timeDate>2012-12-12T00: 00: 00< /timeDate >在这个指定的日期启动一次流程 |
| timeDuration | 设置多长时间之后启动流程 | < timeDuration>PT10M</ timeDuration >部署流程或者输出流的上一个任务完成10分钟之后启动流程 |
| timeCycle | 周期性启动任务,用来设定循环的时间间隔,表示多长时间执行一次循环。同样还是用ISO 8601表示 | < timeCycle>R3/PT10H< /timeCycle>循环3次,每次间隔10小时。在timeDuration的基础上添加了循环次数 |
ISO 8601书写格式
| 字母 | 说明 | 示例 |
|---|---|---|
| P | 开始标记 | |
| Y | 年 | 1Y:1年 |
| M | 月 | 2M:2个月 |
| D | 日 | 10D:10天 |
| T | 时间和日期分割标记 | |
| H | 小时 | 2H:2小时 |
| M | 分钟 | 30M:30分钟 |
| S | 秒 | 15S:15秒 |
时间的例子:
- 2021-08-25T15:23:50
持续的例子:
- P1DT1M:一天一分钟执行一次
- P1W一周执行一次
- PT2H:2小时执行一次
- PT10S:10秒执行一次
异常启动事件
作用:触发一个异常子流程,不能通过API(runtimeService.startProcessInstance()方法)方式启动,在另外一个流程抛出异常结束事件时被触发
异常启动事件的图形化表示

异常启动事件XML标签
<startEvent id="xxx" name="xxx">
<!-- errorEventDefinition:异常事件
errorRef="AIA001":指定异常代码:"AIA001"-->
<errorEventDefinition errorRef="AIA001"></errorEventDefinition>
</timerEventDefinition>
</startEvent>
消息启动事件
作用:通过一个消息名称触发,从而启动一个流程实例。可以结合消息抛出事件一起使用由流程自动根据消息的名称启动对应的流程。
应用场景:
为不同的业务处理结果启动不同的流程
消息启动事件图形化表示

消息启动事件XML标签
<startEvent id="xxx" name="xxx">
<messageEventDefinition messageRef="reSendFile" />
</startEvent>
1.2 结束事件
作用:负责一个流程结束,和启动事件成对出现,允许没有结束事件(开始事件不能少),结束事件为抛出型,流程执行到结束事件会抛出一个结果
结束事件分类:
- 空结束事件
- 异常结束事件
- 终止结束事件
- 取消结束事件
空结束事件
空结束事件不抛出结果,流程结束不执行其他操作,终止整个流程
结束事件图形化表示

结束事件XML标签
<endEvent id="end" name="my end event"/>
异常结束事件
作用:抛出型,定义需要抛出的错误代码,如果找到了异常开始事件定义的异常代码,则会触发异常开始事件,找不到按空处理
注意:异常结束事件的错误代码不能为空
结束事件图形化表示

结束事件XML标签
<endEvent id="endevent" name="my end event">
<!-- errorEventDefinition:表示异常结束事件 errorRef:描述错误编号,不能为空-->
<errorEventDefinition errorRef="AIA-001"></errorEventDefinition>
</endEvent>
遇到异常结束事件:引擎查询定义为errorRef属性值的异常启动事件并触发
终止结束事件
作用:终止一个流程实例的执行。空结束事件,结束一条输出流,终止结束事件,结束流程
应用场景:
付费流程中因为某些原因导致流程不能继续运行,最终的结果是取消本次付费,需要提前结束流程实例的执行,这时可以把某个输出流执行到终止结束事件
终止结束事件图形化表示

终止结束事件XML标签
<endEvent id="terminateendevent1" name="TerminateEndEvent">
<terminateEventDefinition></terminateEventDefinition>
</endEvent>
取消结束事件
使用条件:事务子流程
作用:取消一个事务子流程的执行,只能在子流程中使用。可以和取消边界事件配合使用针对取消操作做后续处理
应用场景
子流程执行过程中出现异常需要取消,设置取消结束事件,输出流只想到取消结束事件时流程将会中断执行
取消结束事件图形化表示

结束事件XML标签
<endEvent id="myCancelEndEvent">
<cancelEventDefinition />
</endEvent>
1.3 边界事件
作用:绑定在活动上的**“捕获型”**事件,一直监听所有出于运行中活动的某种事件的触发,捕获发生事件后中断活动,从边界事件类型的输出流继续执行
注意:一旦触发边界事件,当前的活动就会被终端,然后按照边界事件之后的输出流执行。一个活动只能绑定一个边界时间。
边界事件分类
- 定时边界事件
- 异常边界事件
- 信号边界事件
- 取消边界事件
- 补偿边界事件
边界事件与中间事件的基本图形

边界事件的XML描述
注意:边界事件和所关联的活动有一个特殊的关系"附加",一个活动只能绑定一个边界事件,每个边界事件类型都是通过属性attachedToRef指定“附加”到抛出事件的活动上
<!-- 所有边界事件子类型都需要包含在boundaryEvent标签中
cancelActivity可以取true和false两个值,指定在捕获到边界事件之后是否取消执行输出流指定的活动(只适用部分边界事件)
-->
<boundaryEvent id="boundary" attachedToRef="someActivity" cancelActivity= "true | false">
<xxxxEventDefinition />
</boundaryEvent>
定时边界事件
作用:指定时间启动新流程,附属在非自动任务(用户任务)、调用活动、子流程上,上有任务完成之后开始倒计时预设的事件、到达预设事件之后触发定时器边界事件的输出流
定时边界事件图形

定时边界事件XML
<boundaryEvent id="boundarytimer1" cancelActivity=" false" attachedToRef="hrAudit">
<timerEventDefinition>
<timeDuration>P3D</timeDuration>
</timerEventDefinition>
</boundaryEvent>
异常边界事件
作用:捕获嵌入子流程或调用活动抛出的异常。异常抛出后被主流程的异常边界事件捕获,同时嵌入子流程或调用活动中的活动也被中断执行
异常边界事件图形

定时边界事件XML
<boundaryEvent id="boundaryerror1"cancelActivity="false"attachedToRef="subprocess1">
<errorEventDefinition errorRef="A001" />
</boundaryEvent>
信号边界事件
作用:捕获流程执行过程中抛出的信号,可以“附加”在各种活动和子流程上。信号边界事件不仅可以捕捉到本流程的信号,还可以捕获到其他流程的信号事件。一个活动或子流程定义多个信号边界事件并监听同一个信号,则会同时触发。
信号边界事件图形

信号边界事件XML
<boundaryEvent id="boundary" attachedToRef="task" cancelActivity="true">
<signalEventDefinition signalRef="alertSignal"/>
</boundaryEvent>
取消边界事件
前提:事务子流程
作用:捕获子流程中抛出的取消事件
注意:
- 一个事务子流程只允许附加一个取消边界事件
- 如果事务子流程中嵌套了子流程,仅仅触发已经完成了的子流程的补偿事件
- 对于多实例的事务子流程,如果其中一个实例触发了取消事件,那么其他的实例也同样会被触发取消边界事件
取消边界事件图形

信号边界事件XML
<boundaryEvent id="boundary" attachedToRef="transaction" >
<cancelEventDefinition />
</boundaryEvent>
补偿边界事件
前提:事务子流程(嵌入子流程不支持补偿边界事件)
作用:针对事务失败后的业务补偿逻辑及逆行补偿
取消边界事件图形

信号边界事件XML
<boundaryEvent id="Event 1" name="捕获取消结束事件" attachedToRef="Task 2">
<compensateEventDefinition id="EventDef 1"/>
</boundaryEvent>
<association id="Association 1" sourceRef="Event 1" targetRef="Task 4" associationDirection="One"/>
<!-- isForCompensation:声明补偿类型 -->
<seryiceTask id="Task 4" name="退回已扣金额" isForCompensation="true"/>
1.4 中间事件
1.4.1 中间捕获事件
中间事件按类型分类,中间捕获事件和中间抛出事件
中间捕获事件:必须连接一个输入流一个输出流
中间捕获事件的基本XML描述
<intermediateCatchEvent id="event1">
<xxxxEventDefinition />
</intermediatecatchEvent >
定时中间捕获事件
作用:和定时启动事件、定时器边界事件功能类似,都在一个特定的事件或指定间隔多长时间触发,执行之后活动
定时中间捕获事件图形

定时中间捕获事件XML
<intermediateCatchEvent id="timerintermediatecatchevent1" name="TimerCatchEvent">
<timerEventDefinition>
<timeDuration>PT5M</timeDuration>
</timerEventDefinition>
</intermediateCatchEvent>
信号中间捕获事件
捕获被当前流程或其他流程抛出的信号事件,信号是广播式传播
信号中间捕获事件图形

信号中间捕获事件XML
<intermediateCatchEvent id="signal">
<siqnalEventDefinition signalRef="doXxxSignal" />
</intermediateCatchEvent>
消息中间捕获事件
定向一对一传递消息
消息中间捕获事件图形

消息中间捕获事件XML
<intermediateCatchEvent id="messageCatch">
<messageEventDefinition messaqeRef="continuexxx" />
</intermediateCatchEvent>
1.4.2 中间抛出事件
空中间抛出事件
执行到空中间抛出事件直接跳过
空中间抛出事件事件图形

空中间抛出事件事件XML
<intermediateThrowEvent id="noneintermediatethrowevent1" name="NoneThrowEvent">
</intermediateThrowEvent>
信号中间抛出事件
抛出一个信号,然后交给传播引擎信号事件
空中间抛出事件事件图形

空中间抛出事件事件XML
<intermediateThrowEvent id="noneintermediatethrowevent1" name=" SignalThrowEvent ">
<signalEventDefinition signalRef="siqnal-001"></siqnalEventDefinition>
</intermediateThrowEvent>
2. 任务
任务是一个流程中最重要的组成部分,根据业务需求不同也分为很多类型
- 用户任务
- Java service任务
- 手动任务
- 脚本任务
- 业务规则任务
- 邮件任务
- 接收任务
- Web Service任务
- Mule任务
- Camel任务
- Shell任务
- 多实例任务-会签
2.1 用户任务
用户任务:需要人来参与,必须被人为触发(完成任务动作)。用户任务可以定义任务的名称(如领导审批)、优先级、到期日和任务处理人(人、组、或者是人和组的结合)
用户任务图形

用户任务XML
<userTask id="leaderAudit" name="领导审批"><!-- 定义“领导审批”任务 -->
<humanPerformer><!-- 指定分配人 -->
<resourceAssignmentExpression>
<formalExpression>henryyan</formalExpression><!-- 指定给用户henryyan处理 -->
</resourceAssignmentExpression>
</humanPerformer></userTask>
用户任务属性
| 属性名称 | 属性说明 | 示例 |
|---|---|---|
| activiti:assignee | 指定用户任务的处理人,代替了humanPerformer的功能 | <userTask id=“leaderAudit”" name=“领导审批” activiti:assignee=“henryyan”> |
| activiti:cadidateUsers | 指定用户任务的候选人,多个用逗号分开,代替了potentialOwner的功能 | <userTask id="leaderAudit"name=“领导审批” activiti:cadidateUsers=“henryyan” /> |
| activiti:cadidateGroups | 指定候选组,多个用逗号分开,代替了potentialOwner的功能 | <userTask id=“leaderAudit” name="领导审批 activiti:cadidateGroups=“leader,manager”/> |
| activiti:dueDate | 设置用户任务到期日,通常用变量代替,而不是具体日期 | <userTask id=“leaderAudit”. name=“领导审批"activiti:dueDate=”${overDate}"/> |
| activiti:priority | 用户任务优先级,取值区间[0,100] | <userTask id=“leaderAudit"name=“领导审批"activiti:priority=”${priority}”/> |
2.2 Java Service任务
声明:Java Service不属于BPMN2.0规范,Activiti拓展专门用于Java的serviceTask
作用:Java Service任务允许定义一个实现了指定接口的Java类,或者执行一个表达式,可以像脚本任务一样把结果保存到一个变量中
应用场景
- 发短信
- 发邮件
- 调用其它接口
JavaService任务图形

JavaService任务XML
<serviceTask id="myserviceTask"
name="Learn Java Service Task"activiti:class="me. kafeitu.activiti. JavaServiceDeleqate" >
</seryiceTask>
JavaService任务拓展属性
| 属性名称 | 属性说明 | 示例 |
|---|---|---|
| activiti:class | 实现了接口JavaDelegate 或 Activity-Behavior的Java类 | <serviceTask id="serviceTask1"Pactiviti:class="me.kafeitu.activiti.JavaServiceDelegate "/> |
| activiti:expression | 可使用UEL定义需要执行的任务内容,计算公式、调用Bean的方法,执行时可使用流程变量作为参数。Bean实例除了可以使用new创建外,还可以使用Spring代理 | < serviceTask id=" serviceTask1"activiti:expression="#{leaveService.back);"其中leaveService作为一个流程变量存在,和activiti:class一样需要实现JavaDelegate接口或ActivityBehavior接口,另外还实现了java.io.Serializable接口以便引擎可以序列化变量 |
| activiti:delegateExpression | 功能和activiti:class类似, 而且同样需要实现JavaDelegate或ActivityBehavior中一个接口, 只不过这里不是指定一个具体的实现类,而是在运行时动态设置。和activiti:expression似, Bean可以使用new创建也可以用spring代理 | < serviceTask id=" serviceTask1"activiti:expression"S{leaveBackDelegate)"/>执行到此任务时引擎会从变量中查询名称为leaveBackDelegate的Bean对象,然后调用实现接口的方法 |
| activiti:resultVariable | 此属性仅适用于activiti:expressior类型的Java Service,可以把一个表达式的执行结果保存到activiti:resultVariable指定的变量名称中 | <serviceTask id= " serviceTask1" activiti:expression="# {leaveService.backO)} "activiti:result Variable=“backDate”/>把leaveService.back()执行的结果保存到变量backDate中 |
2.3 手动任务
特殊任务:不做任何事情,进用来定义BPM不能完成的任务,需要人工参与建模,当到达此任务时由引擎自动完成并转向下一个任务
手动任务图形

手动任务XML
<manualTask id="manualTask" name="Manual task" />
2.4 脚本任务
脚本任务:可以运行引擎以来的语言之外的脚本语言,例如Groovy、Javascript、Juel
注意:脚本任务代码要符合JSR-223规范
任务图形

使用Groovy作为脚本引擎的脚本任务
<scriptrask id="initvars" name="初始化变量"scriptFormat="groovy">
<script>
<! [CDATA[def name = "HenryYan";execution. setVariable ('name', name);]]>
</script>
</scriptTask>
<scriptTask id="printvars" name="输出变量"scriptFormat="groovy">
<script>
<! [CDATA [out: println name;]]>
</script>
</scriptTask>
脚本任务拓展属性
| 属性名称 | 属性说明 | 示例 |
|---|---|---|
| scriptFormat | 用来指定符合JSR-223规范的脚本语言的类型 | <scriptTask id-="scripttask1"name="初始化变量"scriptFormat=“groovy”/> |
| activiti:resultvariable | Activiti在原BPMN 2.0规范中的脚本任务基础上进行了扩展,可以把脚本处理的结果保存到一个变量中 | <scriptTask id=“scripttask1” name="初始化变量"scriptFormat=“juel” activiti:resultVariable=“name”/注意activiti:resultVariable指定的变量名称需要在脚本中预先定义才能使用 |
2.5 业务规则任务
业务规则任务:企业应用中使用可维护的规则库管理复杂多变的业务规则,可以把业务逻辑和规则分开维护,一旦有变动,只需要更改预设规则。目前支持比较流行的JBoss规则引擎-Drools
作用:根据流程变量的值处理预设的业务规则
规则引擎:把业务数据交给规则引擎,规则引擎根据不同业务规则(各种条件的判断)计算出最终结果,最后把结果返回给调用者
业务规则任务图形

用户任务XML
<businessRuleTask id="businessruletask1"
name="Business rule task"
activiti:rules="rulel, rule2"
activiti:ruleVariablesInput="${message)"
activiti:exclude=" false"
activiti:resultVariableName="rulesOutput">
</businessRuleTask>
任务规则任务的拓展属性
| 属性名称 | 属性说明 | 示例 |
|---|---|---|
| activiti:rules | 在规则文件.drl中定义的规则名称,多个规则用逗号分隔。要执行规则文件中的全部规则,将该属性设置为空即可 | <businessRuleTaskid="businessruletask1"activiti:rules=“rule1, rule2” /> |
| activiti:ruleVariablesInput | 业务规则执行需要的数据源,使用sfooVar}方式定义,多个规则用逗号分隔 | <businessRuleTask id-“businessruletask1"activiti:rule VariablesInput-”${message}“/> |
| activiti:resultVariableName | 规则执行结果变量,变量的值为rule VariablesInput定义的变量集合(ArrayList) | <businessRuleTaskid="businessruletask1"activiti: resultVariableName =“rulesOutputVaraibleList”/> |
| activiti:execlude | 用来设置是否排除某些规则(rule),如果值为false,不排除按照activiti:rules规则执行;如果设置为true,则忽略activitirules指定的规则。如果设置为false的同时activiti:rules值为空,则不执行任何规则 | <businessRuleTaskid="businessruletask1"activiti:rules="rule2"activiti: execlude =“true”/>此例中忽略规则rule2,仅执行规则rule1 |
2.6 邮件任务
邮件任务:不属于BPMN2.0规范,和Java Service任务类似,由Activiti拓展专门处理邮件任务
作用:通过activiti发送邮件,邮件信息通过变量方式传递。
邮件任务图形

邮件任务XML
在serviceTask基础上添加拓展属性 activiti:type="mail"实现的
<servicerask id="mailtask1" name="Mail Task" activiti:type="mail">
<extensionElements>
<activiti:field name="to" expression="henryyan@qmail.com"></activiti:field>
<activiti:field name="from" expression="yanhonglei@gmail.com"></activiti:field>
<activiti:field name="subject" expression="hello henryyan"></activiti:field>
<activiti:field name="charset" expression="UTF-8"></activiti:field>
<activiti:field name="html">
<activiti:expression><! [CDATA[你好,我是$(userName), ]]></activiti:expression>
</activiti:field>
</extensionElements>
</seryiserask>
邮件任务的属性说明
| 属性名称 | 属性说明 | 示例 |
|---|---|---|
| to | 必填,收件人,多收件人用逗号分隔 | <activiti:field name=“to” expression="$ {to}"/> |
| from | 邮件发件人地址。不设置,使用引擎的mailServerFrom属性指定发件人 | <activiti:fieldname=“from” expression="${from)"/> |
| subject | 发件人email,不设置默认为activiti@aactiviti.org | activiti:fieldname=“subject"expression=”${subject}"/ |
| cc | 抄送人列表 | <activiti:fieldname=“cc” expression="${cc}"/> |
| bcc | 密送人列表 | <activiti:field name="cc"expression=“S {cc}”/> |
| charset | 邮件内容字符集,建议使用 UTF-8,防止中文乱码 | <activiti:fieldname=“charset” expression="${charset}"/> |
| text | 纯文本格式的邮件内容 | activiti:fieldname=“text"expression=”${email}"/ |
| html | html格式的邮件内容 | <activiti:field name=“html”>activiti:expression<
用户任务XML
<receiveTask id="receiveTask" name="Receive task"/>
2.8 Web service任务
Web Service任务:通过Web Service任务可以调用外部的Web Service资源,完成调用只需要一些必须的配置就可以,并且支持标准的Web Service 和REST风格的Service
Web Service任务图形

用户任务XML
<serviceTask id="webServiceTask" implementation="##WebService">
<ioSpecification>
<dataInput itemSubjectRef="tns:prettyPrintCountRequestItem"
id="dataInputofServiceTask"/>
<dataOutput itemSubiectRef="tns:prettyPrintCountResponsertem"
id="dataoutputofServiceTask"/>
<inputset>
<dataInputRefs>dataInputofServiceTask</dataInputRefs>
</inputSet>
<outputSet>
<dataOutputRefs>
dataoutputofServiceTask
</dataOutputRefs>
</outputset>
</ioSpecification>
<dataInputAssociation>
<sourceRef>PrefixVariable</sourceRef>
<tarqetRef>prefix</targetRef>
</dataInputAssociation>
<dataInputAssociation>
<sourceRef>SuffixVariable</sourceRef>
<targetRef>suffix</tarqetRef>
</dataInputAssociation>
<dataOutputAssociation>
<sourceRef>prettyPrint</sourceRef>
<targetRef>OutputVariable</targetRef>
</dataoutputAssociation>
</serviceTask>
2.9 Camel任务
Camel任务:由Java编写,不包含在BPMN2.0中
Camel任务图形

用户任务XML
<serviceTask id= "camelTask1" name="Camel Task" activiti:delegateExpression="$(camel)" />
2.10 Mule任务
Mule任务:不是BPMN2.0规范的一部分,是由MuleSoft开发的ESB产品,和Camle功能类似,但是由不同标准实现
Mule任务图形

用户任务XML
<sendTask id="muleTask" activiti:type="mule">
<extensionElements>
<activiti:fieldname="endpointUrl">
<activiti:string>vm://in</activiti:string>
</activiti:field>
<activiti :fieldname="language">
<activiti:string>juel</activiti:string>
</activiti:field>
<activiti:fieldname="payloadExpression">
<activiti:string>"hi"</activiti:strinq>
</activiti:field>
<activiti:fieldname="resultVariable">
<activiti:string>resultVar</activiti:string>
</activiti:field>
</extensionElements>
</sendTask>
2.11 Shell任务
Shell任务:允许在流程运行过程中执行本地操作系统中的脚本、命令,是Activiti基于serviceTask拓展的一种任务,BPMN2.0中没有对应图形
Shell任务图形

用户任务XML
<serviceTask id="shellEcho" activiti:type="shel1">
<extensionElements><activiti:field name="command" strinqValue="echo" />
<activiti:field name="arq1" stringValue="hello" />
<activiti:field name="wait" stringValue="true" />
<activiti:field name="outputVariable" stringValue="resultVar" />
</extensionElements>
</serviceTask>
Shell任务的参数和邮件任务类似
| 属性名称 | 是否必选 | 属性类型 | 属性说明 | 默认值 |
|---|---|---|---|---|
| command | 是 | String | 执行的脚本、命令 | |
| arg-0-5 | 否 | String | 参数,限制6个,从0-5;在执行时用空格分隔多个参数 | |
| wait | 否 | true/false | 是否等待脚本执行完成 | true |
| redirectError | 否 | true/false | 合并错误输出至标准输出 | false |
| cleanEnv | 否 | String | 是否继承当前的环境变量 | false |
| outputVariable | 否 | String | 脚本、命令执行结果保存变量 | 空,不记录 |
| errorCodeVariable | 否 | String | 脚本、命令执行失败后反馈的错误编码保存变量 | 空,为错误绑定 |
| directory | 否 | String | 在那个目录执行脚本、命令 | 当前项目目录 |
2.12 多实例任务
多实例任务:允许流程中某一个任务神之子流程可以重复多次,在实际的应用中一个申请由多人审批是多实例典型的应用场景。多实例可以选择顺序执行,也可以选择并行执行
应用场景:会签
多实例支持的任务类型:
- 用户任务
- Java service任务
- 手动任务
- 脚本任务
- 业务规则任务
- 邮件任务
- 接收任务
- Web Service任务
- 子流程(嵌入式)
- 子流程(调用活动)
多实例(顺序执行)

多实例(并行执行)

多实例XML
<userTask id="audit" name="领导审批">
<multiInstanceLoopCharacteristics isSequential="true">
<loopCardinality>3</loopCardinality>
</multiInstanceLoopCharacteristics>
</userTask>
多实例的配置元素及属性
| 属性名称 | 属性说明 | 示例 |
|---|---|---|
| loopCardinality | 实例的数量。可以用常量设置,也可以使用表达式计算设置 | 略 |
| loopDatalnputRef | 任务参与人列表。以参与人集合的数量决定创建多少个实例。和loopCardinality是互斥的关系 | 略 |
| inputDatalten | 需要配合loopDatalnputRef使用,用来指定在loop-DatalnputRef中定义的办理人集合在循环过程中单个变量的名称,例如指定userTask的activiti:assignee属性表示用户任务的办理人由变量assignee的值决定 | 略 |
| completionCCondition | 多实例循环结束条件。当满足一定条件时退出多实例循环。例如在投票表决场景中当通过率达到70%时结束任务,剩余未办理的任务不再执行 | 略 |
| isSequential | 是否按照顺序创建任务。值为true时表示按照顺序执行,只有在第一个任务处理完成之后才会继续创建第二个任务,以此类推;值为false时表示不按照顺序执行,而是一次创建多个任务(数量由其他的条件决定),这样多个任务可以同时办理,也就是并行处理 | 略 |
| activiti:collection | 用来简化BPMN 2.0规范中的loopDatalnputRef元素 | 略 |
| activiti:elementVariabler | 用来简化BPMN 2.0规范的inputDataltem元素 | 略 |
多实例的属性变量
| 属性名称 | 属性说明 |
|---|---|
| nrOfInstances | 实例的总数 |
| nrOfActivitiInstances | 当前活动的(未完成的)实例数量。对于按照顺序执行的多实例,该值总为1 |
| nrOfCompletedInstances | 已经完成的实例数量 |
| loopCounter | 多实例运行过程中,for-each循环中当前的索引值 |
3. 网关
网关的作用:控制流程的走向,根据功能不同可分为四种
- 排他网关
- 并行网关
- 包容网关
- 事件网关
3.1 排他网关
排他网关:对流程的决定进行建模,多个路线为true,只会执行第一个值为true的网关,所有网关没true,抛出异常,配合条件顺序流使用
排他网关图形

排他网关的XML
<exclusiveGateway id="exclusiveGateway" default="flow1"/>
3.2 并行网关
一般成对出现,分为拆分和合并,对并发任务进行建模,保证有始有终即可,所有路线都执行完成才会继续向下执行
- 拆分:并行执行所有输出顺序流,为每一条顺序流创建一个并行执行线路。
- 合并:所有从并行网关拆分并执行完成的线路均在此等候,直到所有的线路都执行完成才继续向下执行。
并行网关图形

并行网关的XML
<parallelGateway id="fork" name="Parallel Gateway Fork">
</parallelGateway>
3.3 包容网关
包容网关:融合排他网关和并行网关的特性,排他允许在每条线路上设置条件,并行网关可以同时执行多条线路。包容既可以多条同时,又可以设置条件
包容网关图形

包容网关XML
<inclusiveGateway id="inclusivegateway1" name="Inclusive Gateway Fork">
</inclusiveGateway>
3.4 事件网关
事件网关:为捕获中间事件设计的
注意:
- 事件网关的输出流量必须大于2个
- 事件网关的输出流类型只能是中间捕获事件,Activiti不支持接受任务后面的事件网关
中间捕获事件的输出流只能有1个
事件网关图形

事件网关XML
<eventBasedGateway id="eventgateway1" name="Event Gateway">
</eventBasedGateway>
5. 顺序流
顺序流:两个模型之间的连接者
- 标准顺序流
- 条件顺序流
5.1 标准顺序流
标准顺序流的图形

标准顺序流的XML
<sequenceFlow id="flow" sourceRef="startEvent" targetRef-"userTask">
</semienceFl ow>
5.2 条件顺序流
条件顺序流:在标准顺序流的基础上添加了条件表达式(UEL表达式)
条件顺序流

条件顺序流的XML
<sequenceFlow id="flow5" name="" sourceRef="startevent2" targetRef="usertask1">
<conditionExpression xsi:type="tFormalExpression">
<! [CDATA [${pass == true)]]>
</conditionExpression>
</sequenceFlow>
6. 子流程与调用活动
在实际企业应用中,业务流程往往比较复杂,仔细分析之后一般可以将其划分为多个不同的阶段,可以将这些阶段规划为一个子流程作为主流程的一部分
6.1 子流程
子流程限制:
- 有且只有一个空启动事件
- 至少有一个结束事件
- 子流程中顺序流不能直接输出流到子流程之外的活动上,有需要可以通过边界事件替代
子流程的图形

子流程的XML
<subProcess id="subprocess1" name="付款子流程">
...
</subProcess>
6.2 调用活动
调用活动:解决流程通用性,和子流程作用一致,表现方式不同
调用活动的图形

调用活动的XML
<callActivity id="callactivity1" name="Call Activity" calledElement="payment">
</callActivity>
调用活动的拓展属性
| 属性名称 | 属性说明 | 示例 |
|---|---|---|
| calledElement | 流程的ID,对应的流程应独立存在 | <callActivity id="callactivityl"name="调用付款流程"calledElement=“payment”> |
| activiti:in | 用外部流程时传入的变量,被调用活动需要获取主流程的信息(必须显示定义,否则不能获取)。 | <activiti:in source="amount"target-“amount”></activiti:in> -source :主流程中的变量名称,也可以在使用表,单时计算 -target:在将变量传递给调用活动时使用的名称,一般和sourse同名避免错误的出现 |
| activiti:out | 调用活动执行完成后的结果 | <activiti:in source="amount"target=“amount”></activiti:in>,口 source :主流程中的变量名称,也可以在使用表,单时计算O target:在将变量传递给调用活动时使用的名称,一般和source同名避免错误的出现 |
子流程和调用活动的区别
| 区别 | 子流程 | 调用活动 |
|---|---|---|
| 表现形式 | 直接嵌入在主流程中,使用subProcess定义子流程 | 作为一个普通的模型,定义外部流程的ID |
| 模型约束 | 启动事件只能使用空启动事件 | 无任何限制,被调用的外部流程本身就是一个完整的流程 |
| 流程变量 | 子流程共享主流程的所有变量 | 需要指定输入、输出变量 |
6.3 事件子流程
事件子流程:和子流程类似,把一系列的活动归结到一起处理,不同点在于事件子流程不能直接启动,要被动由其他的事件触发启动
事件子流程的图形:虚线

事件子流程的XML
<subProcess id="eventsubprocess1" name="完善账号信息" triggeredByEvent="true">
</subprocess>
6.4 事务子流程
事务子流程:也称作事务块,用来处理一组必须在同一个事务中完成的活动,这些事务要么一起成功,要么一起失败。事务子流程具有ACID(数据库的四个特性)特性,如果其中有一个活动失败或者取消,整个事务子流程的所有活动回滚
事务子流程的图形

事件子流程的XML
<transaction id="myTransaction" >
...
</transaction>
7. 监听器
监听器:监听各种动作,例如流程启动、结束、任务创建、任务完成等
监听器分类
- 执行监听器
- 任务监听器
7.1 执行监听器
执行监听器:允许在执行流程过程中执行Java代码(实现了监听器接口)或表达式,可以拿到流程实例的相关数据,需要实现ExecutionListener
可以捕获的事件:
- 流程实例启动、结束
- 输出流捕获
- 活动启动、结束
- 路由开始、结束
- 中间事件开始、结束
- 触发事件开始、触发事件结束
应用:
- 存储读取变量
- 处理业务信息
7.2 任务监听器
任务监听器:任务监听器:可以拿到任务的相关数据,实现TaskListener接口
- 提醒:任务来了,给客户发一条短信/邮件/微信公众号
- 指定执行人:动态赋值下一环节执行人
适用范围比执行监听器小,只能应用于用户任务,用来监听三种事件
任务监听器只能监听三种事件
- create:在任务被创建且所有的人物属性设置完成之后才能触发
- assignment:在任务被分配给某个办理人之后触发。有一点需要注意, 事件总是在create事件触发之前被触发,因为任务的办理人是一个属性,而create事件需要逐一处理任务的办理人、候选人、候选组属性
- complete:在配置了监听器的上一个任务完成时触发,也就是在运行时任务数据被删除之前( Activiti的数据分为运行时和历史两种类别,当运行时数据处理完毕后将会被清理)触发。
| 监听器执行类型 | 属性说明及示例 |
|---|---|
| class | 需要实现接口: org.activiti.engine.delegate. TaskListener |
| expression | 定义一个表达式,类似EL的语法。<activiti:taskListenerexpression=“S {pojo.method(execution.eventName)}” event="end"这里的pojo是一个Bean的名称(可以用spring代理),还可以在expression中通过i算一个表达式配置监听器的名称 |
| delegateExpression | class属性必须显示指定一个class的全路径,如me.kafeitu.TaskListenerOnXxxEvent。在有些情况下需要根据业务的不同动态指定一个接口实现, delegateExpression允许指定一个实现了监听接口(参考class属性的限制)类的name,具体的类可以在引擎中配置或由spring代理。<activiti:taskListener event=“start” delegateExpression=“S (taskListenerBean,”/>其中$( taskListenerBean!为一个Bean 对象的名称 |
8. 泳池与泳道
作用:清晰展示不同角色、岗位人员的职能
请假流程举例:请假流程涉及角色:员工、部门领导、人事
泳池:请假流程
泳道:员工、部门领导、人事
