别再手动画流程图了!用Flowable 6.8.1 + SpringBoot 3分钟搞定请假审批系统
3分钟集成Flowable 6.8.1SpringBoot请假审批系统实战指南当团队需要快速上线一个请假审批模块时传统开发方式往往需要编写大量状态流转代码。去年我们团队就遇到过这种情况——产品经理突然要求三天内上线OA系统的请假功能而当时我们连数据库表都还没设计。那次经历让我深刻体会到工作流引擎的价值用FlowableBPMN标准文件我们最终只花了1小时就完成了核心流程开发。1. 环境准备与基础配置1.1 初始化SpringBoot项目创建标准的SpringBoot项目时建议使用最新的稳定版本。以下是必须的依赖配置基于Mavendependencies dependency groupIdorg.flowable/groupId artifactIdflowable-spring-boot-starter/artifactId version6.8.1/version /dependency dependency groupIdcom.mysql/groupId artifactIdmysql-connector-j/artifactId scoperuntime/scope /dependency /dependencies提示Flowable 6.8.1默认使用Spring Boot 2.7.x若使用Spring Boot 3.x需要额外处理兼容性问题1.2 数据库配置优化在application.yml中配置数据库连接时建议增加以下优化参数spring: datasource: url: jdbc:mysql://localhost:3306/flowable-demo?useSSLfalseserverTimezoneUTCallowPublicKeyRetrievaltrue username: root password: 123456 hikari: maximum-pool-size: 15 minimum-idle: 5 flowable: database-schema-update: true async-executor-activate: false关键配置说明参数推荐值作用database-schema-updatetrue自动创建/更新数据库表结构async-executor-activatefalse开发环境关闭异步执行器maximum-pool-size10-20根据并发量调整连接池大小2. 流程建模与BPMN设计2.1 可视化流程设计使用Flowable Modeler设计请假流程时推荐采用以下节点结构开始事件 → 提交申请(用户任务) → 主管审批(用户任务) → 网关 → → [同意] 人事备案(用户任务) → 结束事件 → [拒绝] 返回申请人在IntelliJ IDEA中安装BPMN插件后可以直接编辑可视化流程图。这是我常用的节点配置模板userTask idleaderAudit name主管审批 flowable:candidateGroupsdeptLeader extensionElements flowable:formProperty idauditResult name审批结果 typeenum requiredtrue flowable:value idagree name同意/ flowable:value idreject name拒绝/ /flowable:formProperty /extensionElements /userTask2.2 高效部署流程的三种方式Classpath资源部署适合开发环境repositoryService.createDeployment() .addClasspathResource(processes/leave-request.bpmn20.xml) .name(请假流程v1.0) .deploy();数据库存储部署适合生产环境DeploymentBuilder deployment repositoryService.createDeployment(); deployment.addBytes( leave-request.bpmn20.xml, Files.readAllBytes(Paths.get(/path/to/file.bpmn)) );动态模型部署适合可视化编辑器集成BpmnModel model new BpmnJsonConverter() .convertToBpmnModel(JsonNodeFactory.instance.objectNode()); repositoryService.createDeployment() .addBpmnModel(dynamic-model.bpmn20.xml, model) .deploy();3. 核心业务逻辑实现3.1 启动流程实例的最佳实践在Controller层处理流程启动时建议采用DTO模式PostMapping(/start) public Result startProcess(RequestBody LeaveRequestDTO request) { // 1. 业务数据持久化 LeaveRecord record leaveService.createRecord(request); // 2. 设置流程变量 MapString, Object variables new HashMap(); variables.put(applicant, currentUserId()); variables.put(days, request.getDays()); variables.put(recordId, record.getId()); // 3. 启动流程实例 ProcessInstance instance runtimeService.startProcessInstanceByKey( leaveProcess, businessKey_ record.getId(), variables ); return Result.success(instance.getId()); }注意务必保持业务ID与流程实例的businessKey关联这是后续数据关联的关键3.2 任务查询与处理的性能优化处理分页查询任务列表时推荐使用Native Query提升性能public PageInfoTaskVO queryUserTasks(TaskQueryDTO query) { // 使用原生SQL查询提高性能 String sql SELECT T.*, P.NAME_ as PROCESS_NAME FROM ACT_RU_TASK T JOIN ACT_RE_PROCDEF P ON T.PROC_DEF_ID_ P.ID_ WHERE T.ASSIGNEE_ #{userId} ORDER BY T.CREATE_TIME_ DESC; PageHelper.startPage(query.getPageNum(), query.getPageSize()); ListMapString, Object tasks taskMapper.selectByNativeQuery(sql, query.getUserId()); // 转换为VO对象 ListTaskVO list tasks.stream() .map(this::convertToVO) .collect(Collectors.toList()); return new PageInfo(list); }任务处理时的完整事务控制示例Transactional public void completeTask(String taskId, TaskCompleteDTO dto) { // 1. 验证任务状态 Task task taskService.createTaskQuery() .taskId(taskId) .singleResult(); if (task null) { throw new BusinessException(任务不存在或已完成); } // 2. 更新业务数据 leaveService.updateStatus( extractBusinessKey(task.getProcessInstanceId()), dto.getStatus() ); // 3. 设置流程变量 MapString, Object variables new HashMap(); variables.put(auditComment, dto.getComment()); variables.put(auditor, currentUserId()); // 4. 完成任务 taskService.complete(taskId, variables); }4. 生产环境进阶配置4.1 高可用配置方案在application.yml中添加集群配置flowable: async-executor: activate: true core-pool-size: 5 max-pool-size: 10 queue-size: 100 lock-poll-rate: 500 lock-wait-time: 5m关键集群参数说明lock-poll-rate: 锁获取频率毫秒lock-wait-time: 最大锁等待时间queue-size: 异步任务队列容量4.2 性能监控与调优集成Prometheus监控的配置示例Configuration public class FlowableMetricsConfig { Bean public MeterBinder flowableMetrics( ProcessEngine processEngine) { return binder - { new FlowableMetrics(processEngine) .bindTo(binder); }; } }常见性能瓶颈及解决方案瓶颈类型症状解决方案数据库IO任务查询慢增加ACT_RU_TASK索引内存泄漏长时间运行OOM定期清理历史数据线程阻塞异步任务堆积调整线程池大小4.3 历史数据归档策略配置自动归档的示例Scheduled(cron 0 0 2 * * ?) public void archiveProcessInstances() { historyService.createHistoricProcessInstanceQuery() .finishedBefore(DateUtils.addDays(new Date(), -30)) .list() .forEach(instance - { // 归档到MongoDB mongoTemplate.save(instance, archived_processes); // 删除原始数据 historyService.deleteHistoricProcessInstance(instance.getId()); }); }在实际项目中我们团队通过这套方案将审批系统的开发效率提升了80%。最让我惊喜的是当业务需要增加审批层级时只需要在BPMN文件中插入新的节点完全不需要修改Java代码。这种灵活性让我们在应对紧急需求变更时游刃有余。
本文来自互联网用户投稿,该文观点仅代表作者本人,不代表本站立场。本站仅提供信息存储空间服务,不拥有所有权,不承担相关法律责任。如若转载,请注明出处:http://www.coloradmin.cn/o/2458284.html
如若内容造成侵权/违法违规/事实不符,请联系多彩编程网进行投诉反馈,一经查实,立即删除!