3 Drools7 之 HelloWorld
3.2 API 解析
运行单元测试打印结果为:
命中了 1 条规则!
商品 GOLD 的商品折扣为 25%。
以上实例首先定义了一个商品,支持 DIAMOND 和 GOLD,并在规则文件中配置了这两 种商品的折扣信息。然后传入商品类型为 GLOD 的 FACT 对象,并调用规则引擎,规则引擎 执行了 1 条规则,并返回了此商品的折扣。
至此,我们已经完成了一个规则引擎的使用。通过上面的实例我们可以清楚的看到 Drools7 版本与 Drools5 版本之间所使用的 API 是完全两套 API。
3.2 API 解析
针对上面的实例,我们逐步了解一下使用到的 API 的使用说明及相关概念性知识。
3.2.1 什么是 KIE
KIE(Knowledge Is Everything),知识就是一切的简称。JBoss 一系列项目的总称,在《Drools 使用概述》章节已经介绍了 KIE 包含的大部分项目。它们之间有一定的关联,通用一些 API。
比如涉及到构建(building)、部署(deploying)和加载(loading)等方面都会以 KIE 作为前 缀来表示这些是通用的 API。
下图为 KIE 所包含的子项目结构图:
3.2.2 KIE 生命周期
无论是 Drools 还是 JBPM,生命周期都包含以下部分:
编写:编写规则文件,比如:DRL,BPMN2、决策表、实体类等。
构建:构建一个可以发布部署的组件,对于 KIE 来说是 JAR 文件。
测试:部署之前对规则进行测试。
部署:利用 Maven 仓库将 jar 部署到应用程序。
使用:程序加载 jar 文件,通过 KieContainer 对其进行解析创建 KieSession。
执行:通过 KieSession 对象的 API 与 Drools 引擎进行交互,执行规则。
交互:用户通过命令行或者 UI 与引擎进行交互。
管理:管理 KieSession 或者 KieContainer 对象。
3.2.3 FACT 对象
Fact 对象是指在使用 Drools 规则时,将一个普通的 JavaBean 对象插入到规则引擎的 WorkingMemory 当中的对象。规则可以对 Fact 对象进行任意的读写操作。Fact 对象不是对 原来的 JavaBean 对象进行 Clone,而是使用传入的 JavaBean 对象的引用。规则在进行计算 时需要的应用系统数据设置在 Fact 对象当中,这样规则就可以通过对 Fact 对象数据的读写 实现对应用数据的读写操作。
Fact 对象通常是一个具有 getter 和 setter 方法的 POJO 对象,通过 getter 和 setter 方法 可以方便的实现对 Fact 对象的读写操作,所以我们可以简单的把 Fact 对象理解为规则与 应用系统数据交互的桥梁或通道。
当 Fact 对象插入到 WorkingMemory 当中后,会与当前 WorkingMemory 当中所有的规 则进行匹配,同时返回一个 FactHandler 对象。FactHandler 对象是插入到 WorkingMemory 当中 Fact 对象的引用句柄,通过 FactHandler 对象可以实现对 Fact 对象的删除及修改等操 作。
前面的实例中通过调用 insert 方法将 Product 对象插入到 WorkingMemory 当中,Product 对象插入到规则中之后就是说为的 FACT 对象。如果需要插入多个 FACT 对象,多次调用 insert 方法,并传入对应 FACT 对象即可。
3.2.4 KieServices
该接口提供了很多方法,可以通过这些方法访问 KIE 关于构建和运行的相关对象,比如 说可以获取 KieContainer,利用 KieContainer 来访问 KBase 和 KSession 等信息;可以获取 KieRepository 对象,利用 KieRepository 来管理 KieModule 等。
KieServices 就是一个中心,通过它来获取的各种对象来完成规则构建、管理和执行等操 作。
示例 demo:
// 通过单例创建 KieServices
KieServices kieServices = KieServices.Factory.get();
// 获取 KieContainer
KieContainer kieContainer = kieServices.getKieClasspathContainer();
// 获取 KieRepository
KieRepository kieRepository = kieServices.getRepository();
3.2.5 KieContainer
可以理解 KieContainer 就是一个 KieBase 的容器。提供了获取 KieBase 的方法和创建 KieSession 的方法。其中获取 KieSession 的方法内部依旧通过 KieBase 来创建 KieSession。
// 通过单例创建 KieServices
KieServices kieServices = KieServices.Factory.get();
// 获取 KieContainer
KieContainer kieContainer = kieServices.getKieClasspathContainer();
// 获取 KieBase
KieBase kieBase = kieContainer.getKieBase();
// 创建 KieSession
KieSession kieSession = kieContainer.newKieSession("session-name");
3.2.6 KieBase
KieBase 就是一个知识仓库,包含了若干的规则、流程、方法等,在 Drools 中主要就是规 则和方法,KieBase 本身并不包含运行时的数据之类的,如果需要执行规则 KieBase 中的规 则的话,就需要根据 KieBase 创建 KieSession。
// 获取 KieBase
KieBase kieBase = kieContainer.getKieBase();
KieSession kieSession = kieBase.newKieSession();
StatelessKieSession statelessKieSession = kieBase.newStatelessKieSession();
3.2.7 KieSession
KieSession 就是一个跟 Drools 引擎打交道的会话,其基于 KieBase 创建,它会包含运行 时数据,包含“事实 Fact”,并对运行时数据实时进行规则运算。通过 KieContainer 创建 KieSession 是一种较为方便的做法,其本质上是从 KieBase 中创建出来的。KieSession 就是 应用程序跟规则引擎进行交互的会话通道。
创建 KieBase 是一个成本非常高的事情,KieBase 会建立知识(规则、流程)仓库,而创
建 KieSession 则是一个成本非常低的事情,所以 KieBase 会建立缓存,而 KieSession 则不必。
3.2.8 KieRepository
KieRepository 是一个单例对象,它是存放 KieModule 的仓库,KieModule 由 kmodule.xml 文件定义(当然不仅仅只是用它来定义)。
// 通过单例创建 KieServices
KieServices kieServices = KieServices.Factory.get();
// 获取 KieRepository
KieRepository kieRepository = kieServices.getRepository();
3.2.9 KieProject
KieContainer 通过 KieProject 来初始化、构造 KieModule,并将 KieModule 存放到 KieRepository 中,然后 KieContainer 可以通过 KieProject 来查找 KieModule 定义的信息,并 根据这些信息构造 KieBase 和 KieSession。
3.2.10 ClasspathKieProject
ClasspathKieProject 实 现 了 KieProject 接 口 , 它 提 供 了 根 据 类 路 径 中 的 META-INF/kmodule.xml 文件构造 KieModule 的能力,是基于 Maven 构造 Drools 组件的基本保障 之一。意味着只要按照前面提到过的 Maven 工程结构组织我们的规则文件或流程文件,只 include 的 KieBase 的 rule、process 定 义制品文件。非强制属性。 到该 KieBase,但是每一个 module 最 多只能有一个 KieBase。
equalsBehavior identity identity,equality 顾名思义就是定义“equals”(等于)的 行为,这个 equals 是针对 Fact(事实) equality 的话,就是通过 Fact 对象的 equals 方法来判断。
eventProcessingMode cloud cloud, stream 当以云模式编译时,KieBase 将事件视 为正常事实,而在流模式下允许对其 进行时间推理。
declarativeAgenda disabled disabled,enabled 这是一个高级功能开关,打开后规则 将可以控制一些规则的执行与否。
ksession 的属性:
属性名 默认值 合法的值 描述
name none any KieSession 的名称,该值必须唯一,也是强
制的,必须设置。
type stateful stateful, stateless 定义该 session 到底是有状态(stateful)的还 是无状态(stateless)的,有状态的 session 可 以利用 Working Memory 执行多次,而无状 态的则只能执行一次。
default false true, false 定义该 session 是否是默认的,如果是默认的 话则可以不用通过 session 的 name 来创建 session,在同一个 module 中最多只能有一个 默认的 session。
clockType realtime realtime,pseudo 定义时钟类型,用在事件处理上面,在复合事 件处理上会用到,其中 realtime 表示用的是 系统时钟,而 pseudo 则是用在单元测试时模 拟用的。
beliefSystem simple simple,defeasible, jtms
定义 KieSession 使用的 belief System 的类型。