别再手动写审批流了!用Spring Boot + Flowable 6.7.2快速搞定请假/报销流程(附完整代码)
告别低效审批基于Spring Boot与Flowable 6.7.2的智能流程引擎实战当企业OA系统中每天堆积上百条请假申请时技术团队往往陷入这样的困境审批逻辑与业务代码深度耦合每次流程变更都需要重新部署服务多级审批的权限判断散落在各个Controller层历史审批记录难以追溯统计分析。这种手工编写状态机的开发模式已经成为制约企业数字化转型的典型瓶颈。作为Java生态中最成熟的轻量级流程引擎Flowable 6.7.2通过BPMN 2.0标准实现了业务逻辑与流程控制的彻底解耦。本文将演示如何构建一个可复用的审批微服务其核心优势在于可视化配置通过BPMN流程图替代硬编码状态跳转动态路由基于业务变量的条件分支自动决策历史追溯完整的流程实例数据持久化快速适配相同引擎可支持请假、报销等不同场景1. 环境准备与基础配置1.1 项目初始化使用Spring Initializr创建项目时需特别注意依赖选择dependencies dependency groupIdorg.springframework.boot/groupId artifactIdspring-boot-starter-web/artifactId /dependency dependency groupIdorg.flowable/groupId artifactIdflowable-spring-boot-starter/artifactId version6.7.2/version /dependency dependency groupIdmysql/groupId artifactIdmysql-connector-java/artifactId scoperuntime/scope /dependency /dependencies关键配置项说明配置项示例值作用说明spring.datasource.urljdbc:mysql://localhost:3306/flowable?useSSLfalse流程引擎专用数据库flowable.async-executor-activatetrue启用异步任务执行器flowable.database-schema-updatetrue自动创建流程引擎表结构1.2 数据库初始化启动项目后Flowable会自动创建约60张表主要分为以下几类ACT_RE_存储流程定义和静态资源ACT_RU_运行时流程实例数据ACT_HI_历史流程实例数据ACT_ID_身份认证相关表建议为流程引擎配置独立数据库实例避免与企业业务库产生性能竞争。2. 流程建模与BPMN设计2.1 安装可视化插件推荐使用IntelliJ IDEA的Flowable BPMN插件进行建模打开插件市场搜索Flowable BPMN安装后重启IDE在resources/processes目录新建ask_for_leave.bpmn20.xml2.2 设计请假流程图典型的多级审批流程应包含以下元素process idask_for_leave name请假流程 isExecutabletrue !-- 定义审批节点 -- userTask idstaffSubmit name员工提交 flowable:assignee${staffId}/ userTask iddeptApprove name部门审批 flowable:assignee${deptLeaderId}/ userTask idhrApprove nameHR审批 flowable:assignee${hrId}/ !-- 网关决策 -- exclusiveGateway iddecisionGateway/ !-- 条件流转 -- sequenceFlow idtoApproval sourceRefdecisionGateway targetRefhrApprove conditionExpression xsi:typetFormalExpression ${days 3} /conditionExpression /sequenceFlow sequenceFlow iddirectEnd sourceRefdecisionGateway targetRefendEvent conditionExpression xsi:typetFormalExpression ${days 3} /conditionExpression /sequenceFlow /process关键设计原则任务分配使用flowable:assignee动态绑定处理人条件路由通过exclusiveGateway实现分支决策变量传递${variable}语法引用流程变量3. Spring Boot集成实战3.1 核心服务注入Flowable通过自动配置暴露以下关键服务Autowired private RuntimeService runtimeService; // 流程运行时管理 Autowired private TaskService taskService; // 任务操作 Autowired private HistoryService historyService; // 历史数据查询 Autowired private RepositoryService repositoryService; // 流程定义管理3.2 流程实例操作启动新流程实例的典型代码public String startLeaveProcess(LeaveRequest request) { MapString, Object variables new HashMap(); variables.put(staffId, request.getStaffId()); variables.put(days, request.getDays()); variables.put(reason, request.getReason()); ProcessInstance instance runtimeService.startProcessInstanceByKey( ask_for_leave, variables ); return instance.getId(); }审批任务处理的通用模式public void approveTask(String taskId, String approverId, boolean approved) { MapString, Object vars new HashMap(); vars.put(approved, approved); vars.put(approverId, approverId); taskService.complete(taskId, vars); }3.3 历史数据查询获取流程历史记录的示例public ListHistoricActivityInstance getProcessHistory(String processId) { return historyService.createHistoricActivityInstanceQuery() .processInstanceId(processId) .orderByHistoricActivityInstanceStartTime() .asc() .list(); }4. 高级功能实现4.1 动态任务分配通过监听器实现灵活的任务分配public class DynamicAssigneeListener implements TaskListener { Override public void notify(DelegateTask task) { String role (String) task.getVariable(approveRole); String assignee roleService.findAssigneeByRole(role); task.setAssignee(assignee); } }在BPMN中配置userTask idtask1 name审批任务 extensionElements flowable:taskListener eventcreate classcom.example.DynamicAssigneeListener/ /extensionElements /userTask4.2 会签与或签多人并行审批的实现方案userTask idmultiApprove name会签审批 multiInstanceLoopCharacteristics isSequentialfalse flowable:collection${approverList} flowable:elementVariableapprover completionCondition${nrOfCompletedInstances/nrOfInstances 0.6}/completionCondition /multiInstanceLoopCharacteristics /userTask4.3 流程版本控制当需要更新流程定义时public void deployNewVersion(String bpmnFile) { repositoryService.createDeployment() .addClasspathResource(bpmnFile) .enableDuplicateFiltering() .deploy(); // 自动迁移运行中的实例到新版本 repositoryService.updateProcessDefinitionHistoryTimeToLive( processDefinitionId, Duration.ofDays(30) ); }5. 生产环境最佳实践5.1 性能优化配置在application.yml中添加flowable: async-executor: core-pool-size: 10 max-pool-size: 50 queue-capacity: 1000 process-definition-cache-limit: 1005.2 监控与告警集成Prometheus监控指标Bean public FlowableMetrics metrics(ProcessEngine processEngine) { return new FlowableMetrics(processEngine); } Bean public MeterRegistryCustomizerMeterRegistry metricsCommonTags() { return registry - registry.config().commonTags(application, approval-service); }5.3 异常处理策略全局异常处理器示例ControllerAdvice public class FlowableExceptionHandler { ExceptionHandler(FlowableException.class) public ResponseEntityErrorResponse handleFlowableError(FlowableException ex) { ErrorResponse response new ErrorResponse( FLOW_ERR_ ex.getClass().getSimpleName(), ex.getMessage() ); return ResponseEntity.status(HttpStatus.CONFLICT).body(response); } }在实际项目部署中我们发现流程引擎的数据库连接池配置需要单独优化特别是在高并发审批场景下建议将连接数与业务库隔离配置。对于跨国企业的多时区支持可以通过在流程变量中携带时区信息在服务任务中自动转换时间显示。