目录
- Flowable
- 工作流分类:
- 一、会签流程
- 二、或签流程
- 分支流程
- 四、并行流程
- 第二步:源码及表结构对应关系
- 部署一次流程
- 第三步 流程监听器与任务监听器
Flowable
工作流分类:
参考: link
官方中文文档:网关
一、会签流程
- 适用场景
会签是一种联合审批的特殊审批节点,可理解为一种多人投票机制,一个任务需要多个人同时处理,然后汇总多个人的意见,决定流程下一步该如何执行。流程设计时,若会签审批节点中设置多个参与人,流程运行时,会签节点任务需要多人共同处理,然后汇总多人的处理意见,决定会签节点的处理结果。
例如:员工发起采购申请,需经过多名领导共同审批后,才决定是否可以采购,只要其中1名领导不同意,便退回申请人。
- 具体规则
会签分并行会签和顺序会签两种:
(1)并行会签
指同一个审批节点同时设置多个人,如ABC三人,三人会同时收到待办,需全部同意之后,审批才可到下一审批节点。
(2)顺序会签
指同一个审批设置多个人,如ABC三人,三人按顺序人依次收到待办,即A先审批,A提交后B才能审批,需全部同意之后,审批才可下一审批节点。
- 设置方法
二、或签流程
- 适用场景
一个流程审批节点里有多个处理人,任意一个人处理后就能进入下一个节点。
例如:员工发起采购申请,提交给多名领导审批,只要有一名领导同意即可提交到下一节点。
- 具体规则
指同一个审批节点设置多个人,如ABC三人,三人会同时收到审批待办,只要其中任意一人审批即可到下一审批节点。
- 设置方法
分支流程
- 适用场景
分支流程的适用场景:流程中某个节点后有多个分支节点,根据不同条件执行不同的分支,即不同的数据会走不同的流程路径。
例如:请假申请,可根据请假天数走不同的审批路径,3天以内请假由人力资源审批,超过3天的请假由公司领导审批。
- 具体规则
(1)分支流程使用【排他网关】,连接在【排他网关】后面的线条,有分流作用,点击线条可设置流转条件。
(2)上一节点点击【提交】后,根据【排他网关】设置按顺序判断所有分支流转条件,出现满足流转条件时,就进入相应的分支节点。
(3)如果不设置,表示无条件限制,会直接进入该节点;如果设置了流转条件,则只有满足条件才会进入该节点;如果所有条件都不满足,则会流转到设置的默认访问;如果有多个条件满足,则会按设置的条件顺序判断,直到出现第一个满足的条件,就进入该节点。
- 设置方法
四、并行流程
- 适用场景
并行流程适用场景:流程中某个节点后有多个节点需要并行执行,节点的处理人需同时收到流程待办,各自处理待办,当所有分支线上的节点都执行后,流程才进入到下一个节点。
例如:员工提交请假申请,同时送部门经理和人力资源部审批,需要部门经理和人力资源全部审批通过后,才算流程审批通过。
- 具体规则
连接在【并行网关】后面的线条,才有并流作用;
上一节点点击【提交】后,无论线条是否设置条件,都自动进入所有的分支节点。当所有分支都执行后,才进入这些分支同时连接的下一个节点;
- 设置方法
第二步:源码及表结构对应关系
官方中文文档很详细
https://tkjohn.github.io/flowable-userguide/
部署一次流程
第三步 流程监听器与任务监听器
首先创建流程监听器和任务监听器的实体类,个人比较喜欢使用Delegate Expression方式,其他两种方式也可以
流程监听器
package org.mpc.final_activiti;
import java.io.Serializable;
import org.activiti.engine.delegate.DelegateExecution;
import org.activiti.engine.delegate.ExecutionListener;
import org.activiti.engine.delegate.Expression;
/**
*
* 可以使用 CLASS ,EXPRESSION,DELEGATE EXPRESSSION三种方式来创建监听器,这里使用第三种方式,其他两种方式和
* 在servicetask中的使用方式相同
*
* */
public class ExectuionListenerDemo implements Serializable, ExecutionListener {
/**
* @Fields serialVersionUID : TODO(用一句话描述这个变量表示什么)
*/
private static final long serialVersionUID = 8513750196548027535L;
private Expression message;
public Expression getMessage() {
return message;
}
public void setMessage(Expression message) {
this.message = message;
}
@Override
public void notify(DelegateExecution execution) throws Exception {
System.out.println("流程监听器" + message.getValue(execution));
}
}
任务监听器
package org.mpc.final_activiti;
import java.io.Serializable;
import org.activiti.engine.delegate.DelegateTask;
import org.activiti.engine.delegate.Expression;
import org.activiti.engine.delegate.TaskListener;
/**
*
* 任务监听器,实现TaskListener接口
*
* */
public class TaskListenerDemo implements Serializable, TaskListener {
private Expression arg;
public Expression getArg() {
return arg;
}
public void setArg(Expression arg) {
this.arg = arg;
}
@Override
public void notify(DelegateTask delegateTask) {
System.out.println("任务监听器:" + arg.getValue(delegateTask));
}
}
这两个监听器只是简单的表明了自己的身份,并打印出在流程中注入给他们的值
接着是流程定义图
展示一下配置结果的xml文件,特别注意一下加注释的地方
<?xml version="1.0" encoding="UTF-8"?>
<definitions xmlns="http://www.omg.org/spec/BPMN/20100524/MODEL" xmlns:xsi="http://www.w3.org/2001/XMLSchema-instance" xmlns:xsd="http://www.w3.org/2001/XMLSchema" xmlns:activiti="http://activiti.org/bpmn" xmlns:bpmndi="http://www.omg.org/spec/BPMN/20100524/DI" xmlns:omgdc="http://www.omg.org/spec/DD/20100524/DC" xmlns:omgdi="http://www.omg.org/spec/DD/20100524/DI" typeLanguage="http://www.w3.org/2001/XMLSchema" expressionLanguage="http://www.w3.org/1999/XPath" targetNamespace="http://www.activiti.org/test">
<process id="myProcess" name="My process" isExecutable="true">
<extensionElements>
<activiti:executionListener event="start" delegateExpression="${myprocessListener}">
<activiti:field name="message">
<activiti:string><![CDATA[流程启动]]></activiti:string>
</activiti:field>
</activiti:executionListener>
<activiti:executionListener event="end" delegateExpression="${myprocessListener}">
<activiti:field name="message">
<activiti:string><![CDATA[流程结束]]></activiti:string>
</activiti:field>
</activiti:executionListener>
</extensionElements>
<startEvent id="startevent1" name="Start"></startEvent>
<exclusiveGateway id="exclusivegateway1" name="Exclusive Gateway">
<extensionElements>
<activiti:executionListener event="start" delegateExpression="${myprocessListener}">
<activiti:field name="message">
<activiti:string><![CDATA[排他网关开始]]></activiti:string>
</activiti:field>
</activiti:executionListener>
<activiti:executionListener event="end" delegateExpression="${myprocessListener}">
<activiti:field name="message">
<activiti:string><![CDATA[排他网关结束]]></activiti:string>
</activiti:field>
</activiti:executionListener>
</extensionElements>
</exclusiveGateway>
<sequenceFlow id="flow3" sourceRef="startevent1" targetRef="exclusivegateway1"></sequenceFlow>
<userTask id="usertask2" name="User Task" activiti:assignee="${user}">
<extensionElements>
<activiti:taskListener event="create" delegateExpression="${mytaskListener}">
<activiti:field name="arg">
<activiti:string><![CDATA[任务启动]]></activiti:string>
</activiti:field>
</activiti:taskListener>
<activiti:taskListener event="assignment" delegateExpression="${mytaskListener}">
<activiti:field name="arg">
<activiti:string><![CDATA[分配人员]]></activiti:string>
</activiti:field>
</activiti:taskListener>
<activiti:taskListener event="complete" delegateExpression="${mytaskListener}">
<activiti:field name="arg">
<activiti:string><![CDATA[任务完成]]></activiti:string>
</activiti:field>
</activiti:taskListener>
<!-- 在可视化工具中无法给usertask加上流程监听器,但是,我们在xml中可以自己敲进去· -->
<activiti:executionListener event="start" delegateExpression="${myprocessListener}">
<activiti:field name="message">
<activiti:string><![CDATA[流程启动任务]]></activiti:string>
</activiti:field>
</activiti:executionListener>
<activiti:executionListener event="end" delegateExpression="${myprocessListener}">
<activiti:field name="message">
<activiti:string><![CDATA[流程关闭任务]]></activiti:string>
</activiti:field>
</activiti:executionListener>
<!-- ........................................................................................................................................ -->
</extensionElements>
</userTask>
<sequenceFlow id="flow4" sourceRef="exclusivegateway1" targetRef="usertask2">
<extensionElements>
<activiti:executionListener event="take" delegateExpression="${myprocessListener}">
<activiti:field name="message">
<activiti:string><![CDATA[从排他网关到用户任务,好长的一段路]]></activiti:string>
</activiti:field>
</activiti:executionListener>
</extensionElements>
</sequenceFlow>
<intermediateThrowEvent id="noneintermediatethrowevent1" name="NoneThrowEvent">
<extensionElements>
<activiti:executionListener event="start" delegateExpression="${myprocessListener}">
<activiti:field name="message">
<activiti:string><![CDATA[中间事件开始]]></activiti:string>
</activiti:field>
</activiti:executionListener>
<activiti:executionListener event="end" delegateExpression="${myprocessListener}">
<activiti:field name="message">
<activiti:string><![CDATA[中间事件结束]]></activiti:string>
</activiti:field>
</activiti:executionListener>
</extensionElements>
</intermediateThrowEvent>
<sequenceFlow id="flow5" sourceRef="usertask2" targetRef="noneintermediatethrowevent1"></sequenceFlow>
<endEvent id="endevent1" name="End"></endEvent>
<sequenceFlow id="flow6" sourceRef="noneintermediatethrowevent1" targetRef="endevent1"></sequenceFlow>
</process>
<bpmndi:BPMNDiagram id="BPMNDiagram_myProcess">
<bpmndi:BPMNPlane bpmnElement="myProcess" id="BPMNPlane_myProcess">
<bpmndi:BPMNShape bpmnElement="startevent1" id="BPMNShape_startevent1">
<omgdc:Bounds height="35.0" width="35.0" x="160.0" y="180.0"></omgdc:Bounds>
</bpmndi:BPMNShape>
<bpmndi:BPMNShape bpmnElement="exclusivegateway1" id="BPMNShape_exclusivegateway1">
<omgdc:Bounds height="40.0" width="40.0" x="240.0" y="130.0"></omgdc:Bounds>
</bpmndi:BPMNShape>
<bpmndi:BPMNShape bpmnElement="usertask2" id="BPMNShape_usertask2">
<omgdc:Bounds height="55.0" width="105.0" x="325.0" y="123.0"></omgdc:Bounds>
</bpmndi:BPMNShape>
<bpmndi:BPMNShape bpmnElement="noneintermediatethrowevent1" id="BPMNShape_noneintermediatethrowevent1">
<omgdc:Bounds height="35.0" width="35.0" x="475.0" y="133.0"></omgdc:Bounds>
</bpmndi:BPMNShape>
<bpmndi:BPMNShape bpmnElement="endevent1" id="BPMNShape_endevent1">
<omgdc:Bounds height="35.0" width="35.0" x="555.0" y="133.0"></omgdc:Bounds>
</bpmndi:BPMNShape>
<bpmndi:BPMNEdge bpmnElement="flow3" id="BPMNEdge_flow3">
<omgdi:waypoint x="195.0" y="197.0"></omgdi:waypoint>
<omgdi:waypoint x="260.0" y="170.0"></omgdi:waypoint>
</bpmndi:BPMNEdge>
<bpmndi:BPMNEdge bpmnElement="flow4" id="BPMNEdge_flow4">
<omgdi:waypoint x="280.0" y="150.0"></omgdi:waypoint>
<omgdi:waypoint x="325.0" y="150.0"></omgdi:waypoint>
</bpmndi:BPMNEdge>
<bpmndi:BPMNEdge bpmnElement="flow5" id="BPMNEdge_flow5">
<omgdi:waypoint x="430.0" y="150.0"></omgdi:waypoint>
<omgdi:waypoint x="475.0" y="150.0"></omgdi:waypoint>
</bpmndi:BPMNEdge>
<bpmndi:BPMNEdge bpmnElement="flow6" id="BPMNEdge_flow6">
<omgdi:waypoint x="510.0" y="150.0"></omgdi:waypoint>
<omgdi:waypoint x="555.0" y="150.0"></omgdi:waypoint>
</bpmndi:BPMNEdge>
</bpmndi:BPMNPlane>
</bpmndi:BPMNDiagram>
</definitions>