什么是flowable:

基于actives发展而来的一款开源流程引擎工具

入门参考:flowable官方文档

使用流程:

  • 引入jar包(此次仅演示springboot项目中)
  • 绘制bpmn流程图,生成xml文件或直接编写流程的xml文件
  • 根据编写的流程来编写代码

jar包的引入:

<!--   flowable   -->
        <dependency>
            <groupId>org.flowable</groupId>
            <artifactId>flowable-spring-boot-starter</artifactId>
            <version>6.3.0</version>
        </dependency>

注意:在实际应用中,我们常常会在代码中使用到mybatis,直接这样引入之后会发现报错!错误的原因是因为,flowable 集成是也会引入 mybatis jar包,导致jar冲突,所以解决方案是引入 flowable 时,排除 mybatis,所以依赖应该这样引入:

<!--   flowable   -->
        <dependency>
            <groupId>org.flowable</groupId>
            <artifactId>flowable-spring-boot-starter</artifactId>
            <version>6.3.0</version>
            <exclusions>
                <exclusion>
                    <groupId>org.mybatis</groupId>
                    <artifactId>mybatis</artifactId>
                </exclusion>
            </exclusions>
        </dependency>

bpmn流程

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:flowable="http://flowable.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.flowable.org/processdef">
    <process id="fixBug" name="fix-bug" isExecutable="true">
        <!-- 流程开始   -->
        <startEvent id="startEvent"/>
        <sequenceFlow id="start" sourceRef="startEvent" targetRef="createTask"/>

        <userTask id="createTask" name="创建任务" flowable:assignee="${employeeId}"/>
        <sequenceFlow sourceRef="createTask" targetRef="dealTask"/>
        <!--
            assignee 受让人
            candidateGroups 候选组
            candidateUsers 候选人
        -->
        <userTask id="dealTask" name="程序员处理或忽略任务"/>
        <sequenceFlow sourceRef="dealTask" targetRef="isRightDeal"/>
        <!---->
        <userTask id="isRightDeal" name="管理者判断是否正确处理"/>
        <sequenceFlow sourceRef="isRightDeal" targetRef="decision"/>

        <!-- 判断是否已正确处理  -->
        <exclusiveGateway id="decision"/>
        <sequenceFlow sourceRef="decision" targetRef="right">
            <conditionExpression xsi:type="tFormalExpression">
                <![CDATA[
                ${right}
                ]]>
            </conditionExpression>
        </sequenceFlow>
        <sequenceFlow sourceRef="decision" targetRef="wrong">
            <conditionExpression xsi:type="tFormalExpression">
                <![CDATA[
                ${!right}
                ]]>
            </conditionExpression>
        </sequenceFlow>

        <userTask id="wrong" name="没有正确处理任务"/>
        <sequenceFlow sourceRef="wrong" targetRef="dealTask"/>

        <serviceTask id="right" name="已正确处理任务" flowable:class="com.example.project.service.RightDelegate"/>
        <sequenceFlow sourceRef="right" targetRef="compliant"/>

        <endEvent id="compliant"/>
    </process>
</definitions>

definitions标签是固定格式,复制粘贴上即可;process标签开始编写流程,其中id属性较为重要,后面需要用来创建任务。流程的开始由startEvent标签指定,sequenceFlow标签可以理解为顺序流,使用sourceRef属性和targetRef属性来指定流的来源和目的地。userTask是用户任务,相当于由用户操作完成(complete),当受让人(flowable:assignee)在代码中调用了complete方法后,这个userTask接入,流向target所指的任务。exclusiveGateway标签是一个网关,用于作条件判断,如以上代码中判断的字段是rightserviceTask可理解为系统任务,即根据系统代码自行根据编写的规则完成,不需要等待用户操作,如以上代码中flowable:class属性指向了RightDelegate这个类,这个类实现了java的中的委托(delegate)。重写了execute方法,系统走到serviceTask时会自动执行execute中的方法,然后自动complete任务进入下一步。endEvent标签指示流程结束。

代码的编写:

在springboot的项目中,引入了flowable之后,在项目启动的时候,flowable回去检测数据库是否存在flowable的60张表,如果存在则什么也不执行,如果不存在则会自动创建表,需要注意的是,flowable自动创建表的时候会限制当前数据库中不能存在任何表,也就是需要在一个空的数据库中才能成功的自动创建,所以如果我们需要让flowable的表与其它表在同一个库中的时候,我们可以先让flowable在一个空的数据库中创建完成后,我们再手动导入目标数据库即可。

flowable自动创建的表
flowable自动创建的表

此处由于表过多,而且名称也很像,对各个表存储的数据信息我们就参考别人的笔记就可以:flowable表结构
flowable被加载进spring的容器之后,会向外提供一些service,我们在实际的编码中也就是根据它提供的service来对流程进行控制的,这里我们使用自动装配来引入service:

    @Autowired
    private RepositoryService repositoryService;
    @Autowired
    private TaskService taskService;
    @Autowired
    private RuntimeService runtimeService;
    @Autowired
    private HistoryService historyService;
    @Autowired
    private ManagementService managementService;
    @Autowired
    private FormService formService;
    @Autowired
    private IdentityService identityService;

flowable提供的service
flowable提供的service

几个service的不同
RepositoryService:

  • 查询引擎已知的部署和流程定义。
  • 挂起并激活整个部署或特定过程定义。挂起表示无法对其进行进一步的操作,而激活则相反,并且可以再次启用操作。
  • 检索各种资源,例如引擎自动生成的包含在部署或流程图中的文件。
  • 检索流程定义的POJO版本,该版本可用于使用Java而不是XML对流程进行内部检查。
    RuntimeService:
  • 处理启动流程定义的新流程实例(根据流程定义启动一个流程)
  • 获取和存储过程变量
  • 查询流程实例和当前执行位置

TaskService:

  • 查询分配给用户或组的任务
  • 创建新的独立任务。这些是与流程实例无关的任务。
  • 操纵任务分配给哪个用户或该任务涉及某种用户。
  • 声明并完成任务。声明意味着某人决定担任该任务的受让人,这意味着该用户将完成任务。完成意味着“完成任务的工作”。通常,这是一种形式的填充。

IdentityService:

  • 组和用户的管理(创建,更新,删除,查询等)

FormService:

  • 表单服务(具体怎么使用不清楚)

HistoryService:

  • 查询流程的历史数据

ManagementService:

  • 查询数据库表信息和表的元数据
  • 管理各种 jobs 任务,例如计时器,异步,挂起/激活等等

参考文档:flowable API

JavaDelegate.java

public class RightDelegate implements JavaDelegate {
    @Override
    public void execute(DelegateExecution delegateExecution) {
        //TODO 任务处理完成且审核通过,进行消息通知

    }
}