本文目录导读:

我为你整理了一份关于Drools规则引擎的完整案例解析,涵盖从基础概念到实际业务场景的完整代码演示。
项目基础搭建
Maven依赖配置
<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-decisiontables</artifactId>
<version>7.73.0.Final</version>
</dependency>
基础数据模型
// 订单实体
public class Order {
private String orderId;
private Customer customer;
private double amount;
private double discount = 0;
private String discountLevel;
private boolean vip;
private List<String> promotions = new ArrayList<>();
// getters/setters...
}
// 客户实体
public class Customer {
private String name;
private int age;
private int creditScore;
private double totalAmount; // 历史累计消费金额
private String membership; // 会员等级
// getters/setters...
}
// 商品实体
public class Product {
private String productId;
private String category;
private String name;
private double price;
private int stock;
private boolean isPromotional;
// getters/setters...
}
核心业务场景案例
场景1:电商折扣计算系统
业务规则:
- 会员客户享受额外5%折扣
- 累计消费超过10000元享受金卡会员折扣
- 订单金额超过500元且非促销商品,享受10%折扣
- 同时满足多个条件时,折扣可叠加
规则文件 discount-rules.drl:
package com.example.drools.rules
import com.example.drools.model.Order;
import com.example.drools.model.Customer;
// 规则1:普通会员折扣
rule "Member Discount-5%"
when
$customer: Customer(membership == "VIP" && totalAmount >= 5000)
$order: Order(vip == true, discount < 0.15)
then
$order.setDiscount($order.getDiscount() + 0.05);
$order.setDiscountLevel("VIP会员折扣");
System.out.println("应用VIP会员5%折扣");
update($order);
end
// 规则2:大额订单折扣
rule "Large Order Discount-10%"
when
$order: Order(amount > 500, discount < 0.20)
then
$order.setDiscount($order.getDiscount() + 0.10);
$order.setDiscountLevel("大额订单优惠");
System.out.println("应用大额订单10%折扣");
update($order);
end
// 规则3:银联支付优惠
rule "UnionPay Discount-3%"
when
$order: Order(promotions contains "UnionPay", discount < 0.25)
then
$order.setDiscount($order.getDiscount() + 0.03);
$order.getPromotions().add("银联支付优惠");
System.out.println("应用银联支付3%折扣");
update($order);
end
// 规则4:新客首单优惠
rule "New Customer First Order"
when
$customer: Customer(totalAmount == 0)
$order: Order()
then
$order.setDiscount($order.getDiscount() + 0.15);
$order.setDiscountLevel("新客首单优惠");
System.out.println("应用新顾客15%折扣");
update($order);
end
调用代码:
public class DiscountCalculator {
private static KieContainer kieContainer;
static {
KieServices kieServices = KieServices.Factory.get();
kieContainer = kieServices.newKieClasspathContainer();
}
public static Order calculateDiscount(Order order) {
KieSession kieSession = kieContainer.newKieSession("discount-session");
kieSession.insert(order);
kieSession.insert(order.getCustomer());
kieSession.fireAllRules();
kieSession.dispose();
// 计算最终金额
double finalAmount = order.getAmount() * (1 - order.getDiscount());
order.setFinalAmount(finalAmount);
return order;
}
public static void main(String[] args) {
// 测试案例
Customer customer = new Customer();
customer.setName("张三");
customer.setTotalAmount(12000);
customer.setMembership("VIP");
Order order = new Order();
order.setOrderId("ORD001");
order.setCustomer(customer);
order.setAmount(800);
order.setVip(true);
order.getPromotions().add("UnionPay");
Order result = calculateDiscount(order);
System.out.println("订单原价:" + order.getAmount());
System.out.println("总折扣率:" + (result.getDiscount() * 100) + "%");
System.out.println("最终金额:" + result.getFinalAmount());
}
}
场景2:风控可疑交易检测
业务规则:
- 单笔交易超过50000元且时间在凌晨0-5点,高风险
- 5分钟内连续多笔交易累计超过30000元,中高风险
- 新开户3天内大额交易,高风险
- CEO/高管账户大额交易,允许但需通知
规则文件 risk-rules.drl:
package com.example.drools.risk
import java.time.LocalDateTime;
import com.example.drools.model.Transaction;
import com.example.drools.model.User;
// 规则1:凌晨大额交易检测
rule "Detect Late Night Major Transaction"
when
$transaction: Transaction(amount > 50000)
eval(判断交易时间是否在凌晨0-5点)
$user: User(accountType != "CEO")
then
TransactionAlert alert = new TransactionAlert();
alert.setLevel("HIGH");
alert.setType("凌晨大额交易");
alert.setTransactionId($transaction.getTransactionId());
alert.setDescription("疑似洗钱行为,金额超过5万且时间异常");
insert(alert);
drools.halt();
end
// 规则2:高频连续交易检测
rule "Detect Rapid Multiple Transactions"
when
$user: User()
$transactions: List(size > 3) from collect
(Transaction(userId == $user.getUserId(),
timestamp > $user.getLastCheckedTime()))
eval(累计金额超过30000)
then
TransactionAlert alert = new TransactionAlert();
alert.setLevel("MEDIUM_HIGH");
alert.setType("高频交易");
alert.setUserId($user.getUserId());
alert.setTransactionCount($transactions.size());
insert(alert);
end
// 规则3:新开户交易限制
rule "New Account Transaction Monitoring"
when
$user: User(accountAge <= 3)
$transaction: Transaction(amount > 20000, userId == $user.getUserId())
then
TransactionAlert alert = new TransactionAlert();
alert.setLevel("HIGH");
alert.setType("新账户异常");
insert(alert);
end
// 规则4:高管账户通知(非拦截)
rule "CEO Account Notification"
when
$user: User(accountType == "CEO", status == "ACTIVE")
$transaction: Transaction(amount >= 100000, userId == $user.getUserId())
then
TransactionNotification notification = new TransactionNotification();
notification.setType("CEO交易确认");
notification.setMessage("高管大额交易需人工确认");
insert(notification);
end
场景3:货物配送路径优化
业务规则:
- 依据邮编和距离选择最近配送中心
- 考虑货物重量、体积、紧急程度
- 如果配送中心库存不足,自动寻找替代方案
- 包裹丢失时自动触发理赔流程
// 规则1:超出配送范围检测
rule "Out of Delivery Range"
when
$package: PackageObject(deliveryCode != null )
$address: Address(scope == "distance" || $package.getDistance() > 50)
then
System.out.println("该地址超出配送范围,请联系客服");
retract($package);
// 触发特殊流程
insert(new DeliveryException($package, "超出配送范围"));
end
// 规则2:紧急包裹优先处理
rule "Priority Emergency Package"
when
$package: PackageObject(priority == "EMERGENCY",
deliveryTime > 8,
deliveryTime <= 10)
$carrier: Carrier(freeCapacity > $package.getWeight())
then
assignPackageToCarrier($package, $carrier);
update($carrier);
end
决策表(Excel)案例
Excel决策表结构:
| RuleSet | package: com.example.drools.rules | | |----------|----------------------------------|--| | Import | com.example.drools.model.Order | | | Notes | 折扣计算规则决策表 | | |----------------------------------------------------------------| | RuleTable 折扣计算 | | | | 触发条件 | 属性 | 成员属性 | 结果 | |----------|--------------------------|-----------------|------------| | 条件 | 会员等级 | 订单金额 | 折扣率 | | 条件 | 枚举类型 | double | double | | VIP | 金卡会员 | 金额 > 1000 | 0.15 | | 普通用户 | 无会员 | 金额 > 2000 | 0.10 | | 新用户 | 首单 | 任意金额 | 0.20 |
复杂事件处理(CEP)案例
实时监控系统
package com.example.drools.cep
import com.example.drools.model.SensorData;
import java.util.Date;
import java.util.concurrent.TimeUnit;
// 定义事件窗口和时序逻辑
declare SensorAlarm
@role(event)
@timestamp(timestamp)
@expires(24h)
end
// 连续高频异常检测
rule "Detect Continuous High Temperature"
when
// 在10秒内连续3次高温报警
$threshold : Number(doubleValue > 85) from accumulate(
SensorData(time > currentTime - 10s, temperature > 80),
count($count))
$count : Number(intValue >= 3)
then
System.out.println("设备温度异常!连续高温报警次数:" + $count);
insert(new SensorAlarm("HIGH_TEMPERATURE",
"设备连续高温,需要停机检查"));
end
完整项目配置(kmodule.xml)
<?xml version="1.0" encoding="UTF-8"?>
<kmodule xmlns="http://www.drools.org/xsd/kmodule">
<kbase name="rules" packages="com.example.drools.rules">
<ksession name="discount-session" type="stateful"/>
<ksession name="stateless-session" type="stateless"/>
</kbase>
<kbase name="risk-rules" packages="com.example.drools.risk">
<ksession name="risk-session" type="stateful"/>
</kbase>
<kbase name="cep-rules" packages="com.example.drools.cep">
<ksession name="cep-session" type="stateful">
<clock type="realtime"/>
</ksession>
</kbase>
</kmodule>
性能优化与最佳实践
规则冲突解决
// 设置规则优先级
rule "High Priority Rule"
salience 100 // 数值越大优先级越高
when
// 条件
then
// 执行逻辑
end
// 使用组和议程
rule "Group A Rule"
agenda-group "main"
activation-group "critical"
end
rule "Alternating Rule"
agenda-group "main"
activation-group "alternating"
end
动态规则加载
public class DynamicRuleLoader {
public static KieSession loadRuleFromString(String ruleContent) {
KieHelper helper = new KieHelper();
helper.addContent(ruleContent, ResourceType.DRL);
KieBase kbase = helper.build();
return kbase.newKieSession();
}
public static void updateRuleInRuntime(KieSession session, String newRule) {
// 重新加载并替换规则
}
}
大数据量优化
// 使用无状态会话
StatelessKieSession statelessSession = kContainer.newStatelessKieSession("stateless-session");
statelessSession.execute(orderList);
// 启用增量编译
KieServices kieServices = KieServices.Factory.get();
KieRepository kr = kieServices.getRepository();
KieBuilder kieBuilder = kieServices.newKieBuilder(kr);
kieBuilder.setIncremental(true);
版权声明:NBA直播
NBA直播
NBA直播
NBA直播
NBA直播
NBA直播
NBA直播
NBA直播
NBA直播
NBA直播
NBA直播
NBA直播
NBA直播
NBA直播
NBA直播
NBA直播
NBA直播
NBA直播
NBA直播
NBA直播
NBA直播
NBA直播
NBA直播
NBA直播
NBA直播
NBA直播
NBA直播
NBA直播
NBA直播
NBA直播
NBA直播
NBA直播
NBA直播
NBA直播
NBA直播
NBA直播
NBA直播
NBA直播
NBA直播
NBA直播
足球直播
足球直播
足球直播
篮球直播
篮球直播
篮球直播
NBA直播
NBA直播
NBA直播
CBA直播
CBA直播
CBA直播
亚冠直播
亚冠直播
亚冠直播
欧冠直播
欧冠直播
欧冠直播
英超直播
英超直播
英超直播
西甲直播
西甲直播
西甲直播
中超直播
中超直播
中超直播
足球直播
足球直播
足球直播
篮球直播
篮球直播
篮球直播
NBA直播
NBA直播
NBA直播
CBA直播
CBA直播
CBA直播
亚冠直播
亚冠直播
亚冠直播
欧冠直播
欧冠直播
欧冠直播
英超直播
英超直播
英超直播
西甲直播
西甲直播
西甲直播
中超直播
中超直播
中超直播
足球直播
足球直播
足球直播
篮球直播
篮球直播
篮球直播
NBA直播
NBA直播
NBA直播
CBA直播
CBA直播
CBA直播
亚冠直播
亚冠直播
亚冠直播
欧冠直播
欧冠直播
欧冠直播
英超直播
英超直播
英超直播
西甲直播
西甲直播
西甲直播
中超直播
中超直播
中超直播
足球直播
足球直播
足球直播
篮球直播
篮球直播
篮球直播
NBA直播
NBA直播
NBA直播
CBA直播
CBA直播
CBA直播
亚冠直播
亚冠直播
亚冠直播
欧冠直播
欧冠直播
欧冠直播
英超直播
英超直播
英超直播
西甲直播
西甲直播
西甲直播
中超直播
中超直播
中超直播
曼联直播
曼联直播
曼联直播
日职联直播
日职联直播
日职联直播
澳超直播
澳超直播
澳超直播
阿森纳直播
阿森纳直播
阿森纳直播
足球直播
足球直播
足球直播
NBA直播
NBA直播
NBA直播
曼联直播
曼联直播
曼联直播
日职联直播
日职联直播
日职联直播
澳超直播
澳超直播
澳超直播
阿森纳直播
阿森纳直播
阿森纳直播
足球直播
足球直播
足球直播
NBA直播
NBA直播
NBA直播
曼联直播
曼联直播
曼联直播
日职联直播
日职联直播
日职联直播
澳超直播
澳超直播
澳超直播
阿森纳直播
阿森纳直播
阿森纳直播
足球直播
足球直播
足球直播
NBA直播
NBA直播
NBA直播
曼联直播
曼联直播
曼联直播
日职联直播
日职联直播
日职联直播
澳超直播
澳超直播
澳超直播
阿森纳直播
阿森纳直播
阿森纳直播
足球直播
足球直播
足球直播
NBA直播
NBA直播
NBA直播
欧冠直播
欧冠直播
欧冠直播
欧冠直播
欧冠直播
欧冠直播
欧冠直播
欧冠直播
欧冠直播
欧冠直播
欧冠直播
欧冠直播
欧冠直播
欧冠直播
欧冠直播
欧冠直播
欧冠直播
欧冠直播
欧冠直播
欧冠直播
中超直播
中超直播
中超直播
中超直播
中超直播
中超直播
中超直播
中超直播
中超直播
中超直播
中超直播
中超直播
中超直播
中超直播
中超直播
中超直播
中超直播
中超直播
中超直播
中超直播
NBA直播
NBA直播
NBA直播
NBA直播
NBA直播
足球直播
足球直播
足球直播
足球直播
足球直播
英超直播
英超直播
英超直播
英超直播
英超直播
篮球直播
篮球直播
篮球直播
篮球直播
篮球直播
CBA直播
CBA直播
CBA直播
CBA直播
CBA直播
中超直播
中超直播
中超直播
中超直播
中超直播
NBA直播
NBA直播
NBA直播
NBA直播
NBA直播
足球直播
足球直播
足球直播
足球直播
足球直播
英超直播
英超直播
英超直播
英超直播
英超直播
篮球直播
篮球直播
篮球直播
篮球直播
篮球直播
CBA直播
CBA直播
CBA直播
CBA直播
CBA直播
中超直播
中超直播
中超直播
中超直播
中超直播
NBA直播
NBA直播
NBA直播
NBA直播
NBA直播
NBA直播
NBA直播
NBA直播
NBA直播
NBA直播
NBA直播
NBA直播
NBA直播
NBA直播
NBA直播
NBA直播
NBA直播
NBA直播
NBA直播
NBA直播
NBA直播
NBA直播
NBA直播
NBA直播
NBA直播
NBA直播
NBA直播
NBA直播
NBA直播
NBA直播
NBA直播
NBA直播
NBA直播
NBA直播
NBA直播
NBA直播
NBA直播
NBA直播
NBA直播
NBA直播
中超直播
中超直播
中超直播
中超直播
中超直播
中超直播
中超直播
中超直播
中超直播
中超直播
中超直播
中超直播
中超直播
中超直播
中超直播
中超直播
中超直播
中超直播
中超直播
中超直播
中超直播
中超直播
中超直播
中超直播
中超直播
中超直播
中超直播
中超直播
中超直播
中超直播
中超直播
中超直播
中超直播
中超直播
中超直播
中超直播
中超直播
中超直播
中超直播
中超直播