Activiti流程引擎原理
2021-09-26 12:58:05 4 举报
AI智能生成
Activiti流程引擎原理
作者其他创作
大纲/内容
工作流
什么工作流
工作流(Workflow),就是通过计算机对业务流程自动化执行管理。它主要解决的是“使在多个参与者 之间按照某种预定义的规则自动进行传递文档、信息或任务的过程,从而实现某个预期的业务目标, 或者促使此目标的实现”。
工作流实现原理
原始工作流
在小场景或久远之前为了实现工作流程控制,常的做法就是采用状态字段的值来
跟踪流程的变化情况。
跟踪流程的变化情况。
但是当我们的流程发生变更的时候, 这种方式所编写的代码也要进行调整。
存在的问题
如何可以做到我们在业务流程发生变更后,我们的业务系统代码可以不发生改变?
Activiti流程引擎实现
以BPMN标准定义流程,将复杂业务流程抽取出来,用Activiti来管理这些业务流程变更和流转
减少业务系统由于流程变更进行系统升级改造的工作量,从而提高系统的 健壮性,同时也减少了系统开发维护成本。
Activiti数据库介绍
表命名规则
一共生成25张表,都以act_开头,第二部分是表示表的用途的两个字母缩写标识,用途也和服务的API对应
act_hi_*
'hi’表示 history,此前缀的表包含历史数据,如历史(结束)流程实例,变量,任务等等
act_ge_*
'ge’表示 general,此前缀的表为通用数据,用于不同场景中
act_evt_*
'evt’表示 event,此前缀的表为事件日志。
act_procdef_*
'procdef’表示 processdefine,此前缀的表为记录流程定义信息
act_re_*
're’表示 repository,此前缀的表包含了流程定义和流程静态资源(图片,规则等等)
act_ru_*
'ru’表示 runtime,此前缀的表是记录运行时的数据,包含流程实例,任务,变量,异步任务等运行中的数据。Activiti只在流程实例执行过程中保存这些数据,在流程结束时就会删除这些记录
表功能
通用数据(act_ge_)
act_ge_bytearray
二进制数据表,存储通用的流程定义和流程资源。
act_ge_property
系统相关属性,属性数据表存储整个流程引擎级别的数据,初始化表结构时,会默认插入三条记录
流程定义表(act_re_)
act_re_deployment
部署信息表
act_re_model
流程设计模型部署表
act_re_procdef
流程定义数据表
运行实例表(act_ru_)
act_ru_deadletter_job
作业死亡信息表,作业失败超过重试次数
act_ru_event_subscr
运行时事件表
act_ru_execution
运行时流程执行实例表
act_ru_identitylink
运行时用户信息表
act_ru_integration
运行时积分表
act_ru_job
运行时作业信息表
act_ru_suspended_job
运行时作业暂停表
act_ru_task
运行时任务信息表
act_ru_timer_job
运行时定时器作业表
act_ru_variable
运行时变量信息表
历史流程表(act_hi_)
act_hi_actinst
历史节点表
act_hi_attachment
历史附件表
act_hi_comment
历史意见表
act_hi_detail
历史详情表,提供历史变量的查询
act_hi_procinst
历史流程实例表
act_hi_taskinst
历史任务实例表
act_hi_varinst
历史变量表
其他表
act_evt_log
流程引擎的通用事件日志记录表
act_procdef_info
流程定义的动态变更信息
表详细结构信息:https://blog.csdn.net/laozhaishaozuo/article/details/84651795
https://www.verydocs.com/activiti-table-summary.html
https://www.verydocs.com/activiti-table-summary.html
BPMN文件解析
元素
流程(Process)
流程定义根元素,代表了一个流程定义的开始
属性
id
流程唯一id,启动流程时需要
isExecutable
流程是否可执行
name
流程名称
type
流程类型
isClosed
流程是否已关闭,关闭不能执行
事件(Event)
开始事件
StartEvent
流程启动事件,一个process只能有一个,且必须为流程起始元素
属性
id
启动节点id
name
启动节点名称
avtiviti:formKey
Activiti扩展的formKey属性,可以用来指定启动事件关联的表单文件
activiti:initiator
activiti扩展的initiator事件,可以用来记录启动流程人的ID,启动流程之后此属性指定的变量就会自动设置当前人的名称
结束事件
EndEvent
流程结束事件,一个process只能有一个,且必须为流程结束元素
属性同开始事件
任务(Task)
用户任务
UserTask
流程中间用户任务
属性
id
任务id,使用id操作任务
name
任务名称
activiti:assignee
任务所属用户,只能指定用户完成这个任务,即任务办理人
activiti:candidateUsers
多个任务办理人
activiti:candidateGroups
任务处理人候选组,处理人必须在这个组内
activiti:exclusive
独家的,好像是在排它性网关中使用,意思应该是在有并行分支情况下,只会走其中一条
activiti:dueDate
设置任务的到期日,通常用变量代替而不是设定一个具体的日期
activiti:priority
设定任务的优先级,取值区间[0,100]
formKey
任务节点关联的form表单
owner
任务所有者
activiti:taskListener
扩展元素之一,用于监听某个任务的运行
event
监听的任务事件名,create、assignment(分配任务)、complete
class
任务监听器类,需要实现TaskListener
服务任务
ServiceTask
JavaService 任务允许指定一个实现了指定接口的java类,或者执行一个表达式,可以把一个结果保存到一个变量中
属性
activiti:class
实现了接口JavaDelegate的Java类
activit:expression
一个表达式
activiti:delegateExpression
实现了指定接口的表达式
activiti:resultvariable
把脚本处理的结果保存到一个变量中
业务规则任务
BusinessRuleTask
业务规则任务可以根据流程变量的值预设的业务规则,就是把业务数据交由规则引擎处理,规则引擎根据不同的业务规则得到最终的结果在返回给调用者
属性
activiti:relues
定义规则的名称,多个用逗号隔开
activit:ruleVariablesInput
业务规则需要的 数据源使用${fooVar方式定义,多个用逗号隔开}
activit:ruleVariablesName
规则执行结果变量,变量的值为ruleVariablesInput定义的变量集合
activiti:execlude
用来设置是否排除某些规则
邮件任务
MailTask
邮件任务可以通过Activiti发送邮件,其中邮件的信息通过变量的方式传递
手工任务
ManualTask
脚本任务
ScriptTask
可以使用groovy脚本执行
属性
scriptFormat
用来指定符合规范的脚本类型
activiti:resultvariable
把脚本处理的结果保存到一个变量中
activiti:priority
设定任务的优先级,取值区间[0,100]
网关(Gateway)
并行网关
ParallelGateway
并行网关允许将流程分成多条分支,也可以把多条分支汇聚到一起,并行网关的功能是基于进 入和外出顺序流的
fork分支并行
并行后的所有外出顺序流,为每个顺序流都创建一个并发分支
join汇聚
所有到达并行网关,在此等待的进入分支, 直到所有进入顺序流的分支都到达以后, 流程就会通 过汇聚网关
并行网关不会解析条件。 即使顺序流中定义了条件,也会被忽略。
排他网关
ExclusiveGateway
排他网关(也叫异或(XOR)网关,或叫基于数据的排他网关),用来在流程中实现决策。
当流程 执行到这个网关,所有分支都会判断条件是否为 true,如果为 true 则执行该分支, 注意,排他网关只会选择一个为 true 的分支执行。(即使有两个分支条件都为 true,排他网关也会只 选择一条分支去执行)
若是不用排他网关时,如果条件都不满足,不使用排他网关,流程就结束了(是异常结束)
若是用排他网关,条件都不满足,则会抛出异常
包容网关
InclusiveGateway
包含网关可以看做是排他网关和并行网关的结合体
和排他网关一样,你可以在外出顺序流上 定义条件,包含网关会解析它们。 但是主要的区别是包含网关可以选择多于一条顺序流,这和并行 网关一样。
多个条件满足,走多条路
基于进入和外出顺序流的
分支
所有外出顺序流的条件都会被解析,结果为 true 的顺序流会以并行方式继续执行, 会为每个顺序流创建一个分支
汇聚
所有并行分支到达包含网关,会进入等待状态, 直到每个包含流程 token 的进入顺序流的分支都 到达。 这是与并行网关的最大不同。换句话说,包含网关只会等待被选中执行了的进入顺序流。 在 汇聚之后,流程会穿过包含网关继续执行。
链接对象
顺序流(连线)
SequenceFlow
标准顺序流(SequenceFlow)
属性
id
顺序流ID
sourceRef
连线的起始节点id,即接近startEvent的节点
targetRef
线结束节点id,即接近endEvent的节点
条件顺序流(conditionExpression)
属性
condition
UEL表达式,${days <= 3}
activiti 支持两个 UEL 表达式:UEL-value 和 UEL-method
子流程
把一切需要处理的任务归结到一起作为作为一个大流程的一部分,因为子流程嵌入在主流程中,所有也叫"嵌入式子流程"
嵌入子流程 subProcess
调用子流程 callActivity
限制
只能包含一个空启动事件
至少有一个结束事件
在子流程中不能把输出流设置到子流程之外的活动上
属性
activiti:in
调用外部流程时传入的变量,被调用活动需要获取主流的信息
activiti:out
调用活动完成后的结果
监听器(Listener)
执行监听器与任务监听器在生产中经常会用在几个方面
动态分配节点处理人。通过前一个节点设置的变量,在运行到下一个节点时设置对应的处理人
当流程运行到某个节点时,发送邮件或短信给待办用户
统计流程处理时长,是否超时等
业务层面数据处理
全局的监听器(ExecutionListener)
监听流程的所有节点和连线。主要有start、end、take事件。其中节点有start、end两种事件,而连线则有take事件。下图是执行监听器的生命周期
捕获的事件有
流程实例的开始和结束
连线过程
活动的开始和结束
网关的开始和结束
中间事件的开始和结束
结束开始事件或开始结束事件
节点的监听器(TaskListener)
会经历assignment、create、complete、all。当流程引擎触发这四种事件类型时,对应的任务监听器会捕获其事件类型,再按照监听器的处理逻辑进行处理
事件监听器(ActivitiEventListener)
ENGINE_CREATED
监听器监听的流程引擎已经创建完毕,并准备好接受API调用。
ENGINE_CLOSED
监听器监听的流程引擎已经关闭,不再接受API调用。
ENTITY_CREATED
创建了一个新实体。实体包含在事件中。
ENTITY_INITIALIZED
创建了一个新实体,初始化也完成了。如果这个实体的创建会包含子实体的创建,这个事件会在子实体都创建/初始化完成后被触发,这是与ENTITY_CREATED的区别。
ENTITY_UPDATED
更新了已存在的实体。实体包含在事件中。
ENTITY_DELETED
删除了已存在的实体。实体包含在事件中。
ENTITY_SUSPENDED
暂停了已存在的实体。实体包含在事件中。会被ProcessDefinitions, ProcessInstances 和 Tasks抛出。
ENTITY_ACTIVATED
激活了已存在的实体,实体包含在事件中。会被ProcessDefinitions, ProcessInstances 和 Tasks抛出。
JOB_EXECUTION_SUCCESS
作业执行成功。job包含在事件中。
JOB_EXECUTION_FAILURE
作业执行失败。作业和异常信息包含在事件中。
JOB_RETRIES_DECREMENTED
因为作业执行失败,导致重试次数减少。作业包含在事件中。
TIMER_FIRED
触发了定时器。job包含在事件中。
JOB_CANCELED
取消了一个作业。事件包含取消的作业。作业可以通过API调用取消, 任务完成后对应的边界定时器也会取消,在新流程定义发布时也会取消。
ACTIVITY_STARTED
一个节点开始执行
ACTIVITY_COMPLETED
一个节点成功结束
ACTIVITY_SIGNALED
一个节点收到了一个信号
ACTIVITY_MESSAGE_RECEIVED
一个节点收到了一个消息。在节点收到消息之前触发。收到后,会触发ACTIVITY_SIGNAL或ACTIVITY_STARTED,这会根据节点的类型(边界事件,事件子流程开始事件)
ACTIVITY_ERROR_RECEIVED
一个节点收到了一个错误事件。在节点实际处理错误之前触发。 事件的activityId对应着处理错误的节点。 这个事件后续会是ACTIVITY_SIGNALLED或ACTIVITY_COMPLETE, 如果错误发送成功的话。
UNCAUGHT_BPMN_ERROR
抛出了未捕获的BPMN错误。流程没有提供针对这个错误的处理器。 事件的activityId为空。
ACTIVITY_COMPENSATE
一个节点将要被补偿。事件包含了将要执行补偿的节点id。
VARIABLE_CREATED
创建了一个变量。事件包含变量名,变量值和对应的分支或任务(如果存在)。
VARIABLE_UPDATED
更新了一个变量。事件包含变量名,变量值和对应的分支或任务(如果存在)。
VARIABLE_DELETED
删除了一个变量。事件包含变量名,变量值和对应的分支或任务(如果存在)。
TASK_ASSIGNED
任务被分配给了一个人员。事件包含任务。
TASK_CREATED
创建了新任务。它位于ENTITY_CREATE事件之后。当任务是由流程创建时, 这个事件会在TaskListener执行之前被执行。
TASK_COMPLETED
任务被完成了。它会在ENTITY_DELETE事件之前触发。当任务是流程一部分时,事件会在流程继续运行之前, 后续事件将是ACTIVITY_COMPLETE,对应着完成任务的节点。
TASK_TIMEOUT
任务已超时,在TIMER_FIRED事件之后,会触发用户任务的超时事件, 当这个任务分配了一个定时器的时候。
PROCESS_COMPLETED
流程已结束。在最后一个节点的ACTIVITY_COMPLETED事件之后触发。 当流程到达的状态,没有任何后续连线时, 流程就会结束。
MEMBERSHIP_CREATED
用户被添加到一个组里。事件包含了用户和组的id。
MEMBERSHIP_DELETED
用户被从一个组中删除。事件包含了用户和组的id。
MEMBERSHIPS_DELETED
所有成员被从一个组中删除。在成员删除之前触发这个事件,所以他们都是可以访问的。 因为性能方面的考虑,不会为每个成员触发单独的MEMBERSHIP_DELETED事件。
监听器监听的流程引擎已经创建完毕,并准备好接受API调用。
ENGINE_CLOSED
监听器监听的流程引擎已经关闭,不再接受API调用。
ENTITY_CREATED
创建了一个新实体。实体包含在事件中。
ENTITY_INITIALIZED
创建了一个新实体,初始化也完成了。如果这个实体的创建会包含子实体的创建,这个事件会在子实体都创建/初始化完成后被触发,这是与ENTITY_CREATED的区别。
ENTITY_UPDATED
更新了已存在的实体。实体包含在事件中。
ENTITY_DELETED
删除了已存在的实体。实体包含在事件中。
ENTITY_SUSPENDED
暂停了已存在的实体。实体包含在事件中。会被ProcessDefinitions, ProcessInstances 和 Tasks抛出。
ENTITY_ACTIVATED
激活了已存在的实体,实体包含在事件中。会被ProcessDefinitions, ProcessInstances 和 Tasks抛出。
JOB_EXECUTION_SUCCESS
作业执行成功。job包含在事件中。
JOB_EXECUTION_FAILURE
作业执行失败。作业和异常信息包含在事件中。
JOB_RETRIES_DECREMENTED
因为作业执行失败,导致重试次数减少。作业包含在事件中。
TIMER_FIRED
触发了定时器。job包含在事件中。
JOB_CANCELED
取消了一个作业。事件包含取消的作业。作业可以通过API调用取消, 任务完成后对应的边界定时器也会取消,在新流程定义发布时也会取消。
ACTIVITY_STARTED
一个节点开始执行
ACTIVITY_COMPLETED
一个节点成功结束
ACTIVITY_SIGNALED
一个节点收到了一个信号
ACTIVITY_MESSAGE_RECEIVED
一个节点收到了一个消息。在节点收到消息之前触发。收到后,会触发ACTIVITY_SIGNAL或ACTIVITY_STARTED,这会根据节点的类型(边界事件,事件子流程开始事件)
ACTIVITY_ERROR_RECEIVED
一个节点收到了一个错误事件。在节点实际处理错误之前触发。 事件的activityId对应着处理错误的节点。 这个事件后续会是ACTIVITY_SIGNALLED或ACTIVITY_COMPLETE, 如果错误发送成功的话。
UNCAUGHT_BPMN_ERROR
抛出了未捕获的BPMN错误。流程没有提供针对这个错误的处理器。 事件的activityId为空。
ACTIVITY_COMPENSATE
一个节点将要被补偿。事件包含了将要执行补偿的节点id。
VARIABLE_CREATED
创建了一个变量。事件包含变量名,变量值和对应的分支或任务(如果存在)。
VARIABLE_UPDATED
更新了一个变量。事件包含变量名,变量值和对应的分支或任务(如果存在)。
VARIABLE_DELETED
删除了一个变量。事件包含变量名,变量值和对应的分支或任务(如果存在)。
TASK_ASSIGNED
任务被分配给了一个人员。事件包含任务。
TASK_CREATED
创建了新任务。它位于ENTITY_CREATE事件之后。当任务是由流程创建时, 这个事件会在TaskListener执行之前被执行。
TASK_COMPLETED
任务被完成了。它会在ENTITY_DELETE事件之前触发。当任务是流程一部分时,事件会在流程继续运行之前, 后续事件将是ACTIVITY_COMPLETE,对应着完成任务的节点。
TASK_TIMEOUT
任务已超时,在TIMER_FIRED事件之后,会触发用户任务的超时事件, 当这个任务分配了一个定时器的时候。
PROCESS_COMPLETED
流程已结束。在最后一个节点的ACTIVITY_COMPLETED事件之后触发。 当流程到达的状态,没有任何后续连线时, 流程就会结束。
MEMBERSHIP_CREATED
用户被添加到一个组里。事件包含了用户和组的id。
MEMBERSHIP_DELETED
用户被从一个组中删除。事件包含了用户和组的id。
MEMBERSHIPS_DELETED
所有成员被从一个组中删除。在成员删除之前触发这个事件,所以他们都是可以访问的。 因为性能方面的考虑,不会为每个成员触发单独的MEMBERSHIP_DELETED事件。
解析架构设计
Activiti的解析工作,就是将配置文件中的元素转换为对应的Java类,在这两者中间就是转换器与解析器
首先对于每一个元素都有公共的属性,比如id、name等,对于这些公共属性,我们可以将其提取到公共的方法中进行解析
每个元素都有自己独特的属性,所以Activiti为每一个元素都定义了解析器或转换器,以便当每个元素增添属性时,只需要修改特定的解析器就可以实现
元素与转换
BpmnXMLConverter转换的入口
读取配置文件并进行循环解析,通过注册不同的转换器来转换不同的元素,而在转换器中通过自己解析或调用解析器解析元素,并最终构建BpmnModel对象
有些元素有公共的属性,拥有公共的扩展属性(ExtensionAttribute),这些使用同一个解析器循环处理
转换器
解析器
基本简单使用过程
集成Activiti
依赖
配置
流程定义
使用activiti流程建模工具定义业务流程(.bpmn文件)
部署流程定义
使用 activiti 提供的 api 向 activiti 中部署.bpmn 文件,解析.bpmn文件并持久化
启动流程实例
启动一个流程实例表示开始一次业务流程的运行,每一次请求都是一个流程实例
任务节点操作
查询
通过 activiti 就可以查询当前流程执行位置
处理
针对任务节点进行对应操作处理
流程结束
当任务办理完成没有下一个任务/结点了,这个流程实例就完成了
实现过程及原理
Bean创建
使用的是SpringBoot的Activiti的starter,不需要复杂的xml配置,一些基本的Service已经注册完成
抽象方法:AbstractProcessEngineAutoConfiguration
Service简概
RepositoryService
activiti 的资源管理类,提供了管理和控制流程发布包和流程定义的操作
RuntimeService
activiti 的流程运行管理类,可以从这个服务类中获取很多关于流程执行相关的信息
TaskService
activiti 的任务管理类,可以从这个类中获取任务的信息。
HistoryService
activiti 的历史管理类,可以查询历史信息,执行流程时,引擎会保存很多数据(根据配置),比 如流程实例启动时间,任务的参与者, 完成任务的时间,每个流程实例的执行路径,等等
ManagerService
activiti 的引擎管理类,提供了对 Activiti 流程引擎的管理和维护功能,这些功能不在工作流驱动 的应用程序中使用,主要用于 Activiti 系统的日常维护
部署流程定义
主要将.bpmn文件部署持久化
代码示例
主要原理
首先在ACT_RE_PROCDEF(流程定义表)中按key选择最新版本的流程定义
在ACT_RU_TIMER_JOB(运行时定时器表)中按类型和流程定义键 查找数据
删除部署流程
根据deploymentId删除流程定义
代码示例
启动流程实例
启动一个流程表示发起一个新的流程单,这就相当于 java 类与 java 对象的关系,类定义好后需要 new 创建一个对象使用,当然可以 new 多个对象
代码示例
查询任务
查询当前个人待执行的任务
代码示例
流程变更
0 条评论
下一页