阅读更多
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)
timeDate
timeDuration
timeCycle
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 event
timer 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"> |
以下名称是保留字符,不可用于变量名
out
out:print
lang:import
context
elcontext
参考
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.sql
org.flowable:flowable-idm-engine:xxx
中的org/flowable/idm/db/create/flowable.mysql.create.identity.sql
org.flowable:flowable-identitylink-service:xxx
中的org/flowable/identitylink/service/db/create/flowable.mysql.create.identitylink.sql
org.flowable:flowable-identitylink-service:xxx
中的org/flowable/identitylink/service/db/create/flowable.mysql.create.identitylink.history.sql
org.flowable:flowable-variable-service:xxx
中的org/flowable/variable/service/db/create/flowable.mysql.create.variable.sql
org.flowable:flowable-variable-service:xxx
中的org/flowable/variable/service/db/create/flowable.mysql.create.variable.history.sql
org.flowable:flowable-job-service:xxx
中的org/flowable/job/service/db/create/flowable.mysql.create.job.sql
org.flowable:flowable-task-service:xxx
中的org/flowable/task/service/db/create/flowable.mysql.create.task.sql
org.flowable:flowable-task-service:xxx
中的org/flowable/task/service/db/create/flowable.mysql.create.task.history.sql
org.flowable:flowable-engine:xxx
中的org/flowable/db/create/flowable.mysql.create.engine.sql
org.flowable:flowable-engine:xxx
中的org/flowable/db/create/flowable.mysql.create.history.sql
- 共计34张表
参考