JBoss Rules 學(xué)習(xí)(三): Drools規(guī)則引擎 (上)
從今天開始,我們將分兩期來詳細(xì)的介紹Drools規(guī)則引擎的原理,和各關(guān)鍵類的使用方法。1. 概述 :
Drools 分為兩個主要部分:構(gòu)建( Authoring )和運行時( Runtime )。
構(gòu)建的過程涉及到 .drl 或 .xml 規(guī)則文件的創(chuàng)建,它們被讀入一個解析器,使用 ANTLR 3 語法進(jìn)行解析。解析器對語法進(jìn)行正確性的檢查,然后產(chǎn)生一種中間結(jié)構(gòu)“ descr ”, descr 用 AST 來描述規(guī)則。 AST 然后被傳到 PackageBuilder ,由 PackagBuilder 來產(chǎn)生 Packaged 對象。 PackageBuilder 還承擔(dān)著一些代碼產(chǎn)生和編譯的工作,這些對于產(chǎn)生 Package 對象都時必需的。 Package 對象是一個可以配置的,可序列化的,由一個或多個規(guī)則組成的對象。下圖闡明了上述過程:

Figure 1.1 Authoring Components
RuleBase 是一個運行時組件,它包含了一個或多個 Package 對象。可以在任何時刻將一個 Package 對象加入或移出 RuleBase 對象。一個 RuleBase 對象可以在任意時刻實例化一個或多個 WorkingMemory 對象,在它的內(nèi)部保持對這些 WorkingMemory 的弱引用。 WorkingMemory 由一系列子組件組成。當(dāng)應(yīng)用程序中的對象被 assert 進(jìn) WorkingMemory ,可能會導(dǎo)致一個或多個 Activation 的產(chǎn)生,然后由 Agenda 負(fù)責(zé)安排這些 Activation 的執(zhí)行。下圖說明了上述過程:

2.構(gòu)建(Authoring):
主要有三個類用來完成構(gòu)建過程:DrlParser, XmlParser 和 PackageBuilder。兩個解析器類從傳入的Reader實例產(chǎn)生descr AST模型。PackageBuilder提供了簡便的API,使你可以忽略那兩個類的存在。這兩個簡單的方法是:“addPackageFromDrl”和“addPackageFromXml”,兩個都只要傳入一個Reader實例作為參數(shù)。下面的例子說明了如何從classpath中的xml和drl文件創(chuàng)建一個Package對象。注意:所有傳入同一個PackageBuilder實例的規(guī)則源,都必須是在相同的package 命名空間(namespace)中。
builder.addPackageFromDrl(?new?InputStreamReader(?getClass().getResourceAsStream(?"package1.drl"?)?)?);
builder.addPackageFromXml(?new?InputStreamReader(?getClass().getResourceAsStream(?"package2.drl"?)?)?);
Package?pkg?=?builder.getPackage();

Figure 2.1 PackageBuilder
PackageBuilder是可以配置的,使用PackageBuilderConfiguration。通常,你可以指定另一個parent ClassLoader和用什么編譯器(compiler),默認(rèn)是Eclipse JDT。下面顯示了如何指定JANINO編譯器:
conf.setCompiler(?PackageBuilderConfiguration.JANINO?);
PackageBuilder?builder?=?new?PackageBuilder(?conf?);

Figure 2.2 .?PackageBuilderConfiguration
3.RuleBase:

Figure 3.1 .?RuleBase
一個RuleBase包含了多個將被使用的規(guī)則包(packages of rules)。一個RuleBase是可以序列化的,所以它可以被配置到JNDI或其他類似的服務(wù)。通常,第一次使用時,一個RuleBase被創(chuàng)建并緩存。RuleBase用RuleBaseFactory來實例化,默認(rèn)返回一個ReteOO RuleBase。可以傳入?yún)?shù)來指定采用ReteOO或Leaps。然后,用addPackage方法加入Package實例。你可以加入有相同命名空間(namespace)的多個Package。
ruleBase.addPackage(pkg);

Figure 3.2. RuleBaseFactory
一個 rulebase instance 是線程安全的,所有你可以在你的應(yīng)用中,讓一個 rulebase instance 在多個線程中共享。對于一個 rulebase 的最通常的操作是產(chǎn)生一個新的 WorkingMemory 。
這個 rulebase 保持著到它所產(chǎn)生的 WorkingMemoryd 的弱引用,所以在長時間運行的 WorkingMemory 中,如果 rules 發(fā)生改變,這些 WorkingMemory 可以即使的根據(jù)最新的 rules 進(jìn)行更新,而不必重啟 WorkingMemory 。你也可以指定 RuleBase 不必保持一個弱引用,但是你要保證 RuleBase 不用更新。
ruleBase.newWorkingMemory(?
false
?);?
//
?do?not?maintain?a?weak?reference
任何時候, Package 可以被加入或移除;所有的改變都會被反映到現(xiàn)存的 WorkingMemory 中。不要忘了調(diào)用 fireAllRules() 讓 Activations 激發(fā)。
ruleBase.removePackage(?
"
org.com.sample
"
??);??
//
?remove?a?package,?and?all?its?parts,
by?it's?namespace
ruleBase.removeRule(?
"
org.com.sample
"
,?
"
my?rule
"
?);?
//
?remove?a?specific?rule?from?a
namespace
雖然有刪除一個單獨規(guī)則的方法,但是卻沒有加入一個單獨規(guī)則的方法(要達(dá)到這個目的只有加入一個只有一條規(guī)則的 package )。
RuleBaseConfigurator 可以指定 RuleBase 的附加行為。在加入 RuleBase 后, RuleBaseConfiguration 就變成不可變對象。
conf.setProperty(?RuleBaseConfiguration.PROPERTY_ASSERT_BEHAVIOR,
??????????????????RuleBaseConfiguration.WM_BEHAVIOR_EQUALITY?);
RuleBase?ruleBase? = ? new ?ReteooRuleBase(?conf?);
兩個主要的屬性是: PROPERT_ASSERT_BEHAVIOR 和 PROPERTY_LOGICAL_OVERRIDE_BEHAVIOR (在以后的部分中會解釋)。所有的屬性值都是 RuleBaseConfiguration 類中的靜態(tài)域常量。

Figure 3.3 RuleBaseConfiguration
posted on 2006-06-04 12:50 guangnian 閱讀(22505) 評論(14) 編輯 收藏 所屬分類: JBoss Rules(Drools)