1. 程式人生 > >Drools 基本API的使用學習

Drools 基本API的使用學習

Drools API的使用學習
在 Drools 當中,規則的編譯與執行要通過 Drools 提供的各種 API 來實現,這些 API 總
體來講可以分為三類:規則編譯、規則收集和規則的執行。完成這些工作的 API 主要有
KnowledgeBuilder、KnowledgeBase、StatefulKnowledgeSession、StatelessKnowledgeSession


1.KnowledgeBuilder 的作用就是用來在業務程式碼當中收集已
經編寫好的規則,然後對這些規則檔案進行編譯,最終產生一批編譯好的規則包
(KnowledgePackage)給其它的應用程式使用。KnowledgeBuilder 在編譯規則的時候可以通
過其提供的 hasErrors()方法得到編譯規則過程中發現規則是否有錯誤,如果有的話通過其提
供的 getErrors()方法將錯誤打印出來,以幫助我們找到規則當中的錯誤資訊。建立 KnowledgeBuilder 物件
使用的是 KnowledgeBuilderFactory的 newKnowledgeBuilder方法
示例程式碼如下:
package test;
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);
KnowledgeBuilderErrors errors = kbuilder.getErrors();
if (errors.size() > 0) {
for (KnowledgeBuilderError error: errors) {
System.err.println(error);
}
throw new IllegalArgumentException("Could not parse knowledge.");
}
Collection<KnowledgePackage> kpackage=kbuilder.getKnowledgePackages();//產生規則包的集合
}
}


2.KnowledgeBase 是 Drools 提供的用來收集應用當中知識(knowledge)定義的知識庫物件,在一個 KnowledgeBase 當中可以包含
普通的規則(rule) 、規則流(rule flow)、函式定義(function)、使用者自定義物件(type model)等。
建立一個 KnowledgeBase 要通過 KnowledgeBaseFactory 物件提供的 newKnowledgeBase()方法來實現, 這其中建立的時候
還可以為其指定一個 KnowledgeBaseConfiguration 物件,KnowledgeBaseConfiguration 物件是一個用來存放規則引擎執行時
相關環境引數定義的配置物件。示例程式碼如下:
package test;
import org.drools.KnowledgeBase;
import org.drools.KnowledgeBaseConfiguration;
import org.drools.KnowledgeBaseFactory;

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-版本號.jar 包下
META-INF/drools.default.rulebase.conf 檔案裡的規則執行環境配置資訊,載入完成後,我們
可以在程式碼中對這些預設的資訊重新賦值,以覆蓋載入的預設值,比如這裡我們就把
org.drools.sequential 的值修改為 true,它的預設值為 false。


KnowledgeBase 建立完成之後, 接下來就可以將我們前面使用 KnowledgeBuilder 生成的
KnowledgePackage 的集合新增到 KnowledgeBase 當中,以備使用

package test;
import java.util.Collection;
import org.drools.KnowledgeBase;
import org.drools.KnowledgeBaseConfiguration;
import org.drools.KnowledgeBaseFactory;
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();

KnowledgeBaseConfiguration kbConf = KnowledgeBaseFactory.newKnowledgeBaseConfiguration();
kbConf.setProperty("org.drools.sequential", "true");
KnowledgeBase kbase = KnowledgeBaseFactory.newKnowledgeBase(kbConf);

kbase.addKnowledgePackages(kpackage);//將KnowledgePackage集合新增到KnowledgeBase當中
}
}

 

3.規則編譯完成之後,接下來就需要使用一個 API 使編譯好的規則包檔案在規則引擎當中執行起來。
在 Drools5 當中提供了兩個物件與規則引擎進行互動: StatefulKnowledgeSession 和 StatelessKnowledgeSession
3.1 StatefulKnowledgeSession 物件是一種最常用的與規則引擎進行互動的方式, 它可以與規則引擎建立一個持續的互動通道, 在推理計算的過程當中可能會多次觸發同一資料集。 在使用者的程式碼當中,最後使用完 StatefulKnowledgeSession 物件之後,一定要呼叫其 dispose()方法以釋放相關記憶體資源。
示例程式碼如下:
package test;
import java.util.Collection;
import org.drools.KnowledgeBase;
import org.drools.KnowledgeBaseConfiguration;
import org.drools.KnowledgeBaseFactory;
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;
import org.drools.runtime.StatefulKnowledgeSession;
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();
KnowledgeRuntimeLogger logger = KnowledgeRuntimeLoggerFactory.newFileLogger(ksession, "test");

statefulKSession.setGlobal("globalTest", new Object());//設定一個global物件
statefulKSession.insert(new Object());//插入一個fact物件
statefulKSession.fireAllRules();
statefulKSession.dispose();

logger.close();
}
}

3.2 StatelessKnowledgeSession 的作用與 StatefulKnowledgeSession 相仿,它們都是用來接收業務資料、執行規則的。
事實上,StatelessKnowledgeSession 對 StatefulKnowledgeSession做了包裝,使得在使用StatelessKnowledgeSession物件
時不需要再呼叫 dispose()方法釋放記憶體資源了。示例程式碼如下:
package test;
import java.util.ArrayList;
import java.util.Collection;
import org.drools.KnowledgeBase;
import org.drools.KnowledgeBaseConfiguration;
import org.drools.KnowledgeBaseFactory;
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;
import org.drools.runtime.StatelessKnowledgeSession;
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當中

StatelessKnowledgeSession statelessKSession=kbase.newStatelessKnowledgeSession();
ArrayList list=new ArrayList();
list.add(new Object());
list.add(new Object());
statelessKSession.execute(list);
}
}
//通 過 新 建 了 一 個 ArrayList 對 象 ,將 需 要 插 入 到StatelessKnowledgeSession 當中的物件放到這個 ArrayList 當中,
將這個 ArrayList 作為引數傳給 execute(…)方法,這樣在 StatelessKnowledgeSession 內部會對這個 ArrayList 進行迭代,取出其
中的每一個 Element,將其作為 fact,呼叫 StatelessKnowledgeSession 物件內部的StatefulKnowledgeSession 對 象 的 insert()
方 法 將 產 生 的 fact 逐 個 插 入 到StatefulKnowledgeSession 當中,然後呼叫 StatefulKnowledgeSession 的 fireAllRules()
方法,最後執行 dispose()方法釋放記憶體資源。

 


4.Fact物件是指在Drools規則應用當中, 將一個普通的JavaBean插入到規則的WorkingMemory
當中後的物件。規則可以對 Fact 物件進行任意的讀寫操作,當一個 JavaBean 插入到
WorkingMemory 當中變成 Fact 之後,Fact 物件不是對原來的 JavaBean 物件進行 Clon,而是
原來 JavaBean 物件的引用。規則在進行計算的時候需要用到應用系統當中的資料,這些數
據設定在 Fact 物件當中,然後將其插入到規則的 WorkingMemory 當中,這樣在規則當中就
可以通過對 Fact 物件資料的讀寫,從而實現對應用資料的讀寫操作。一個 Fact 物件通常是
一個具有 getter 和 setter 方法的 POJO 物件, 通過這些 getter 和 setter 方法可以方便的實現對
Fact 物件的讀寫操作,所以我們可以簡單的把 Fact 物件理解為規則與應用系統資料互動的
橋樑或通道。

5.Agenda物件
規則的呼叫與執行是通過 StatelessSession 或 StatefulSession 來實現的,一般的順序是創
建一個 StatelessSession 或 StatefulSession,將各種經過編譯的規則的 package 新增到 session
當中, 接下來將規則當中可能用到的 Global 物件和 Fact 物件插入到 Session 當中, 最後呼叫
fireAllRules 方法來觸發、執行規則。在沒有呼叫最後一步 fireAllRules 方法之前,所有的規
則及插入的 Fact 物件都存放在一個名叫 Agenda 表的物件當中,這個 Agenda 表中每一個規
則及與其匹配相關業務資料叫做 Activation,在呼叫 fireAllRules 方法後,這些 Activation 會
依次執行,這些位於 Agenda 表中的 Activation 的執行順序在沒有設定相關用來控制順序的
屬性時(比如 salience 屬性) ,它的執行順序是隨機的,不確定的。

原文地址: https://www.cnblogs.com/ciade/p/5234791.html