阅读更多
1 Overview
概念
Process:文中称为流程、执行流instance:文中称为实例
Event:文中称为事件Flow:文中称为连线Gateway:文中称为网关Task:文中称为任务Activity:流程中的一个实体都可以成为Activity,包括Event、Gateway、Task等等Variable:变量Expression:表达式,通常指UEL
2 Event
BPMN 2.0中,存在两种主要的event类型
Catching:当process执行到此类event时,它会等待某个trigger来触发Throwing:当process执行到此类event时,一个trigger被触发
参考
2.1 Event Definitions
Event Definitions定义了event的具体语义(semantics),如果一个event不包含Event Definitions,那么这个事件不执行任何操作
2.1.1 Timer Event Definitions
Description
顾名思义,
Timer events由一个事先定义好的timer来触发,可以用于start event、intermediate event、boundary event
我们可以定义多种不同的
timer,主要包括如下三种(关于timer的详细语法请参考ISO 8601)
timeDatetimeDurationtimeCycle
XML representation
1 | <!-- timeDate --> |
2.1.2 Error Event Definitions
Description
首先,声明一点:
BPMN error与Java exception是完全不同的,不能拿来类比。BPMN error仅用于描述业务异常
XML representation
1 | <endEvent id="myErrorEndEvent"> |
2.1.3 Signal Event Definitions
Description
Signal Event指向了一个signal。signal的作用域是全局的
XML representation
1 | <definitions... > |
2.1.4 Message Event Definitions
Description
Message Event指向了一个message,一个message拥有一个name以及payload。与signal不同,一个message只能有一个receiver
XML representation
1 | <definitions id="definitions" |
2.2 Start Events
Description
顾名思义,
start event就是一个process开始的节点,start event的类型定义着process的开始方式
start event永远是catching event,意思是说,start event一直处于wait状态,直到被触发(trigger)
XML representation
1 | <startEvent id="request" flowable:initiator="initiator" /> |
2.2.1 None Start Event
Description
从技术上来说,
none start event意味着trigger未指定,因此这种process只能手动启动
XML representation
1 | <startEvent id="start" name="my start event" /> |
1 | ProcessInstance processInstance = runtimeService.startProcessInstanceByXXX(); |
2.2.2 Timer Start Event
Description
顾名思义,
timer start event会在指定的时间启动process
XML representation
1 | <startEvent id="theStart"> |
注意事项
sub-process不允许含有timer start eventtimer start event在部署时就被scheduler(后台运行一个job,定时启动process)。因此不需要手动启动process(不需要而不是不能)- 当一个新版本部署时,旧版本的
timer(后台那个job)会被移除
2.2.3 Message Start Event
Description
message start event用于启动一个process,一个process definition允许存在多个message start event
- 在一个
process definition内,message start event的名字必须唯一,否则flowable engine在部署时会抛出异常- 不允许不同
process definition包含具有相同名字的message start event,否则否则flowable engine在部署时会抛出异常- 当部署新版本的
process definition时,之前的message订阅关系将会被移除
XML representation
1 | <definitions id="definitions" |
注意事项
message start event仅支持顶层process,即不支持sub-process- 如果
process definition包含多个message start event,那么runtimeService.startProcessInstanceByMessage(…)会选择适当的message来启动process - 如果
process definition包含多个message start event以及一个none start event,runtimeService.startProcessInstanceByKey(…)以及runtimeService.startProcessInstanceById(…)会使用none start event来启动process - 如果
process definition包含多个message start event但不包含none start event,runtimeService.startProcessInstanceByKey(…)以及runtimeService.startProcessInstanceById(…)会抛出异常 - 如果
process definition包含一个message start event,那么runtimeService.startProcessInstanceByKey(…)以及runtimeService.startProcessInstanceById(…)会使用message start event来启动process
2.2.4 Signal Start Event
Description
signal start event可用于使用命名信号启动process实例。可以使用intermediary signal throw event或通过API(runtimeService.signalEventReceivedXXX方法)从流程实例中触发信号。在这两种情况下,将启动具有相同名称的信号启动事件的所有流程定义
XML representation
1 | <signal id="theSignal" name="The Signal" /> |
2.2.5 Error Start Event
Description
error start event可用于触发sub-process。error start event不能用于启动process实例。error start event总是在中断
XML representation
1 | <startEvent id="messageStart" > |
2.3 End Events
end event表示process或sub-process的结束。end event一定是throwing event。这意味着当process执行到达end event时,将抛出result
2.3.1 None End Event
Description
none end event表示执行动作未定义。因此,除了结束当前的执行的process外,引擎不会做任何额外的事情
XML representation
1 | <endEvent id="end" name="my end event" /> |
2.3.2 Error End Event
Description
当
process执行到达error end event时,当前执行路径结束并抛出error。匹配的intermediate event或boundary event可以捕获此错误。如果未找到匹配的边界错误事件,则将引发异常
XML representation
1 | <endEvent id="myErrorEndEvent"> |
2.3.3 Terminate End Event
Description
到达
terminate end event时,将终止当前process实例或sub-process。从概念上讲,当执行到达terminate end event时,将确定并结束第一范围(process或sub-process)。请注意,在BPMN 2.0中,子流程可以是一个embedded sub-process,call activity,event sub-process或transaction sub-process。此规则通常适用:例如,当存在call activity或embedded sub-process时,仅该实例结束,其他实例和流程实例不受影响
XML representation
1 | <endEvent id="myEndEvent" > |
2.3.4 Cancel End Event
Description
cancel end event只能与BPMNtransaction sub-process结合使用。当到达cancel end event时,抛出cancel event,必须由cancel boundary event捕获。cancel boundary event随后取消事务并触发补偿
XML representation
1 | <endEvent id="myCancelEndEvent"> |
2.4 Boundary Events
boundary event捕获附加到activity的事件(boundary event一定是catching event)。这意味着当activity正在运行时,事件正在侦听某种类型的trigger。当事件被捕获时,activity被中断并且遵循事件的执行流
文档中说,boundary event不可以有多个output sequence,但实际上是可以的,自行验证一下
1 | <boundaryEvent id="myBoundaryEvent" attachedToRef="theActivity"> |
2.4.1 Timer Boundary Event
Description
timer boundary event充当秒表和闹钟。当执行到达附加timer boundary event的activity时,启动计时器。当计时器触发时(例如,在指定的间隔之后),activity被中断并且遵循timer boundary event之外的执行流
XML representation
1 | <boundaryEvent id="escalationTimer" cancelActivity="true" attachedToRef="firstLineSupport"> |
2.4.2 Error Boundary Event
Description
error boundary event捕获在定义它的activity范围内引发的error
XML representation
1 | <boundaryEvent id="catchError" attachedToRef="mySubProcess"> |
2.4.3 Signal Boundary Event
Description
signal boundary event用于捕获指定的signal
XML representation
1 | <boundaryEvent id="boundary" attachedToRef="task" cancelActivity="true"> |
2.4.4 Message Boundary Event
Description
message boundary event用于捕获指定的message
XML representation
1 | <boundaryEvent id="boundary" attachedToRef="task" cancelActivity="true"> |
2.4.5 Cancel Boundary Event
Description
cancel boundary event触发时,它首先中断当前作用域中的所有activity。接下来,它开始补偿事务范围内的所有有效compensation boundary event。补偿是同步进行的,换句话说,boundary event会等待补偿完成后离开事务
XML representation
1 | <boundaryEvent id="boundary" attachedToRef="transaction" > |
2.4.6 Compensation Boundary Event
Description
compensation boundary event作为activity的补偿处理过程
XML representation
1 | <boundaryEvent id="compensateBookHotelEvt" attachedToRef="bookHotel" > |
2.5 Intermediate Catching Events
1 | <intermediateCatchEvent id="myIntermediateCatchEvent" > |
2.5.1 Timer Intermediate Catching Event
Description
timer intermediate catching event充当秒表,当process到达timer intermediate catching event时,timer被触发,经过指定时间后,继续后续处理流程
XML representation
1 | <intermediateCatchEvent id="timer"> |
2.5.2 Signal Intermediate Catching Event
Description
signal intermediate catching event用于捕获指定的signal
XML representation
1 | <intermediateCatchEvent id="signal"> |
2.5.3 Message Intermediate Catching Event
Description
message intermediate catching event用于捕获指定的message
XML representation
1 | <intermediateCatchEvent id="message"> |
2.6 Intermediate Throwing Event
1 | <intermediateThrowEvent id="myIntermediateThrowEvent" > |
2.6.1 Intermediate Throwing None Event
Description
intermediate throwing none event通常用来表示process到达某种状态
XML representation
1 | <intermediateThrowEvent id="noneEvent"> |
2.6.2 Signal Intermediate Throwing Event
Description
signal intermediate throwing event抛出一个signal
XML representation
1 | <intermediateThrowEvent id="signal"> |
2.6.3 Compensation Intermediate Throwing Event
Description
compensation intermediate throwing event抛出compensation event来触发compensation
XML representation
1 | <intermediateThrowEvent id="throwCompensation"> |
3 Sequence Flow
sequence flow用于表示两个process元素的连接关系(路由关系,带有方向)。当process执行到某个节点时,所有通过sequence flow连接出去的路径都会被同时执行,也就是并发的两条/多条执行链路。这是BPMN 2.0的默认行为(相当于默认有一个parallel gateway)
1 | <sequenceFlow id="flow1" sourceRef="theStart" targetRef="theTask" /> |
参考
3.1 Conditional sequence flow
Description
顾名思义,
conditional sequence flow允许附带一个条件。条件为真时,继续执行当前路径的后续流程,否则终止当前路径
XML representation
1 | <!-- conditionExpression仅支持 UEL --> |
3.2 Default sequence flow
Description
default sequence flow当且仅当当前节点的其他sequence flow没有被触发时才会生效,起到一个默认路由的作用
XML representation
1 | <!-- The following XML snippet shows an example of an exclusive gateway that has as default sequence flow, flow 2. Only when conditionA and conditionB both evaluate to false, will it be chosen as the outgoing sequence flow for the gateway. --> |
4 Gateway
gateway用于控制process的执行流。抽象地来说,gateway能够使用或者消耗token
参考
4.1 Exclusive Gateway
Description
exclusive gateway又被称为XOR gateway,通常用于描述decision。当流程执行到exclusive gateway时,所有的sequence flow会按照定义的顺序进行条件判断(针对conditional sequence flow,sequence flow也可以看成一个条件永远为真的conditional sequence flow)。第一个为真的conditional sequence flow将会被选中并继续执行后续流程,其余sequence flow被忽略。全都为假时,将会抛出异常
XML representation
1 | <exclusiveGateway id="exclusiveGw" name="Exclusive Gateway" /> |
4.2 Parallel Gateway
Description
parallel gateway通常用于描述并发执行流,最直接最方便的引入并发特性的元素就是parallel gateway。parallel gateway可以起到fork的作用(从一条路径到多条路径),以及join的作用(从多条执行路径到一条执行路径),这取决于parallel gateway放置的位置
要注意的是,与parallel gateway相连的sequence flow若是conditional sequence flow,则条件的校验将会被直接忽略
XML representation
1 | <startEvent id="theStart" /> |
4.3 Inclusive Gateway
Description
inclusive gateway可以看成是exclusive gateway以及parallel gateway的结合体。与exclusive gateway类似,inclusive gateway会执行conditional sequence flow上的条件;与parallel gateway类似,inclusive gateway同样允许fork以及join
XML representation
1 | <startEvent id="theStart" /> |
5 Task
5.1 User Task
Description
user task用于描述人类需要完成的工作。当流程执行到此类任务时,将在分配给该任务的任何用户或组的任务列表中创建新任务
XML representation
1 | <!-- normal --> |
参考
5.2 Script Task
Description
script task是一个自动的activity,当一个process执行到script task时,相关联的script就会被执行
XML representation
1 | <scriptTask id="theScriptTask" name="Execute script" scriptFormat="groovy"> |
以下名称是保留字符,不可用于变量名
outout:printlang:importcontextelcontext
参考
5.3 Java Service Task
Description
java service task用于触发一个Java方法
XML representation
1 | <!-- normal --> |
Implementation
- 必须实现
org.flowable.engine.delegate.JavaDelegate的execute方法 - 所有
process的实例共享同一个JavaDelegate的实例,因此这个类的实现必须是线程安全的(最好无状态) - 当第一次被使用时,才会创建
JavaDelegate的实例
Field Injection
- 通常,会通过setter方法来为
delegated class注入属性值(超级无敌神坑:若写的是private的字段,而没有提供public的set方法,有时候注入会失败) - 字段类型必须是
org.flowable.engine.delegate.Expression
Using a Flowable service from within a JavaDelegate
RuntimeService runtimeService = Context.getProcessEngineConfiguration().getRuntimeService();- …
参考
5.4 Web Service Task
Description
web service task用于同步地触发一个外部的Web service
参考
5.5 Business Rule Task
Description
business rule task用于同步地执行一个或多个rule。Flowable使用Drools Rule Engine来执行具体的rule
参考
5.6 Email Task
Description
Flowable允许您使用向一个或多个收件人发送电子邮件的自动邮件服务任务来增强业务流程
XML representation
1 | <serviceTask id="sendMail" flowable:type="mail"> |
参考
5.7 Http Task
Description
http task允许发出HTTP请求,增强了Flowable的集成功能。请注意,http task不是BPMN 2.0规范的官方任务(因此没有专用图标)。因此,在Flowable中,http task被实现为专用服务任务
XML representation
1 | <serviceTask id="httpGet" flowable:type="http"> |
参考
5.8 Mule Task
Description
mule task允许您向Mule发送消息,增强Flowable的集成功能。请注意,Mule任务不是BPMN 2.0规范的官方任务(因此没有专用图标)。因此,在Flowable中,mule task任务被实现为专用服务任务
参考
5.9 Camel Task
Description
camel task允许您向Camel发送消息和从Camel接收消息,从而增强Flowable的集成功能。请注意,camel task不是BPMN 2.0规范的官方任务(因此没有专用图标)。因此,在Flowable中,Camel任务被实现为专用服务任务。另请注意,必须在项目中包含Flowable Camel模块才能使用Camel任务功能
参考
5.10 Manual Task
Description
manual task定义BPM引擎外部的任务。它用于模拟由某人完成的工作,引擎不需要知道,也没有系统或用户界面。对于引擎,手动任务作为传递活动处理,从流程执行到达时自动继续流程
XML representation
1 | <manualTask id="myManualTask" name="Call client for more information" /> |
参考
5.11 Java Receive Task
Description
java receuve task务是一个等待某个消息到达的简单任务。目前,我们只为此任务实现了Java语义。当process执行到达接收任务时,process状态将提交给持久性存储。这意味着process将保持此等待状态,直到引擎接收到特定消息,进而触发java receuve task,继续执行process
XML representation
1 | <receiveTask id="waitState" name="wait" /> |
参考
5.12 Shell Task
Description
shell task允许您运行shell脚本和命令。请注意,shell task不是BPMN 2.0规范的官方任务(因此没有专用图标)
XML representation
1 | <!-- cmd /c echo EchoTest --> |
参考
5.13 Execution listener
Description
execution listener允许您在流程执行期间发生某些事件时执行外部Java代码或计算表达式。可以捕获的事件是:
- 启动或停止
process- 进行转移,即
sequence flow- 启动或停止
activity- 启动或停止
gateway- 启动或停止
intermediate event- 结束
start event或启动end event
示例
1 | <process id="executionListenersProcess"> |
需要实现的接口:org.flowable.engine.delegate.ExecutionListener
参考
5.14 Task listener
Description
task listener用于在发生某个与任务相关的事件时执行自定义Java逻辑或表达式。task listener只能作为user task的子元素添加到流程定义中。请注意,这也必须作为BPMN 2.0的extensionElements子元素或flowable namespace,因为task listener是Flowable特定的构造
XML representation
1 | <userTask id="myTask" name="My Task" > |
event的类型(触发的时刻)
create:当Task被创建后,且所有属性设置完毕后assignment:当Task被分配给某人时。当执行流程到达UserTask时,assignment event会优先于create event触发complete:当Task被完成后,且被删除前delete:当Task即将被删除时
需要实现的接口:org.flowable.engine.delegate.TaskListener
参考
5.15 Multi-instance (for each)
Description
multi-instance用于重复执行业务流程中的某个步骤。在编程概念中,multi-instance同于for each语句:它允许您按顺序或并行地为给定集合中的每个元素执行某个步骤,甚至是完整的子流程
参考
5.16 Compensation Handlers
Description
如果某个
activity用于补偿另一个activity,则可以将其声明为compensation handler。compensation handler在正常流程中不存在,仅在抛出compensation event时执行
参考
6 Variables
在Flowable中,与process相关的这些数据被称为variables,这些数据存储在数据库中,这些变量可以在表达式中,或者Java Service Task中被使用
详细内容请参考Variables
7 Expression
Expression通常指UEL Expression,UEL的全称是Unified Expression Language
详细内容请参考Expression
7.1 Value Expression
1 | ${myVar} |
7.2 Method Expression
1 | ${printer.print()} |
7.3 default Object
execution:DelegateExecution的对象task:DelegateTask的对象authenticatedUserId:当前已通过身份验证的用户的id
8 Table
8.1 Database table names explained
所有Flowable的表名前缀都是ACT_
Flowable的表名的第二段表示了用途,与API对应
ACT_RE_*:RE表示repository,通常用于存储静态数据,比如process definitions、process resources等等ACT_RU_*:RU表示runtime,通常用于存储运行时数据,比如tasks、variables、jobs等等ACT_HI_*:HI表示history,通常保存历史数据,例如已经执行过的process instance、variables、tasks等等ACT_GE_*:GE表示general,通常表示全局通用数据及设置
参考
8.2 Creating the database tables
flowable的建表语句都在org.flowable:xxx中的org/flowable/db/create路径下
1 | flowable.{db}.{create|drop}.{type}.sql |
{db}:代表数据库类型{create|drop}:创建还是销毁{type}:类型,就两种history或engine
sql文件路径(按如下顺序依次执行,表之间是有依赖关系的,切记按顺序执行)
org.flowable:flowable-engine-common:xxx中的org/flowable/common/db/create/flowable.mysql.create.common.sqlorg.flowable:flowable-idm-engine:xxx中的org/flowable/idm/db/create/flowable.mysql.create.identity.sqlorg.flowable:flowable-identitylink-service:xxx中的org/flowable/identitylink/service/db/create/flowable.mysql.create.identitylink.sqlorg.flowable:flowable-identitylink-service:xxx中的org/flowable/identitylink/service/db/create/flowable.mysql.create.identitylink.history.sqlorg.flowable:flowable-variable-service:xxx中的org/flowable/variable/service/db/create/flowable.mysql.create.variable.sqlorg.flowable:flowable-variable-service:xxx中的org/flowable/variable/service/db/create/flowable.mysql.create.variable.history.sqlorg.flowable:flowable-job-service:xxx中的org/flowable/job/service/db/create/flowable.mysql.create.job.sqlorg.flowable:flowable-task-service:xxx中的org/flowable/task/service/db/create/flowable.mysql.create.task.sqlorg.flowable:flowable-task-service:xxx中的org/flowable/task/service/db/create/flowable.mysql.create.task.history.sqlorg.flowable:flowable-engine:xxx中的org/flowable/db/create/flowable.mysql.create.engine.sqlorg.flowable:flowable-engine:xxx中的org/flowable/db/create/flowable.mysql.create.history.sql
- 共计34张表
参考