Camunda:BPMN 自动化与决策引擎
Camunda:BPMN 自动化与决策引擎
你是否需要为请假审批、订单处理或用户引导流程实现自动化?Camunda 是一个轻量级、开源的工作流和决策自动化平台,它让你能够用标准的 BPMN(业务流程模型与标记法)和 DMN(决策模型与标记法)来定义、执行和监控流程。无论你是 Java 开发者还是希望无代码管理流程的业务用户,Camunda 都能提供对应的工具。本教程将带你从零开始,理解 Camunda 的核心概念,搭建第一个流程,并驱动它运行。
Camunda 的核心能力与适用场景
Camunda 不是一个只能画图的工具,它是一个执行引擎。你通过模型定义了流程,Camunda 负责驱动流程实例从一个任务流转到下一个任务,并在恰当时机调用你的代码或外部服务。它特别适合以下场景:
- 微服务编排:协调多个独立服务完成一次业务请求。
- 人工任务管理:审批、表单填写等需要人参与的任务。
- 监控与审计:绘制出每个业务实例的流转路径,知晓当前处于哪一个步骤。
- 决策自动化:将业务规则从代码中抽离,通过决策表维护,引擎自动计算输出。
理解三大核心组件
在开始编写代码前,你需要熟悉 Camunda 的三个关键组成部分,它们构成了自动化流程的基础。
- 流程引擎:Java 库,提供运行 BPMN 和 DMN 的能力。你可以将其嵌入到 Spring Boot 应用中,或作为独立服务运行。
- Modeler(建模器):桌面或 Web 工具,用于绘制 BPMN 流程图和 DMN 决策表。它生成标准的 XML 文件,引擎可以直接部署。
- Tasklist & Cockpit(任务列表与控制台):Web 应用,为用户提供待办任务列表,为管理员提供流程实例监控和操作界面。
技术栈选择:Camunda 7 vs. Camunda 8
本教程聚焦于应用最广泛的 Camunda 7(社区版),它基于 Java 并支持 Spring Boot 深度集成。如果你需要云原生、水平扩展和 Zeebe 引擎,可以探索 Camunda 8,但初期学习成本更高。对于绝大多数传统 BPM 需求,Camunda 7 是快速入门的理想选择。
搭建你的第一个 Camunda 项目
我们将使用 Spring Boot 和 Maven 快速构建一个可执行的请假流程。这个流程包含一个用户任务(“审批请假”)和一个服务任务(“自动记录日志”)。
步骤 1:初始化 Spring Boot 项目
在 start.spring.io 中选择:
- Spring Boot 版本:2.7+ 或 3.x(Camunda 7.20+ 支持 Spring Boot 3)
- 依赖:
Camunda BPM(会自动引入camunda-bpm-spring-boot-starter)、H2 Database(内存数据库,用于存储流程实例)
或者直接在你的 pom.xml 中添加:
<dependency>
<groupId>org.camunda.bpm.springboot</groupId>
<artifactId>camunda-bpm-spring-boot-starter-webapp</artifactId>
<version>7.21.0</version>
</dependency>
该 starter 会同时引入 REST API、Web 控制台和任务列表。
步骤 2:绘制第一个 BPMN 流程
在 src/main/resources/ 下创建 leave-approval.bpmn 文件。你可以使用 Camunda Modeler 绘制后保存,或直接编写 XML。以下是简化内容:
<?xml version="1.0" encoding="UTF-8"?>
<definitions xmlns="http://www.omg.org/spec/BPMN/20100524/MODEL"
xmlns:camunda="http://camunda.org/schema/1.0/bpmn"
targetNamespace="http://camunda.org/examples">
<process id="leave-approval" name="请假审批" isExecutable="true">
<startEvent id="start" name="开始"/>
<serviceTask id="notifyService" name="通知服务" camunda:class="com.example.workflow.NotifyDelegate"/>
<userTask id="approveTask" name="经理审批" camunda:assignee="demo"/>
<endEvent id="end" name="结束"/>
<sequenceFlow sourceRef="start" targetRef="notifyService"/>
<sequenceFlow sourceRef="notifyService" targetRef="approveTask"/>
<sequenceFlow sourceRef="approveTask" targetRef="end"/>
</process>
</definitions>
流程解释:
- 流程 ID 为
leave-approval,启动时会用到。 - 一个服务任务执行 Java 类
NotifyDelegate。 - 一个用户任务分配给用户
demo(实际项目应来自流程变量)。 - 流程自动按顺序流转。
步骤 3:实现服务任务的 Java Delegate
创建 NotifyDelegate.java:
package com.example.workflow;
import org.camunda.bpm.engine.delegate.DelegateExecution;
import org.camunda.bpm.engine.delegate.JavaDelegate;
import org.slf4j.Logger;
import org.slf4j.LoggerFactory;
import org.springframework.stereotype.Component;
@Component
public class NotifyDelegate implements JavaDelegate {
private final Logger logger = LoggerFactory.getLogger(this.getClass());
@Override
public void execute(DelegateExecution execution) {
logger.info("请假申请已提交,申请人:{},天数:{}",
execution.getVariable("applicant"),
execution.getVariable("days"));
}
}
该方法从流程变量中获取 applicant 和 days。
步骤 4:配置 Camunda 并启动应用
在 application.properties 中添加基本配置:
camunda.bpm.admin-user.id=admin
camunda.bpm.admin-user.password=admin
spring.datasource.url=jdbc:h2:mem:camunda
启动 Spring Boot 应用。访问 http://localhost:8080,你会看到 Camunda 的欢迎页,你可以进入 Cockpit(控制台)、Tasklist(任务列表)和 Admin(管理)。
用过程代码来驱动流程
Camunda 的核心是与你的业务代码交互。通过注入 RuntimeService 和 TaskService 来启动流程和完成用户任务。
创建一个 REST 控制器或命令行运行器来演示:
import org.camunda.bpm.engine.RuntimeService;
import org.camunda.bpm.engine.TaskService;
import org.camunda.bpm.engine.runtime.ProcessInstance;
import org.camunda.bpm.engine.task.Task;
import org.springframework.beans.factory.annotation.Autowired;
import org.springframework.web.bind.annotation.*;
import java.util.HashMap;
import java.util.Map;
@RestController
@RequestMapping("/leave")
public class LeaveController {
@Autowired
private RuntimeService runtimeService;
@Autowired
private TaskService taskService;
@PostMapping("/start")
public String startLeave(@RequestParam String applicant, @RequestParam int days) {
Map<String, Object> variables = new HashMap<>();
variables.put("applicant", applicant);
variables.put("days", days);
ProcessInstance instance = runtimeService
.startProcessInstanceByKey("leave-approval", variables);
return "流程已启动,ID: " + instance.getId();
}
@PostMapping("/approve")
public String approveTask() {
// 查询分配给 'demo' 的待办任务,实际应用中可通过流程变量或角色查询
Task task = taskService.createTaskQuery()
.taskAssignee("demo")
.singleResult();
if (task != null) {
taskService.complete(task.getId());
return "任务已审批";
}
return "没有待办任务";
}
}
测试:POST /leave/start?applicant=张三&days=3 启动流程。此时,Cockpit 中会显示等待在“经理审批”节点。通过 POST /leave/approve 完成任务,流程结束。
引入决策自动化:DMN 示例
流程中经常需要根据条件决定路径。例如,请假 3 天以内由经理审批,超过则需要总监审批。用 DMN 决策表可以清晰维护,避免硬编码。
定义决策表
创建 src/main/resources/approval-rule.dmn,内容如下(简化 XML):
<?xml version="1.0" encoding="UTF-8"?>
<definitions xmlns="http://www.omg.org/spec/DMN1_3/20210308/MODEL/"
name="approval" namespace="http://camunda.org/schema/1.0/dmn">
<decision id="approvalDecision" name="审批规则">
<decisionTable hitPolicy="UNIQUE">
<input id="daysInput" label="请假天数" camunda:inputVariable="days"/>
<output id="approverOutput" label="审批人角色" name="approverRole" typeRef="string"/>
<rule>
<inputEntry><text>[0..3]</text></inputEntry>
<outputEntry>"manager"</outputEntry>
</rule>
<rule>
<inputEntry><text>>3</text></inputEntry>
<outputEntry>"director"</outputEntry>
</rule>
</decisionTable>
</decision>
</definitions>
该决策表根据输入的天数返回审批人角色。
在流程中调用 DMN
修改 BPMN 流程,使用业务规则任务(Business Rule Task)来调用决策,并将结果存入流程变量。
在 BPMN 文件里,将之前的 notifyService 替换为一个业务规则任务:
<businessRuleTask id="ruleTask" name="计算审批角色" camunda:decisionRef="approvalDecision" camunda:resultVariable="approverRole"/>
<sequenceFlow sourceRef="start" targetRef="ruleTask"/>
<sequenceFlow sourceRef="ruleTask" targetRef="userTask"/>
<!-- 用户任务使用变量指派 -->
<userTask id="userTask" name="请审批" camunda:assignee="${approverRole}"/>
这样,无需编写额外 Java 代码。Camunda 引擎会自动调用决策表,将输出 approverRole 设置为变量,然后用户任务将指派给该角色(在实际中,你可能需要将角色解析为具体人员列表)。
流程的部署与生产化建议
开发完成后,你需要将流程定义部署到 Camunda 引擎中。Spring Boot 启动时,默认会扫描 classpath 下所有 .bpmn 和 .dmn 文件自动部署。你也可以通过 API 手动部署:
repositoryService.createDeployment()
.addClasspathResource("leave-approval.bpmn")
.deploy();
生产环境注意事项:
- 使用外部数据库(如 PostgreSQL)替代 H2,并确保 camunda 表已自动创建。
- 启用历史数据清理服务,避免流程实例无限增长。
- 配置日志和监控(Prometheus + Grafana 集成)。
- 对于外部任务模式(External Tasks),可以将耗时的工作交给外部微服务处理,优化引擎吞吐。
进一步实践方向
掌握核心流程后,你可以尝试:
- 网关控制:使用排他网关(XOR)实现条件分支,或并行网关处理多步并进。
- 事件机制:定时器边界事件实现超时自动处理,消息事件实现跨流程通信。
- 自定义表单:与 React/Vue 前端结合,用 Camunda REST API 驱动 Tasklist。
- 单元测试:使用
camunda-bpm-assert进行流程回归测试。
Camunda 社区活跃,官方文档和示例丰富。有了以上基础,你已经可以应付日常 80% 的流程自动化需求。保持 BPMN 图的可读性、将业务规则外置为 DMN,是成功交付项目的关键。