SpringBoot与Flowable实现极简请假审批流程
1. 项目概述SpringBoot一行代码搞定请假审批流程这个标题乍看有些夸张但确实反映了现代Java开发中一个非常实用的场景。作为在OA系统开发中摸爬滚打多年的老手我见过太多团队在审批流实现上过度设计。实际上对于中小型企业的标准请假审批用SpringBoot的自动化配置特性完全可以极简实现。核心思路是利用SpringBoot Starter的自动装配机制配合Activiti或Flowable这样的轻量级工作流引擎。通过预定义的审批规则配置开发者只需要关注业务实体定义审批流程的流转、通知等繁琐细节都可以交给框架处理。这种方案特别适合5人以下审批层级的场景实测从零搭建到上线不超过2小时。2. 技术选型与准备2.1 基础框架选择首先需要明确的是所谓一行代码并非字面意思而是强调通过合理的架构设计将复杂度隐藏在底层。我的技术栈组合是SpringBoot 2.7.x自动配置核心Flowable 6.7.0比Activiti更轻量Lombok减少样板代码MySQL 8.0事务支持完善选择Flowable而非Activiti的原因主要有三点内存占用减少约40%REST API开箱即用与SpringBoot的集成更无感知2.2 依赖配置在pom.xml中关键依赖如下dependency groupIdorg.flowable/groupId artifactIdflowable-spring-boot-starter/artifactId version6.7.0/version /dependency dependency groupIdorg.springframework.boot/groupId artifactIdspring-boot-starter-data-jpa/artifactId /dependency特别注意需要排除SpringSecurity自动配置除非确实需要exclusion groupIdorg.springframework.boot/groupId artifactIdspring-boot-starter-security/artifactId /exclusion3. 核心实现解析3.1 审批流程定义在resources/processes目录下创建leave-approval.bpmn20.xml文件process idleaveApproval nameLeave Approval Process startEvent idstart/ userTask idleaderApproval name直属领导审批 flowable:assignee${applicant.directLeader}/ sequenceFlow sourceRefstart targetRefleaderApproval/ endEvent idend/ /process这个最简单的流程定义了开始节点领导审批节点动态指定审批人结束节点3.2 业务实体设计请假单实体关键字段Entity Data public class LeaveApplication { Id GeneratedValue private Long id; private String applicant; // 申请人 private String directLeader; // 直属领导 private LocalDate startDate; private LocalDate endDate; private String reason; Enumerated(EnumType.STRING) private LeaveStatus status; // 审批状态 }3.3 传说中的一行代码在Service层实现审批触发Transactional public void startApproval(LeaveApplication leave) { runtimeService.startProcessInstanceByKey( leaveApproval, Map.of(applicant, leave) ); }这行代码的背后Flowable自动完成了流程实例创建第一个审批任务的生成审批人分配历史记录初始化4. 进阶优化技巧4.1 自动审批人解析实践中建议实现ApproverResolver接口public interface ApproverResolver { String resolveDirectLeader(String applicant); } // 在流程启动时自动注入 runtimeService.startProcessInstanceByKey( leaveApproval, Map.of( applicant, leave, directLeader, approverResolver.resolveDirectLeader(leave.getApplicant()) ) );4.2 审批状态同步通过事件监听实现状态自动更新EventListener public void onTaskCompleted(TaskCompletedEvent event) { leaveRepo.updateStatus( event.getProcessInstanceId(), event.getApproved() ? APPROVED : REJECTED ); }4.3 审批超时处理在bpmn文件中添加定时边界事件boundaryEvent idtimeout attachedToRefleaderApproval timerEventDefinition timeDurationPT24H/timeDuration /timerEventDefinition /boundaryEvent5. 生产环境注意事项事务管理确保流程引擎操作与业务操作在同一个事务中Transactional // 必须添加 public void approve(String taskId) { taskService.complete(taskId); updateBizStatus(); }性能调优设置asyncExecutorActivatetrue启用异步执行调整history级别为audit默认是full异常处理捕获FlowableOptimisticLockingException实现自动重试数据库选择MySQL建议使用InnoDB引擎PostgreSQL性能更佳6. 常见问题排查6.1 流程定义未加载检查点application.yml中是否配置flowable: check-process-definitions: truebpmn文件是否在resources/processes/目录下6.2 审批人无法显示典型原因流程变量未正确传递使用了错误的变量名区分大小写调试方法runtimeService.getVariable(executionId, directLeader);6.3 历史数据缺失需要检查history配置级别是否手动清理了ACT_HI_*表7. 扩展建议对于更复杂的场景可以考虑动态分支审批exclusiveGateway iddecision/ sequenceFlow sourceRefdecision targetRefhrApproval conditionExpression xsi:typetFormalExpression ![CDATA[${days 3}]] /conditionExpression /sequenceFlow会签模式多人审批userTask idgroupApproval flowable:candidateUsersuser1,user2,user3/与钉钉/企业微信集成// 审批通过后调用第三方API taskService.complete(taskId, Map.of( callbackUrl, https://oapi.dingtalk.com/... ));这套方案在我参与的多个中小型企业OA系统中稳定运行最长的一个已经连续工作3年多。关键是要清楚它的边界——适合标准化程度高、审批逻辑简单的场景。对于特别复杂的流程还是建议采用专业的BPM平台。
上一篇/下一篇内容由系统自动关联
返回资讯列表 →