基于Flowable的工作流

1. Flowable简介

Flowable提供了一个组高效的核心开源业务流程引擎,为开发人员,系统管理员和业务用户提供工作流和业务流程管理(BPM)平台。全部用Java编写,并且基于Apache 2.0许可的开源,代码在社区维护。其核心是一个快速,经过试验和测试的动态BPMN流程引擎,附带DMN决策表和CMMN Case管理引擎。

Flowable是一个功能强大、易用性好、可扩展性强的工作流和业务流程管理引擎,提供了一套可扩展的基于Java的API,可以帮助我们设计、部署和执行各种复杂的业务流程。

2. Flowable常用理论知识点

基本概念

  • 流程定义(Process Definition) :描述流程的结构和行为,可以看作是流程的蓝图。
  • 流程实例(Process Instance) :流程定义的一个运行时实例,表示一个实际的业务流程。
  • 任务(Task) :流程中的一项工作,常见的有用户任务、服务任务、脚本任务等。用户任务可以被分配给一个或多个用户。
  • 用户(User) :参与业务流程的人员,可以执行任务。
  • 组(Group) :用户的集合,用于任务分配和权限管理。
  • 变量(Variable) :实例运行过程中存储的数据,分为全局变量和本地变量。2者主要区别是作用域,前者作用于整个流程实例中,后者只是本次任务内。使用变量是需要注意java对象序列化以及指定序列化版本ID。
  • 监听器(Listener) :常用的有任务监听器和执行监听器。2者监听的事件类型不同。任务监听器主要用于监听任务的创建、完成、删除等;执行监听器用于监听执行动作开始、结束。
  • 子流程(SubProcess) : 子流程分为嵌套子流程和调用子流程。在一个流程中,嵌套一个或多个子流程,但是这些子流程没有流程实例Id,它是属于当前流程内部的;在UI画图的时候,嵌套子流程的子流程是在当前流程中画的。调用子流程的子流程是一个独立的流程,是外部的流程;调用子流程的子流程被启动之后,是有流程实例id的,会与主流程(调用它的流程)的实例id关联。
  • 事件(Event) : BPMN中的事件包括 开始、结束、边界、中间捕获、抛出等。
  • 网关(Gateway) : 用于在工作流程中进行流程控制和流转,根据不同的条件选择不同的路径,以实现业务流程的灵活性和可定制性。按类型分为排他、并行、包容、事件。

常用service

  • RepositoryService :提供了对流程定义和流程实例的创建、修改、删除、查询等操作。这个Service主要用于管理流程定义和流程实例,例如部署流程定义、启动流程实例等。
  • RuntimeService :提供了对流程实例的操作,包括启动、暂停、恢复、终止、查询等操作。这个Service主要用于管理流程实例的运行时状态,例如启动流程实例、查询流程实例状态等。
  • TaskService :提供了对任务的操作,包括查询任务、分配任务、完成任务等操作。这个Service主要用于管理流程中的任务,例如查询待办任务、完成任务等。
  • HistoryService :提供了对历史数据的查询,包括查询流程实例的历史数据、查询任务的历史数据等。这个Service主要用于查询流程实例或任务的历史数据,例如查询已完成的流程实例、查询任务的历史处理记录等。
  • IdentityService :提供了对用户和组的管理,包括创建用户、创建组、查询用户、查询组等操作。这个Service主要用于管理用户和组,例如创建用户、查询用户信息等。
  • FormService :提供了对表单的管理,包括获取表单数据、提交表单数据等操作。这个Service主要用于管理表单数据,例如获取表单数据、提交表单数据等。

数据库表 命名规则

  • ACT_RE_*   : **   ** ’RE’表示repository(存储)。RepositoryService接口操作的表。带此前缀的表包含的是静态信息,如,流程定义,流程的资源(图片,规则等)。
  • ACT_RU_*   : **   ** ’RU’表示runtime。RuntimeService、TaskService等接口操作的表。这是运行时的表存储着流程变量,用户任务,变量,职责(job)等运行时的数据。flowable只存储实例执行期间的运行时数据,当流程实例结束时,将删除这些记录。这就保证了这些运行时的表小且快。
  • ACT_ID_*   : **    ** ’ID’表示identity(组织机构)。IdentityService接口操作的表。这些表包含标识的信息,如用户,用户组,等等。
  • ACT_HI_*   : **   ** ’HI’表示history。HistoryService接口操作的表。就是这些表包含着历史的相关数据,如结束的流程实例,变量,任务,等等。
  • ACT_GE_*   : **   ** 普通数据,各种情况都使用的数据。

3. 实现一个简单的工作流程

我们将实现一个简单的请假流程,包括以下步骤:

  1. 员工提交请假申请。
  2. 部门经理审批。
  3. HR审批。
  4. 通知员工审批结果。

3.1 编写BPMN流程定义

首先,我们需要使用Flowable Modeler或其他BPMN建模工具来绘制流程图。流程图中包含开始事件、用户任务、网关和结束事件等元素。

请假流程的BPMN流程定义文件(leave_process.bpmn20.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"
targetNamespace="http://www.flowable.org/processdef">

  <process id="leave_process" name="Leave Process">
    <startEvent id="start" />
    <sequenceFlow id="flow1" sourceRef="start" targetRef="apply_leave" />

    <userTask id="apply_leave" name="Apply for leave" flowable:assignee="${applicant}" />
    <sequenceFlow id="flow2" sourceRef="apply_leave" targetRef="manager_approval" />

    <userTask id="manager_approval" name="Manager approval" flowable:candidateGroups="managers" />
    <sequenceFlow id="flow3" sourceRef="manager_approval" targetRef="hr_approval" />

    <userTask id="hr_approval" name="HR approval" flowable:candidateGroups="hr" />
    <sequenceFlow id="flow4" sourceRef="hr_approval" targetRef="notify_employee" />

    <userTask id="notify_employee" name="Notify employee" flowable:assignee="${applicant}" />
    <sequenceFlow id="flow5" sourceRef="notify_employee" targetRef="end" />

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

3.2 集成Spring Boot

3.2.1 添加依赖

pom.xml 文件中添加Flowable和Spring Boot相关依赖:

<dependencies>
  <dependency>
    <groupId>org.springframework.boot</groupId>
    <artifactId>spring-boot-starter-web</artifactId>
  </dependency>

  <dependency>
   <groupId>org.flowable</groupId>
    <artifactId>flowable-spring-boot-starter</artifactId>
    <version>${flowable.version}</version>
  </dependency>
</dependencies>
3.2.2 配置Flowable

application.properties 文件中配置Flowable:

注意使用的mysql服务中仅可以存在一个flowable的数据库
flowable:
  # true 会对数据库中所有表进行更新操作。如果表不存在,则自动创建(建议开发时使用)
  database-schema-update: false
  # 异步执行定时任务JOB
  async-executor-activate: true
3.2.3 编写业务代码

在Spring Boot应用中,我们可以使用Flowable提供的API来操作流程。以下是一个简单的例子:

@Service
public class LeaveService {

  @Autowired
  private RuntimeService runtimeService;
  @Autowired
  private TaskService taskService;

  public void startLeaveProcess(String applicant) {
    Map<String, Object> variables = new HashMap<>();
    variables.put("applicant", applicant);
    runtimeService.startProcessInstanceByKey("leave_process", variables);
  }

  public List<Task> getTasksByCandidateGroup(String group) {
    return taskService.createTaskQuery().taskCandidateGroup(group).list();
  }

  public void completeTask(String taskId) {
    taskService.complete(taskId);
  }
}

在这个例子中,我们使用 RuntimeService 启动流程实例,使用 TaskService 获取任务列表并完成任务。