第3章 Drools入门:从零跑通第一个规则
好,咱们正式开始接触Drools。这一章的目标很简单——让你亲手写一个能跑的规则文件,并且在Java代码里调用它。我见过不少新手卡在环境搭建和Session概念上,其实没那么复杂。跟着我走一遍,半小时内你就能看到控制台打印出“Hello World”。
3.1 Drools到底是什么?
Drools是一个基于Rete算法的规则引擎。说白了,它就是一个“如果…就…”的自动执行器。你把业务规则写在.drl文件里,把数据塞进去,它自动匹配、自动执行。
我个人习惯把Drools理解成一个“超级if-else处理器”。你想想看,传统代码里写几十个if-else,维护起来多痛苦。Drools把条件和动作分离,规则变了改文件就行,不用重新编译部署。
核心能力: 规则与代码解耦、动态修改、高性能匹配。
3.2 Maven依赖配置
我用的是Maven项目。别问为什么不用Gradle,团队里统一用Maven,我也习惯了。先贴依赖,版本我用的是7.73.0.Final,比较稳定。
<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>
<dependency>
<groupId>org.slf4j</groupId>
<artifactId>slf4j-simple</artifactId>
<version>1.7.36</version>
</dependency>
避坑: 我曾经遇到过drools-compiler和drools-core版本不一致,启动直接报ClassNotFoundException。记住,三个drools依赖的版本号必须完全一致。
3.3 第一个Hello World规则文件
规则文件后缀是.drl。我习惯放在src/main/resources/rules目录下。新建一个hello.drl,内容如下:
package com.example.rules
import com.example.model.Person
rule "Hello World"
when
$p: Person(age > 18)
then
System.out.println("Hello, " + $p.getName() + "! 你已经成年了。");
end
解释一下:
- package:规则包的命名空间,类似Java包名。
- import:导入要使用的Java类。
- rule:定义一个规则,后面跟规则名称。
- when:条件部分,这里匹配年龄大于18的Person对象。
- then:动作部分,满足条件后执行。
对应的Java模型类:
package com.example.model;
public class Person {
private String name;
private int age;
// getter和setter必须写,Drools靠它们访问属性
public String getName() { return name; }
public void setName(String name) { this.name = name; }
public int getAge() { return age; }
public void setAge(int age) { this.age = age; }
}
注意: DRL文件里的import路径必须和Java类的全限定名一致。大小写敏感,别写错了。
3.4 KIE Session的创建与使用
KIE Session是Drools的执行入口。我刚开始学的时候,老觉得这个概念很抽象。其实你就把它当成一个“规则执行容器”——你把数据放进去,它帮你跑规则。
创建Session的标准步骤:
- 构建KieServices实例(入口)
- 获取KieContainer(管理规则文件的容器)
- 从KieContainer创建KieSession
- 插入数据(insert)
- 触发规则执行(fireAllRules)
- 释放资源(dispose)
看代码:
import org.kie.api.KieServices;
import org.kie.api.runtime.KieContainer;
import org.kie.api.runtime.KieSession;
public class DroolsHelloWorld {
public static void main(String[] args) {
// 1. 获取KieServices
KieServices ks = KieServices.Factory.get();
// 2. 获取KieContainer(自动加载classpath下的kmodule.xml和drl文件)
KieContainer kContainer = ks.getKieClasspathContainer();
// 3. 创建KieSession,名称对应kmodule.xml中的ksession name
KieSession kSession = kContainer.newKieSession("helloSession");
// 4. 准备数据
Person p = new Person();
p.setName("张三");
p.setAge(20);
// 5. 插入数据到Session
kSession.insert(p);
// 6. 触发规则执行
kSession.fireAllRules();
// 7. 释放资源
kSession.dispose();
}
}
还需要一个kmodule.xml文件,放在src/main/resources/META-INF目录下:
<?xml version="1.0" encoding="UTF-8"?>
<kmodule xmlns="http://www.drools.org/xsd/kmodule">
<kbase name="helloKBase" packages="rules">
<ksession name="helloSession"/>
</kbase>
</kmodule>
个人经验: 我早期犯过一个低级错误——忘了在resources目录下建META-INF文件夹,结果KieContainer一直报空指针。检查了半小时才发现。嗯,目录结构一定要对。
3.5 核心流程可视化
下面这张图展示了从规则文件到执行结果的完整链路。我画得比较直观,你一看就明白。
3.6 运行与验证
直接运行main方法。如果一切正常,控制台会输出:
Hello, 张三! 你已经成年了。
没输出?别急。检查这几项:
- Person类的getter/setter是否完整?Drools通过反射调用它们。
- kmodule.xml里的ksession name是否和代码里一致?
- drl文件是否放在
resources/rules目录下? - 依赖版本是否冲突?
我曾经踩过的坑: 有一次规则怎么都不触发,查了半天发现是Person类里age字段写了Integer,但规则里判断的是int。Drools对类型匹配很严格,包装类型和基本类型不能混用。
3.7 本章小结
这一章我们走通了Drools的完整链路:从Maven依赖、规则文件编写、KIE Session创建到执行。你想想看,核心就三步:写规则、建Session、触发执行。后面的章节会在这个基础上不断扩展,但底子就是这些。
嗯,记住一个原则:规则引擎不是银弹,但它能把频繁变化的业务逻辑从代码里抽出来。这一章你亲手跑通了,后面学起来会轻松很多。