Camunda:BPMN 自动化与决策引擎

FreeGuideOnline 23阅读 2026-07-03

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"));
    }
}

该方法从流程变量中获取 applicantdays

步骤 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 的核心是与你的业务代码交互。通过注入 RuntimeServiceTaskService 来启动流程和完成用户任务。

创建一个 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>&gt;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,是成功交付项目的关键。