
在 spring boot 中直接使用 drools ruleunit 会因类路径扫描与 kiebase 初始化机制缺失而失败;推荐采用 kogito 框架(含 incubation api)实现零配置、编译期规则注入与 spring 原生兼容。
Drools 8.x 的 RuleUnitProvider.get() 依赖运行时自动发现并注册 RuleUnit 类及其关联的 .drl 规则文件,该过程需完整的 KieProject 构建上下文支持。在标准 Spring Boot 应用中(JAR 打包、无 kie-maven-plugin),KieBase 默认无法加载 src/main/resources 下的规则文件,导致 RuleUnitProvider 抛出 Cannot find any rule unit for RuleUnitData 错误——根本原因并非缺少 kjar 包,而是缺乏 Drools 所需的元数据注册与 KieBase 编译流程。
✅ 推荐方案:迁移到 Kogito(Spring Boot 原生友好)
Kogito 将规则编译移至构建期,生成类型安全的 Java 接口与实现,并通过 Spring Boot Auto-Configuration 自动装配 RuleUnit Bean,完全规避运行时 KieBase 扫描问题:
-
替换依赖(移除 drools-ruleunits-engine):
org.kie.kogito kogito-spring-boot-starter-ruleunit 2.0.0.Final -
定义 RuleUnit(保持原有逻辑):
public class RequestAccessUnit implements RuleUnit { private final DataStreamrequests = DataStream.of(); private final DataStream permissions = DataStream.of(); // getter/setter + @RuleUnitScoped beans as needed } -
编写 .drl 文件(放在 src/main/resources/rules/):
package rules; unit RequestAccessUnit;
rule "Grant access for admin" when $r: Request(role == "ADMIN") then permissions.insert(new Permission("ACCESS_GRANTED")); end
4. **在 Controller 中直接注入(无需手动创建实例)**:
```java
@RestController
public class AccessController {
@Autowired
private RequestAccessUnit ruleUnit; // Kogito 自动装配已编译的 RuleUnit 实例
@PostMapping("/evaluate")
public List evaluate(@RequestBody Request request) {
var session = ruleUnit.createInstance();
session.fire(request);
return session.getPermissions().toList(); // 假设 permissions 是公开的 DataStream
}
} ⚠️ 关键注意事项:
- 不要再调用 RuleUnitProvider.get() —— Kogito 已将其抽象为 Spring Bean 生命周期管理;
- 确保 .drl 文件位于 src/main/resources 且包名(package)与 RuleUnit 类所在包或 kmodule.xml 中声明一致;
- 若必须保留 Drools 原生 API(非推荐),则需显式配置 KieContainer 并手动注册规则资源,但会丧失 Spring Boot 的自动配置优势,且易出错;
- Kogito Incubation API(如 org.kie.kogito.incubation.rules.RuleUnits)提供更灵活的动态单元控制,适用于高级场景。
总结:RuleUnit 在 Spring Boot 中“开箱即用”的唯一可靠路径是 Kogito。它消除了对 kie-maven-plugin、kjar 或手动 KieBase 构建的依赖,将规则验证、编译与注入全部纳入 Maven/Gradle 构建流程,同时完美融入 Spring 的依赖注入与启动生命周期。










