Drools API的使用學習
在 Drools 當中,規則的編譯與運行要經過 Drools 提供的各類 API 來實現,這些 API 總
體來說能夠分爲三類:規則編譯、規則收集和規則的執行。完成這些工做的 API 主要有
KnowledgeBuilder、KnowledgeBase、StatefulKnowledgeSession、StatelessKnowledgeSessionjava
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();//產生規則包的集合
}
}session
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;less
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 當中,以備使用ui
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 屬性) ,它的執行順序是隨機的,不肯定的。get