Flowable 是一款非常强大的开源业务流程管理(BPM)和工作流引擎,用于设计、执行和监控自动化业务流程。下面这个表格汇总了它的核心构成,帮你快速建立整体认知。
核心维度 | 关键概念/组件 | 核心职责与价值 |
架构核心 | 流程引擎 (ProcessEngine) | 所有操作的总入口,通过它获取各种服务,是引擎的“大脑”和“指挥中心”。 |
数据抽象 | 流程定义 (Process Definition) | 业务流程的“设计图”或“蓝图”,通常是一个BPMN 2.0格式的XML文件,定义了流程的结构、节点和流转规则。 |
流程实例 (Process Instance) | 流程定义的一次具体运行。例如,一个“请假流程定义”可以被启动多次,产生多个不同的“请假流程实例”。 | |
运行时服务 | RepositoryService | 负责流程定义的部署、查询和删除等管理操作,相当于“图纸管理员”。 |
RuntimeService | 负责启动流程实例、管理运行时的流程实例和设置流程变量,是流程的“启动按钮”和“运行控制器”。 | |
TaskService | 管理“用户任务”,例如查询某个用户待办的任务、完成任务等,是与人交互最频繁的服务。 | |
HistoryService | 查询所有已经执行完毕的历史数据,用于生成报表和监控分析。 | |
数据持久化 | 数据库表 (ACT_)* | 引擎运行状态和历史数据的持久化存储,表名以 ACT_开头,后跟两位字母表示用途(如 ACT_RE_*表示存储库表,ACT_RU_*表示运行时表等)。 |
快速入门指南
我们通过一个经典的“请假审批”流程,来实际体验如何使用 Flowable。
1. 环境准备与依赖引入
首先,在一个 Spring Boot 项目中,通过 Maven 引入 Flowable 相关依赖。
<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>6.8.0</version> </dependency> <!-- 数据库驱动,以H2内存数据库为例 --> <dependency> <groupId>com.h2database</groupId> <artifactId>h2</artifactId> <scope>runtime</scope> </dependency></dependencies>引入依赖后,Flowable 在应用启动时会自动创建所需的数据库表。
2. 设计流程定义(BPMN 2.0)
在 src/main/resources/processes/下创建 leave-request.bpmn20.xml文件。这个 XML 文件定义了一个简单的请假流程:员工申请 → 经理审批 → 结束。
<?xml version="1.0" encoding="UTF-8"?><definitions ...> <process id="leave-process" name="请假流程" isExecutable="true"> <!-- 1. 开始事件 --> <startEvent id="start"/> <!-- 2. 员工申请任务 --> <userTask id="employeeApplyTask" name="提交请假申请" flowable:assignee="#{employee}"/> <!-- 3. 经理审批任务 --> <userTask id="managerApproveTask" name="经理审批" flowable:candidateGroups="managers"/> <!-- 4. 排他网关,根据经理的审批意见决定流程走向 --> <exclusiveGateway id="decisionGateway"/> <!-- 5. 批准路径:系统存档(自动任务) --> <serviceTask id="archiveTask" name="归档申请" flowable:class="org.example.ArchiveService"/> <!-- 6. 拒绝路径:发送通知(自动任务) --> <serviceTask id="sendRejectionTask" name="发送拒绝通知" flowable:class="org.example.SendRejectionService"/> <!-- 7. 结束事件 --> <endEvent id="end"/> <!-- 连接线 --> <sequenceFlow sourceRef="start" targetRef="employeeApplyTask"/> <sequenceFlow sourceRef="employeeApplyTask" targetRef="managerApproveTask"/> <sequenceFlow sourceRef="managerApproveTask" targetRef="decisionGateway"/> <sequenceFlow sourceRef="decisionGateway" targetRef="archiveTask"> <conditionexpression xsi:type="tFormalexpression">${approved == true}</conditionexpression> </sequenceFlow> <sequenceFlow sourceRef="decisionGateway" targetRef="sendRejectionTask"> <conditionexpression xsi:type="tFormalexpression">${approved == false}</conditionexpression> </sequenceFlow> <sequenceFlow sourceRef="archiveTask" targetRef="end"/> <sequenceFlow sourceRef="sendRejectionTask" targetRef="end"/> </process></definitions>代码关键点解读:
- isExecutable="true":声明该流程是可执行的。
- userTask:需要人工处理的任务。assignee指定具体处理人,candidateGroups指定候选用户组。
- exclusiveGateway:排他网关,根据条件表达式 conditionexpression决定流程走向。这里的 approved是一个流程变量。
- serviceTask:系统自动执行的任务,通过 class属性关联到自定义的Java类。
3. 部署流程定义
使用 RepositoryService将设计好的BPMN文件部署到引擎中。
@Autowiredprivate RepositoryService repositoryService;public void deployProcess() { Deployment deployment = repositoryService.createDeployment() .addClasspathResource("processes/leave-request.bpmn20.xml") .name("请假流程部署") .deploy(); // 执行部署 System.out.println("流程部署成功,部署ID: " + deployment.getId());}部署成功后,流程定义信息会被存入 ACT_RE_PROCDEF等表中。
4. 启动流程实例
流程定义部署后,就可以使用 RuntimeService根据其唯一Key(即BPMN中 process标签的 id属性)来启动一个具体的流程实例了。
@Autowiredprivate RuntimeService runtimeService;public void startProcessInstance() { // 设置流程变量 Map<String, Object> variables = new HashMap<>(); variables.put("employee", "zhangsan"); // 设置申请人 variables.put("leaveDays", 3); // 设置请假天数 // 根据流程定义的Key启动实例 ProcessInstance instance = runtimeService.startProcessInstanceByKey("leave-process", variables); System.out.println("流程实例启动成功,实例ID: " + instance.getId());}5. 查询与处理任务
在实际应用中,员工“张三”登录系统后,需要查询并处理他的待办任务。这是通过 TaskService完成的。
@Autowiredprivate TaskService taskService;// 1. 查询用户的待办任务public List<Task> getTasks(String assignee) { return taskService.createTaskQuery().taskAssignee(assignee).list();}// 2. 完成任务,并设置审批结果(approved)这个流程变量public void completeTask(String taskId, boolean isApproved) { Map<String, Object> taskVariables = new HashMap<>(); taskVariables.put("approved", isApproved); taskService.complete(taskId, taskVariables); // 完成任务并推进流程 System.out.println("任务处理完成");}6. 历史数据查询
流程实例结束后,可以通过 HistoryService来查询历史记录,用于生成报表或审计。
@Autowiredprivate HistoryService historyService;public void getHistoricProcessInstances() { List<HistoricProcessInstance> list = historyService.createHistoricProcessInstanceQuery() .processDefinitionKey("leave-process") .finished() // 查询已结束的实例 .list(); // 处理查询结果...}核心进阶特性
当基本流程跑通后,以下高级特性可以帮助你构建更复杂、更智能的应用。
- 流程变量 (Process Variables)
- 流程变量是流程实例的“状态”或“记忆”,用于在流程的不同节点间传递数据(如请假天数、审批意见)。它们以键值对的形式存储,并支持复杂对象。
- 任务分配策略
- Flowable 提供了灵活的任务分配方式:
- 固定分配:在BPMN中写死 assignee="zhangsan"。
- 表达式分配:动态指定,如 assignee="#{applicant}",其中 applicant是流程变量。
- 候选组/人:candidateGroups="managers",允许一个组内的任何用户认领并处理该任务。
- 监听器 (Listeners)
- 你可以在流程执行的关键点(如任务创建、完成,流程启动、结束)上挂载监听器,执行自定义逻辑(如发送邮件通知、记录日志),实现业务逻辑的解耦。
总结
总而言之,Flowable 的核心价值在于它将复杂的业务流程可视化、可执行、可监控。通过将业务逻辑从代码中抽离出来,用标准化的BPMN图形进行描述和管理,极大地提高了流程的灵活性和可维护性。
希望这份指南能帮助你清晰地理解 Flowable 并成功迈出第一步。
