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-cidrools-decisiontables 查询。

3. 在Excel中定义规则

以客户折扣计算为例,定义以下业务规则:

  • 个人客户:年限>3年享15%折扣
  • 个人客户:年限≤3年享5%折扣
  • 企业客户:统一享20%折扣

3.1 Excel文件结构

按 Drools 要求创建 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规则的完整流程:

  1. 按特定结构创建Excel决策表
  2. 通过Kie组件加载规则文件
  3. 执行规则并验证结果

完整示例代码可在 GitHub项目 中获取。


原始标题:Drools Using Rules from Excel Files