在 Drools 当中,规则的编译与运行要通过 Drools 提供的各种 API 来实现,这些 API 总
体来讲可以分为三类:规则编译、规则收集和规则的执行。完成这些工作的 API 主要有
KnowledgeBuilder、KnowledgeBase、StatefulKnowledgeSession、StatelessKnowledgeSession
1.KnowledgeBuilder 的作用就是用来在业务代码当中收集已
经编写好的规则,然后对这些规则文件进行编译,最终产生一批编译好的规则包
(KnowledgePackage)给其它的应用程序使用。KnowledgeBuilder 在编译规则的时候可以通
过其提供的 hasErrors()方法得到编译规则过程中发现规则是否有错误,如果有的话通过其提
供的 getErrors()方法将错误打印出来,以帮助我们找到规则当中的错误信息。创建 KnowledgeBuilder 对象
使用的是 KnowledgeBuilderFactory的 newKnowledgeBuilder方法
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);
}
}
Collection<KnowledgePackage> kpackage=kbuilder.getKnowledgePackages();//产生规则包的集合
}
}
2.KnowledgeBase 是 Drools 提供的用来收集应用当中知识(knowledge)定义的知识库对象,在一个 KnowledgeBase 当中可以包含
普通的规则(rule) 、规则流(rule flow)、函数定义(function)、用户自定义对象(type model)等。
创建一个 KnowledgeBase 要通过 KnowledgeBaseFactory 对象提供的 newKnowledgeBase()方法来实现, 这其中创建的时候
还可以为其指定一个 KnowledgeBaseConfiguration 对象,KnowledgeBaseConfiguration 对象是一个用来存放规则引擎运行时
相关环境参数定义的配置对象。
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 当中,以备使用
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()方法以释放相关内存资源。
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()方法释放内存资源了。
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 属性) ,它的执行顺序是随机的,不确定的。
转载请注明来源网站:blog.ytso.com谢谢!
原创文章,作者:奋斗,如若转载,请注明出处:https://blog.ytso.com/tech/pnotes/14847.html