Spring Boot 2.x 整合 Activiti 7 工作流引擎:从零搭建一个请假审批Demo
2026/6/16 11:10:22 网站建设 项目流程

Spring Boot 2.x 整合 Activiti 7 工作流引擎:从零搭建一个请假审批Demo

在微服务架构盛行的今天,如何将传统的工作流引擎与现代开发框架无缝整合,成为许多企业级应用开发的关键挑战。Activiti 7作为新一代BPMN 2.0规范的实现,通过与Spring Boot 2.x的深度集成,为开发者提供了更简洁的配置方式和更强大的流程管理能力。本文将以一个真实的"员工请假-部门审批"业务场景为例,带你从零开始构建完整的解决方案。

1. 环境准备与项目初始化

1.1 创建Spring Boot项目

使用Spring Initializr快速生成项目骨架,选择以下核心依赖:

<dependencies> <dependency> <groupId>org.springframework.boot</groupId> <artifactId>spring-boot-starter-web</artifactId> </dependency> <dependency> <groupId>org.activiti</groupId> <artifactId>activiti-spring-boot-starter</artifactId> <version>7.1.0.M6</version> </dependency> <dependency> <groupId>mysql</groupId> <artifactId>mysql-connector-java</artifactId> <scope>runtime</scope> </dependency> <dependency> <groupId>org.projectlombok</groupId> <artifactId>lombok</artifactId> <optional>true</optional> </dependency> </dependencies>

1.2 数据库配置

在application.yml中配置数据源和Activiti参数:

spring: datasource: url: jdbc:mysql://localhost:3306/activiti_demo?useSSL=false&serverTimezone=UTC 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时自动创建表结构
  • history-level: 控制历史记录保存级别
  • async-executor-activate: 是否启用异步任务执行

2. 流程设计与建模

2.1 使用BPMN设计请假流程

在resources/processes目录下创建leave-request.bpmn20.xml文件:

<bpmn2:definitions> <bpmn2:process id="leaveProcess" name="员工请假流程"> <bpmn2:startEvent id="startEvent" /> <bpmn2:userTask id="applyLeave" name="提交请假申请" activiti:assignee="${applicant}" /> <bpmn2:userTask id="managerApprove" name="经理审批" activiti:assignee="${approver}" /> <bpmn2:exclusiveGateway id="decisionGateway" /> <bpmn2:endEvent id="endEvent" /> <!-- 流程连线定义 --> <bpmn2:sequenceFlow sourceRef="startEvent" targetRef="applyLeave" /> <bpmn2:sequenceFlow sourceRef="applyLeave" targetRef="managerApprove" /> <bpmn2:sequenceFlow sourceRef="managerApprove" targetRef="decisionGateway" /> <bpmn2:sequenceFlow sourceRef="decisionGateway" targetRef="endEvent"> <bpmn2:conditionExpression xsi:type="tFormalExpression"> ${approvalResult == true} </bpmn2:conditionExpression> </bpmn2:sequenceFlow> </bpmn2:process> </bpmn2:definitions>

2.2 流程变量设计

为请假流程定义关键变量:

变量名类型描述
applicantString申请人ID
approverString审批人ID
startDateDate请假开始日期
endDateDate请假结束日期
reasonString请假原因
approvalResultBoolean审批结果

3. 业务逻辑实现

3.1 创建请假服务层

@Service @RequiredArgsConstructor public class LeaveService { private final RuntimeService runtimeService; private final TaskService taskService; public String startLeaveProcess(LeaveRequest request) { Map<String, Object> variables = new HashMap<>(); variables.put("applicant", request.getApplicant()); variables.put("approver", request.getApprover()); variables.put("startDate", request.getStartDate()); variables.put("endDate", request.getEndDate()); variables.put("reason", request.getReason()); ProcessInstance instance = runtimeService.startProcessInstanceByKey( "leaveProcess", variables); return instance.getId(); } public List<Task> getUserTasks(String userId) { return taskService.createTaskQuery() .taskAssignee(userId) .list(); } public void completeTask(String taskId, boolean approved) { Map<String, Object> variables = new HashMap<>(); variables.put("approvalResult", approved); taskService.complete(taskId, variables); } }

3.2 构建REST API接口

@RestController @RequestMapping("/api/leave") @RequiredArgsConstructor public class LeaveController { private final LeaveService leaveService; @PostMapping public ResponseEntity<String> applyLeave(@RequestBody LeaveRequest request) { String processId = leaveService.startLeaveProcess(request); return ResponseEntity.ok("流程已启动,ID: " + processId); } @GetMapping("/tasks") public ResponseEntity<List<Task>> getTasks(@RequestParam String userId) { return ResponseEntity.ok(leaveService.getUserTasks(userId)); } @PostMapping("/approve") public ResponseEntity<String> approveTask( @RequestParam String taskId, @RequestParam boolean approved) { leaveService.completeTask(taskId, approved); return ResponseEntity.ok("任务处理完成"); } }

4. 流程监控与管理

4.1 历史数据查询

@Service @RequiredArgsConstructor public class ProcessHistoryService { private final HistoryService historyService; public List<HistoricProcessInstance> getCompletedProcesses() { return historyService.createHistoricProcessInstanceQuery() .finished() .list(); } public List<HistoricActivityInstance> getProcessActivities(String processId) { return historyService.createHistoricActivityInstanceQuery() .processInstanceId(processId) .orderByHistoricActivityInstanceStartTime() .asc() .list(); } }

4.2 流程可视化

利用Activiti提供的REST API获取流程图:

@GetMapping(value = "/diagram/{processId}", produces = MediaType.IMAGE_PNG_VALUE) public byte[] getProcessDiagram(@PathVariable String processId) throws IOException { ProcessInstance pi = runtimeService.createProcessInstanceQuery() .processInstanceId(processId) .singleResult(); BpmnModel model = repositoryService.getBpmnModel(pi.getProcessDefinitionId()); InputStream diagram = new DefaultProcessDiagramGenerator() .generateDiagram(model, "png", runtimeService.getActiveActivityIds(pi.getId())); return IOUtils.toByteArray(diagram); }

5. 高级配置与优化

5.1 自定义用户任务监听器

@Component public class LeaveTaskListener implements TaskListener { @Override public void notify(DelegateTask delegateTask) { if ("managerApprove".equals(delegateTask.getTaskDefinitionKey())) { // 发送审批通知 String message = String.format( "您有一条来自%s的请假申请待审批", delegateTask.getVariable("applicant")); System.out.println(message); } } }

5.2 异步执行器配置

在application.yml中启用异步执行:

activiti: async-executor-activate: true async-executor-core-pool-size: 5 async-executor-max-pool-size: 10 async-executor-queue-capacity: 100

5.3 性能优化建议

  1. 流程实例缓存:配置流程引擎缓存策略

    @Bean public ProcessEngineConfiguration processEngineConfiguration( DataSource dataSource, PlatformTransactionManager transactionManager) { SpringProcessEngineConfiguration config = new SpringProcessEngineConfiguration(); config.setDataSource(dataSource); config.setTransactionManager(transactionManager); config.setDatabaseSchemaUpdate("true"); config.setAsyncExecutorActivate(true); config.setProcessDefinitionCacheLimit(100); return config; }
  2. 批量操作:对于大量任务处理使用批量API

    taskService.createTaskQuery() .taskAssignee("user1") .listPage(0, 100) .forEach(task -> taskService.complete(task.getId()));
  3. 历史数据归档:定期归档历史数据减少主表压力

6. 常见问题排查

6.1 流程无法启动

检查步骤:

  1. 确认流程定义已正确部署
    repositoryService.createProcessDefinitionQuery() .processDefinitionKey("leaveProcess") .list();
  2. 验证必要流程变量是否设置
  3. 检查Activiti自动配置日志

6.2 任务分配异常

典型解决方案:

  • 确保assignee变量已正确设置
  • 实现自定义任务分配逻辑
    taskService.setAssignee(taskId, newAssignee);

6.3 性能瓶颈处理

监控指标:

ManagementService managementService = processEngine.getManagementService(); TablePage tablePage = managementService.createTablePageQuery() .tableName("ACT_RU_TASK") .listPage(0, 100);

优化方向:

  • 增加异步执行器线程池
  • 优化数据库索引
  • 拆分复杂流程为子流程

7. 安全与权限控制

7.1 集成Spring Security

@Configuration @EnableWebSecurity public class SecurityConfig extends WebSecurityConfigurerAdapter { @Override protected void configure(HttpSecurity http) throws Exception { http.authorizeRequests() .antMatchers("/api/leave/**").authenticated() .and() .httpBasic(); } }

7.2 流程数据权限过滤

taskService.createTaskQuery() .taskCandidateOrAssigned(userId) .list();

7.3 敏感数据保护

对流程变量进行加密处理:

variables.put("reason", encryptService.encrypt(reason));

8. 测试策略

8.1 单元测试配置

@SpringBootTest @ActivitiTest public class LeaveProcessTest { @Autowired private RuntimeService runtimeService; @Test public void testLeaveProcess() { // 测试流程启动和任务分配 Map<String, Object> vars = new HashMap<>(); vars.put("applicant", "user1"); vars.put("approver", "manager1"); ProcessInstance instance = runtimeService .startProcessInstanceByKey("leaveProcess", vars); assertNotNull(instance); } }

8.2 集成测试要点

测试场景覆盖:

  1. 正常审批流程
  2. 审批拒绝路径
  3. 多实例并发处理
  4. 超时自动处理

8.3 性能测试建议

使用JMeter模拟:

  • 并发流程启动
  • 批量任务处理
  • 长时间运行流程监控

9. 部署与运维

9.1 Docker容器化部署

示例Dockerfile:

FROM openjdk:11-jre COPY target/leave-app.jar /app.jar ENTRYPOINT ["java","-jar","/app.jar"]

9.2 数据库迁移策略

使用Liquibase管理数据库变更:

<dependency> <groupId>org.liquibase</groupId> <artifactId>liquibase-core</artifactId> </dependency>

9.3 监控端点配置

启用Actuator端点:

management: endpoints: web: exposure: include: health,info,activiti

10. 扩展与定制

10.1 自定义表单集成

集成方案选择:

  • 直接使用流程变量
  • 关联外部表单数据
  • 实现动态表单引擎

10.2 多租户支持

配置多数据源策略:

@Bean public MultiTenantProcessEngineConfiguration processEngineConfiguration() { MultiTenantProcessEngineConfiguration config = new MultiTenantProcessEngineConfiguration(); config.setTenantConfigurator(new CustomTenantConfigurator()); return config; }

10.3 移动端适配

构建轻量级API:

@GetMapping("/mobile/tasks") public List<MobileTask> getMobileTasks(@RequestParam String userId) { return taskService.createTaskQuery() .taskAssignee(userId) .list() .stream() .map(this::convertToMobileTask) .collect(Collectors.toList()); }

需要专业的网站建设服务?

联系我们获取免费的网站建设咨询和方案报价,让我们帮助您实现业务目标

立即咨询