Drools API的使用学习
在 Drools 当中,规则的编译与运行要通过 Drools 提供的各种 API 来实现,这些 API 总
体来讲可以分为三类:规则编译、规则收集和规则的执行。完成这些工作的 API 主要有
KnowledgeBuilder、KnowledgeBase、StatefulKnowledgeSession、StatelessKnowledgeSession

1.KnowledgeBuilder 的作用就是用来在业务代码当中收集已
经编写好的规则,然后对这些规则文件进行编译,最终产生一批编译好的规则包
(KnowledgePackage)给其它的应用程序使用。KnowledgeBuilder 在编译规则的时候可以通
过其提供的 hasErrors()方法得到编译规则过程中发现规则是否有错误,如果有的话通过其提
供的 getErrors()方法将错误打印出来,以帮助我们找到规则当中的错误信息。创建 KnowledgeBuilder 对象
使用的是 KnowledgeBuilderFactory的 newKnowledgeBuilder方法
示例代码如下:
package test;
import java.util.Collection;
import org.drools.builder.KnowledgeBuilder;
import org.drools.builder.KnowledgeBuilderFactory;
import org.drools.builder.ResourceType;
import org.drools.definition.KnowledgePackage;
import org.drools.io.ResourceFactory;
public class Test {
public static void main(String[] args) {
KnowledgeBuilder kbuilder=KnowledgeBuilderFactory.newKnowledgeBuilder();
kbuilder.add(ResourceFactory.newClassPathResource("test.drl",Test.class),ResourceType.DRL);
KnowledgeBuilderErrors errors = kbuilder.getErrors();
if (errors.size() > 0) {
for (KnowledgeBuilderError error: errors) {
System.err.println(error);
}
throw new IllegalArgumentException("Could not parse knowledge.");
}
Collection<KnowledgePackage> kpackage=kbuilder.getKnowledgePackages();//产生规则包的集合
}
}

2.KnowledgeBase 是 Drools 提供的用来收集应用当中知识(knowledge)定义的知识库对象,在一个 KnowledgeBase 当中可以包含
普通的规则(rule) 、规则流(rule flow)、函数定义(function)、用户自定义对象(type model)等。
创建一个 KnowledgeBase 要通过 KnowledgeBaseFactory 对象提供的 newKnowledgeBase()方法来实现, 这其中创建的时候
还可以为其指定一个 KnowledgeBaseConfiguration 对象,KnowledgeBaseConfiguration 对象是一个用来存放规则引擎运行时
相关环境参数定义的配置对象。示例代码如下:
package test;
import org.drools.KnowledgeBase;
import org.drools.KnowledgeBaseConfiguration;
import org.drools.KnowledgeBaseFactory;

public class Test {
public static void main(String[] args) {

KnowledgeBaseConfiguration kbConf = KnowledgeBaseFactory.newKnowledgeBaseConfiguration();
kbConf.setProperty( "org.drools.sequential", "true");
KnowledgeBase kbase = KnowledgeBaseFactory.newKnowledgeBase(kbConf);
}
}

从代码清单中可以看到,创建一个 KnowledgeBaseConfiguration 对象的方法也是使
用 KnowldegeBaseFactory,使用的是其提供的 newKnowledgeBaseConfiguration()方法,该方
法创建好的 KnowledgeBaseConfiguration 对象默认情况下会加载 drools-core-版本号.jar 包下
META-INF/drools.default.rulebase.conf 文件里的规则运行环境配置信息,加载完成后,我们
可以在代码中对这些默认的信息重新赋值,以覆盖加载的默认值,比如这里我们就把
org.drools.sequential 的值修改为 true,它的默认值为 false。

KnowledgeBase 创建完成之后, 接下来就可以将我们前面使用 KnowledgeBuilder 生成的
KnowledgePackage 的集合添加到 KnowledgeBase 当中,以备使用

package test;
import java.util.Collection;
import org.drools.KnowledgeBase;
import org.drools.KnowledgeBaseConfiguration;
import org.drools.KnowledgeBaseFactory;
import org.drools.builder.KnowledgeBuilder;
import org.drools.builder.KnowledgeBuilderFactory;
import org.drools.builder.ResourceType;
import org.drools.definition.KnowledgePackage;
import org.drools.io.ResourceFactory;
public class Test {
public static void main(String[] args) {
KnowledgeBuilder kbuilder = KnowledgeBuilderFactory.newKnowledgeBuilder();
kbuilder.add(ResourceFactory.newClassPathResource("test.drl",Test.class), ResourceType.DRL);
Collection<KnowledgePackage> kpackage = kbuilder.getKnowledgePackages();

KnowledgeBaseConfiguration kbConf = KnowledgeBaseFactory.newKnowledgeBaseConfiguration();
kbConf.setProperty("org.drools.sequential", "true");
KnowledgeBase kbase = KnowledgeBaseFactory.newKnowledgeBase(kbConf);

kbase.addKnowledgePackages(kpackage);//将KnowledgePackage集合添加到KnowledgeBase当中
}
}

3.规则编译完成之后,接下来就需要使用一个 API 使编译好的规则包文件在规则引擎当中运行起来。
在 Drools5 当中提供了两个对象与规则引擎进行交互: StatefulKnowledgeSession 和 StatelessKnowledgeSession
3.1 StatefulKnowledgeSession 对象是一种最常用的与规则引擎进行交互的方式, 它可以与规则引擎建立一个持续的交互通道, 在推理计算的过程当中可能会多次触发同一数据集。 在用户的代码当中,最后使用完 StatefulKnowledgeSession 对象之后,一定要调用其 dispose()方法以释放相关内存资源。
示例代码如下:
package test;
import java.util.Collection;
import org.drools.KnowledgeBase;
import org.drools.KnowledgeBaseConfiguration;
import org.drools.KnowledgeBaseFactory;
import org.drools.builder.KnowledgeBuilder;
import org.drools.builder.KnowledgeBuilderFactory;
import org.drools.builder.ResourceType;
import org.drools.definition.KnowledgePackage;
import org.drools.io.ResourceFactory;
import org.drools.runtime.StatefulKnowledgeSession;
public class Test {
public static void main(String[] args) {
KnowledgeBuilder kbuilder = KnowledgeBuilderFactory.newKnowledgeBuilder();
kbuilder.add(ResourceFactory.newClassPathResource("test.drl",Test.class), ResourceType.DRL);
Collection<KnowledgePackage> kpackage = kbuilder.getKnowledgePackages();

KnowledgeBaseConfiguration kbConf = KnowledgeBaseFactory.newKnowledgeBaseConfiguration();
kbConf.setProperty("org.drools.sequential", "true");
KnowledgeBase kbase = KnowledgeBaseFactory.newKnowledgeBase(kbConf);
kbase.addKnowledgePackages(kpackage);//将KnowledgePackage集合添加到KnowledgeBase当中

StatefulKnowledgeSession statefulKSession=kbase.newStatefulKnowledgeSession();
KnowledgeRuntimeLogger logger = KnowledgeRuntimeLoggerFactory.newFileLogger(ksession, "test");

statefulKSession.setGlobal("globalTest", new Object());//设置一个global对象
statefulKSession.insert(new Object());//插入一个fact对象
statefulKSession.fireAllRules();
statefulKSession.dispose();

logger.close();
}
}

3.2 StatelessKnowledgeSession 的作用与 StatefulKnowledgeSession 相仿,它们都是用来接收业务数据、执行规则的。
事实上,StatelessKnowledgeSession 对 StatefulKnowledgeSession做了包装,使得在使用StatelessKnowledgeSession对象
时不需要再调用 dispose()方法释放内存资源了。示例代码如下:
package test;
import java.util.ArrayList;
import java.util.Collection;
import org.drools.KnowledgeBase;
import org.drools.KnowledgeBaseConfiguration;
import org.drools.KnowledgeBaseFactory;
import org.drools.builder.KnowledgeBuilder;
import org.drools.builder.KnowledgeBuilderFactory;
import org.drools.builder.ResourceType;
import org.drools.definition.KnowledgePackage;
import org.drools.io.ResourceFactory;
import org.drools.runtime.StatelessKnowledgeSession;
public class Test {
public static void main(String[] args) {
KnowledgeBuilder kbuilder = KnowledgeBuilderFactory.newKnowledgeBuilder();
kbuilder.add(ResourceFactory.newClassPathResource("test.drl",Test.class), ResourceType.DRL);
Collection<KnowledgePackage> kpackage = kbuilder.getKnowledgePackages();

KnowledgeBaseConfiguration kbConf = KnowledgeBaseFactory.newKnowledgeBaseConfiguration();
kbConf.setProperty("org.drools.sequential", "true");
KnowledgeBase kbase = KnowledgeBaseFactory.newKnowledgeBase(kbConf);
kbase.addKnowledgePackages(kpackage);//将KnowledgePackage集合添加到KnowledgeBase当中

StatelessKnowledgeSession statelessKSession=kbase.newStatelessKnowledgeSession();
ArrayList list=new ArrayList();
list.add(new Object());
list.add(new Object());
statelessKSession.execute(list);
}
}
//通 过 新 建 了 一 个 ArrayList 对 象 ,将 需 要 插 入 到StatelessKnowledgeSession 当中的对象放到这个 ArrayList 当中,
将这个 ArrayList 作为参数传给 execute(…)方法,这样在 StatelessKnowledgeSession 内部会对这个 ArrayList 进行迭代,取出其
中的每一个 Element,将其作为 fact,调用 StatelessKnowledgeSession 对象内部的StatefulKnowledgeSession 对 象 的 insert()
方 法 将 产 生 的 fact 逐 个 插 入 到StatefulKnowledgeSession 当中,然后调用 StatefulKnowledgeSession 的 fireAllRules()
方法,最后执行 dispose()方法释放内存资源。

4.Fact对象是指在Drools规则应用当中, 将一个普通的JavaBean插入到规则的WorkingMemory
当中后的对象。规则可以对 Fact 对象进行任意的读写操作,当一个 JavaBean 插入到
WorkingMemory 当中变成 Fact 之后,Fact 对象不是对原来的 JavaBean 对象进行 Clon,而是
原来 JavaBean 对象的引用。规则在进行计算的时候需要用到应用系统当中的数据,这些数
据设置在 Fact 对象当中,然后将其插入到规则的 WorkingMemory 当中,这样在规则当中就
可以通过对 Fact 对象数据的读写,从而实现对应用数据的读写操作。一个 Fact 对象通常是
一个具有 getter 和 setter 方法的 POJO 对象, 通过这些 getter 和 setter 方法可以方便的实现对
Fact 对象的读写操作,所以我们可以简单的把 Fact 对象理解为规则与应用系统数据交互的
桥梁或通道。

5.Agenda对象
规则的调用与执行是通过 StatelessSession 或 StatefulSession 来实现的,一般的顺序是创
建一个 StatelessSession 或 StatefulSession,将各种经过编译的规则的 package 添加到 session
当中, 接下来将规则当中可能用到的 Global 对象和 Fact 对象插入到 Session 当中, 最后调用
fireAllRules 方法来触发、执行规则。在没有调用最后一步 fireAllRules 方法之前,所有的规
则及插入的 Fact 对象都存放在一个名叫 Agenda 表的对象当中,这个 Agenda 表中每一个规
则及与其匹配相关业务数据叫做 Activation,在调用 fireAllRules 方法后,这些 Activation 会
依次执行,这些位于 Agenda 表中的 Activation 的执行顺序在没有设置相关用来控制顺序的
属性时(比如 salience 属性) ,它的执行顺序是随机的,不确定的。

Drools API的使用学习的更多相关文章

  1. ArcGIS API for Silverlight学习笔记

    ArcGIS API for Silverlight学习笔记(一):为什么要用Silverlight API(转) 你用上3G手机了吗?你可能会说,我就是喜欢用nokia1100,ABCDEFG跟我都 ...

  2. arcgis api for javascript 学习(七) 调用发布地图信息,并将地图属性信息输出到Excel表格---进阶版

    我们在arcgis api for javascript 学习(三)已经学习到了关于调用地图信息进行属性输出的问题,不过通过代码我们实现后会发现还是有一些小瑕疵的,比如我们只能单个数据属性的输出,如果 ...

  3. 基于TensorFlow Object Detection API进行迁移学习训练自己的人脸检测模型(二)

    前言 已完成数据预处理工作,具体参照: 基于TensorFlow Object Detection API进行迁移学习训练自己的人脸检测模型(一) 设置配置文件 新建目录face_faster_rcn ...

  4. ArcGIS api fo silverlight学习二(silverlight加载GraphicsLayer)

    上一节学习了silverlight加载GeoServer发布的WMS地图,这一节学习一下加载GraphicsLayer 一.加载.png或jpg文件图标 1.在MainPage.xaml中添加资源配置 ...

  5. ArcGIS api fo silverlight学习一(silverlight加载GeoServer发布的WMS地图)

    最好的学习资料ArcGIS api fo silverlight官网:http://help.arcgis.com/en/webapi/silverlight/samples/start.htm 一. ...

  6. ArcGIS API for Silverlight 学习笔记

    这里主要讲解展示不同的服务地图 先看一个实例: 新建一个Silverlight项目,在MainPage.xaml文件中,引入 ESRI.ArcGIS.Client 命名空间和 ESRI.ArcGIS. ...

  7. JAVA微服务应用(1)--SpringBoot中的REST API调用(学习笔记)

    好长时间没有写学习小结了,最近宁正好看了小马哥的微服务系列之<Spring Boot>系列,颇有收获,并且公司也布置一个课题就是关于Spring中的REST API调用.于是乎回归本行,再 ...

  8. ArcGIS api fo silverlight学习三(利用ElementLayer实现鼠标悬浮弹出自定义窗体)

    接着上一节继续学习,本节主要是利用ElementLayer实现鼠标悬浮弹出自定义窗体 参考博文:http://www.cnblogs.com/luxiaoxun/p/3322218.html 一.新建 ...

  9. itnesse实现api接口自动化测试学习

    上午在园子里乱逛,看了不少小伙伴们分享的接口测试方面的知识,大家所叙述到的一些经验或多或少,我也曾遇到过,突然意识到知识的点滴积累是多么的重要,我记得我最早接触接口测试的时候,就是只在浏览器里人工测试 ...

随机推荐

  1. .NET开源资源汇总

    1>>  力软信息化系统快速开发框架 2>>  金碟友商网 3>>

  2. vtkPlane和vtkPlaneSource

    1.vtkPlane vtkPlane provides methods for various plane computations. These include projecting points ...

  3. 【转】MySQL性能优化的最佳21条经验

    文章转自: http://blog.csdn.net/waferleo/article/details/7179009 今天,数据库的操作越来越成为整个应用的性能瓶颈了,这点对于Web应用尤其明显.关 ...

  4. sql手工注入时的探测技巧汇总

    工具的灵活性肯定比不上人,在手工探测的基础上再去自定义工具,才是正道. sql注入时手工探测技巧 =================================================== ...

  5. CJCMS系列--demo代码篇

    CJCMS之前写了不多的文章,但是一直没有上代码,也许代码写得很乱很差,但是我觉得总得有个开始,持续改进.作为一个喜欢分享的程序员,我决定分享一下. 前面文章中的结构比较全,而此次我给出的demo,没 ...

  6. windows7设置开机启动方式

    打开计算机(资源管理器)(快捷键win+e),输入 C:\ProgramData\Microsoft\Windows\Start Menu\Programs\Startup 将需要开机启动的软件的快捷 ...

  7. 关于Access restriction: The type 'Application' is not API (restriction on required library)

    原文链接:http://rxxluowei.iteye.com/blog/671893 今天写第一次写JavaFX的入门程序就GG 遇到了导入API的问题,无奈疯狂地通过网络找解决方案.. 我的问题是 ...

  8. zabbix触发器依赖

    触发器依赖 Zabbix - Router1 - Router2 – Host 如果router1宕机了,那么router2和host都不能连上,这样的话就会发router1.router2和host ...

  9. ffmpeg-20161003[04,05.06]-bin.7z

    ESC 退出 0 进度条开关 1 屏幕原始大小 2 屏幕1/2大小 3 屏幕1/3大小 4 屏幕1/4大小 5 屏幕横向放大 20 像素 6 屏幕横向缩小 20 像素 S 下一帧 [ -2秒 ] +2 ...

  10. linux下php-mysql拓展安装

    今天遇到一个奇怪的问题: 在服务器A上部署应用,在服务器B上部署数据库和缓存. 服务器A:apache2.2,php5.3 服务器B:mysql5.5,redis2.4 问题现象: 本地远程连接服务器 ...