Spring Boot 2.5 + Activiti 7.1 实战:手把手教你从零搭建一个请假审批流程(附完整源码)
Spring Boot 2.5 Activiti 7.1 实战从零构建企业级请假审批系统在数字化转型浪潮中业务流程自动化已成为企业提升运营效率的关键。想象这样一个场景当员工提交请假申请后系统自动触发审批流程主管手机即时收到待办提醒审批通过后自动同步至考勤系统——这种丝滑体验的背后正是工作流引擎在发挥作用。本文将带您使用Spring Boot 2.5和Activiti 7.1构建一个完整的请假审批系统涵盖从流程设计到API开发的每个技术细节。1. 环境搭建与基础配置1.1 项目初始化与依赖管理新建Spring Boot项目时建议使用Spring Initializr选择以下核心依赖WebSpring Web MVC支持Security基础权限控制可选Lombok简化实体类编写MySQL Driver数据库连接在pom.xml中添加Activiti 7.1专属依赖dependency groupIdorg.activiti/groupId artifactIdactiviti-spring-boot-starter/artifactId version7.1.0.M6/version /dependency dependency groupIdorg.activiti/groupId artifactIdactiviti-image-generator/artifactId version7.1.0.M6/version /dependency关键配置项application.ymlspring: datasource: url: jdbc:mysql://localhost:3306/activiti_demo?useSSLfalse username: root password: yourpassword driver-class-name: com.mysql.cj.jdbc.Driver activiti: database-schema-update: true history-level: full async-executor-activate: false注意database-schema-update: true会在启动时自动创建28张Activiti表生产环境建议改为false后手动执行SQL脚本1.2 数据库表结构解析Activiti 7.1主要生成五类表表前缀说明示例表名ACT_RE流程定义与部署资源ACT_RE_DEPLOYMENTACT_RU运行时流程实例与任务ACT_RU_TASKACT_HI历史流程实例与变量ACT_HI_PROCINSTACT_GE通用数据如二进制资源ACT_GE_BYTEARRAYACT_ID身份信息用户/组ACT_ID_USER通过spring.activiti.db-history-level可控制历史数据存储粒度none不记录历史activity仅记录节点事件audit记录节点与变量默认full完整历史含细节2. 流程设计与模型部署2.1 使用BPMN 2.0设计请假流程典型请假审批包含以下节点开始事件员工提交申请用户任务直属主管审批排他网关根据天数判断路径用户任务HR备案3天假期结束事件流程终止使用Eclipse插件或在线工具如bpmn.io绘制流程图时需注意bpmn2:sequenceFlow idFlow_1 sourceRefGateway_1 targetRefTask_HR name大于3天 bpmn2:conditionExpression xsi:typebpmn2:tFormalExpression ${days 3} /bpmn2:conditionExpression /bpmn2:sequenceFlow2.2 程序化部署流程定义通过RepositoryService实现动态部署public String deployProcess(MultipartFile file) throws IOException { Deployment deployment repositoryService.createDeployment() .addInputStream(file.getOriginalFilename(), file.getInputStream()) .name(请假流程V1) .deploy(); return deployment.getId(); }检查部署结果SELECT * FROM ACT_RE_PROCDEF WHERE KEY_ leaveProcess;3. 核心API开发实战3.1 流程实例启动与任务查询启动流程实例需关联业务Keypublic String startProcess(Long leaveId, String userId) { MapString, Object variables new HashMap(); variables.put(applicant, userId); variables.put(days, 5); // 从数据库读取实际天数 ProcessInstance instance runtimeService.startProcessInstanceByKey( leaveProcess, LEAVE_ leaveId, variables ); return instance.getId(); }任务查询支持多条件过滤public ListTask getTasksByUser(String userId) { return taskService.createTaskQuery() .taskCandidateOrAssigned(userId) .orderByTaskCreateTime().desc() .list(); }3.2 任务审批与流程变量完成任务时更新审批意见public void completeTask(String taskId, boolean approved, String comment) { MapString, Object variables new HashMap(); variables.put(approved, approved); taskService.addComment(taskId, null, comment); taskService.complete(taskId, variables); }重要流程变量会持久化到ACT_RU_VARIABLE表复杂对象需实现Serializable接口4. 高级功能实现4.1 动态任务分配通过监听器实现灵活指派EventListener public void onTaskCreated(ActivitiEvent event) { if (event.getType() ActivitiEventType.TASK_CREATED) { Task task ((ActivitiEntityEvent)event).getEntity(); if (leaderAudit.equals(task.getTaskDefinitionKey())) { String deptLeader userService.getDeptLeader( runtimeService.getVariable(task.getExecutionId(), applicant) ); taskService.setAssignee(task.getId(), deptLeader); } } }4.2 流程版本控制当需要修改已部署的流程时修改BPMN文件后重新部署生成新版本默认新实例使用最新版本旧实例继续按原定义执行查询所有版本ListProcessDefinition definitions repositoryService .createProcessDefinitionQuery() .processDefinitionKey(leaveProcess) .list();5. 系统集成与优化5.1 与Spring Security集成实现用户-任务关联Override protected void configure(AuthenticationManagerBuilder auth) throws Exception { auth.userDetailsService(username - { User user userRepository.findByUsername(username); return new org.springframework.security.core.userdetails.User( user.getUsername(), user.getPassword(), AuthorityUtils.createAuthorityList(user.getRoles()) ); }); }5.2 性能优化建议异步执行配置spring.activiti.async-executor-activate: true历史数据清理定时任务删除ACT_HI_*表旧数据缓存配置启用流程定义缓存# 在application.properties中添加 spring.activiti.process-definition-cache-limit100开发过程中遇到最多的问题往往是网关条件表达式书写错误建议在测试环境开启DEBUG日志logging.level.org.activitiDEBUG正文结束