1. 简介
本文将带你快速实现 Drools 规则引擎与 Spring 框架的集成。如果你是 Drools 新手,建议先阅读这篇入门文章打好基础。
2. Maven 依赖
首先在 pom.xml
中添加以下核心依赖:
<dependency>
<groupId>org.drools</groupId>
<artifactId>drools-core</artifactId>
<version>9.44.0.Final</version>
</dependency>
<dependency>
<groupId>org.kie</groupId>
<artifactId>kie-spring</artifactId>
<version>7.74.1.Final</version>
</dependency>
最新版本可在以下仓库查询:
3. 初始数据模型
我们通过一个出租车计费场景来演示。核心逻辑是根据行驶里程和夜间附加费标志计算车费。
3.1 事实对象(Fact)
定义两个核心业务对象:
public class TaxiRide {
private Boolean isNightSurcharge;
private Long distanceInMile;
// 标准构造器、getter/setter
}
public class Fare {
private Long nightSurcharge;
private Long rideFare;
// 标准构造器、getter/setter
}
3.2 业务规则
创建计费规则文件 TAXI_FARE_RULE.drl
:
global com.baeldung.spring.drools.model.Fare rideFare;
dialect "mvel"
rule "Calculate Taxi Fare - Scenario 1"
when
taxiRideInstance:TaxiRide(isNightSurcharge == false && distanceInMile < 10);
then
rideFare.setNightSurcharge(0);
rideFare.setRideFare(70);
end
规则逻辑说明:
- ✅ 当
isNightSurcharge
为false
且里程小于 10 英里时触发 - ✅ 设置夜间附加费为 0
- ✅ 基础车费固定为 70
- ⚠️ 计算结果会写入全局变量
rideFare
对象
4. Spring 集成实现
4.1 Spring 配置类
创建配置类管理 Drools 核心组件:
@Configuration
@ComponentScan("com.baeldung.spring.drools.service")
public class TaxiFareConfiguration {
private static final String drlFile = "TAXI_FARE_RULE.drl";
@Bean
public KieContainer kieContainer() {
KieServices kieServices = KieServices.Factory.get();
KieFileSystem kieFileSystem = kieServices.newKieFileSystem();
kieFileSystem.write(ResourceFactory.newClassPathResource(drlFile));
KieBuilder kieBuilder = kieServices.newKieBuilder(kieFileSystem);
kieBuilder.buildAll();
KieModule kieModule = kieBuilder.getKieModule();
return kieServices.newKieContainer(kieModule.getReleaseId());
}
}
关键组件解析:
- KieServices:单例工厂,提供所有 KIE 服务入口
- KieFileSystem:虚拟文件系统,加载规则文件
- KieBuilder:编译规则文件生成 KieModule
- KieContainer:规则引擎容器,管理 KieModule 生命周期
💡 简单粗暴的理解:
KieContainer
就像规则引擎的运行时环境,KieModule
是规则包,KieBase
是规则库(隐藏在 KieModule 内部)
4.2 业务服务层
创建服务类执行规则引擎:
@Service
public class TaxiFareCalculatorService {
@Autowired
private KieContainer kieContainer;
public Long calculateFare(TaxiRide taxiRide, Fare rideFare) {
KieSession kieSession = kieContainer.newKieSession();
kieSession.setGlobal("rideFare", rideFare);
kieSession.insert(taxiRide);
kieSession.fireAllRules();
kieSession.dispose();
return rideFare.getTotalFare();
}
}
执行流程详解:
- 创建
KieSession
(规则会话) - 设置全局变量
rideFare
(相当于规则引擎的全局参数) - 插入事实对象
TaxiRide
(规则引擎的输入数据) - 触发规则执行
fireAllRules()
- 清理会话资源
dispose()
(⚠️ 必须执行,否则内存泄漏)
5. 实战测试
编写测试用例验证规则逻辑:
@Test
public void whenNightSurchargeFalseAndDistLessThan10_thenFixWithoutNightSurcharge() {
TaxiRide taxiRide = new TaxiRide();
taxiRide.setIsNightSurcharge(false);
taxiRide.setDistanceInMile(9L);
Fare rideFare = new Fare();
Long totalCharge = taxiFareCalculatorService.calculateFare(taxiRide, rideFare);
assertNotNull(totalCharge);
assertEquals(Long.valueOf(70), totalCharge);
}
测试场景说明:
- ✅ 非夜间时段(
isNightSurcharge=false
) - ✅ 短途行程(9英里 < 10英里)
- ✅ 预期车费 70(无附加费)
6. 总结
本文通过出租车计费场景,完整演示了 Drools 与 Spring 的集成方案。核心要点包括:
- 依赖管理:正确引入
drools-core
和kie-spring
- 规则定义:使用
.drl
文件声明业务规则 - Spring 配置:通过
KieContainer
管理规则引擎生命周期 - 服务封装:在业务层调用规则引擎并管理资源
- 测试验证:确保规则逻辑符合预期
完整示例代码可在 GitHub 获取。实际项目中建议结合 Spring Boot 进一步简化配置。