一、Java 使用 Flowable 所需的基础知识
1. Java 编程基础
- 核心 Java:熟悉 Java SE,包括面向对象编程(OOP)、集合框架(如 List、Map)、异常处理、I/O 操作等。
- Java 依赖管理:了解 Maven 或 Gradle,用于管理 Flowable 的依赖库。
- Spring Boot(推荐):Flowable 通常与 Spring Boot 集成,需掌握 Spring Boot 的基本概念,如依赖注入、配置、REST API 开发等。
- 多线程与并发:工作流可能涉及异步任务,了解 Java 的线程池、ExecutorService 有助于优化性能。
2. BPMN 2.0 基础(详细描述)
BPMN(Business Process Model and Notation) 是一种标准化的业务流程建模语言,用于描述业务流程的可视化和自动化执行。BPMN 2.0 是目前广泛使用的版本,不仅支持建模,还支持流程执行(可被工作流引擎如 Flowable 解析和运行)。以下是 BPMN 2.0 的核心概念和元素的详细说明:
2.1 BPMN 核心元素
BPMN 2.0 模型由以下主要元素组成:
- Flow Objects(流程对象):定义流程的行为。
- Events(事件):表示流程中发生的事情,如开始、结束或中间事件。
- Start Events:流程的起点(如手动触发、定时触发)。
- Intermediate Events:流程中途的事件(如捕获消息、抛出信号)。
- End Events:流程的终点(如正常结束、错误结束)。
- Activities(活动):表示工作或任务。
- Task:单一的工作单元(如用户任务、服务任务)。
- Subprocess:包含多个子步骤的复杂活动。
- Gateways(网关):控制流程的分支和合并。
- Exclusive Gateway:单一路径选择。
- Parallel Gateway:并行执行。
- Inclusive Gateway:多路径选择。
- Events(事件):表示流程中发生的事情,如开始、结束或中间事件。
- Connecting Objects(连接对象):连接流程元素。
- Sequence Flow(顺序流):表示流程的执行顺序。
- Message Flow(消息流):表示不同流程或系统之间的消息交互。
- Association(关联):连接数据对象或注释。
- Data Objects(数据对象):表示流程中的数据。
- Data Object:存储或传递的数据。
- Data Store:持久化数据。
- Swimlanes(泳道):组织流程元素。
- Pool:表示流程的整体边界,通常代表一个组织或系统。
- Lane:池内的子分区,表示角色、部门或系统组件。
- Artifacts(人工制品):提供附加信息。
- Text Annotation:流程的注释。
- Group:逻辑分组。
2.2 BPMN 2.0 的执行语义
- 流程定义:BPMN 模型以 XML 格式定义,包含流程的结构和行为。工作流引擎(如 Flowable)解析 XML 并执行。
- 流程实例:基于流程定义的运行时实例,每个实例有独立的变量和状态。
- 令牌(Token):BPMN 使用令牌概念表示流程的当前执行位置。令牌沿顺序流移动,触发活动或事件。
- 事件上下文:事件(如消息、信号)可在全局或局部范围内触发,影响流程的执行路径。
2.3 BPMN 2.0 的 XML 结构
BPMN 2.0 使用 XML 格式定义流程,核心标签包括:
- <process>:定义流程。
- <startEvent>、<endEvent>:定义开始和结束事件。
- <userTask>、<serviceTask>:定义任务。
- <exclusiveGateway>、<parallelGateway>:定义网关。
- <sequenceFlow>:定义流程路径。
示例 BPMN XML(请假审批流程):
<?xml version="1.0" encoding="UTF-8"?>
<definitions xmlns="http://www.omg.org/spec/BPMN/20100524/MODEL" targetNamespace="http://www.flowable.org/processdef">
<process id="leaveProcess" name="Leave Approval Process">
<startEvent id="startEvent" />
<sequenceFlow id="flow1" sourceRef="startEvent" targetRef="submitTask" />
<userTask id="submitTask" name="Submit Leave Request" flowable:assignee="${applicant}" />
<sequenceFlow id="flow2" sourceRef="submitTask" targetRef="gateway1" />
<exclusiveGateway id="gateway1" name="Check Days" />
<sequenceFlow id="flow3" sourceRef="gateway1" targetRef="managerTask" flowable:condition="${days <= 3}" />
<sequenceFlow id="flow4" sourceRef="gateway1" targetRef="directorTask" flowable:condition="${days > 3}" />
<userTask id="managerTask" name="Manager Approval" flowable:assignee="manager" />
<userTask id="directorTask" name="Director Approval" flowable:assignee="director" />
<sequenceFlow id="flow5" sourceRef="managerTask" targetRef="endEvent" />
<sequenceFlow id="flow6" sourceRef="directorTask" targetRef="endEvent" />
<endEvent id="endEvent" />
</process>
</definitions>
显示内联
2.4 BPMN 建模工具
- Flowable Modeler:Flowable 提供的 Web 建模工具,支持拖拽创建 BPMN 模型。
- Activiti Modeler:与 Flowable 兼容的建模工具。
- Camunda Modeler:第三方工具,支持 BPMN 2.0。
- Signavio、Bizagi:商业化建模工具。
2.5 BPMN 2.0 的优势与挑战
- 优势:
- 标准化:全球通用,跨工具和引擎兼容。
- 可视化:业务和技术人员都能理解。
- 可执行:支持直接运行于工作流引擎。
- 挑战:
- 复杂性:大型流程模型可能难以维护。
- 学习曲线:需要熟悉 BPMN 规范和工具。
- 性能:复杂流程可能影响引擎性能。
3. Flowable 核心概念
- Flowable 引擎:Flowable 提供 Process Engine(流程引擎),用于执行 BPMN 流程。核心服务包括:
- RepositoryService:管理流程定义和部署。
- RuntimeService:管理流程实例和执行。
- TaskService:处理用户任务。
- HistoryService:查询历史数据。
- IdentityService:管理用户和组。
- 流程定义与实例:流程定义是 BPMN 模型的蓝图,流程实例是基于定义的运行时状态。
- 事件与监听器:Flowable 支持事件监听器(Event Listener)和任务监听器(Task Listener),用于在特定节点执行自定义逻辑。
4. 数据库与持久化
- 关系型数据库:Flowable 默认使用数据库(如 MySQL、PostgreSQL)存储流程定义、实例和历史数据。需了解基本的 SQL 和数据库配置。
- JPA/Hibernate:Flowable 内部使用 JPA,熟悉 JPA 有助于处理复杂的数据交互。
5. 集成与扩展
- REST API:Flowable 提供 REST API,适合前后端分离的应用。需了解 HTTP 请求和 JSON 处理。
- 自定义扩展:掌握如何编写 JavaDelegate 或 Spring Bean 来实现 Service Task 的自定义逻辑。
- Spring 集成:Flowable 与 Spring 的深度集成,需了解 Spring 的 ApplicationContext 和事务管理。
6. 工具与环境
- IDE:推荐 IntelliJ IDEA 或 Eclipse,熟悉调试和代码补全。
- 建模工具:Flowable 提供 Web 建模器,需掌握如何通过 UI 或 XML 创建流程。
- 单元测试:了解 JUnit 和 Flowable 的测试支持,用于验证流程逻辑。
二、Flowable 核心服务方法详解
以下是 Flowable 核心服务的详细方法说明,基于 Flowable 7.x 版本(截至 2025 年 7 月)。每个服务的方法按功能分组,并提供用途和示例。
1. RepositoryService
用途:管理流程定义、部署、资源和模型。
1.1 部署管理
- createDeployment(): 创建一个新的部署对象。
- 返回:DeploymentBuilder
- 示例:repositoryService.createDeployment().addClasspathResource("process.bpmn20.xml").deploy();
- deploy(): 执行部署,将流程定义和资源保存到数据库。
- 返回:Deployment
- 示例:见上。
- deleteDeployment(String deploymentId, boolean cascade): 删除部署,cascade 为 true 时删除相关流程实例。
- 示例:repositoryService.deleteDeployment("dep123", true);
- getDeployment(String deploymentId): 查询指定部署。
- 返回:Deployment
- 示例:Deployment dep = repositoryService.getDeployment("dep123");
1.2 流程定义管理
- createProcessDefinitionQuery(): 创建流程定义查询。
- 返回:ProcessDefinitionQuery
- 示例:List<ProcessDefinition> defs = repositoryService.createProcessDefinitionQuery().processDefinitionKey("leaveProcess").list();
- suspendProcessDefinitionById(String processDefinitionId): 挂起流程定义,阻止新实例启动。
- 示例:repositoryService.suspendProcessDefinitionById("procDef123");
- activateProcessDefinitionById(String processDefinitionId): 激活挂起的流程定义。
- 示例:repositoryService.activateProcessDefinitionById("procDef123");
- getProcessDefinition(String processDefinitionId): 获取流程定义。
- 返回:ProcessDefinition
- 示例:ProcessDefinition def = repositoryService.getProcessDefinition("procDef123");
1.3 资源管理
- getResourceAsStream(String deploymentId, String resourceName): 获取部署的资源(如 BPMN 文件)。
- 返回:InputStream
- 示例:InputStream is = repositoryService.getResourceAsStream("dep123", "process.bpmn20.xml");
- addCandidateStarterUser(String processDefinitionId, String userId): 为流程定义添加启动候选用户。
- 示例:repositoryService.addCandidateStarterUser("procDef123", "user1");
- addCandidateStarterGroup(String processDefinitionId, String groupId): 为流程定义添加启动候选组。
- 示例:repositoryService.addCandidateStarterGroup("procDef123", "group1");
1.4 模型管理
- createModel(): 创建新的流程模型。
- 返回:Model
- 示例:Model model = repositoryService.createModel(); model.setName("New Model");
- saveModel(Model model): 保存模型。
- 示例:repositoryService.saveModel(model);
- getModel(String modelId): 获取模型。
- 返回:Model
- 示例:Model model = repositoryService.getModel("model123");
- getBpmnModel(String processDefinitionId): 获取 BPMN 模型对象。
- 返回:BpmnModel
- 示例:BpmnModel bpmnModel = repositoryService.getBpmnModel("procDef123");
1.5 流程图生成
- getProcessDiagram(String processDefinitionId): 生成流程图。
- 返回:InputStream
- 示例:InputStream diagram = repositoryService.getProcessDiagram("procDef123");
2. RuntimeService
用途:管理流程实例、执行、信号和消息。
2.1 流程实例管理
- startProcessInstanceByKey(String processDefinitionKey, Map<String, Object> variables): 通过流程定义 Key 启动流程实例。
- 返回:ProcessInstance
- 示例:ProcessInstance pi = runtimeService.startProcessInstanceByKey("leaveProcess", Map.of("days", 2));
- startProcessInstanceById(String processDefinitionId, Map<String, Object> variables): 通过流程定义 ID 启动流程实例。
- 返回:ProcessInstance
- 示例:runtimeService.startProcessInstanceById("procDef123", variables);
- deleteProcessInstance(String processInstanceId, String deleteReason): 删除流程实例。
- 示例:runtimeService.deleteProcessInstance("pi123", "Cancelled");
- createProcessInstanceQuery(): 创建流程实例查询。
- 返回:ProcessInstanceQuery
- 示例:List<ProcessInstance> instances = runtimeService.createProcessInstanceQuery().processDefinitionKey("leaveProcess").list();
2.2 执行管理
- createExecutionQuery(): 创建执行查询。
- 返回:ExecutionQuery
- 示例:Execution exec = runtimeService.createExecutionQuery().processInstanceId("pi123").singleResult();
- trigger(String executionId): 触发执行继续。
- 示例:runtimeService.trigger("exec123");
- setVariable(String executionId, String variableName, Object value): 设置流程变量。
- 示例:runtimeService.setVariable("pi123", "approved", true);
- getVariable(String executionId, String variableName): 获取流程变量。
- 返回:Object
- 示例:Object value = runtimeService.getVariable("pi123", "approved");
2.3 事件管理
- signalEventReceived(String signalName): 全局触发信号事件。
- 示例:runtimeService.signalEventReceived("orderConfirmed");
- messageEventReceived(String messageName, String executionId): 触发消息事件。
- 示例:runtimeService.messageEventReceived("orderReceived", "exec123");
- startProcessInstanceByMessage(String messageName, Map<String, Object> variables): 通过消息启动流程。
- 返回:ProcessInstance
- 示例:runtimeService.startProcessInstanceByMessage("orderReceived", Map.of("orderId", "123"));
3. TaskService
用途:管理用户任务,包括分配、完成和查询。
3.1 任务管理
- createTaskQuery(): 创建任务查询。
- 返回:TaskQuery
- 示例:List<Task> tasks = taskService.createTaskQuery().taskAssignee("user1").list();
- newTask(): 创建独立任务(不绑定流程)。
- 返回:Task
- 示例:Task task = taskService.newTask(); task.setName("Ad-hoc Task");
- saveTask(Task task): 保存任务。
- 示例:taskService.saveTask(task);
- complete(String taskId, Map<String, Object> variables): 完成任务并设置变量。
- 示例:taskService.complete("task123", Map.of("approved", true));
3.2 任务分配
- claim(String taskId, String userId): 认领任务。
- 示例:taskService.claim("task123", "user1");
- unclaim(String taskId): 取消认领。
- 示例:taskService.unclaim("task123");
- setAssignee(String taskId, String userId): 设置任务分配人。
- 示例:taskService.setAssignee("task123", "user1");
- addCandidateUser(String taskId, String userId): 添加候选用户。
- 示例:taskService.addCandidateUser("task123", "user2");
- addCandidateGroup(String taskId, String groupId): 添加候选组。
- 示例:taskService.addCandidateGroup("task123", "group1");
3.3 任务变量
- setVariable(String taskId, String variableName, Object value): 设置任务变量。
- 示例:taskService.setVariable("task123", "comment", "Looks good");
- getVariable(String taskId, String variableName): 获取任务变量。
- 返回:Object
- 示例:Object value = taskService.getVariable("task123", "comment");
4. HistoryService
用途:查询流程历史数据,包括实例、任务和变量。
4.1 历史查询
- createHistoricProcessInstanceQuery(): 查询历史流程实例。
- 返回:HistoricProcessInstanceQuery
- 示例:List<HistoricProcessInstance> instances = historyService.createHistoricProcessInstanceQuery().finished().list();
- createHistoricTaskInstanceQuery(): 查询历史任务。
- 返回:HistoricTaskInstanceQuery
- 示例:List<HistoricTaskInstance> tasks = historyService.createHistoricTaskInstanceQuery().taskAssignee("user1").list();
- createHistoricActivityInstanceQuery(): 查询历史活动。
- 返回:HistoricActivityInstanceQuery
- 示例:List<HistoricActivityInstance> activities = historyService.createHistoricActivityInstanceQuery().processInstanceId("pi123").list();
- createHistoricVariableInstanceQuery(): 查询历史变量。
- 返回:HistoricVariableInstanceQuery
- 示例:List<HistoricVariableInstance> vars = historyService.createHistoricVariableInstanceQuery().processInstanceId("pi123").list();
4.2 删除历史
- deleteHistoricProcessInstance(String processInstanceId): 删除历史流程实例。
- 示例:historyService.deleteHistoricProcessInstance("pi123");
- deleteHistoricTaskInstance(String taskId): 删除历史任务。
- 示例:historyService.deleteHistoricTaskInstance("task123");
5. IdentityService
用途:管理用户、组和权限。
5.1 用户管理
- newUser(String userId): 创建新用户。
- 返回:User
- 示例:User user = identityService.newUser("user1"); user.setFirstName("John");
- saveUser(User user): 保存用户。
- 示例:identityService.saveUser(user);
- createUserQuery(): 查询用户。
- 返回:UserQuery
- 示例:List<User> users = identityService.createUserQuery().userId("user1").list();
- deleteUser(String userId): 删除用户。
- 示例:identityService.deleteUser("user1");
5.2 组管理
- newGroup(String groupId): 创建新组。
- 返回:Group
- 示例:Group group = identityService.newGroup("group1"); group.setName("Managers");
- saveGroup(Group group): 保存组。
- 示例:identityService.saveGroup(group);
- createGroupQuery(): 查询组。
- 返回:GroupQuery
- 示例:List<Group> groups = identityService.createGroupQuery().groupId("group1").list();
- deleteGroup(String groupId): 删除组。
- 示例:identityService.deleteGroup("group1");
5.3 关系管理
- createMembership(String userId, String groupId): 将用户添加到组。
- 示例:identityService.createMembership("user1", "group1");
- deleteMembership(String userId, String groupId): 从组中移除用户。
- 示例:identityService.deleteMembership("user1", "group1");
三、Flowable 实现工作流中各节点的作用
以下基于你提供的参考内容,结合 Flowable 的实现,详细说明各节点的作用。Flowable 完全支持 BPMN 2.0,因此你的参考内容可以直接映射到 Flowable 的实现中。
1. Start Events(开始事件)
- Start Event:流程的起点,通常由用户手动触发。例如,提交请假申请。
- Flowable 实现:通过 RuntimeService.startProcessInstanceByKey() 启动流程实例。
- Start Conditional Event:当满足特定条件(如变量值达到阈值)时自动触发。
- Flowable 实现:配置 conditionExpression(如 ${amount > 1000})。
- Start Message Event:接收特定消息(如外部系统发送的 REST 请求)时触发。
- Flowable 实现:定义 messageRef 并通过 RuntimeService.startProcessInstanceByMessage() 触发。
- Start Error Event:当特定错误发生时触发,通常用于异常处理流程。
- Flowable 实现:配置 errorRef 并在错误发生时触发子流程。
- Start Escalation Event:当需要升级(如超时未处理)时触发。
- Flowable 实现:结合 escalationCode 和事件子流程。
- Start Signal Event:接收全局信号(如广播事件)时触发。
- Flowable 实现:通过 RuntimeService.signalEventReceived() 触发。
- Start Timer Event:在指定时间(如每天 9:00)或延时后触发。
- Flowable 实现:配置 timeDate 或 timeDuration(如 PT5M 表示 5 分钟)。
2. Activities(活动)
- Task:通用的用户任务,如填写表单或审批。
- Flowable 实现:通过 TaskService 分配任务,调用 complete() 完成。
- Service Task:系统自动执行的任务,如调用外部 API。
- Flowable 实现:使用 JavaDelegate 或 expression(如 ${bean.method()})实现逻辑。
- User Task:分配给特定用户或组的任务。
- Flowable 实现:配置 assignee(如 ${userId})或 candidateGroups,通过 TaskService.claim() 认领。
- Script Task:运行脚本(如 JavaScript 或 Groovy)来执行逻辑。
- Flowable 实现:配置 script 和 scriptFormat(如 javascript)。
- Business Rule Task:基于规则引擎(如 DMN)执行决策。
- Flowable 实现:结合 Flowable DMN 引擎,配置 ruleRef。
- Manual Task:需要人工操作但不涉及系统交互的任务。
- Flowable 实现:无需代码,标记为手动任务,流程继续。
3. Structural(结构)
- Subprocess:嵌套的子流程,可复用或模块化。
- Flowable 实现:定义 <subProcess>,支持独立的事务和变量作用域。
- Transaction:确保一组操作要么全成功,要么全失败。
- Flowable 实现:使用 <transaction> 标签,结合数据库事务。
- Ad-hoc Subprocess:运行时动态创建的子流程。
- Flowable 实现:配置 adHocSubProcess,支持动态任务。
- Event Subprocess:由特定事件触发的子流程。
- Flowable 实现:定义 <eventSubProcess>,绑定到事件(如错误或信号)。
4. Gateways(网关)
- Exclusive Gateway:根据条件选择单一路径。
- Flowable 实现:配置 conditionExpression(如 ${amount < 1000})。
- Parallel Gateway:启动多个并行分支或合并分支。
- Flowable 实现:自动分叉或等待所有分支完成。
- Inclusive Gateway:根据条件选择多条路径。
- Flowable 实现:支持动态评估条件,允许多路径并行。
- Complex Gateway:结合多种网关逻辑。
- Flowable 实现:自定义条件和分支逻辑。
5. Boundary Events(边界事件)
- Boundary Timer Event:在任务超时时触发。
- Flowable 实现:配置 timeDuration,绑定到任务。
- Boundary Error Event:捕获任务中的特定错误。
- Flowable 实现:配置 errorRef,跳转到错误处理流程。
- Boundary Signal Event:接收信号时触发。
- Flowable 实现:通过 signalRef 绑定信号。
- Boundary Message Event:接收消息时触发。
- Flowable 实现:通过 messageRef 绑定消息。
- Boundary Cancel Event:当事务取消时触发。
- Flowable 实现:绑定到事务子流程。
- Boundary Compensation Event:处理补偿逻辑(如撤销操作)。
- Flowable 实现:配置 compensationHandler。
6. Intermediate Catching Events(中间捕获事件)
- Intermediate Message Event:等待外部消息。
- Flowable 实现:通过 messageRef 和 RuntimeService.messageEventReceived()。
- Intermediate Timer Event:等待指定时间。
- Flowable 实现:配置 timeDuration 或 timeCycle。
- Intermediate Signal Event:等待信号。
- Flowable 实现:通过 signalRef。
- Intermediate Conditional Event:等待条件满足。
- Flowable 实现:配置 conditionExpression。
7. Intermediate Throwing Events(中间抛出事件)
- Intermediate Message Throw Event:发送消息。
- Flowable 实现:配置 messageRef,触发其他流程。
- Intermediate Signal Throw Event:发送信号。
- Flowable 实现:通过 signalRef。
- Intermediate Escalation Event:触发升级。
- Flowable 实现:配置 escalationCode。
- Intermediate Link Event:跨流程链接。
- Flowable 实现:通过 linkRef 跳转。
8. End Events(结束事件)
- End Event:正常结束流程。
- Flowable 实现:流程实例完成,状态更新。
- Error End Event:以错误状态结束。
- Flowable 实现:抛出 errorCode,触发父流程的错误处理。
- Escalation End Event:以升级状态结束。
- Flowable 实现:抛出 escalationCode。
- Message End Event:发送消息后结束。
- Flowable 实现:配置 messageRef。
- Signal End Event:发送信号后结束。
- Flowable 实现:配置 signalRef。
- Terminate End Event:强制终止流程。
- Flowable 实现:立即结束所有分支。
9. Save to PNGInputStream diagram = repositoryService.getProcessDiagram(processDefinitionId);
-
FileUtils.copyInputStreamToFile(diagram, new File("process.png"));
四、三个流程示例及节点作用分析
以下是三个典型的工作流示例,使用 Flowable 实现,并分析每个节点的作用。每个流程包括 BPMN 模型描述、节点作用、模拟流程和伪代码。
示例 1:请假审批流程
场景:员工提交请假申请,经理审批,超过 3 天的需总监审批。
BPMN 模型:
Start Event -> User Task (提交请假申请) -> Exclusive Gateway (假期天数?)
-> (天数 <= 3) -> User Task (经理审批) -> End Event
-> (天数 > 3) -> User Task (总监审批) -> End Event
节点作用分析:
- Start Event:员工手动触发,启动请假流程。
- 作用:创建流程实例,初始化变量(如 days)。
- User Task (提交请假申请):员工填写请假天数和原因。
- 作用:分配给申请人,收集输入数据,保存到流程变量。
- Exclusive Gateway (假期天数?):根据 days 决定走哪条路径。
- 作用:条件分支,${days <= 3} 或 ${days > 3}。
- User Task (经理审批):经理审批短假期。
- 作用:分配给经理,完成审批后更新流程状态。
- User Task (总监审批):总监审批长假期。
- 作用:分配给总监,处理复杂审批逻辑。
- End Event:流程结束。
- 作用:标记流程完成,记录历史数据。
模拟流程:
- 员工提交 2 天请假。
- 经理审批通过,流程结束。
- 员工提交 5 天请假。
- 经理审批通过后,转总监审批,总监通过,流程结束。
// 部署流程
repositoryService.createDeployment()
.addClasspathResource("leave.bpmn20.xml")
.deploy();
// 启动流程
Map<String, Object> variables = new HashMap<>();
variables.put("days", 2);
variables.put("applicant", "employee1");
ProcessInstance instance = runtimeService.startProcessInstanceByKey("leaveProcess", variables);
// 完成提交任务
Task submitTask = taskService.createTaskQuery().taskAssignee("employee1").singleResult();
taskService.complete(submitTask.getId());
// 经理审批
Task managerTask = taskService.createTaskQuery().taskAssignee("manager").singleResult();
taskService.complete(managerTask.getId());
// 如果天数 > 3,转总监审批
if (variables.get("days") > 3) {
Task directorTask = taskService.createTaskQuery().taskAssignee("director").singleResult();
taskService.complete(directorTask.getId());
}
示例 2:订单处理流程
场景:客户下订单,系统检查库存,库存不足时通知管理员,库存充足时发货。
BPMN 模型:
Start Message Event (接收订单) -> Service Task (检查库存) -> Exclusive Gateway (库存充足?)
-> (充足) -> Service Task (发货) -> End Event
-> (不足) -> User Task (通知管理员) -> End Event
节点作用分析:
- Start Message Event (接收订单):接收外部订单消息。
- 作用:通过消息触发流程,初始化订单数据。
- Service Task (检查库存):调用库存服务,检查商品数量。
- 作用:自动执行,设置流程变量 stockAvailable。
- Exclusive Gateway (库存充足?):根据 stockAvailable 分支。
- 作用:条件评估,${stockAvailable == true} 或 ${stockAvailable == false}。
- Service Task (发货):调用物流系统发货。
- 作用:自动执行,更新订单状态。
- User Task (通知管理员):通知管理员补货。
- 作用:分配给管理员,等待人工处理。
- End Event:流程结束。
- 作用:记录订单处理结果。
模拟流程:
- 客户下单,库存充足,自动发货,流程结束。
- 客户下单,库存不足,通知管理员,管理员确认后结束。
伪代码:
// 部署流程
repositoryService.createDeployment()
.addClasspathResource("order.bpmn20.xml")
.deploy();
// 接收订单消息
runtimeService.startProcessInstanceByMessage("orderReceived", Map.of("orderId", "123"));
// Service Task: 检查库存
public class CheckStockDelegate implements JavaDelegate {
@Override
public void execute(DelegateExecution execution) {
boolean stockAvailable = checkStock(execution.getVariable("orderId"));
execution.setVariable("stockAvailable", stockAvailable);
}
}
// Service Task: 发货
public class ShipOrderDelegate implements JavaDelegate {
@Override
public void execute(DelegateExecution execution) {
shipOrder(execution.getVariable("orderId"));
}
}
// 管理员处理
Task adminTask = taskService.createTaskQuery().taskCandidateGroup("admin").singleResult();
if (adminTask != null) {
taskService.complete(adminTask.getId());
}
示例 3:报销审批流程(带边界事件)
场景:员工提交报销申请,部门经理审批,超时未审批则升级到总监。
BPMN 模型:
Start Event -> User Task (提交报销申请) -> User Task (经理审批, Boundary Timer Event: 3天)
-> End Event
Boundary Timer Event -> User Task (总监审批) -> End Event
节点作用分析:
- Start Event:员工触发报销流程。
- 作用:初始化流程实例,设置变量(如 amount)。
- User Task (提交报销申请):员工填写报销金额和明细。
- 作用:收集数据,分配给申请人。
- User Task (经理审批):经理审批报销。
- 作用:分配给经理,等待审批结果。
- Boundary Timer Event (3天):如果经理 3 天未审批,触发升级。
- 作用:超时检测,跳转到总监审批。
- User Task (总监审批):总监处理超时报销。
- 作用:分配给总监,完成审批。
- End Event:流程结束。
- 作用:记录审批结果。
模拟流程:
- 员工提交 500 元报销,经理 2 天内审批通过,流程结束。
- 员工提交 1000 元报销,经理未在 3 天内审批,自动转总监,总监审批后结束。
// 部署流程
repositoryService.createDeployment()
.addClasspathResource("expense.bpmn20.xml")
.deploy();
// 启动流程
Map<String, Object> variables = new HashMap<>();
variables.put("amount", 500);
variables.put("applicant", "employee1");
runtimeService.startProcessInstanceByKey("expenseProcess", variables);
// 提交报销
Task submitTask = taskService.createTaskQuery().taskAssignee("employee1").singleResult();
taskService.complete(submitTask.getId());
// 经理审批
Task managerTask = taskService.createTaskQuery().taskAssignee("manager").singleResult();
taskService.complete(managerTask.getId());
// 超时转总监(由 Flowable 引擎自动处理)
Task directorTask = taskService.createTaskQuery().taskAssignee("director").singleResult();
if (directorTask != null) {
taskService.complete(directorTask.getId());
}
五、总结与建议
总结
- 基础知识:掌握 Java、Spring Boot、BPMN 2.0(包括其核心元素、XML 结构和执行语义)以及 Flowable 核心服务是使用 Flowable 的前提。
- 核心服务:RepositoryService、RuntimeService、TaskService、HistoryService 和 IdentityService 提供了全面的流程管理功能,覆盖部署、执行、任务、历史和用户管理。
- 节点作用:Flowable 支持完整的 BPMN 2.0 元素,从开始事件到结束事件,每个节点都有明确的作用,灵活组合可实现复杂流程。
- 流程示例:通过请假、订单、报销三个场景,展示了如何设计和实现工作流,涵盖了用户任务、网关、边界事件等关键节点。
学习建议
- 实践建模:使用 Flowable Modeler 创建 BPMN 流程,尝试导出 XML 并手动调整。
- 探索核心服务:通过 Flowable 的单元测试或小项目,调用每个核心服务的方法,理解其功能。
- 阅读源码:查看 Flowable 的示例项目(如 flowable-engine-examples)。
- 调试流程:使用 Flowable 的 REST API 或 UI 工具(如 Flowable IDM)监控流程实例,理解节点执行顺序。
- 扩展功能:尝试实现复杂逻辑,如动态分配用户、集成外部服务或添加事件监听器。
- 查阅文档:参考 Flowable 官方文档 (https://www.flowable.com/open-source/documentation/) 和 BPMN 2.0 标准。
745

被折叠的 条评论
为什么被折叠?



