drools集成springboot

Drools學習二

開始第一個工程

Drools版本:7.19.0.Final
Spingboot版本:2.1.4.RELEASE

引入依賴

		<dependency>
			<groupId>org.drools</groupId>
			<artifactId>drools-core</artifactId>
		    <version>7.19.0.Final</version>
		</dependency>
		<dependency>
			<groupId>org.drools</groupId>
			<artifactId>drools-compiler</artifactId>
			<version>7.19.0.Final</version>
		</dependency>
		<dependency>
			<groupId>org.kie</groupId>
			<artifactId>kie-api</artifactId>
			<version>7.19.0.Final</version>
		</dependency>

創建實體類

這裏以任務實體爲例

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文件

<?xml version="1.0" encoding="UTF-8"?>
<kmodule xmlns ="http://www.drools.org/xsd/kmodule">
<kbase name ="rules">
   <ksession name ="ksession-rules"/>
</kbase>
</kmodule>

創建測試類

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

可以看到:
輸出的debug日誌
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<FactHandle> HandleList = kieSession.getFactHandles();

釋放KieSession中的句柄可以調用下面的封裝函數:

 /**
	 * 移除KieSesion中的FactHandle
	 * @param kieSession
	 */
	public static void removeFactHandle(KieSession kieSession) {
		if(null==kieSession)
			return;
		Collection<FactHandle> HandleList = kieSession.getFactHandles();
		Iterator<FactHandle> Iterator = HandleList.iterator();
		while(Iterator.hasNext()) {
			kieSession.delete(Iterator.next());
		}
	}

關於FactHandle部分詳細的介紹,可以參考官方文檔。

工程源碼

下載鏈接:鏈接:https://pan.baidu.com/s/1aa-CdOiaPdlV7rLzp3Tlaw
提取碼:14pl

結語

在下節中,將介紹不通過配置kmodule.xml和drl文件的方式進行規則的fire, 即規則的動態編譯。
如果覺得這篇文章幫助了您,歡迎點贊和評論,有問題也歡迎在評論區指出,您的支持是我創作的動力。

發表評論
所有評論
還沒有人評論,想成為第一個評論的人麼? 請在上方評論欄輸入並且點擊發布.
相關文章