Camunda DMN 决策引擎实战:独立运行与 BPMN 业务规则任务集成指南

发布时间:2026/9/18 17:17:39

Camunda DMN 决策引擎实战:独立运行与 BPMN 业务规则任务集成指南 Camunda DMN 决策引擎实战独立运行与 BPMN 业务规则任务集成指南【免费下载链接】camunda-bpm-platformCamunda 7 CE is End of Life (EoL). Please check out Camunda 8 instead (https://github.com/camunda/camunda) or read about Camunda 7 Enterprise End of Life (https://camunda.com/blog/2025/02/camunda-7-enterprise-end-of-life-extension/) – Camunda 7 CE was a flexible framework for workflow and decision automation using BPMN and DMN.项目地址: https://gitcode.com/GitHub_Trending/ca/camunda-bpm-platformcamunda-engine-dmn是 Camunda 7 平台中基于 Java 编写的轻量级 DMNDecision Model and Notation决策执行引擎能够解析 DMN 决策模型并求值决策。本文将围绕 engine-dmn/README.md 的核心内容展开先讲解如何以独立Standalone方式把引擎引入 Maven 工程并用纯 Java API 解析、求值决策再演示如何让 BPMN 流程中的业务规则任务Business Rule Task通过camunda:decisionRef无缝引用 DMN 决策将决策逻辑编排进工作流。读完本文你将掌握 DMN 引擎的最小可运行工程搭建、决策表求值结果 API、底层求值与命中策略实现以及它与 Camunda 流程引擎的完整集成链路。一、模块定位可独立运行、也可与 BPMN/CMMN 组合使用根据 engine-dmn/README.md 的定位说明该决策引擎以 Java 实现核心价值在于轻量Lightweight Execution Engine for DMN并且既可以与 BPMN、CMMN 无缝组合使用也可以完全独立运行。从仓库结构看engine-dmn模块是一个由多个子模块组成的多模块工程engine-dmn/engine引擎主体提供DmnEngine接口、默认实现与全部内部机制engine-dmn/feel-apiFEEL 表达式的 SPI 接口FeelEngine、FeelEngineFactoryengine-dmn/feel-juel将 FEEL 语法翻译为 JUEL 求值的兼容实现engine-dmn/feel-scala对 Scala FEEL Engine 的集成实现参见 feel-scala/README.md是现代版本默认使用的 FEEL 引擎。从 engine-dmn/engine/pom.xml 的依赖声明可以印证引擎的组成它依赖camunda-dmn-modelDMN 模型 API、camunda-engine-feel-api、camunda-engine-feel-juel、camunda-engine-feel-scala、feel-enginescala-shaded以及camunda-juel表达式语言求值、camunda-commons-typed-values类型化变量与camunda-commons-utils。这意味着一个引擎实例内部实际串联起了 DMN 模型解析、表达式求值与类型化变量三大能力。二、独立使用三分钟跑通一个 DMN 引擎2.1 引入 Maven 坐标独立使用方式下只需在项目中加入如下依赖原文档示例groupId 为org.camunda.bpm.dmndependency groupIdorg.camunda.bpm.dmn/groupId artifactIdcamunda-engine-dmn/artifactId version${version.camunda}/version /dependency${version.camunda}需要替换为具体的版本号。需要说明的是当前仓库的engine-dmn/engine/pom.xml中版本为7.24.0-SNAPSHOT且注明7.24.0 是 Camunda 7 社区版在 Maven Central 发布的最后一个版本后续该构件不会再发布新版本企业版提供扩展维护使用时应留意这一版本前提。2.2 编写第一个求值程序原文档给出了一个完整的独立使用示例核心步骤分为构建引擎 → 解析决策 → 准备输入数据 → 求值决策表四步public class DmnApp { public static void main(String[] args) { // configure and build the DMN engine DmnEngine dmnEngine DmnEngineConfiguration.createDefaultDmnEngineConfiguration().buildEngine(); // parse a decision DmnDecision decision dmnEngine.parseDecision(orderDecision, CheckOrder.dmn); MapString, Object data new HashMapString, Object(); data.put(status, gold); data.put(sum, 354.12d); // evaluate a decision DmnDecisionTableResult result dmnEngine.evaluateDecisionTable(decision, data); } }各步骤的关键点如下构建引擎DmnEngineConfiguration.createDefaultDmnEngineConfiguration().buildEngine()。从源码看DmnEngineConfiguration.java 是抽象类createDefaultDmnEngineConfiguration()返回默认实现DefaultDmnEngineConfigurationbuildEngine()在 DefaultDmnEngineConfiguration.java 中会先调用init()依次初始化指标收集器、决策表求值监听器、决策求值监听器、脚本引擎解析器、表达式语言默认值、EL Provider 与 FEEL 引擎随后返回new DefaultDmnEngine(this)。解析决策parseDecision(orderDecision, CheckOrder.dmn)。其中orderDecision是 DMN 文件中dmn:decision元素的id属性即决策 key第二个参数可以是InputStream或DmnModelInstance。DmnEngine.java 中定义了完整的 API 面除parseDecision外还提供parseDecisions(...)解析文件中的全部决策parseDecisionRequirementsGraph(...)解析决策需求图DRGevaluateDecisionTable(...)以决策表结果形式求值evaluateDecision(...)求值任意支持的决策逻辑决策表、字面量表达式等返回更通用的DmnDecisionResult。 若给定的 key 找不到对应决策DefaultDmnEngine.java 会抛出unableToFindDecisionWithKey异常。准备输入数据普通MapString, Object即可引擎内部会通过Variables.fromMap(variables).asVariableContext()将其转换为类型化的VariableContext供表达式求值使用。求值决策表evaluateDecisionTable返回DmnDecisionTableResult。注意该方法要求目标决策必须实现为决策表decision table否则抛出decisionIsNotADecisionTable异常。2.3 读取求值结果DmnDecisionTableResult APIevaluateDecisionTable的返回值是DmnDecisionTableResult本质是ListDmnDecisionRuleResult。DmnDecisionTableResult.java 定义了以下便捷方法方法语义getFirstResult()返回第一条命中的决策规则结果无命中则返回 nullgetSingleResult()返回唯一命中结果若命中多于一条则抛出DmnEngineExceptioncollectEntries(outputName)按输出名收集所有命中规则在该输出列上的值getResultList()返回所有命中规则的输出名→值映射列表getSingleEntry()断言仅一条命中且仅一个输出返回该输出值getSingleEntryTyped()同getSingleEntry()但返回类型化值TypedValue在唯一命中 单输出的典型场景例如 UNIQUE 命中策略的审批人决策中一行result.getSingleEntry()即可取回最终决策值。三、决策表求值原理输入列逐列过滤、命中策略收敛为了让求值不只是黑盒调用这里结合源码补充其底层实现。DecisionTableEvaluationHandler.java 是决策表求值的核心处理器其evaluate流程为逐输入列求值对每个输入列先求值输入表达式Input Expression得到类型化输入值TypedValue并把当前输入值注入局部VariableContext可通过输入列的inputVariable在规则条件中引用逐列过滤规则从全部规则开始用每一列的输入项Input Entry即条件表达式对候选规则做过滤只有条件求值为true的规则进入下一轮最终得到全部匹配规则Matching Rules求值输出对匹配规则逐列求值输出项Output Entry并将原始值按输出列的类型定义Type Definition转换为类型化值可参考type包下的StringDataTypeTransformer、IntegerDataTypeTransformer、BooleanDataTypeTransformer、DateDataTypeTransformer、DoubleDataTypeTransformer、LongDataTypeTransformer等内置类型转换器应用命中策略调用决策表配置的HitPolicyHandler收敛匹配规则见下文通知监听器向所有注册的决策表求值监听器广播DmnDecisionTableEvaluationEvent。其中输入项条件若为 FEEL 表达式会走evaluateFeelSimpleUnaryTests即用 FEEL 引擎的evaluateSimpleUnaryTests求值简单一元测试simple unary tests空白输入项恒视为true。3.1 命中策略Hit Policy全景命中策略决定多条规则命中时如何处理输出。DefaultHitPolicyHandlerRegistry.java 中的默认注册表完整覆盖了 DMN 规范定义的策略Hit Policy聚合器行为UNIQUE无恰好命中一条规则否则异常FIRST无返回命中顺序中第一条规则输出ANY无多条命中时要求所有输出一致否则抛DmnHitPolicyExceptionRULE ORDER无返回所有命中规则的输出保持规则顺序COLLECT无返回所有命中规则的输出COLLECTCOUNT返回命中规则数量COLLECTSUM返回命中规则输出的总和COLLECTMIN返回命中规则输出的最小值COLLECTMAX返回命中规则输出的最大值以 ANY 为例AnyHitPolicyHandler.java 在apply中会比较所有匹配规则的输出映射若全部相等则只保留第一条并返回若存在不等则抛出anyHitPolicyRequiresThatAllOutputsAreEqual异常。该注册表支持通过addHandler扩展自定义命中策略处理器SPI 位于impl.spi.hitpolicy。四、表达式语言与引擎配置4.1 默认表达式语言DMN 引擎支持 FEEL 与 JUEL 两类表达式。DefaultDmnEngineConfiguration.java 定义了四类表达式语言默认值defaultInputExpressionExpressionLanguage输入表达式defaultInputEntryExpressionLanguage输入项条件defaultOutputEntryExpressionLanguage输出项结论defaultLiteralExpressionLanguage字面量表达式。在不开启 FEEL 遗留行为时四者默认均为 FEEL若设置enableFeelLegacyBehavior(true)则输入表达式与输出项回退为 JUEL仅输入项保持 FEEL。注意表达式若在 DMN 文件中显式声明了expressionLanguage将优先使用显式声明配置值仅作用于未声明的表达式。4.2 引擎默认依赖链从 engine-dmn/engine/pom.xml 可以看到 FEEL 支持的完整依赖链默认使用feel-enginescala-shaded与camunda-engine-feel-scala而camunda-engine-feel-juel则作为 FEEL 遗留行为的实现对应 DefaultDmnEngineConfiguration.java 中enableFeelLegacyBehavior为 true 时使用FeelEngineFactoryImpl否则使用ScalaFeelEngineFactory的逻辑。camunda-juel为 JUEL 表达式提供底层 EL 求值能力。4.3 常用可配置项DmnEngineConfiguration及默认实现DefaultDmnEngineConfiguration还支持以下常用扩展点指标收集器engineMetricCollector(...)默认实现为DefaultEngineMetricCollector内部以AtomicLong统计累计执行的决策实例数executed decision instances与决策元素数executed decision elements并提供clearExecutedDecisionInstances()/clearExecutedDecisionElements()清零方法见 DefaultEngineMetricCollector.java求值监听器customPreDecisionTableEvaluationListeners(...)/customPostDecisionTableEvaluationListeners(...)以及决策级customPreDecisionEvaluationListeners(...)/customPostDecisionEvaluationListeners(...)可用于审计、日志或指标采集脚本引擎解析器scriptEngineResolver(...)用于解析表达式语言对应的脚本引擎EL ProviderelProvider(...)默认JuelElProviderFEEL 自定义函数feelCustomFunctionProviders(...)向 Scala FEEL 引擎注册自定义函数转换器transformer(...)默认DefaultDmnTransformer负责把 DMN 模型实例转换为引擎内部结构空白输出处理setReturnBlankTableOutputAsNull(true)时空白输出项也作为null写入结果默认策略是丢弃空白输出项。该选项有专门的测试类 ReturnBlankTableOutputAsNullTest.java 覆盖。配置接口的完整方法清单参见 DmnEngineConfiguration.java引擎的解析/求值 API 参见 DmnEngine.java。五、在 BPMN 流程中实现业务规则任务独立运行之外更常见的生产场景是把 DMN 决策嵌入 BPMN 流程。原文档的第二部分给出了完整方案。5.1 依赖与准备在流程引擎应用中需要引入流程引擎本体与内存数据库示例中 H2 仅用于测试作用域dependency groupIdorg.camunda.bpm/groupId artifactIdcamunda-engine/artifactId version${version.camunda}/version /dependency dependency groupIdcom.h2database/groupId artifactIdh2/artifactId version1.3.168/version scopetest/scope /dependency5.2 在 BPMN 中引用 DMN 决策在 BPMN 流程文件里声明一个业务规则任务Business Rule Task并通过 Camunda 扩展属性camunda:decisionRef指向 DMN 决策bpmn:businessRuleTask idassignApprover camunda:decisionRefinvoice-assign-approver camunda:resultVariableapproverGroups nameAssign Approver Group(s) /bpmn:businessRuleTaskcamunda:decisionRef必填值为 DMN 文件中决策的id注意是id而非name即invoice-assign-approvercamunda:resultVariable可选指定将决策结果保存到流程变量名示例中为approverGroups不声明时结果默认写入流程变量decisionResult。对应的 DMN 文件片段dmn:decision idinvoice-assign-approver nameAssign Approver ... /dmn:decision从流程引擎的解析源码看camunda:decisionRef的处理位于 BpmnParse.java解析器读取CAMUNDA_BPMN_EXTENSIONS_NS命名空间下的decisionRef属性并将其包装为参数值提供者ParameterValueProvider同时支持以下配套绑定属性camunda:decisionRefBinding绑定方式latest/deployment/version/versionTagcamunda:decisionRefVersion结合version绑定指定决策版本camunda:decisionRefVersionTag结合versionTag绑定指定版本标签camunda:decisionRefTenantId指定多租户场景下的租户。5.3 部署并启动流程最后把 BPMN 文件与 DMN 文件作为一个 Deployment 一起部署再按流程 key 启动流程实例public class App { public static void main(String[] args) { ProcessEngine processEngine ProcessEngineConfiguration.createStandaloneInMemProcessEngineConfiguration() .buildProcessEngine(); try { processEngine.getRepositoryService() .createDeployment() .name(invoice deployment) .addClasspathResource(invoice.bpmn) .addClasspathResource(assign-approver-groups.dmn) .deploy(); processEngine.getRuntimeService() .startProcessInstanceByKey(invoice, createVariables() .putValue(invoceNumber, 2323)); } finally { processEngine.close(); } } }要点说明createStandaloneInMemProcessEngineConfiguration()创建基于内存数据库的独立流程引擎适合测试与演示addClasspathResource同时注册 BPMN 与 DMN 资源流程引擎会在部署阶段解析 DMN 文件并建立decisionRef与决策 id 的映射startProcessInstanceByKey(invoice, ...)中的invoice是 BPMN 流程的id启动后流程流转至业务规则任务时会自动执行对应的 DMN 决策并把结果写入resultVariable指定的流程变量finally中的processEngine.close()用于释放引擎资源。5.4 组合使用时的求值结果形态需要留意的是当 DMN 决策被流程引擎调用时引擎内部同样走DmnEngine的求值链路决策表求值 → 命中策略收敛 → 监听器通知最终结果以DmnDecisionTableResult形式映射为流程变量。因此第四节中关于命中策略与输出行为的说明同样适用于 BPMN 集成场景。六、版本说明与注意事项当前仓库engine-dmn/engine的版本为7.24.0-SNAPSHOT根据 engine-dmn/engine/pom.xml 的说明7.24.0 是 Camunda 7 社区版在 Maven Central 的最后一个发布版本之后社区版不再发布新版本如需要扩展维护请关注企业版方案在实际项目中应把${version.camunda}替换为可用的正式版本号。camunda:decisionRef引用的是 DMN 决策的id属性拼写错误或文件中不存在该 id 时求值/解析阶段会抛出异常unableToFindDecisionWithKey。evaluateDecisionTable只适用于决策表类型的决策若决策以字面量表达式literal expression等其他决策逻辑实现应使用evaluateDecision通用求值 API见 DmnEngine.java。七、延伸阅读引擎完整 APIDmnEngine.java配置与构建DmnEngineConfiguration.java、DefaultDmnEngineConfiguration.java决策表求值实现DecisionTableEvaluationHandler.java命中策略注册表DefaultHitPolicyHandlerRegistry.java求值结果 APIDmnDecisionTableResult.java引擎功能测试示例DmnEngineApiTest.java、EvaluateDecisionTest.java、HitPolicyTest.javaBPMNdecisionRef解析逻辑BpmnParse.java【免费下载链接】camunda-bpm-platformCamunda 7 CE is End of Life (EoL). Please check out Camunda 8 instead (https://github.com/camunda/camunda) or read about Camunda 7 Enterprise End of Life (https://camunda.com/blog/2025/02/camunda-7-enterprise-end-of-life-extension/) – Camunda 7 CE was a flexible framework for workflow and decision automation using BPMN and DMN.项目地址: https://gitcode.com/GitHub_Trending/ca/camunda-bpm-platform创作声明:本文部分内容由AI辅助生成(AIGC),仅供参考
延伸阅读

更多相关文章

2026/9/18 18:42:49

低功耗段码LCD驱动芯片TM16C21:原理、设计与实战排坑

/* MD / 富文本中的 .toc(含博客园搬家等嵌套结构);.toc-box 在侧栏,不受影响 */#content_views .toc,/* 编辑器常在目录前后插入空 p(:empty 仍占 20px),一并去掉避免顶空隙 */#content_views.markdown_views > p:empty:has(+ .toc),#content_views.markdown_views …

2026/9/18 18:42:49

Element UI 样式文件深度解析:SCSS 变量、BEM 规范与主题定制实践

所有 Vue 2 项目里,Element UI 算是国内前端最熟悉的一张脸。但你有没有认真想过一个问题:我们在入口文件里写下import element-ui/lib/theme-chalk/index.css之后,浏览器到底加载了多少样式?这些样式文件又是按什么规则组织出来的…

2026/9/18 18:42:49

CANN pyasc 标量加法接口 `asc.language.basic.adds` 使用与原理深度解析

CANN pyasc 标量加法接口 asc.language.basic.adds 使用与原理深度解析 【免费下载链接】pyasc 本项目为Python用户提供算子编程接口,支持在昇腾AI处理器上加速计算,接口与Ascend C一一对应并遵守Python原生语法。 项目地址: https://gitcode.com/cann…

2026/9/18 18:42:49

AI Agent 驱动 Unity 自动化构建与测试:批处理模式与桥接层实战

前阵子,我们工作室一直在做 Unity 项目的自动化构建和持续验证,效果还行,但人肉参与度还是太高——每天打开编辑器、切平台、点 PlayMode 测试、看日志、传包,这一套下来少说半小时。后来我决定把 AI Agent 引进来,让它…

2026/9/18 18:37:48

沃尔玛物流系统建模:多级仓配与动态库存状态机设计

/* MD / 富文本中的 .toc(含博客园搬家等嵌套结构);.toc-box 在侧栏,不受影响 */#content_views .toc,/* 编辑器常在目录前后插入空 p(:empty 仍占 20px),一并去掉避免顶空隙 */#content_views.markdown_views > p:empty:has(+ .toc),#content_views.markdown_views …

2026/9/18 14:13:01

拯救者Y7000黑屏故障排查与维修实战指南

1. 项目概述:一台黑屏的拯救者Y7000,到底卡在哪一步? 联想拯救者Y7000系列笔记本,从2018年第一代搭载i5-8300H开始,到后来的i7-9750H、i7-10750H、i5-11400H,再到2023年款的R7-7840HS,它始终是学…

2026/9/18 0:01:09

Google Colab 实战:运行模型、数据加载与报错排查

1. 为什么我劝你先搞懂 Colab 的运行模型1.1 Colab 到底是什么,跟本地跑代码差在哪Google Colab 简单说就是一台跑在浏览器里的 Linux 虚拟机,你打开一个 Notebook,背后就连上了一台带 GPU 的远程机器。你在单元格里敲的每一行 Python&#x…

2026/9/18 0:01:09

C语言数据类型与表达式详解

1. C语言数据与数据类型概述在C语言编程中,数据是程序处理的核心对象。理解数据的分类和特性是掌握C语言的基础。C语言中的数据主要分为四大类:常量、变量、表达式和函数。这些数据类型构成了C语言程序的基本元素,每种类型都有其独特的特性和…

2026/9/18 0:01:09

SQL时间字段指定时间段查询:区间语义、索引与时区避坑

上周排查一个线上问题&#xff0c;用户反馈"昨天的订单一条都没查到"&#xff0c;但数据库里明明躺着两千多条。最后定位下来&#xff0c;不是数据丢了&#xff0c;也不是接口挂了&#xff0c;而是那个查询条件把时间段写成了> 2024-05-20 00:00:00 AND < 2024…

2026/9/18 14:13:03

USB Type-C PCB布局分区设计:电源、高速信号与PD协议全攻略

做硬件这行&#xff0c;Type-C接口算是典型的“看着简单&#xff0c;做起来全坑”的东西。光引脚就24个&#xff0c;高低速信号、电源、控制线全部塞在一个小小的连接器里&#xff0c;如果PCB布局不做规划&#xff0c;打样回来基本就是“插上没反应”、“高速掉线”、“静电一打…

2026/9/18 14:13:02

系统编程学习原型如何补齐稳定性边界

系统编程学习原型如何补齐稳定性边界预算有限时&#xff0c;我先优化明显多余的复制&#xff0c;而不是猜测性地换容器。用借用传递只读数据通常就能减少分配&#xff1a; fn parse(line: &str) -> Result<Item, Error> { /* ... */ }用基准确认热点确实在分配&am…

2026/9/18 14:13:02

雨花区哪家财务公司代理记账比较好?

在雨花区&#xff0c;企业处理财税事务常常面临诸多挑战&#xff0c;选择一家靠谱的财务公司至关重要。湖南巨勤财务管理咨询有限公司就是本地正规实体财税服务机构&#xff0c;深耕本地工商财税行业多年&#xff0c;熟悉当地工商局、税务局最新政策与申报流程。主营公司注册、…

还想了解更多?直接咨询顾问

免费诊断 + 免费方案 + 透明报价。

全国咨询热线400-8866-253
免费获取方案
咨询二维码