☰
SpringBoot集成Activiti工作流引擎开发指南
2026/10/15 11:27:00 网站建设 项目流程

1. 为什么需要工作流引擎

在传统企业级应用开发中,业务流程管理往往是最复杂的部分之一。以请假审批流程为例,需要处理:

  • 员工提交申请
  • 主管审批
  • HR备案
  • 系统同步考勤记录
  • 结果通知申请人

如果采用硬编码方式实现,代码中会充满各种if-else分支,流程变更需要重新开发部署。而工作流引擎通过可视化流程设计+运行时引擎的方式,将业务流程从业务代码中解耦出来。

Activiti作为Apache旗下的开源工作流引擎,具有以下核心优势:

  1. 基于BPMN 2.0标准规范
  2. 轻量级设计,易于集成
  3. 丰富的Java API支持
  4. 活跃的社区生态

2. 环境准备与基础集成

2.1 依赖配置

在SpringBoot项目中引入Activiti 7的starter依赖:

<dependency> <groupId>org.activiti</groupId> <artifactId>activiti-spring-boot-starter</artifactId> <version>7.1.0.M6</version> </dependency>

关键依赖说明:

  • activiti-spring-boot-starter:核心引擎
  • mybatis-plus:Activiti 7默认使用MyBatis作为ORM框架
  • h2:内存数据库(开发环境推荐)

注意:生产环境建议使用MySQL等正式数据库,需额外配置数据源

2.2 自动配置原理

SpringBoot启动时会自动:

  1. 创建28张工作流相关表(ACT_开头)
  2. 初始化ProcessEngine流程引擎实例
  3. 配置事务管理
  4. 暴露REST API端点(需手动开启)

可以通过application.yml调整配置:

activiti: database-schema-update: true # 自动更新数据库结构 async-executor-activate: true # 启用异步执行器 history-level: audit # 历史记录级别

3. 流程设计与部署

3.1 BPMN 2.0设计规范

使用Eclipse插件或在线工具设计请假流程:

<bpmn2:process id="leaveProcess" name="请假流程"> <bpmn2:startEvent id="startEvent"/> <bpmn2:userTask id="leaderAudit" name="主管审批"/> <bpmn2:exclusiveGateway id="exclusiveGateway"/> <bpmn2:endEvent id="endEvent"/> <!-- 连线定义 --> </bpmn2:process>

关键元素说明:

  • UserTask:人工任务节点
  • ServiceTask:自动服务节点
  • ExclusiveGateway:排他网关(相当于if-else)
  • ParallelGateway:并行网关(相当于and)

3.2 流程部署API

通过RepositoryService部署流程:

@Autowired private RepositoryService repositoryService; public void deployProcess() { Deployment deployment = repositoryService.createDeployment() .addClasspathResource("processes/leave.bpmn20.xml") .name("请假流程") .deploy(); log.info("部署ID: {}", deployment.getId()); }

部署后可在ACT_RE_PROCDEF表查看流程定义。

4. 运行时流程控制

4.1 启动流程实例

@Autowired private RuntimeService runtimeService; public void startProcess(String businessKey) { Map<String, Object> variables = new HashMap<>(); variables.put("days", 3); // 流程变量 ProcessInstance instance = runtimeService.startProcessInstanceByKey( "leaveProcess", businessKey, variables ); }

4.2 任务处理

查询待办任务:

@Autowired private TaskService taskService; public List<Task> getTasks(String assignee) { return taskService.createTaskQuery() .taskAssignee(assignee) .list(); }

完成任务:

public void completeTask(String taskId) { Map<String, Object> variables = new HashMap<>(); variables.put("approved", true); taskService.complete(taskId, variables); }

5. 高级特性实现

5.1 监听器配置

实现任务分配逻辑:

@Component public class LeaderTaskListener implements TaskListener { @Override public void notify(DelegateTask task) { String dept = (String) task.getVariable("dept"); String leader = userService.findDeptLeader(dept); task.setAssignee(leader); } }

在BPMN中配置:

<bpmn2:userTask id="leaderAudit" activiti:assignee="${initiator}"> <bpmn2:extensionElements> <activiti:taskListener event="create" class="com.example.LeaderTaskListener"/> </bpmn2:extensionElements> </bpmn2:userTask>

5.2 异步执行器

对于耗时操作(如调用外部API),应配置为异步:

<bpmn2:serviceTask id="syncAttendance" activiti:class="com.example.SyncAttendanceDelegate" activiti:async="true"/>

需在application.yml中启用:

activiti: async-executor-activate: true async-executor-thread-pool-size: 10

6. 生产环境最佳实践

6.1 性能优化建议

  1. 数据库配置:

    spring: datasource: hikari: maximum-pool-size: 20 connection-timeout: 30000
  2. 历史数据归档:

    historyService.createHistoricProcessInstanceQuery() .finished() .listPage(0, 100) .forEach(instance -> { historyService.deleteHistoricProcessInstance(instance.getId()); });

6.2 集群部署方案

  1. 共享数据库配置
  2. 启用分布式锁:
    activiti: async-executor-lock-wait-time: 600000
  3. 建议使用Redis作为分布式锁存储

7. 常见问题排查

7.1 流程定义找不到

可能原因:

  1. 部署时XML文件路径错误
  2. 流程定义key不匹配
  3. 未正确配置资源目录

解决方案:

repositoryService.createProcessDefinitionQuery() .processDefinitionKey("leaveProcess") .list() // 验证流程定义是否存在

7.2 事务回滚问题

典型场景:

  • 业务流程异常时,需要回滚工作流状态

解决方案:

@Transactional public void approveLeave(Long leaveId) { leaveService.approve(leaveId); // 业务操作 taskService.complete(taskId); // 工作流操作 // 两者处于同一事务 }

关键点:确保业务Service和TaskService在同一个@Transactional中

8. 监控与运维

8.1 监控指标暴露

通过SpringBoot Actuator暴露:

management: endpoints: web: exposure: include: activiti

访问端点:

  • /actuator/activiti:流程引擎状态
  • /actuator/activiti/jobs:异步作业队列

8.2 日志配置建议

logging: level: org.activiti: DEBUG # 核心引擎日志 org.mybatis: WARN # 减少SQL日志

建议结合ELK等日志系统实现:

  • 流程执行轨迹追踪
  • 异常任务告警
  • 性能统计分析

9. 扩展开发建议

9.1 自定义表单开发

替代默认表单属性:

public class LeaveForm { @FormProperty(id = "reason", name = "请假原因") private String reason; @FormProperty(id = "days", name = "请假天数") private Integer days; }

在流程变量中自动转换:

formService.saveFormData(taskId, form);

9.2 REST API扩展

自定义Controller示例:

@RestController @RequestMapping("/api/workflow") public class WorkflowController { @PostMapping("/start") public Response startProcess(@RequestBody StartRequest request) { // 封装启动逻辑 } @GetMapping("/tasks") public List<TaskDTO> getTasks(@RequestParam String userId) { // 转换任务对象 } }

建议实现:

  • 分页查询
  • 条件过滤
  • DTO转换

10. 版本升级策略

从Activiti 5/6升级到7的注意事项:

  1. 数据库变更:

    ALTER TABLE ACT_RU_TASK ADD COLUMN BUSINESS_KEY_ VARCHAR(255);
  2. API变化:

    • 废弃IdentityService部分方法
    • FormService接口调整
  3. 推荐步骤:

    1. 备份数据库
    2. 在新环境测试迁移
    3. 逐步替换旧服务
    4. 数据校验

实际项目中,我们通过灰度发布方式,用3周时间完成了核心流程引擎的升级,期间处理的主要兼容性问题包括历史任务查询API的变化和表单属性的存储格式调整。

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

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

立即咨询