Activiti:轻量级 Java 工作流引擎
FreeGuideOnline
46阅读
2026-07-03
xml org.activiti activiti-spring-boot-starter 7.1.0.M6
Spring Boot 会自动配置 Activiti 引擎,并扫描 `classpath:processes/` 下的 `.bpmn20.xml` 或 `.bpmn` 文件。
### 编写第一个流程:简单请假流程
在 `src/main/resources/processes/` 下创建 `leave.bpmn20.xml`:
```xml
<?xml version="1.0" encoding="UTF-8"?>
<definitions xmlns="http://www.omg.org/spec/BPMN/20100524/MODEL"
xmlns:activiti="http://activiti.org/bpmn"
targetNamespace="http://www.activiti.org/processdef">
<process id="leaveProcess" name="请假流程" isExecutable="true">
<startEvent id="start" />
<sequenceFlow sourceRef="start" targetRef="apply" />
<userTask id="apply" name="提交请假申请" activiti:assignee="${employee}" />
<sequenceFlow sourceRef="apply" targetRef="managerAudit" />
<userTask id="managerAudit" name="经理审批" activiti:assignee="${manager}" />
<sequenceFlow sourceRef="managerAudit" targetRef="end" />
<endEvent id="end" />
</process>
</definitions>
启动流程并完成任务
在服务类中注入 RuntimeService 和 TaskService:
@Autowired
private RuntimeService runtimeService;
@Autowired
private TaskService taskService;
public void startLeaveProcess() {
// 设置流程变量,指定参与者
Map<String, Object> vars = new HashMap<>();
vars.put("employee", "张三");
vars.put("manager", "李经理");
// 启动流程实例
ProcessInstance instance = runtimeService
.startProcessInstanceByKey("leaveProcess", vars);
// 查询张三的任务并完成
Task applyTask = taskService.createTaskQuery()
.taskAssignee("张三").singleResult();
taskService.complete(applyTask.getId());
// 查询李经理的任务并完成
Task auditTask = taskService.createTaskQuery()
.taskAssignee("李经理").singleResult();
taskService.complete(auditTask.getId());
// 此时流程结束
}
流程设计:从简单到复杂
实际项目中流程远比线性复杂,下面介绍常见模式。
排他网关 (Exclusive Gateway)
用于根据条件走不同的分支。例如请假天数小于3天由经理审核,否则由总监审核。
BPMN 片段:
<exclusiveGateway id="gateway1" />
<sequenceFlow sourceRef="gateway1" targetRef="managerAudit">
<conditionExpression xsi:type="tFormalExpression">${days <= 3}</conditionExpression>
</sequenceFlow>
<sequenceFlow sourceRef="gateway1" targetRef="directorAudit">
<conditionExpression xsi:type="tFormalExpression">${days > 3}</conditionExpression>
</sequenceFlow>
服务任务 (Service Task)
自动执行 Java 代码或调用外部服务。例如在流程中发送邮件、记录日志。
简单实现:activiti:class="com.example.MyJavaDelegate",该类需实现 JavaDelegate 接口:
public class SendEmailDelegate implements JavaDelegate {
@Override
public void execute(DelegateExecution execution) {
String applicant = (String) execution.getVariable("employee");
// 发送邮件逻辑
System.out.println("发送邮件给 " + applicant);
}
}
并行网关 (Parallel Gateway) 与包容网关 (Inclusive Gateway)
用于多任务并行执行或多条件分支。画图时注意分叉与合并配对。
子流程与调用活动
- 子流程 (Sub Process):在流程内部嵌套一个子流程,适用于复杂任务的分解。
- 调用活动 (Call Activity):调用另一个独立的流程定义,实现流程复用。
Activiti 核心 API 一览
熟悉以下服务接口是使用 Activiti 的关键。
| API 服务 | 作用 |
|---|---|
RepositoryService |
管理流程定义和部署(部署、查询、删除) |
RuntimeService |
启动、查询、操作流程实例与执行对象 |
TaskService |
管理用户任务(认领、完成、委派、加签等) |
HistoryService |
查询历史流程实例、任务和活动记录 |
ManagementService |
引擎管理和维护,如查询作业(Job)、执行命令行 |
示例:查询当前用户的任务
List<Task> tasks = taskService.createTaskQuery()
.taskAssignee("李经理")
.processDefinitionKey("leaveProcess")
.list();
流程部署与版本管理
部署方式
- 自动部署:Spring Boot 启动时扫描
processes文件夹。 - 编程式部署:通过
RepositoryService从InputStream或资源文件部署。
repositoryService.createDeployment()
.addClasspathResource("processes/leave.bpmn20.xml")
.deploy();
版本机制
每次部署相同 key 的流程定义会生成新版本。默认启动流程时会使用最新版本,历史运行中的实例继续沿用旧版本定义。
Activiti 与 Spring Boot 深度集成
Spring Boot Starter 为我们做了大量自动配置,可进一步自定义。
配置数据源
Activiti 默认使用项目的数据源,流程数据会与业务数据存储在同一个数据库。可以通过配置 spring.activiti 前缀属性调整行为,例如:
spring.activiti.database-schema-update=true
spring.activiti.db-history-used=true
spring.activiti.history-level=full