Drools 规则引擎:声明式业务逻辑

FreeGuideOnline 最新 2026-07-03

规则引擎 Drools:声明式业务逻辑

为什么需要规则引擎?

在传统 Java 开发中,业务逻辑往往以命令式代码形式嵌入系统——大量的 if-elseswitch 与多层嵌套判断。当规则频繁变更时,修改代码、测试、部署的成本极高,且业务人员无法直观理解程序中的规则。

规则引擎将业务决策从应用代码中分离,以声明式方式描述“在什么条件下执行什么动作”。这带来了三大核心价值:

  • 业务可读性:规则使用接近自然语言的 DSL 编写,业务人员也能参与维护。
  • 变更灵活性:修改规则无需重新编译、部署应用,可实现热加载。
  • 逻辑集中管理:所有规则统一存放,避免分散在代码各处导致的维护黑洞。

Drools 正是 Java 生态中最成熟、功能最全面的开源规则引擎。

什么是 Drools?

Drools 是 Red Hat 旗下的开源业务规则管理系统 (BRMS),提供规则引擎、决策表、复杂事件处理(CEP)等能力。其核心基于 Rete 算法 的高效模式匹配网络,能够在对大量事实(数据)与规则进行匹配时保持优异性能。

Drools 使用 DRL (Drools Rule Language) 定义规则,语法简洁,支持与 Java 无缝集成,很容易嵌入任意 Java 应用。

核心概念速览

在动手之前,先理解 Drools 的四个核心角色:

概念 说明
Fact(事实) 输入到规则引擎的数据对象,通常是普通的 POJO。
Rule(规则) 由条件(LHS)和动作(RHS)组成的业务逻辑单元。
KieSession(会话) 规则执行的核心运行时,持有规则库和插入的事实,并触发推理。
KieBase(知识库) 编译后的规则集合,可以从 DRL、决策表等资源创建。

简单执行流程:创建 KieBase → 创建 KieSession → 插入事实 → 触发所有匹配规则 → 执行动作

环境准备

推荐使用 Maven 快速构建,引入核心依赖:

<dependencyManagement>
    <dependencies>
        <dependency>
            <groupId>org.drools</groupId>
            <artifactId>drools-bom</artifactId>
            <version>8.44.0.Final</version>
            <type>pom</type>
            <scope>import</scope>
        </dependency>
    </dependencies>
</dependencyManagement>

<dependencies>
    <dependency>
        <groupId>org.drools</groupId>
        <artifactId>drools-core</artifactId>
    </dependency>
    <dependency>
        <groupId>org.drools</groupId>
        <artifactId>drools-compiler</artifactId>
    </dependency>
</dependencies>

提示:若使用 Spring Boot,可集成 kie-spring-boot-starter,后文会给出示例。

第一个 Drools 规则:Hello World

假设我们要实现一个简单的会员积分奖励规则:消费超过 100 元送 10 积分。

1. 定义事实对象

public class Order {
    private double amount;
    private int points;
    // 构造函数、getter/setter 省略
}

2. 编写 DRL 规则文件(rules/order.drl

package com.example.rules

import com.example.Order

rule "Give 10 points for orders over 100"
    when
        $order : Order( amount > 100 )
    then
        $order.setPoints( $order.getPoints() + 10 );
        System.out.println("Order " + $order + " gets 10 points.");
end

3. 在 Java 中执行规则

KieServices ks = KieServices.Factory.get();
KieContainer kc = ks.getKieClasspathContainer();  // 自动加载 classpath 下的 kmodule.xml 及规则
KieSession session = kc.newKieSession("ksession-rules");

Order order = new Order(120, 0);
session.insert(order);       // 插入事实
session.fireAllRules();      // 触发所有匹配的规则
session.dispose();

System.out.println("Final points: " + order.getPoints()); // 输出 10

META-INF 下需放置 kmodule.xml 配置:

<kmodule xmlns="http://www.drools.org/xsd/kmodule">
    <kbase name="rules" packages="rules">
        <ksession name="ksession-rules"/>
    </kbase>
</kmodule>

DRL 规则语法精要

Drools 规则采用 rule...end 块,基本结构如下:

rule "规则名称"
    attributes       // 可选属性,如 no-loop, salience, date-effective
    when
        // 条件(LHS – Left Hand Side)
    then
        // 动作(RHS – Right Hand Side)
end

条件部分 (LHS):模式匹配

  • 字段约束Order(amount > 100),支持 >, <, ==, !=, contains, matches 等。
  • 绑定变量$order : Order(...) 将匹配的事实绑定到变量,后续可使用。
  • 多个模式:并列写出,表示“同时满足” (AND 关系)。例如:
    when
        $order : Order(amount > 100)
        Customer(status == "VIP") from $order.customer
    
  • 组合条件:可使用 andornotexists 关键字。
  • 复杂值操作eval() 可调用任意 Java 表达式(慎用,影响性能)。

动作部分 (RHS):执行业务

  • 直接修改绑定事实的属性,如 $order.setPoints(10)
  • 调用 Java 方法、输出日志、插入新事实 (insert) 或修改事实 (modify)。
  • 使用 drools 内置函数:kcontext.getKieRuntime() 获取运行时。

常用属性

属性 功能
salience 优先级,数字越大越先执行,默认 0。
no-loop 防止规则在修改自身导致的事实变化后重新触发,避免死循环。
date-effective / date-expires 生效/失效时间,格式 dd-MMM-yyyy
activation-group 同一组内仅触发一个规则。
agenda-group 将规则分组,可控制执行流。

进阶:使用业务人员友好的决策表

如果规则由非技术人员维护,DRL 文件可能仍有门槛。Drools 支持通过 Excel 决策表 定义规则,将条件-动作映射为表格。

示例:会员等级折扣决策表(.xls 文件)

RuleSet 会员折扣计算
RuleTable 会员折扣
CONDITION ACTION
消费金额 >= 等级 ==
1000 "VIP"
500 "NORMAL"

在代码中加载决策表只需让 KieBase 加载对应的 .xls 资源即可,Drools 会自动解析。

与 Spring Boot 集成

Spring Boot 项目可使用 kie-spring-boot-starter 快速集成:

  1. 添加依赖:
<dependency>
    <groupId>org.kie</groupId>
    <artifactId>kie-spring-boot-starter</artifactId>
    <version>8.44.0.Final</version>
</dependency>
  1. application.yml 中配置规则文件路径:
kieserver:
  resources: classpath:rules/**/*.drl
  1. 注入 KieContainerKieService 便可直接使用,无需手动编写 kmodule.xml

最佳实践与性能提示

  • 避免在 LHS 中使用 evaleval 会放弃索引优化,尽量使用字段约束。
  • 注意 modifyupdate:修改已存在的事实必须通过 modifyupdate 通知引擎,否则规则不会重新评估。
  • 使用 no-looplock-on-active 防止无限循环触发。
  • 合理设计事实模型:将频繁变化的数据与静态属性分离,降低重新评估的范围。
  • 策略化会话:对于高频调用,可使用 KieSessionPool 复用会话,避免频繁创建销毁。

总结

Drools 让开发者从“如何实现”转向“声明规则是什么”,极大提升了业务逻辑的可维护性与敏捷性。本文从核心概念和第一个规则入手,覆盖了 DRL 语法、决策表以及 Spring Boot 集成,为你后续深入学习(复杂事件处理 CEP、规则流、BRMS 等)打下了扎实基础。

将规则外置,迈向声明式业务逻辑,正是企业级应用应对变化的不二选择。