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 屬性) ,它的執行順序是隨機的,不確定的。

 


免責聲明!

本站轉載的文章為個人學習借鑒使用,本站對版權不負任何法律責任。如果侵犯了您的隱私權益,請聯系本站郵箱yoyou2525@163.com刪除。



 
粵ICP備18138465號   © 2018-2025 CODEPRJ.COM