Drools版本:7.19.0.Final
Spingboot版本:2.1.4.RELEASE
org.drools
drools-core
7.19.0.Final
org.drools
drools-compiler
7.19.0.Final
org.kie
kie-api
7.19.0.Final
这里以任务实体为例
public class Person {
private String name;
private int age;
private String desc;
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 Person(String name,int age) {
this.name=name;
this.age=age;
}
}
在src/main/resources文件下,创建rules文件夹存放我们的规则文件,创建test.drl.
//created on: 2019-4-7
package com.demo //package任意的
import com.demo.test.entity.Person; //import语句,引入创建的实体
rule "isAdult"
when
person:Person(age>=18)
then
System.out.println("This is an adult");
person.setDesc("adult");
end
在src/main/resources文件夹下创建META-INF文件夹,在该文件夹下创建kmodule.xml文件
OneTest.java
import org.kie.api.KieServices;
import org.kie.api.runtime.KieContainer;
import org.kie.api.runtime.KieSession;
import com.demo.test.entity.Person;
public class OneTest {
public static void test() {
KieServices ks = KieServices.Factory.get();
KieContainer kContainer = ks.getKieClasspathContainer();
KieSession kSession = kContainer.newKieSession("ksession-rules");
Person person =new Person("Jhon",20);
kSession.insert(person);
kSession.fireAllRules();
System.out.println(person.getDesc());
}
}
启动类Test1Application.java
package com.demo.test;
import org.springframework.boot.SpringApplication;
import org.springframework.boot.autoconfigure.SpringBootApplication;
import com.demo.test.service.OneTest;
@SpringBootApplication
public class Test1Application {
public static void main(String[] args)
SpringApplication.run(Test1Application.class, args);
OneTest.test();
}
}
可以看到规则触发,打印出了"This is an adult" , person的desc属性也被赋值为"adult"。
添加规则触发事件和debug打印:
//RuleRuntimeEventManager规则触发事件
kSession.addEventListener(new DefaultAgendaEventListener() {
public void afterMatchFired(AfterMatchFiredEvent event) {
super.afterMatchFired(event);
System.out.println("命中:"+event);
}
});
//提供debug打印功能
kSession.addEventListener(new DebugRuleRuntimeEventListener());
可以看到:
Fact对象是指在使用Drools 规则时,将一个普通的JavaBean对象(上例中为Person)插入到规则引擎的 WorkingMemory当中的对象。debug日志打印出了Fact对象的信息。
当Fact对象插入到WorkingMemory当中后,会与当前WorkingMemory当中所有的规则进行匹配,同时返回一个FactHandler对象。FactHandler对象是插入到WorkingMemory当中Fact对象的引用句柄,通过FactHandler对象可以实现对Fact对象的删除及修改等操作。
KieServices ks = KieServices.Factory.get();
KieContainer kContainer = ks.getKieClasspathContainer();
KieSession kSession = kContainer.newKieSession("ksession-rules");
//RuleRuntimeEventManager规则触发事件
kSession.addEventListener(new DefaultAgendaEventListener() {
public void afterMatchFired(AfterMatchFiredEvent event) {
super.afterMatchFired(event);
System.out.println("命中:"+event);
}
});
//提供debug打印功能
kSession.addEventListener(new DebugRuleRuntimeEventListener());
Person person =new Person("Jhon",20);
FactHandle handle =kSession.insert(person); // 获取FactHandle
System.out.println(handle);
kSession.fireAllRules();
System.out.println(person.getDesc());
打印结果为:org.drools.core.impl.StatefulKnowledgeSessionImpl$O
bjectStoreWrapper@58606c91
有一点需要记住的是,当一个普通的Java Bean插入Working Memory中,每次规则fire完是不会释放的,drools本身耗内存,大量的堆积可能导致溢出。
通过句柄进行Fact对象的delete操作:
KieServices ks = KieServices.Factory.get();
KieContainer kContainer = ks.getKieClasspathContainer();
KieSession kSession = kContainer.newKieSession("ksession-rules");
//RuleRuntimeEventManager规则触发事件
//kSession.addEventListener(new DefaultAgendaEventListener() {
// public void afterMatchFired(AfterMatchFiredEvent event) {
// super.afterMatchFired(event);
// System.out.println("命中:"+event);
// }
// });
//提供debug打印功能
//kSession.addEventListener(new DebugRuleRuntimeEventListener());
Person person =new Person("Jhon",20);
FactHandle handle =kSession.insert(person); // 获取FactHandle
kSession.fireAllRules();
kSession.delete(handle); //移除句柄
kSession.dispose(); //销毁kSession
对于插入多个对象的情况,可以直接获取KieSession对应的所有已插入的FactHandle对象的集合。
Collection HandleList = kieSession.getFactHandles();
释放KieSession中的句柄可以调用下面的封装函数:
/**
* 移除KieSesion中的FactHandle
* @param kieSession
*/
public static void removeFactHandle(KieSession kieSession) {
if(null==kieSession)
return;
Collection HandleList = kieSession.getFactHandles();
Iterator Iterator = HandleList.iterator();
while(Iterator.hasNext()) {
kieSession.delete(Iterator.next());
}
}
关于FactHandle部分详细的介绍,可以参考官方文档。
下载链接:链接:https://pan.baidu.com/s/1aa-CdOiaPdlV7rLzp3Tlaw
提取码:14pl
在下节中,将介绍不通过配置kmodule.xml和drl文件的方式进行规则的fire, 即规则的动态编译。
如果觉得这篇文章帮助了您,欢迎点赞和评论,有问题也欢迎在评论区指出,您的支持是我创作的动力。