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

规则逻辑说明:

  • ✅ 当 isNightSurchargefalse 且里程小于 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());
    }
}

关键组件解析:

  1. KieServices:单例工厂,提供所有 KIE 服务入口
  2. KieFileSystem:虚拟文件系统,加载规则文件
  3. KieBuilder:编译规则文件生成 KieModule
  4. 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();
    }
}

执行流程详解:

  1. 创建 KieSession(规则会话)
  2. 设置全局变量 rideFare(相当于规则引擎的全局参数)
  3. 插入事实对象 TaxiRide(规则引擎的输入数据)
  4. 触发规则执行 fireAllRules()
  5. 清理会话资源 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 的集成方案。核心要点包括:

  1. 依赖管理:正确引入 drools-corekie-spring
  2. 规则定义:使用 .drl 文件声明业务规则
  3. Spring 配置:通过 KieContainer 管理规则引擎生命周期
  4. 服务封装:在业务层调用规则引擎并管理资源
  5. 测试验证:确保规则逻辑符合预期

完整示例代码可在 GitHub 获取。实际项目中建议结合 Spring Boot 进一步简化配置。


原始标题:Drools Spring Integration