《Activiti实战》笔记java
RepositoryService | 管理流程定义 |
---|---|
RuntimeService | 执行管理,包括启动、推动、删除流程实例等操做 |
TaskService | 任务管理 |
HistoryService | 历史管理(执行完的数据的管理) |
IdentityService | 组织机构管理 |
FormService | 一个可选服务,任务表单管理 |
ManagerService |
表前缀 | 类型 | 含义 |
---|---|---|
ACT_RE_* | repository | 包含了流程定义和流程静态资源 (图片,规则,等等) |
ACT_RU_* | runtime | 运行时的表,包含流程实例,任务,变量,异步任务等运行中的数据,只在流程实例执行过程当中保存数据,在流程结束时删除记录, 这样运行时表能够一直很小速度很快。 |
ACT_ID_* | identity | 包含身份信息,好比用户,组等 |
ACT_HI_* | history | 包含历史数据,好比历史流程实例, 变量,任务等 |
ACT_GE_* | general | 用于不一样场景下,如存放资源文件 |
表分类 | 表名 | 解释 |
---|---|---|
通常数据 | ACT_GE_BYTEARRAY | 通用的流程定义和流程资源 |
通常数据 | ACT_GE_PROPERTY | 系统相关属性 |
流程历史记录 | ACT_HI_ACTINST | 历史的流程实例 |
流程历史记录 | ACT_HI_ATTACHMENT | 历史的流程附件 |
流程历史记录 | ACT_HI_COMMENT | 历史的说明性信息 |
流程历史记录 | ACT_HI_DETAIL | 历史的流程运行中的细节信息 |
流程历史记录 | ACT_HI_IDENTITYLINK | 历史的流程运行过程当中用户关系 |
流程历史记录 | ACT_HI_PROCINST | 历史的流程实例 |
流程历史记录 | ACT_HI_TASKINST | 历史的任务实例 |
流程历史记录 | ACT_HI_VARINST | 历史的流程运行中的变量信息 |
用户用户组表 | ACT_ID_GROUP | 身份信息-组信息 |
用户用户组表 | ACT_ID_INFO | 身份信息-组信息 |
用户用户组表 | ACT_ID_MEMBERSHIP | 身份信息-用户和组关系的中间表 |
用户用户组表 | ACT_ID_USER | 身份信息-用户信息 |
流程定义表 | ACT_RE_DEPLOYMENT | 部署单元信息 |
流程定义表 | ACT_RE_MODEL | 模型信息 |
流程定义表 | ACT_RE_PROCDEF | 已部署的流程定义 |
运行实例表 | ACT_RU_EVENT_SUBSCR | 运行时事件 |
运行实例表 | ACT_RU_EXECUTION | 运行时流程执行实例 |
运行实例表 | ACT_RU_IDENTITYLINK | 运行时用户关系信息 |
运行实例表 | ACT_RU_JOB | 运行时做业 |
运行实例表 | ACT_RU_TASK | 运行时任务 |
运行实例表 | ACT_RU_VARIABLE | 运行时变量表 |
表明流程定义的执行实例。流程实例就表示一个流程从开始到结束的最大的流程分支,即一个流程中流程实例只有一个。数据库
执行对象Execution,流程按照流程定义的规则执行一次的过程;缓存
Deployment deployment = processEngine.getRepositoryService()//
.createDeployment()
.addClasspathResource("diagrams/LeaveBill.bpmn")
.addClasspathResource("diagrams/LeaveBill.png")
.deploy();
复制代码
这一步在数据库中将操做三张表:并发
注意:当流程定义的key相同的状况下,使用的是版本升级框架
ACT_RE_PROCDEF
流程解析表,解析成功了,在该表保存一条记录。业务流程定义数据表 ACT_RE_PROCDEF(act_re_procdef)
异步
NAME | 字段名 | 字段描述 |
---|---|---|
ID_ | 流程ID | {processDefinitionKey}:{processDefinitionVersion}:{generated-id} |
REV_ | 版本号 | |
CATEGORY_ | 流程命名空间 | 流程定义的Namespace就是类别 |
NAME_ | 流程名称 | 该编号就是流程文件process元素的name属性值 |
KEY_ | 流程定义ID | 该编号就是流程文件process元素的id属性值 |
VERSION_ | 流程版本号 | 由程序控制,新增即为1,修改后依次加1来完成的 |
DEPLOYMENT_ID_ | 部署编号 | 部署表ID |
RESOURCE_NAME_ | 流程bpmn文件名称 | |
DGRM_RESOURCE_NAME_ | png流程图片名称 | |
DESCRIPTION_ | 描述信息 | 描述 |
HAS_START_FORM_KEY_ | start节点是否存在formKey | 0否 1是 |
SUSPENSION_STATE_ | 是否挂起 | 1激活 2挂起 |
此表和ACT_RE_DEPLOYMENT是多对一的关系,即一个部署的bar包里可能包含多个流程定义文件,每一个流程定义文件都会有一条记录在ACT_RE_PROCDEF表内,每一个流程定义的数据,都会对于ACT_GE_BYTEARRAY表内的一个资源文件和PNG图片文件。和ACT_GE_BYTEARRAY的关联是经过程序用ACT_GE_BYTEARRAY.NAME与ACT_RE_PROCDEF.NAME_完成的, 在数据库表结构中没有体现ide
ACT_RE_DEPLOYMENT
用来存储部署时须要持久化保存下来的信息ui
是否主键 | 字段名 | 字段描述 |
---|---|---|
ID_ | 部署编号,自增加 | |
NAME_ | 部署包的名称 | |
CATEGORY_ | 类型 | VARCHAR(255) |
DEPLOY_TIME_ | 部署时间 | TIMESTAMP |
ACT_GE_BYTEARRAY
保存全部二进制数据 LeaveBill.bpmn和LeaveBill.png都是ResourceEntity,被添加入表中
ACT_GE_BYTEARRAY(act_ge_bytearray)
spa
Name | 字段名 | 字段描述 |
---|---|---|
ID_ | ID_ | 主键ID,资源文件编号,自增加 |
REV_ | 版本号 | INT(11) |
NAME_ | 部署的文件名称, | |
DEPLOYMENT_ID_ | 来自于父表ACT_RE_DEPLOYMENT的主键 | |
BYTES_ | 大文本类型,存储文本字节流 | LONGBLOB |
GENERATED_ | 是不是引擎生成 | 0为用户生成,1为Activiti生成 |
RuntimeService().startProcessInstanceByKey()
当流程到达一个节点时,会在ACT_RU_EXECUTION表中产生1条数据,若是当前节点是用户任务节点,这是会在ACT_RU_TASK表中添加一条记录设计
ACT_RU_TASK(运行时任务数据表)
(执行中实时任务)代办任务查询表
ACT_RU_TASK(act_ru_task)
是否主键 | 字段名 | 字段描述 |
---|---|---|
ID_ | ||
REV_ | 版本号 | INT(11) |
EXECUTION_ID_ | 实例id(外键EXECUTION_ID_) | 执行实例ID |
** PROC_INST_ID_** | 流程实例ID(外键PROC_INST_ID_) | VARCHAR(64) |
PROC_DEF_ID_ | 流程定义ID | VARCHAR(64) |
NAME_ | 任务名称 | 节点定义名称 |
PARENT_TASK_ID_ | 父节任务ID | 父节点实例ID |
DESCRIPTION_ | 任务描述 | 节点定义描述 |
TASK_DEF_KEY_ | 任务定义key | 任务定义的ID |
OWNER_ | 所属人(老版) | 拥有者(通常状况下为空,只有在委托时才有值) |
ASSIGNEE_ | 代理人员(受让人) | 签收人或委托人 |
DELEGATION_ | 代理团 | 委托类型,DelegationState分为两种:PENDING,RESOLVED。如无委托则为空VARCHAR(64) |
PRIORITY_ | 优先权 | INT(11) |
CREATE_TIME_ | 建立时间 | TIMESTAMP |
DUE_DATE_ | 执行时间 | 耗时 |
SUSPENSION_STATE_ | 暂停状态 | 1表明激活 2表明挂起 |
ACT_RU_EXECUTION(运行时流程执行实例)
核心,个人待办任务查询表
ACT_RU_EXECUTION(act_ru_execution)
是否主键 | 字段名 | 字段描述 |
---|---|---|
ID_ | ID_ | |
REV_ | 版本号 | INT(11) |
PROC_INST_ID_ | 流程实例编号 | VARCHAR(64) |
BUSINESS_KEY_ | 业务主键ID | VARCHAR(255) |
PARENT_ID_ | 父执行流程 | 父节点实例ID |
PROC_DEF_ID_ | 流程定义Id | VARCHAR(64) |
SUPER_EXEC_ | VARCHAR(64) | 64 |
ACT_ID_ | 实例id | 节点实例ID即ACT_HI_ACTINST中ID |
IS_ACTIVE_ | 激活状态 | 是否存活 |
IS_CONCURRENT_ | 并发状态 | 是否为并行(true/false) |
IS_SCOPE_ | TINYINT(4) | |
IS_EVENT_SCOPE_ | TINYINT(4) | |
SUSPENSION_STATE_ | 暂停状态_ | 挂起状态 1激活 2挂起 |
CACHED_ENT_STATE_ | 缓存结束状态_ | INT(11) |
ACT_RU_IDENTITYLINK(身份联系)
主要存储当前节点参与者的信息,任务参与者数据表。
ACT_RU_IDENTITYLINK(act_ru_identitylink)
是否主键 | 字段名 | 字段描述 |
---|---|---|
ID_ | ID_ | |
REV_ | 版本号 | INT(11) |
GROUP_ID_ | 用户组ID | VARCHAR(255) |
TYPE_ | 用户组类型 | 主要分为如下几种:assignee、candidate、owner、starter、participant。即:受让人,候选人,全部者、起动器、参与者 |
USER_ID_ | 用户ID | VARCHAR(255) |
TASK_ID_ | 任务Id | VARCHAR(64) |
PROC_INST_ID_ | 流程实例ID | VARCHAR(64) |
PROC_DEF_ID_ | 流程定义Id | VARCHAR(64) |
ACT_HI_ACTINST(历史节点表)
历史活动信息。这里记录流程流转过的全部节点,与HI_TASKINST不一样的是,taskinst只记录usertask内容
ACT_HI_ACTINST(act_hi_actinst)
是否主键 | 字段名 | 字段描述 |
---|---|---|
ID_ | ID_ | |
PROC_DEF_ID_ | 流程定义ID | VARCHAR(64) |
PROC_INST_ID_ | 流程实例ID | VARCHAR(64) |
EXECUTION_ID_ | 流程执行ID | VARCHAR(64) |
ACT_ID_ | 活动ID | 节点定义ID |
TASK_ID_ | 任务ID | 任务实例ID 其余节点类型实例ID在这里为空 |
CALL_PROC_INST_ID_ | 请求流程实例ID | 调用外部流程的流程实例ID' |
ACT_NAME_ | 活动名称 | 节点定义名称 |
ACT_TYPE_ | 活动类型 | 如startEvent、userTask |
ASSIGNEE_ | 代理人员 | 节点签收人 |
START_TIME_ | 开始时间 | DATETIME |
END_TIME_ | 结束时间 | DATETIME |
DURATION_ | 时长,耗时 | 毫秒值 |
只会返回一条结果。当流程执行到排他网关时,流程引擎会自动检索网关出口,从上到下检索若是发现第一条决策结果为true或者没有设置条件的(默认为成立),则流出。
使用流程变量,设置连线的条件,并按照连线的条件执行工做流,若是没有条件符合的条件,则以默认的连线离开.须要设置流程变量,不设置时抛异常,不会走,默认网关
若是同一个并行网关有多个进入和多个外出顺序流, 它就同时具备分支和汇聚功能。 这时,网关会先汇聚全部进入的顺序流,而后再切分红多个并行分支。
并行网关不会解析条件, 即便顺序流中定义了条件,也会被忽略
在任务建立后,意味着流程会进入等待状态, 直到引擎接收了一个特定的消息, 这会触发流程穿过接收任务继续执行.
ReceiceTask任务,机器自动完成的任务,只会在act_ru_execution
表中产生一条数据
设置任务办理人
processEngine.getTaskService().setAssignee(taskId, userId);
将我的任务从一我的分配给另外一我的,会覆盖监听器设置的代办人
List<IdentityLink> list = processEngine.getTaskService().getIdentityLinksForTask(taskId)
复制代码
act_ru_identitylink
:存听任务的办理人,包括我的任务和组任务,表示正在执行的任务
act_hi_identitylink
:存听任务的办理人,包括我的任务和组任务,表示历史任务
区别在于:
若是是我的任务TYPE的类型表示participant(参与者)
若是是组任务TYPE的类型表示candidate(候选者)和participant(参与者)
使用流程变量
类
processEngine.getTaskService().claim (taskId, userId);
将组任务分配给我的任务,也叫认领任务,即指定某我的去办理这个任务.此时不会校验userId是否在候选人中,若是不在,则将userId加入到候选人列表,对应IdentityLink表格act_id_group
:角色组表
act_id_user
:用户表
act_id_membership
:用户角色表
在部署流程定义和启动流程实例的中间,设置组任务的办理人,向Activiti表中存放组和用户的信息
任务监听
Create 建立任务,assignment分配任务,complete完成任务
Expression,delegateExpression,Alfresco script
activity:initiator=”xxx”
:能够把启动流程实例的操做人以变量名称”xxx”保存到数据库中,须要配合identityService.setAuthenticatedUserId(authenticatedUserId)
使用
能够运行脚本语言
复制代码
能够和drools整合
在serviceTask的基础上由activiti扩展而来,能够发邮件
在serviceTask的基础上由activiti扩展而来,是用来解决消息路由的框架
不作任何处理,流程引擎无需关系如何处理它,activiti把手动任务当作一个空任务来处理,当到达此任务时由引擎自动完成并转向下一个任务
在任务建立后开始等待消息的到来,直到被触发才会完成任务,能够经过RuntimeService接口的signal()方法发送信号触发接收任务
容许一个任务甚至子流程能够重复执行屡次如一个申请由多人审批,能够选择顺序执行和并行执行 能够设置重复执行,设置完成条件
若是多个线路的计算结果为true,则会执行第一个值为true的网关,若线路都没有true,则抛出异常
并行网关聚集处,只有当全部进入的流程都进来了,才能往下走流程
融合了排他网关和并行网关的特性,既能够同时执行多条线路,又容许在网关上设置条件
事件网关是专门为中间捕获事件设置,容许设置多个输出流指向多个不一样的中间捕获事件(最少两个).在流程执行到事件网关后,流程处于”等待”状态,中间捕获事件须要依赖中间抛出事件触发才能更改等待状态为活动状态
子流程能够包含流程规范的大部分模型
最经常使用的是把最通用的流程独立成子流程,嵌入到各个流程当中
和子流程做用一致,但表现方式不一样,可使用一个调用活动取代嵌入子流程的活动,经过建立一个调用活动模型并制定外部流程的id方式做为主流程的一个子活动
和子流程相似,不一样的是事件子流程不能直接启动,而是被动地由其余的事件触发启动 能够由异常事件,信号事件,消息事件,定时器事件,补偿事件等触发
该子流程拥有事务性,ACID,回滚
边界事件是绑定在活动上的”捕获型”事件,一旦触发边界事件,当前活动会被中断而后按照边界事件以后的输出流执行
一个活动只能绑定一个边界事件
部分边界事件中能够设置cancelActivity属性值,以控制是否取消执行输出流指定的活动
定时启动事件:用于在指定的时间启动一个新的流程 定时器边界事件:附属在一个非自动任务,调用活动,子流程上,在上游任务执行完成以后开始倒计时准备触发事件
用来捕获嵌入子流程或调用活动抛出的异常 异常抛出以后被主流程的异常边界事件捕获,同时嵌入子流程或调用活动中的活动也被中断执行 异常边界事件能够直接在流程定义图
<sequenceFlow id="flow-treasurerAudit" name="财务不一样意" sourceRef="exclusivegateway-treasurerAudit" targetRef="errorendevent2">
复制代码
也能够直接抛出异常
信号边界事件能够捕获流程执行中抛出的信号,能够附加在各类活动和子流程上
信号抛出事件是全局的:信号边界事件不只能够捕获本流程的信号,还能够捕获到其余流程的信号事件,若是定义了多个信号边界事件并监听同一个信号,则会同时触发多个边界事件
专门针对事务子流程所设计的,用来捕获子流程中抛出的取消事件,不能附加到其余活动上
用于事务子流程中针对事务失败后的业务逻辑进行补偿 若补偿边界事件附加的活动室多实例的,当抛出补偿事件时,每个实例都会触发补偿边界事件
根据事件不一样的类型须要使用不一样的方式才能继续执行后续的输出流的活动 中间捕获事件必须链接一个输入流和输出流
中间抛出事件须要有对应的捕获事件接收才有意义
中间抛出事件通常用在一个任务完成后须要发送通知或执行其余系统任务的场景,工做流引擎会对抛出的事件进行传播
容许在执行流程中执行java代码
监听类型:start,end,take
能够捕获的事件:
3种监听器执行类型
只能应用于用户任务
监听类型
表单属性
引擎在部署流程以后,引擎对部署的流程定义作一些初始化的工做,其中就包含对定时做业的注册和对消息事件的注册
ACT_RU_JOB表的主要字段说明
在部署流程以后引擎会在初始化中处理消息事件,把消息的类型注册到数据act_ru_event_subscr中
在流程执行过程当中遇到了消息类型事件或经过API触发消息事件触发该表读取数据,而且根据消息的属性调用消息处理器
processInstance = runtimeService.startProcessInstanceByMessage("启动XXX流程");
流程会找到act_ru_event_subscr表中的EVENT_NAME匹配消息名称,找到就启动
终止结束事件:终止整个流程
空结束事件:只结束一条输出流的执行
在历史任务实例中HistoricActivityInstance,有个HistoricActivityInstance.getDeleteReason()
,对应act_hi_taskinst表的DELETE_REASON_字段
若是一个任务正常完成(经过complete方法),则DELETE_REASON_值为completed,若是任务是被删除的,则删除缘由为deleted
好比在空结束事件没有complete,而主流程就completed了,则子流程的记录就为deleted
消息边界事件,信号边界事件与异常边界事件会多出一个cancelActivity属性,可取值为:
True:在边界事件触发后取消已注册的消息事件
False:在边界事件触发后仍然保留已注册的事件,能够再次触发
runtimeService.messageEventReceived(messageName, executionId); //触发消息边界事件
复制代码
同理,触发信号事件runtimeService.signalEventReceived(signalName, executionId);
若是一个任务有附加的消息边界事件,当任务执行完成且边界事件没有被触发时,那么已经注册的事件将在任务完成时被删除
委托人:owner_
办理人:assignee_
//参与人:
taskService.addUserIdentityLink(taskId, userId, identityLinkType);
taskService.getIdentityLinksForTask(taskId);
//签收
processEngine.getTaskService().claim(task.getId(), " user "); // 数据库字段owner_为user
//委派
processEngine.getTaskService().delegateTask(task.getId(), "henryyan"); // //数据库字段assignee _为henryyan
//被委派人完成任务
taskService.resolveTask(task.getId());
复制代码
最终Assignee:user1,owen:user1
owner是任务全部者只能是一个,assignee是任务肯定的接收者,也只能是一个,candidate是可领取任务的人,那么就会有不少,因此candidate单独放在identitylink表中关联task,而前两个就直接在task表中标明便可
当调用taskService.getIdentityLinksForTask("task102");
时,这三种状况(两个表)都要统计进去。
签收: taskService.claim(taskId, userId);
反签收: taskService.claim(taskId, null); // 把已签收的任务办理人置空
taskService.addUserIdentityLink(taskId, userId, identityLinkType)
identityLinkType有分红几类人
设置认证用户有什么用?
一个任务能够拆分出多个任务交给不一样的人处理
当主任务complete时,子任务也会默认完成,从ru表删除进入hi表
Task task2 = taskService.newTask();
task2.setParentTaskId(task.getId());
task2.setAssignee("sub task");
taskService.saveTask(task2); //记录到数据库中
复制代码
List<Execution> processInstances = processEngine.getRuntimeService().createExecutionQuery().processInstanceId("13201").list();
复制代码