在 Drools 当中,规则的编译与运行要通过Drools 提供的各种API 来实现,这些API 总体来讲可以分为三类:规则编译、规则收集和规则的执行。完成这些工作的API 主要有KnowledgeBuilder、KnowledgeBase、StatefulKnowledgeSession、StatelessKnowledgeSession、、等,它们起到了对规则文件进行收集、编译、查错、插入fact、设置global、执行规则或规则流等作用:1 KnowledgeBuilder
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); Collection<KnowledgePackage> kpackage=kbuilder.getKnowledgePackages();//产生规则包的集合 } }
通过KnowledgeBuilder 编译的规则文件的类型可以有很多种,如.drl 文件、.dslr 文件或一个xls 文件等。产生的规则包可以是具体的规则文件形成的,也可以是规则流(rule flow)文件形成的,在添加规则文件时,需要通过使用 ResourceType 的枚举值来指定规则文件的类型;同时在指定规则文件的时候drools 还提供了一个名为 ResourceFactory 的对象,通过该对象可以实现从Classpath、URL、File、ByteArray、Reader 或诸如XLS 的二进制文件里添加载规则。
2 KnowledgeBase
KnowledgeBase 是 Drools 提供的用来收集应用当中知识(knowledge)定义的知识库对象,在一个KnowledgeBase 当中可以包含普通的规则(rule)、规则流(rule flow)、函数定义(function)、用户自定义对象(type model)等。KnowledgeBase 本身不包含任何业务数据对象(fact 对象,后面有相应章节着重介绍fact 对象),业务对象都是插入到由KnowledgeBase产生的两种类型的session 对象当中(StatefulKnowledgeSession 和StatelessKnowledgeSession,后面会有对应的章节对这两种类型的对象进行介绍),通过session 对象可以触发规则执行或开始一个规则流执行。创建一个KnowledgeBase 要通过KnowledgeBaseFactory 对象提供的newKnowledgeBase()方法来实现,这其中创建的时候还可以为其指定一个KnowledgeBaseConfiguration 对象,KnowledgeBaseConfiguration 对象是一个用来存放规则引擎运行时相关环境参数定义的配置对象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-5.0.1.jar 包下META-INF/drools.default.rulebase.conf 文件里的规则运行环境配置信息,加载完成后,我们可以在代码中对这些默认的信息重新赋值,以覆盖加载的默认值,比如这里我们就把org.drools.sequential 的值修改为true,它的默认值为false。除了这种方式创建KnowledgeBaseConfiguration 方法之外,我们还可以为其显示的指定一个Properties 对象,在该对象中设置好需要覆盖默认值的相关属性的值,然后再通过newKnowledgeBaseConfiguration(Properties prop , ClassLoader loader) 方法创建一个KnowledgeBaseConfiguration 对象。该方法方法当中第一个参数就是我们要设置的Properties对象,第二个参数用来设置加载META-INF/drools.default.rulebase.conf 文件的ClassLoader,因为该文件在ClassPath 下,所以采用的是ClassLoader 方法进行加载,如果不指定这个参数,那么就取默认的ClassLoader 对象, 如果两个参数都为null , 那么就和newKnowledgeBaseConfiguration()方法的作用相同了。示例如下:
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 StatefulKnowledgeSessions
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(); statefulKSession.setGlobal("globalTest", new Object());//设置一个global对象 statefulKSession.insert(new Object());//插入一个fact对象 statefulKSession.fireAllRules(); statefulKSession.dispose(); } }4 StateLessKnowledgeSession
StatelessKnowledgeSession statelessKSession=kbase.newStatelessKnowledgeSession(); ArrayList list=new ArrayList(); list.add(new Object()); list.add(new Object()); statelessKSession.execute(list);如果我们要插入的fact 就是这个ArrayList 而不是它内部的Element那该怎么做呢?在StatelessKnowledgeSession 当中,还提供了execute(Command cmd)的方法,在该方法中通过CommandFactory 可以创建各种类型的Command,比如前面的需求要直接将这个ArrayList 作为一个fact 插入,那么就可以采用CommandFactory.newInsert(Object obj)来实现: