[7-05-02].第03节:基本概念 - Drools中API
功能: 这是访问 Drools 运行时功能的单一入口点(工厂模式)。几乎所有其他核心对象的创建都通过它或它返回的对象进行关键方法:: 从类路径加载规则(最常见方式): 获取一个虚拟文件系统,用于以编程方式添加规则文件newKieBuilder(KieFileSystem): 创建 KieBuilder 来编译规则newKieContainer(ReleaseId): 创建 KieContainer
·
一、Drools API开发步骤:

二、Drools中常用API
2.1.API的关系:
- 1.我们在操作Drools时经常使用的API以及它们之间的关系如下图:

2.2.API介绍:
接口1:KieServices
- 功能: 这是访问 Drools 运行时功能的单一入口点(工厂模式)。几乎所有其他核心对象的创建都通过它或它返回的对象进行
- 关键方法:
- getKieClasspathContainer(): 从类路径加载规则(最常见方式)
- getKieFileSystem(): 获取一个虚拟文件系统,用于以编程方式添加规则文件
- newKieBuilder(KieFileSystem): 创建 KieBuilder 来编译规则
- newKieContainer(ReleaseId): 创建 KieContainer(通常从 Maven GAV 坐标)
- newKieContainer(KieModuleModel): 创建 KieContainer(通常用于程序化构建)
- getRepository(): 获取 KieRepository(管理 KieModule/KieContainer)
- newRule() / newQuery() / newFunction() / newKieBaseModel() / newKieSessionModel(): 用于程序化定义规则元素和配置
接口2:KieSession (及其子接口 StatefulKieSession 和 StatelessKieSession)
- 功能: 这是规则引擎的核心运行时执行接口,用于与规则引擎交互。它包含了工作内存(Working Memory),是规则执行发生的场所,
- 主要分为两类:
类别1:StatefulKieSession:是有状态的会话
- 维护一个持续的工作内存(Working Memory),可以多次插入、修改、撤回事实对象,并多次触发规则执行 (fireAllRules())
- 适用于需要维护状态的复杂场景(如监控、长流程)
- 需要显式调用 dispose() 释放资源
类别2:StatelessKieSession:是无状态的会话
- 不维护跨调用之间的工作内存状态。每次 execute(…) 调用时
- 传入一组事实(对象集合或命令)
- 引擎在一个临时工作内存中执行所有规则
- 执行完毕后,临时工作内存被丢弃
- 返回结果(通常是修改后传入对象的集合或命令指定的结果)
- 简化了 API,避免了状态管理,通常性能更好,适用于请求-响应式的、不需要维护状态的场景(如校验、计算、分类)
关键方法 (通用):
- insert(Object fact): (Stateful) 将事实对象插入工作内存
- update(Handle handle, Object object): (Stateful) 更新工作内存中已有的对象(需先获取 Handle)
- delete(Handle handle): (Stateful) 从工作内存中移除事实对象(需先获取 Handle)
- getFactHandle(Object object): (Stateful) 获取工作内存中对象的句柄 (Handle)
- setGlobal(String identifier, Object value): 设置全局变量
- getGlobal(String identifier): 获取全局变量值
- registerChannel(String name, Channel channel): 注册退出通道
- fireAllRules(): (Stateful) 触发所有符合条件的规则执行
- fireAllRules(int max): (Stateful) 触发规则执行,最多触发 max 条规则
- dispose(): (Stateful) 释放会话及其所有资源(非常重要!)
关键方法 (StatelessKieSession 特有):
- execute(Object fact): 执行规则,传入单个事实对象。返回一个 CommandResults(通常较少直接使用)
- execute(Iterable facts): 执行规则,传入一个事实集合。返回一个 CommandResults
- execute(Command command): 执行一个命令(最灵活的方式,可以组合插入、设置全局、查询、执行等)。返回一个 ExecutionResults
接口3:KieContainer
- 功能: 代表一个可部署的规则知识单元(KieModule)的容器。它封装了编译好的知识库(KieBase)和可从中创建的会话(KieSession)
- 关键方法:
- newKieSession(): 创建默认配置的有状态会话 (StatefulKieSession)
- newKieSession(String configurationName): 根据 kmodule.xml 中定义的配置名称创建特定会话
- newStatelessKieSession(): 创建默认配置的无状态会话 (StatelessKieSession)
- newStatelessKieSession(String configurationName): 创建特定配置的无状态会话。
- getKieBase(): 获取容器中的 KieBase 对象。
- getKieBaseNames(): 获取容器中定义的 KieBase 名称列表
- dispose(): 释放容器及其所有创建的资源(会话、知识库等)。非常重要!
接口4:KieBase
- 功能: 代表一个编译好的、只读的规则知识库。它包含了从规则文件(.drl)、决策表、流程文件等编译而来的所有规则、流程、函数、类型定义等。KieBase 本身不包含运行时数据,创建它的成本较高(编译过程),但可以被多个会话共享。
- 关键方法:
- newKieSession(): 基于此 KieBase 创建一个新的有状态会话 (StatefulKieSession)
- newStatelessKieSession(): 基于此 KieBase 创建一个新的无状态会话 (StatelessKieSession)
- getKiePackages(): 获取知识库中包含的所有规则包 (KiePackage)
- getRule(String ruleName): 获取指定名称的规则对象
- KieSession (及其子接口 StatefulKieSession 和 StatelessKieSession)
接口5:KieBuilder
- 功能: 负责编译放在 KieFileSystem 中的规则资源(.drl, .xls, .bpmn 等),生成 KieModule。
- 关键方法:
- buildAll(): 执行完整的编译过程。
- getResults(): 获取编译结果 (Results),包含错误和警告信息。
接口6:KieFileSystem
- 功能: 一个虚拟文件系统,用于以编程方式定义构成 KieModule 的规则文件、配置文件等。是 KieBuilder 的输入来源之一(另一种是类路径/Maven)
- 关键方法:
- write(String path, byte[] content): 写入文件内容
- write(String path, String content): 写入文件内容(常用)
- write(String path, Resource resource): 写入一个 Resource 对象(如 UrlResource, ClassPathResource)
接口6:KieRepository
- 功能: 一个单例仓库,存储所有可用的 KieModule。通常由 KieServices 管理,开发者直接操作较少
- 关键方法:
- addKieModule(KieModule kModule): 添加模块
- getKieModule(ReleaseId releaseId): 根据 GAV 坐标获取模块
- removeKieModule(ReleaseId releaseId): 移除模块
接口7:ReleaseId
- 功能: 代表 Maven 风格的 GAV (GroupId, ArtifactId, Version) 坐标,用于唯一标识一个 KieModule(规则包)
2.3.API 之间的关系 (调用流程)
第1步: 获取入口:
- 通过 KieServices.Factory.get() 获取 KieServices 实例
第2步:定义/获取规则来源:
1、类路径方式 (最常见):
- 确保规则文件在类路径下(如 src/main/resources)
KieContainer kContainer = kieServices.getKieClasspathContainer();
2、程序化构建 (KieFileSystem):
KieFileSystem kfs = kieServices.newKieFileSystem();
kfs.write("src/main/resources/rules/rule1.drl", drlContentString);
KieBuilder kieBuilder = kieServices.newKieBuilder(kfs);
kieBuilder.buildAll(); // 编译
KieContainer kContainer = kieServices.newKieContainer(kieServices.getRepository().getDefaultReleaseId());
3、Maven 仓库方式:
ReleaseId releaseId = kieServices.newReleaseId("com.example", "my-rules", "1.0.0");
KieContainer kContainer = kieServices.newKieContainer(releaseId); // Drools 会自动解析依赖
第3步:获取知识库 (KieBase):
- 通常直接从 KieContainer 获取会话,但也可以:
KieBase kBase = kContainer.getKieBase(); // 获取默认 KieBase
KieBase kBase = kContainer.getKieBase("kbaseName"); // 获取指定名称的 KieBase
第4步:创建会话 (KieSession):
- 有状态:
StatefulKieSession kSession = kContainer.newKieSession(); // 默认
StatefulKieSession kSession = kContainer.newKieSession("ksessionName"); // 指定配置
- 无状态:
StatelessKieSession kSession = kContainer.newStatelessKieSession(); // 默认
StatelessKieSession kSession = kContainer.newStatelessKieSession("statelessKsessionName"); // 指定配置
第5步:使用会话执行规则:
- 有状态 (StatefulKieSession):
kSession.insert(fact1); // 插入事实
kSession.insert(fact2);
kSession.setGlobal("logger", myLogger); // 设置全局变量
kSession.fireAllRules(); // 触发规则
// ... 可能修改事实 (update), 删除事实 (delete), 再次 fireAllRules() ...
kSession.dispose(); // 非常重要!清理资源
无状态 (StatelessKieSession):
// 方式1: 传入集合
List<Object> facts = Arrays.asList(fact1, fact2);
kSession.execute(facts); // 执行规则,facts 会被修改(如果规则修改了它们)
// 方式2: 传入命令 (更灵活)
kSession.execute(CommandFactory.newInsert(fact1));
kSession.execute(CommandFactory.newInsert(fact2));
kSession.execute(CommandFactory.newSetGlobal("logger", myLogger));
kSession.execute(CommandFactory.newFireAllRules());
// 方式3: 组合命令 (推荐)
List<Command> cmds = new ArrayList<>();
cmds.add(CommandFactory.newInsert(fact1));
cmds.add(CommandFactory.newInsert(fact2));
cmds.add(CommandFactory.newSetGlobal("logger", myLogger));
cmds.add(CommandFactory.newFireAllRules());
ExecutionResults results = kSession.execute(CommandFactory.newBatchExecution(cmds));
// 从 results 中获取可能通过命令设置的结果
第6步:清理资源
- 使用完 StatefulKieSession 后必须调用 dispose()。使用完 KieContainer(如果不再需要)也应调用 dispose()。
更多推荐

所有评论(0)