Activiti 5.22 实战入门:从零构建请假审批系统
在数字化转型浪潮中,工作流引擎已成为企业级应用的核心组件。作为Java领域最成熟的流程引擎之一,Activiti以其轻量级架构和BPMN2.0标准支持,成为众多企业的首选方案。本文将基于5.22版本,通过一个完整的请假审批案例,带您从环境搭建到流程实例运行,掌握Activiti的核心使用逻辑。
1. 环境准备与基础配置
1.1 项目初始化
新建Spring Boot项目时,需添加以下关键依赖(以Maven为例):
<dependency> <groupId>org.activiti</groupId> <artifactId>activiti-spring-boot-starter-basic</artifactId> <version>5.22.0</version> </dependency> <dependency> <groupId>com.h2database</groupId> <artifactId>h2</artifactId> <scope>runtime</scope> </dependency>配置文件中需要声明数据库连接和Activiti基础参数:
# 启用自动创建表结构 spring.activiti.database-schema-update=true # 禁用Activiti自带的用户体系 spring.activiti.db-identity-used=false1.2 表结构快速解读
Activiti的25张表按功能可分为五类:
| 表前缀 | 功能描述 | 典型表举例 |
|---|---|---|
| ACT_RE | 流程定义与资源存储 | ACT_RE_PROCDEF(流程定义) |
| ACT_RU | 运行时实例数据 | ACT_RU_TASK(运行中任务) |
| ACT_HI | 历史记录 | ACT_HI_PROCINST(历史实例) |
| ACT_ID | 身份认证(通常不使用) | ACT_ID_USER(用户信息) |
| ACT_GE | 通用数据 | ACT_GE_BYTEARRAY(二进制) |
提示:开发阶段建议开启
database-schema-update,生产环境应改为false并通过SQL脚本管理表结构
2. 请假流程设计与部署
2.1 BPMN可视化设计
使用Eclipse插件或在线工具Camunda Modeler设计请假流程:
<!-- 简化的请假流程定义 --> <process id="leaveProcess" name="员工请假流程"> <startEvent id="start"/> <userTask id="applyLeave" name="提交请假申请"/> <userTask id="managerApprove" name="主管审批"/> <exclusiveGateway id="decision"/> <endEvent id="end"/> <sequenceFlow sourceRef="start" targetRef="applyLeave"/> <sequenceFlow sourceRef="applyLeave" targetRef="managerApprove"/> <sequenceFlow sourceRef="managerApprove" targetRef="decision"/> <sequenceFlow sourceRef="decision" targetRef="end"> <conditionExpression>${approved}</conditionExpression> </sequenceFlow> </process>2.2 流程部署实战
通过RepositoryService部署流程定义:
public class ProcessDeployer { @Autowired private RepositoryService repositoryService; public void deployProcess() { Deployment deployment = repositoryService.createDeployment() .addClasspathResource("processes/leave.bpmn20.xml") .name("员工请假流程v1.0") .deploy(); System.out.println("部署ID: " + deployment.getId()); } }部署成功后可在ACT_RE_PROCDEF表中查询到流程定义信息,关键字段包括:
ID_: 流程定义唯一标识(格式:processKey:version:generatedId)KEY_: 流程业务标识(对应XML中的id属性)VERSION_: 版本号(每次部署相同KEY的流程会自动递增)
3. 流程实例运行与任务处理
3.1 启动流程实例
模拟员工张三发起请假申请:
public class LeaveStarter { @Autowired private RuntimeService runtimeService; public void startProcess() { Map<String, Object> variables = new HashMap<>(); variables.put("applicant", "zhangsan"); variables.put("days", 3); ProcessInstance instance = runtimeService.startProcessInstanceByKey( "leaveProcess", variables); System.out.println("流程实例ID: " + instance.getId()); } }此时数据库变化:
ACT_RU_EXECUTION新增执行记录ACT_RU_TASK生成待办任务(提交请假申请)ACT_RU_VARIABLE存储流程变量
3.2 任务处理与审批
获取并完成任务的标准操作:
public class TaskServiceDemo { @Autowired private TaskService taskService; public void completeTask(String taskId) { // 查询任务 Task task = taskService.createTaskQuery() .taskId(taskId) .singleResult(); // 完成任务时传递审批结果 Map<String, Object> vars = new HashMap<>(); vars.put("approved", true); taskService.complete(taskId, vars); } }任务处理后的状态迁移:
- 当前任务从
ACT_RU_TASK删除 - 新任务(主管审批)插入
ACT_RU_TASK - 历史记录写入
ACT_HI_TASKINST
4. 高级特性与实战技巧
4.1 流程变量管理
Activiti支持多种变量类型:
| 变量类型 | Java类型 | 数据库存储方式 |
|---|---|---|
| 字符串 | String | ACT_RU_VARIABLE.TEXT_ |
| 数字 | Integer/Double等 | ACT_RU_VARIABLE.DOUBLE_ |
| 序列化对象 | 实现Serializable的类 | ACT_RU_VARIABLE.BYTES_ |
| 自定义类型 | 实现VariableType接口 | 根据实现决定 |
设置变量的三种方式:
// 1. 启动流程时设置 runtimeService.startProcessInstanceWithVariables(); // 2. 任务完成时设置 taskService.complete(taskId, variables); // 3. 运行时设置 runtimeService.setVariable(executionId, varName, value);4.2 历史数据查询
通过HistoryService获取已完成流程信息:
// 查询某用户发起的流程 List<HistoricProcessInstance> instances = historyService .createHistoricProcessInstanceQuery() .startedBy("zhangsan") .list(); // 获取流程变量历史 List<HistoricVariableInstance> variables = historyService .createHistoricVariableInstanceQuery() .processInstanceId(instanceId) .list();4.3 异常处理实践
常见问题及解决方案:
外键约束错误
- 现象:删除部署时报错
- 方案:使用级联删除
repositoryService.deleteDeployment(deploymentId, true);事务超时问题
- 现象:长时间运行流程报TransactionException
- 方案:调整事务超时时间
spring.activiti.async-executor-activate=true spring.activiti.async-executor-default-timeout=300000流程版本冲突
- 现象:新部署流程后旧实例报版本错误
- 方案:明确指定流程定义版本
runtimeService.startProcessInstanceById( "leaveProcess:2:32503", variables);
5. 性能优化建议
经过多个项目实践,总结出以下优化方向:
数据库层面:
- 定期清理历史数据(配置
history-level为适当级别) - 为常用查询字段建立索引(如
ACT_RU_TASK.ASSIGNEE_)
代码层面:
- 批量操作使用
saveBatch方法替代循环单条处理 - 避免在流程变量中存储大对象
架构层面:
graph TD A[客户端] --> B[API网关] B --> C[业务微服务] C --> D[Activiti服务] D --> E[数据库集群]典型优化配置示例:
# 启用异步执行器处理定时任务 spring.activiti.async-executor-activate=true # 设置JPA批量插入大小 spring.jpa.properties.hibernate.jdbc.batch_size=50 # 历史数据保留策略 spring.activiti.history-level=audit在电商订单审核系统中,通过上述优化方案,流程处理吞吐量提升了3倍,数据库负载降低40%。关键点在于合理控制历史数据量和采用异步处理机制。