Drools学习大纲


一、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()。

Logo

有“AI”的1024 = 2048,欢迎大家加入2048 AI社区

更多推荐