1. 概述
Drools 支持以电子表格格式管理业务规则。本文将通过一个实际案例,演示如何使用 Excel 文件在 Drools 中定义和执行业务规则。
2. Maven 依赖
首先在项目中添加必要的 Drools 依赖:
<dependency>
<groupId>org.kie</groupId>
<artifactId>kie-ci</artifactId>
<version>9.44.0.Final</version>
</dependency>
<dependency>
<groupId>org.drools</groupId>
<artifactId>drools-decisiontables</artifactId>
<version>9.44.0.Final</version>
</dependency>
最新版本可在 kie-ci 和 drools-decisiontables 查询。
3. 在Excel中定义规则
以客户折扣计算为例,定义以下业务规则:
- 个人客户:年限>3年享15%折扣
- 个人客户:年限≤3年享5%折扣
- 企业客户:统一享20%折扣
3.1 Excel文件结构
按 Drools 要求创建 Excel 文件:
核心关键字说明:
RuleSet
:决策表起始标记Import
:规则中使用的Java类RuleTable
:规则集起始标记Name
:规则名称CONDITION
:条件判断代码片段(至少一个)ACTION
:满足条件时执行的操作(至少一个)
3.2 Customer类
Excel中引用的Customer类定义:
public class Customer {
private CustomerType type;
private int years;
private int discount;
// 标准getter/setter
public enum CustomerType {
INDIVIDUAL,
BUSINESS;
}
}
4. 创建Drools规则引擎实例
执行规则前需初始化Drools引擎核心组件:
4.1 KieServices
KieServices kieServices = KieServices.Factory.get();
提供所有Kie构建和运行时功能的入口。
4.2 KieFileSystem
Resource dt = ResourceFactory
.newClassPathResource("com/baeldung/drools/rules/Discount.drl.xls", getClass());
KieFileSystem kieFileSystem = kieServices.newKieFileSystem().write(dt);
虚拟文件系统,用于加载Excel规则文件。
4.3 KieBuilder
KieBuilder kieBuilder = kieServices.newKieBuilder(kieFileSystem);
kieBuilder.buildAll();
构建KieFileSystem内容,生成KieModule。
4.4 KieRepository
KieRepository kieRepository = kieServices.getRepository();
框架自动将构建结果存入仓库。
4.5 KieContainer
ReleaseId krDefaultReleaseId = kieRepository.getDefaultReleaseId();
KieContainer kieContainer = kieServices.newKieContainer(krDefaultReleaseId);
使用默认ReleaseId创建容器实例。
4.6 KieSession
KieSession kieSession = kieContainer.newKieSession();
获取规则执行会话,用于存储和操作运行时数据。
5. 执行规则
注入数据并触发规则执行:
Customer customer = new Customer(CustomerType.BUSINESS, 2);
kieSession.insert(customer);
kieSession.fireAllRules();
6. 测试用例
验证规则执行结果的测试类:
public class DiscountExcelIntegrationTest {
private KieSession kSession;
@Before
public void setup() {
Resource dt = ResourceFactory
.newClassPathResource("com/baeldung/drools/rules/Discount.drl.xls", getClass());
kSession = new DroolsBeanFactory().getKieSession(dt);
}
@Test
public void giveIndvidualLongStanding_whenFireRule_thenCorrectDiscount() {
Customer customer = new Customer(CustomerType.INDIVIDUAL, 5);
kSession.insert(customer);
kSession.fireAllRules();
assertEquals(customer.getDiscount(), 15);
}
@Test
public void giveIndvidualRecent_whenFireRule_thenCorrectDiscount() {
Customer customer = new Customer(CustomerType.INDIVIDUAL, 1);
kSession.insert(customer);
kSession.fireAllRules();
assertEquals(customer.getDiscount(), 5);
}
@Test
public void giveBusinessAny_whenFireRule_thenCorrectDiscount() {
Customer customer = new Customer(CustomerType.BUSINESS, 0);
kSession.insert(customer);
kSession.fireAllRules();
assertEquals(customer.getDiscount(), 20);
}
}
7. 常见问题排查
Drools会将决策表转换为DRL文件,Excel中的错误常反映在DRL中。调试时可输出DRL内容:
Resource dt = ResourceFactory
.newClassPathResource("com/baeldung/drools/rules/Discount.drl.xls", getClass());
DecisionTableProviderImpl decisionTableProvider = new DecisionTableProviderImpl();
String drl = decisionTableProvider.loadFromResource(dt, null);
8. 总结
本文演示了使用Excel管理Drools规则的完整流程:
- 按特定结构创建Excel决策表
- 通过Kie组件加载规则文件
- 执行规则并验证结果
完整示例代码可在 GitHub项目 中获取。