第3章:Drools入门——从零开始搭建你的第一个规则引擎

各位同学,欢迎来到规则引擎实战的第一站。说实话,我最早接触Drools的时候,心里也犯嘀咕——这东西到底能解决什么问题?后来在储能调度项目里,面对一堆复杂的充放电策略,我算是彻底明白了。规则引擎,说白了就是把业务逻辑从代码里抽出来,让它们变成一条条清晰可见的规则。

这一章,咱们就一起把Drools跑起来。我会带着你从安装配置开始,写出第一个Hello World规则,再聊聊KIE API那些事儿。嗯,别急,一步步来。

3.1 Drools是什么?

Drools是一个基于Java的开源规则引擎。它由Red Hat维护,现在已经发展到7.x版本。我个人的理解是——它就像一个智能裁判,你告诉它规则,它帮你判断结果。

举个例子。在储能系统中,我们经常有这样的逻辑:

  • 如果电池SOC低于20%,且当前电价低于0.3元/kWh,则启动充电
  • 如果电池SOC高于90%,且当前电价高于0.8元/kWh,则启动放电

这些逻辑如果用if-else写,维护起来很痛苦。用Drools,你可以把它们写成独立的规则文件,改起来就像改配置文件一样简单。

核心概念:
  • 规则(Rule):条件+动作的集合
  • 事实(Fact):被规则判断的数据对象
  • 工作内存(Working Memory):存放事实的地方
  • 议程(Agenda):管理规则执行顺序

3.2 安装与配置

安装Drools其实很简单。我个人习惯用Maven来管理依赖,这样版本控制比较清晰。你只需要在pom.xml里加上这几行:

<dependency>
    <groupId>org.drools</groupId>
    <artifactId>drools-core</artifactId>
    <version>7.73.0.Final</version>
</dependency>
<dependency>
    <groupId>org.drools</groupId>
    <artifactId>drools-compiler</artifactId>
    <version>7.73.0.Final</version>
</dependency>
<dependency>
    <groupId>org.drools</groupId>
    <artifactId>drools-mvel</artifactId>
    <version>7.73.0.Final</version>
</dependency>

如果你用的是Gradle,那就这样:

implementation 'org.drools:drools-core:7.73.0.Final'
implementation 'org.drools:drools-compiler:7.73.0.Final'
implementation 'org.drools:drools-mvel:7.73.0.Final'
小提示: 版本号建议用7.x的最新稳定版。我曾经踩过坑,用了8.x的早期版本,结果发现有些API不兼容。嗯,生产环境还是稳一点好。

3.3 第一个Hello World规则

好了,现在我们来写第一个规则。先创建一个Java类,叫HelloWorldRule。然后创建一个规则文件,放在resources/rules目录下,命名为hello.drl

规则文件的内容是这样的:

package com.example.rules

import com.example.model.Message

rule "Hello World"
    when
        $m : Message(status == Message.HELLO)
    then
        System.out.println("Hello, Drools! 消息内容: " + $m.getContent());
        $m.setStatus(Message.GOODBYE);
        update($m);
end

对应的Java模型类:

package com.example.model;

public class Message {
    public static final int HELLO = 0;
    public static final int GOODBYE = 1;

    private String content;
    private int status;

    // getter和setter省略
}

然后,用KIE API来加载并执行规则:

public class DroolsHelloWorld {
    public static void main(String[] args) {
        // 1. 创建KIE容器
        KieServices ks = KieServices.Factory.get();
        KieContainer kContainer = ks.getKieClasspathContainer();

        // 2. 获取会话
        KieSession kSession = kContainer.newKieSession();

        // 3. 插入事实
        Message message = new Message();
        message.setContent("欢迎来到Drools世界");
        message.setStatus(Message.HELLO);
        kSession.insert(message);

        // 4. 触发规则
        kSession.fireAllRules();

        // 5. 关闭会话
        kSession.dispose();
    }
}

运行之后,控制台会输出:Hello, Drools! 消息内容: 欢迎来到Drools世界

注意: 如果你运行后没看到输出,检查一下kmodule.xml文件是否配置正确。这个文件必须放在resources/META-INF目录下。我曾经因为忘记配置这个文件,折腾了半小时。

kmodule.xml的内容:

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

3.4 KIE API基础

KIE API是Drools的核心API。说白了,它就是你和规则引擎之间的桥梁。我刚开始学的时候,觉得这些API名字很绕,但用多了就发现其实就那么几个关键对象。

下面这张图展示了KIE API的核心架构:

KIE API核心架构图 KieServices KieContainer KieBase KieSession KieServices 是入口,创建 KieContainer KieContainer 管理规则,创建 KieBase 和 KieSession KieSession 是运行时环境,负责执行规则

这几个API的关系,我简单总结一下:

API名称 作用 使用场景
KieServices 工厂类,一切从这里开始 获取KieContainer
KieContainer 管理规则资源 加载规则文件
KieBase 规则定义的逻辑容器 编译后的规则集合
KieSession 运行时会话 插入事实、触发规则
我的经验: 在实际项目中,我通常把KieContainer做成单例。因为每次创建KieContainer都要重新编译规则,性能开销很大。而KieSession则可以根据需要创建多个,每个线程一个会话,这样既安全又高效。

你可能会问,为什么要分这么多层?其实想想看,这样做的好处很明显——规则的定义和运行是分离的。KieBase负责规则的定义,KieSession负责规则的执行。这样你可以在运行时动态更新规则,而不用重启应用。我在储能调度项目里就是这么干的,白天和晚上的调度策略不同,我只需要切换不同的KieBase就行。

好了,这一章的内容就到这里。Drools的入门其实不难,关键是理解它的核心思想——把业务逻辑从代码中解放出来。下一章我们会深入规则语法,到时候我会分享更多实战中的坑和技巧。


公众号:蓝海资料掘金营,微信deep3321