Drools 规则引擎快速入门与实战
一、引擎概述与应用场景
Drools 是一款开源的业务规则管理系统(BRMS),能够将复杂的业务决策逻辑从应用程序代码中剥离出来,实现业务规则的集中管理与动态调整。典型应用场景包括:风控策略、促销规则、评分卡模型、审批流程等需要频繁变更业务逻辑的领域。
二、实战案例:电商促销定价
假设某平台双十一活动规则如下:
- 订单金额 (0, 500]:享受 8.5 折优惠
- 订单金额 (500, 1000]:享受 8 折优惠
- 订单金额 (1000, +∞):立减 300 元
三、项目构建步骤
3.1 工程初始化
使用 Gradle 构建工具创建 Java 项目,JDK 版本建议 1.8 及以上。创建包结构 com.example.promotion,并建立核心实体类 OrderItem.java:
package com.example.promotion;
public class OrderItem {
private String skuName;
private double originalAmount;
private double payableAmount;
public OrderItem() {}
public OrderItem(String skuName, double originalAmount) {
this.skuName = skuName;
this.originalAmount = originalAmount;
}
public String getSkuName() {
return skuName;
}
public void setSkuName(String skuName) {
this.skuName = skuName;
}
public double getOriginalAmount() {
return originalAmount;
}
public void setOriginalAmount(double originalAmount) {
this.originalAmount = originalAmount;
}
public double getPayableAmount() {
return payableAmount;
}
public void setPayableAmount(double payableAmount) {
this.payableAmount = payableAmount;
}
}
3.2 依赖配置
在 build.gradle 中引入 Drools 核心库:
plugins {
id 'java'
id 'application'
}
application {
mainClass = 'com.example.promotion.PromotionLauncher'
}
java {
sourceCompatibility = JavaVersion.VERSION_1_8
targetCompatibility = JavaVersion.VERSION_1_8
}
repositories {
mavenCentral()
}
dependencies {
implementation 'org.kie:kie-api:7.5.0.Final'
implementation 'org.drools:drools-compiler:7.5.0.Final'
testImplementation 'junit:junit:4.12'
}
3.3 规则文件编写
于 src/main/resources 下创建 promotion/rules 目录,新建 discount-rules.drl:
package com.example.promotion;
rule "tier_one_discount"
when
item : OrderItem(originalAmount > 0 && originalAmount <= 500)
then
double discounted = item.getOriginalAmount() * 0.85;
item.setPayableAmount(discounted);
System.out.println(item.getSkuName() + " 适用一档优惠,实付:" + discounted);
end
rule "tier_two_discount"
when
item : OrderItem(originalAmount > 500 && originalAmount <= 1000)
then
double discounted = item.getOriginalAmount() * 0.8;
item.setPayableAmount(discounted);
System.out.println(item.getSkuName() + " 适用二档优惠,实付:" + discounted);
end
rule "tier_three_discount"
when
item : OrderItem(originalAmount > 1000)
then
double discounted = item.getOriginalAmount() - 300;
item.setPayableAmount(discounted);
System.out.println(item.getSkuName() + " 适用三档优惠,实付:" + discounted);
end
3.4 引擎配置
在 src/main/resources/META-INF 目录放置 kmodule.xml:
<kmodule xmlns="http://www.drools.org/xsd/kmodule">
<kbase name="promotionBase" packages="promotion.rules">
<ksession name="promotionSession" />
</kbase>
</kmodule>
配置要点说明:
kbase:规则知识库,packages指向规则文件所在资源路径ksession:规则会话实例,name全局唯一,用于运行时获取会话- 单个
kmodule可配置多个kbase,每个kbase可包含多个ksession
3.5 执行入口
创建 PromotionLauncher.java 驱动规则执行:
package com.example.promotion;
import org.kie.api.KieServices;
import org.kie.api.runtime.KieContainer;
import org.kie.api.runtime.KieSession;
public class PromotionLauncher {
public static void main(String[] args) {
new PromotionLauncher().execute();
}
private void execute() {
KieServices services = KieServices.Factory.get();
KieContainer container = services.getKieClasspathContainer();
KieSession session = container.newKieSession("promotionSession");
OrderItem bluetoothSpeaker = new OrderItem("便携式蓝牙音箱", 299);
OrderItem smartphone = new OrderItem("5G智能手机", 998);
OrderItem refrigerator = new OrderItem("双开门冰箱", 2299);
session.insert(bluetoothSpeaker);
session.insert(smartphone);
session.insert(refrigerator);
session.fireAllRules();
session.dispose();
}
}
四、编程式加载方式
除配置文件外,Drools 7.x 仍支持纯代码加载规则,适用于动态规则场景:
package com.example.promotion;
import org.drools.core.builder.conf.impl.DecisionTableConfigurationImpl;
import org.kie.api.KieServices;
import org.kie.api.builder.KieBuilder;
import org.kie.api.builder.KieFileSystem;
import org.kie.api.builder.KieModule;
import org.kie.api.runtime.KieContainer;
import org.kie.api.runtime.KieSession;
public class ProgrammaticLoader {
public static void main(String[] args) {
KieServices ks = KieServices.Factory.get();
KieFileSystem kfs = ks.newKieFileSystem();
kfs.write("src/main/resources/promotion/rules/discount-rules.drl",
ks.getResources().newClassPathResource("promotion/rules/discount-rules.drl"));
KieBuilder kb = ks.newKieBuilder(kfs).buildAll();
KieModule km = kb.getKieModule();
KieContainer kc = ks.newKieContainer(km.getReleaseId());
KieSession session = kc.newKieSession();
OrderItem tablet = new OrderItem("平板电脑", 1899);
session.insert(tablet);
session.fireAllRules();
session.dispose();
}
}
五、规则文件格式扩展
Drools 支持多种规则定义格式,除 .drl 外还包括:
- 决策表:Excel 格式(
.xls/.xlsx),适合业务人员维护 - CSV 表格:轻量级规则批量导入
- DSL 领域语言:贴近自然语言的规则描述
- 决策模型标注:DMN 标准,图形化规则编排