Drools应用实例
Drools 实例介绍
- Drools编译与运行:
-
在Drools当中,规则的编译与运行要通过Drools提供的各种API来实现,这些API总体来讲可以分为三类:规则编译、规则收集和规则的执行。
-
- Kmodule.xml的编写
- kmodule.xml文件放到
src/main/resources/META-INF/文件夹下
- 代码的实现(具体内容)
-
<?xml version="1.0" encoding="UTF-8"?> <kmodule xmlns="http://jboss.org/kie/6.0.0/kmodule"> <kbase name="rules" packages="rules"> <ksession name="ksession-rules"/> </kbase> <kbase name="dtables" packages="dtables"> <ksession name="ksession-dtables"/> </kbase> </kmodule>
-
一个kmodule里面包含了两个kbase,这个也是我们这个例子里面的两个用例
-
分别对应drl规则文件的例子,一个是对应Excel表格的规则例子。每一个kbase都有一个name,可以取任意字符串,但是不能重名。
-
然后都有一个packages,可以看到packages里面的字符串其实就是src/main/resources下面的文件夹的名称,或者叫包名,规则引擎会根据这里定义的包来查找规则定义文件。可以同时定义多个包,以逗号分隔开来就行。每一个kbase下面可以包含多个ksession,当然本例中都自定义了一个。
-
每一个ksession都有一个name,名字也可以是任意字符串,但是也不能重复。
kbase和ksession里面的name属性是全局不能重复的。kbase和ksession中其实还有很多其它的属性,每一个kbase下面可以包含多个ksession。
-
在运行时,KieContainer会根据*Model对象来创建KieModule、KieBase、KieSession对象。其中KieModule和KieBase只会创建一次,而KieSession则有可能创建多次,因为KieSession的创建成本很低,同时KieSession包含了运行时的数据,所以可以销毁、创建若干次。
- kmodule.xml文件放到
- Drools运行测试
- 定义一个POJO类
-
package com.drool.test; public class Person { private String name; private int age; private String desc; public Person(String name, int age) { this.name = name; this.age = age; } public String getName() { return name; } public void setName(String name) { this.name = name; } public int getAge() { return age; } public void setAge(int age) { this.age = age; } public String getDesc() { return desc; } public void setDesc(String desc) { this.desc = desc; } public String toString() { return "[name="+name+",age="+age+",desc="+desc+"]"; } }
- 编辑配置文件
-
<?xml version="1.0" encoding="UTF-8"?> <kmodule xmlns="http://jboss.org/kie/6.0.0/kmodule"> <!-- packages ='表示drl 文件所在位置' --> <kbase name="SimpleRuleKBase" packages="com.drool.test"> <! --kession name='表示 被引用的规则名'--> <ksession name="simpleRuleKSession" default="true"/> </kbase> </kmodule>
- 编辑规则:
person.drl
-
package com.person;<! -- 这里的包路径可以不并写到相应的位置 --> import com.drool.test.Person;<!-- 这里引用的POJO必须是正确的 -- > rule "boy" <! -- 规则名 --> salience 1 <!-- 优先级, 值越大,优先级越高 --> when $p : Person(age > 0); then $p.setDesc("少年"); retract($p); end rule "youth" salience 2 when $p : Person(age > 12); then $p.setDesc("青年"); retract($p); end rule "midlife" salience 3 when $p : Person(age > 24); then $p.setDesc("中年"); retract($p); end rule "old" salience 4 when $p : Person(age > 60); then $p.setDesc("老年"); retract($p); end
- 测试类
-
package com.drool.test; import org.kie.api.KieServices; import org.kie.api.runtime.KieContainer; import org.kie.api.runtime.KieSession; public class Test { static KieSession getSession() { KieServices ks = KieServices.Factory.get(); KieContainer kc = ks.getKieClasspathContainer(); return kc.newKieSession("simpleRuleKSession"); } public static void main(String[] args) { KieSession ks = getSession();// Person p1 = new Person("白展堂", 68); Person p2 = new Person("李大嘴", 32); Person p3 = new Person("佟湘玉", 18); Person p4 = new Person("郭芙蓉", 8); System.out.println("before p1 : " + p1); System.out.println("before p2 : " + p2); System.out.println("before p3 : " + p3); System.out.println("before p4 : " + p4); ks.insert(p1); ks.insert(p2); ks.insert(p3); ks.insert(p4); int count = ks.fireAllRules(); System.out.println("总执行了"+count+"条规则"); System.out.println("after p1 : " + p1); System.out.println("after p2 : " + p2); System.out.println("after p3 : " + p3); System.out.println("after p4 : " + p4); ks.dispose(); } }
-
输出结果
从classpath中读取kmodule,创建KieContainder容器,利用kieContainer对象创建一个新的KieSession,创建session的时候我们传入了一个name:"simpleRuleKSession”,这个字符串很眼熟吧,这个就是我们定义的kmodule.xml文件中定义的ksession的name。
kieContainer根据kmodule.xml定义的ksession的名称找到KieSession的定义,然后创建一个KieSession的实例。
KieSession就是一个到规则引擎的链接,通过它就可以跟规则引擎通讯,并且发起执行规则的操作。
通过kSession.insert方法来将事实(Fact)插入到引擎中,也就是Working Memory中。
然后通过kSession.fireAllRules方法来通知规则引擎执行规则。