drools集成springboot

Drools学习二

开始第一个工程

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();
	}
}

运行结果

drools集成springboot_第1张图片
可以看到规则触发,打印出了"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());

可以看到:
drools集成springboot_第2张图片
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, 即规则的动态编译。
如果觉得这篇文章帮助了您,欢迎点赞和评论,有问题也欢迎在评论区指出,您的支持是我创作的动力。

你可能感兴趣的:(规则引擎)