activiti6学习

架构图&基本概念

activiti根据processDefinitionKey获取任务列表_数据

RepositoryService activiti 的资源管理类
RuntimeService activiti 的流程运行管理类
TaskService activiti 的任务管理类
HistoryService activiti 的历史管理类
ManagerService activiti 的引擎管理类

activiti之任务

在工作流Activiti的使用中,任务是不可或缺的元素,通过各种任务,来完成作业系统中各个环节的执行,任务分为用户任务、脚本任务、Java服务任务、邮件任务、手工任务、业务规则任务、调用活动(子流程)任务

用户任务

用户任务用来设置必须由人员完成的工作。 当流程执行到用户任务,会创建一个新任务, 并把这个新任务加入到分配人或群组的任务列表中。

服务任务

Java服务任务用来调用外部java类。

脚本任务

脚本任务是一个自动节点,当流程到达脚本任务, 会执行对应的脚本。

接收任务

业务规则用户用来同步执行一个或多个规则。activiti使用drools规则引擎执行业务规则。 目前,包含业务规则的.drl文件必须和流程定义一起发布,流程定义里包含了执行这些规则的业务规则任务。 意味着流程使用的所有.drl文件都必须打包在流程BAR文件里,比如任务表单。

手动任务

手动任务定义了BPM引擎外部的任务。 用来表示工作需要某人完成,而引擎不需要知道,也没有对应的系统和UI接口。 对于引擎,手工任务是直接通过的活动, 流程到达它之后会自动向下执行。-- 引擎不参与, 有人工完成

邮件任务

activiti强化了业务流程,支持了自动邮件任务,它可以发送邮件给一个或多个参与者, 包括支持cc, bcc, HTML内容等等。activiti引擎要通过支持SMTP功能的外部邮件服务器发送邮件。 为了实际发送邮件,引擎需知道如何访问邮件服务器。在activiti.cfg.xml配置文件中配置.

骆驼任务

不常用

骡子任务

不常用

决策任务

业务规则用户用来同步执行一个或多个规则。activiti使用drools规则引擎执行业务规则。 目前,包含业务规则的.drl文件必须和流程定义一起发布,流程定义里包含了执行这些规则的业务规则任务。 意味着流程使用的所有.drl文件都必须打包在流程BAR文件里,比如任务表单。

activiti之网关

什么是网关

网关用来控制流程的流向(或像BPMN 2.0里描述的那样,流程的tokens。) 网关可以消费也可以生成token

排他网关(有条件判断, 只能走一条分支)

排他网关(也叫异或(XOR)网关,或叫基于数据的排他网关),用来在流程中实现决策。

当流程执行到这个网关,所有分支都会判断条件是否为true,如果为 true 则执行该分支。

注意:排他网关只会选择一个为 true 的分支执行。(即使有两个分支条件都为 true,排他网关也会只选择一条分支去执行)

并行网关(无条件判断, 走多条分支, 分支都通过后下一步)

并行网关允许将流程分成多条分支,也可以把多条分支汇聚到一起,并行网关的功能是基于进 入和外出顺序流的:

  • fork 分支:
  • 并行后的所有外出顺序流,为每个顺序流都创建一个并发分支。
  • join 汇聚:
  • 所有到达并行网关,在此等待的进入分支,直到所有进入顺序流的分支都到达以后,流程就会通过汇聚网关。

注意:如果同一个并行网关有多个进入和多个外出顺序流,它就同时具有分支和汇聚功能。

这时,网关会先汇聚所有进入的顺序流,然后再切分成多个并行分支。

与其他网关的主要区别是,并行网关不会解析条件。 即使顺序流中定义了条件,也会被忽略

包含网关(有条件判断, 走多条分支,分支都通过后下一步)

包含网关可以看做是排他网关和并行网关的结合体。 和排他网关一样,你可以在外出顺序流上定义条件,包含网关会解析它们。 但是主要的区别是包含网关可以选择多于一条顺序流,这和并行网关一样。

包含网关的功能是基于进入和外出顺序流的:

  • 分支:
  • 所有外出顺序流的条件都会被解析,结果为 true 的顺序流会以并行方式继续执行, 会为每个顺序流创建一个分支。
  • 汇聚:
  • 所有并行分支到达包含网关,会进入等待状态, 直到每个包含流程 token 的进入顺序流的分支都到达。
  • 这是与并行网关的最大不同。
  • 换句话说,包含网关只会等待被选中执行了的进入顺序流。
  • 在汇聚之后,流程会穿过包含网关继续执行。

事件网关

它允许设置多个输出流指向多个不同的中间捕获事件(最少两个)。在流程执行到事件网关后,流程处于“等待”状态。等待捕获事件的触发。

使用注意点:

事件网关是专门使用与中间捕获事件的排斥网关,跟排斥网关决定流程走向的区别是基于捕获的顺序,谁先捕获事件,流程就运行到哪个捕获事件所在的流程。当其中一个中间捕获事件触发后,其余输出流的中间捕获事件便不在进行监听,自动销毁。

activiti之中间事件

什么是中间事件

中间事件提供的特殊功能可以用来处理流程执行过程中抛出、捕获的事件,具体包括:

  • 边界事件
  • 中间捕获事件
  • 中间抛出事件

每种中间事件的图形都有一个共同特点:以双线圆形表示

边界事件

边界事件是绑定在活动上的“捕获型”事件,会一直监听所有处于运行中活动的某种事件的触发,在捕获到事件之后中断活动(部分可配置),然后从边界事件类型的输出流继续执行。

一旦触发边界事件,当前的活动就会被中断(可配置),然后按照边界事件之后的输出流执行。

边界事件和所关联的活动有一个特殊的关系“附加”,而且一个活动只能绑定一个边界事件;每个边界事件类型都是通过属性attachedToRef指定“附加”到抛出边界事件活动上

定时器边界事件

定时器边界事件需要附属在一个非自动任务(用户任务等)、调用活动、子流程上,在上游任务执行完成之后开始倒计时预设的事件,到达预设事件之后触发定时器边界事件的输出流。

异常边界事件

异常边界事件用来捕获嵌入子流程或调用活动抛出的异常。异常在抛出之后被主流程的异常边界事件捕获,同时嵌入子流程或调用活动中的活动也被中断执行。

信号边界事件

信号边界事件可以捕获流程执行过程中抛出的信号,可以“附加”在各种活动和子流程上。

信号边界事件不仅可以捕获本流程的信号,还可以捕获到其他流程的信号事件,而且如果在一个活动或子流程上定义了多个信号边界事件并监听同一个信号,则会同时触发,因为对应的信号抛出事件是全局的 。

取消边界事件

取消边界事件是专门针对事务子流程所设立的,用来捕获子流程中抛出的取消事件,在结合事务子流程使用时需要注意几点:

一个事务子流程只允许附加一个取消边界事件;

如果事务子流程中嵌套了子流程,仅仅触发已经完成了的子流程的补偿实际那。

对于多实例的事务子流程,如果其中一个实例触发了取消事件,那么其他的实例也同样会被触发取消边界事件。

补偿边界事件

补偿边界事件用于事务子流程(嵌入子流程不支持补偿边界事件)中针对事务失败后的业务逻辑进行补偿

中间捕获事件

中间捕获事件必须连接一个输入流和一个输出流,所以根据这个特性命名为中间捕获事件。另外,所有的中间捕获事件的图标都是空心的。

定时中间捕获事件

定时中间事件作为一个监听器当执行到达捕获事件节点,就会启动一个定时器.当定时器触发(比如,一段时间之后),流程就会沿着定时中间事件的外出节点继续执行

信号中间捕获事件

中间捕获信号事件,通过引用信号定义来捕获相同信号名称的信号

消息中间捕获事件

中间捕获消息事件,捕获特定名称的消息

中间抛出事件

中间抛出事件和中间捕获事件时2个相互依赖的关系,中间捕获事件需要有事件抛出才能触发,而中间抛出事件需要有对应的捕获事件接受才有意义。

中间抛出事件一般用于在一个任务完成后需要发送通知或执行其他系统任务的场景,工作流引擎会对抛出的事件进行传播(不同类型的事件有不同的作用范围)。

中间触发空事件

空中间触发事件流程图,用于表示流程中的某个状态, 可以添加执行监听器可以添加自己的代码,把事件发送给BAM工具或DWH.引擎不会为这个事件做任何事情,它直接径直通过

信号中间触发事件

信号中间触发事件为定义的信号抛出一个信号事件

补偿中间触发事件

Activiti源码&执行逻辑

activiti 部署

基于流程模板部署activiti流, 首先会在流程设计模型部署表(ACT_RE_DEPLOYMENT)和流程定义数据表(ACT_RE_PROCDEF)插入部署数据, 并在二进制基础表 (ACT_GE_BYTEARRAY) 存储通用的流程定义和流程资源, 每部署一次对应三张表都会生成一条记录

activiti流程创建

  • 查询流程定义表(ACT_RE_PROCDEF)和流程基础表(ACT_GE_BYTEARRAY) -> 解析流程状态执行并将解析结果加入内存缓存中

  • 插入历史详情表(ACT_HI_DETAIL)数据,和参数
  • 插入历史变量表(ACT_HI_VARINST)变量数据
  • 插入历史任务表(ACT_HI_TASKINST)当前任务数据
  • 插入历史流程实例表(ACT_HI_PROCINST)新建流程实例 (创建时才有)
  • 插入历史节点表(ACT_HI_ACTINST) 历史执行到的节点信息
  • 插入历史流程联系人表(ACT_HI_IDENTITYLINK), 记录当前流程执行人

  • 插入运行时流程执行的实例表(ACT_RU_EXECUTION)记录执行顺序
  • 插入运行时正在执行的任务表(ACT_RU_TASK), 记录当前任务
  • 插入运行时用户信息表(ACT_RU_IDENTITYLINK), 记录当前执行的人员
  • 插入运行时参数表(ACT_RU_VARIABLE), 记录当前运行的参数

activiti流程执行

  • 查询流程定义表和流程基础表 -> 解析流程状态执行
  • 插入历史详情表(ACT_HI_DETAIL)数据,和参数
  • 插入历史变量表(ACT_HI_VARINST)变量数据
  • 插入历史任务表(ACT_HI_TASKINST)当前任务数据
  • 插入历史节点表(ACT_HI_ACTINST) 历史执行到的节点信息
  • 插入历史流程联系人表(ACT_HI_IDENTITYLINK), 记录当前流程执行人

  • 插入运行时正在执的任务表(ACT_RU_TASK), 记录当前任务
  • 插入运行时用户信息表(ACT_RU_IDENTITYLINK), 记录当前执行的人员
  • 插入运行时参数表(ACT_RU_VARIABLE), 记录当前运行的参数

  • 更新运行时流程执行的实例表(ACT_RU_EXECUTION), 记录当前运行实例信息
  • 更新历史节点表(ACT_HI_ACTINST), 更新历史任务
  • 更新任务实例表(ACT_HI_TASKINST), 记录当前任务进度
  • 删除运行时正在执行的任务表(ACT_RU_TASK) ,删除上一个任务

activiti流程结束

  • 删除运行时数据ACT_RU_*

设计理念

tenant

不同系统用一个流程定义来启动流程实例,tenantId用以区分同一个流程定义下分属不同系统的流程实例

执行逻辑

  • activitti执行逻辑依赖于Command接口, 各个实体下名对应的实现类, 例如StartProcessInstanceCmd, 依赖于excute方法执行对应的逻辑, 创建一个process instants, 执行commandContext.getAgenda().planContinueProcessOperation(execution);创建一个线程(ContinueProcessOperation)交给CommandContext的ActivitiEngineAgenda, 然后调起线程执行下一个流程, 到对应的流程后发起task create listener , 由ListenerNotificationHelper监听listener,
  • ContinueProcessOperation.run后获取下一个节点(FlowNode), FlowNode获取ActivityBehavior.execute()执行逻辑, 创建task, 例如UserTaskActivityBehavior