Drools 5.1.1(一)
?http://shikonglaike.iteye.com/blog/1236354
第一章歡迎
我總是和終端業務用戶爭論不休,理解規則和流程、最新規則和事件處理的區別。對此,在他們的意識中有這樣的問題,并且他們希望使用某些軟件模擬它。使用兩個供應商提供的傳統方式,強迫業務用戶與一個剛剛獲得方式的面向流程或面向規則的方法一起工作,他們將使用該工具模擬這點,往往整體是極為混亂的。
PegaSystems和Microsoft做了大量的工作,顯示兩者可以被結合,并且可以使用一個行為的模擬方法。這讓業務用戶更自然地應用提供給他們的各種方法工作,不必使用獲得方式的工具。從面向流程到面向規則或中間的灰色地帶——任何當時的相應問題被模擬。
Drools5.0更進了一步,不僅增加了基于工作流與Drools流的BPMN2,而且增加了事件處理與DroolsFusion(熔合),為軟件開發者創建了一個更全面的方法。此處的術語“全面的”被用來強調整體和它局部間的相互依賴性的重要性。
Drools5.0現在被劃分為5個模塊,每個都自帶手冊——Guvnor(BRMS/BPMS),Expert(Rules),Fusion(CEP),Flow(Process/Workflow)和Planner。Guvnor是我們的基于網頁的管理系統,在規則世界中傳統提及的,如一個BRMS(商業規則管理系統)。我們決定拋棄一個擔當管理工作的BRMS術語,因為它不是規則的細節。Expert是傳統的規則引擎。Fusion是事件處理邊,它擔當數據/傳感器的熔合術語。Flow是我們的工作流模塊,由KrisVerlaenen領導,已經做了一些了不起的工作;他正把流與jBPM5合成一體。第5個模塊是Planner,由GeoffreyDeSmet撰寫,解決分配和調度類型的問題。雖然還處在開發的初期階段,但已顯示了許多期望。我們希望為2011版增加Semantics(語義),基于描述邏輯,并讓它擔當下一代Drools引擎的一部分。
我一直工作在規則領域,現在大約7年了。我終于感覺到我緊握東西,想法開始成形,并且真正的創新開始出現。對我來說,感覺就象我確實知道我們現在將做什么,與過去相比,有許多瘋狂的猜想和探索。我與EdsonTirelli和DavideSottara一起努力工作在DroolsExpert設計文檔上。我邀請你閱讀文檔和參與http://community.jboss.org/wiki/DroolsLanguageEnhancements。該文檔帶有東西給下一級,推動Drools成為一個混合的引擎,不僅是一個有能力生產規則的系統,而且混合了邏輯編程(prolog)與功能編程,以及帶有其他想法的更有表現力和現代感語言的描述邏輯。
我希望你能感覺到我們的團隊和我在Drools上工作的熱情,希望在你的冒險期間能感染你。
MarkProctor(Drools創建者和領導)
第二章Drools發行說明
2.1在Drools5.1.0中,值得注意的新東西。
?
2.1.1DroolsAPI
如在Drools5.0中一樣,仍然可以使用配置配置一個KnowledgeBase(知識庫),通過一個xml改變集合(changeset),而不是編程方式。然而,現在的change-set命名空間被版本化了。這意味著,在Drools5.1.0中,1.0.0xsd應該被引用。
例子2.1下面是一個簡單的版本1.0.0改變集合
<change-setxmlns='http://drools.org/drools-5.0/change-set'
xmlns:xs='http://www.w3.org/2001/XMLSchema-instance'
xs:schemaLocation='http://drools.org/drools-5.0/change-setchange-set-5.0.xsdhttp://anonsvn.jboss.org/repos/labs/labs/jbossrules/trunk/drools-api/src/main/resources/change-set-1.0.0.xsd'>
<add>
<resourcesource='classpath:org/domain/someRules.drl'type='DRL'/>
<resourcesource='classpath:org/domain/aFlow.drf'type='DRF'/>
</add>
</change-set>
?
2.1.2核心
?
2.1.2.1JMX監控
JMX監控被添加來支持知識庫監控。這尤其重要,象一個常需要事件處理的長期運行流程。初始化整合JOPR也被添加。JMX可以被啟用,使用屬性設置知識庫:
drools.mbeans=<enabled|disabled>或者這個選項在運行時啟用:
kbaseConf.setOption(MBeansOption.ENABLED)
2.1.2.2Spring
Drools現在有擴展的Spring支持,XSD可以在drools-springjar中發現。命名空間為"http://drools.org/schema/drools-spring"。
例子2.2知識庫構建器例子
?
<?xmlversion="1.0"encoding="UTF-8"?>
<beansxmlns="http://www.springframework.org/schema/beans"
xmlns:xsi="http://www.w3.org/2001/XMLSchema-instance"
xmlns:drools="http://drools.org/schema/drools-spring"
xmlns:camel="http://camel.apache.org/schema/spring"
xsi:schemaLocation="http://www.springframework.org/schema/beanshttp://www.springframework.org/schema/beans/spring-beans-2.0.xsd
http://drools.org/schema/drools-springhttp://anonsvn.jboss.org/repos/labs/labs/jbossrules/trunk/drools-container/drools-spring/src/main/resources/org/drools/container/spring/drools-spring-1.0.0.xsd
http://camel.apache.org/schema/springhttp://camel.apache.org/schema/spring/camel-spring.xsd">
<drools:resourceid="resource1"type="DRL"source="classpath:org/drools/container/spring/testSpring.drl"/>
<drools:kbaseid="kbase1">
<drools:resources>
<drools:resourcetype="DRL"source="classpath:org/drools/container/spring/testSpring.drl"/>
<drools:resourceref="resource1"/>
<drools:resourcesource="classpath:org/drools/container/spring/IntegrationExampleTest.xls"type="DTABLE">
<drools:decisiontable-confinput-type="XLS"worksheet-name="Tables_2"/>
</drools:resource>
</drools:resources>
<drools:configuration>
<drools:mbeansenabled="true"/>
<drools:event-processing-modemode="STREAM"/>
</drools:configuration>
</drools:kbase>
</beans>
知識庫接受下面的配置:"advanced-process-rule-integration,multithread,mbeans,event-processing-mode,accumulate-functions,evaluatorsandassert-behavior"。
?
根據kbase參考可以創建ksessions
例子2.3知識會話
<drools:ksessionid="ksession1"type="stateless"name="stateless1"kbase="kbase1"/>
<drools:ksessionid="ksession2"type="stateful"kbase="kbase1"/>
象知識庫的知識會話可以接受一些配置,包括"work-item-handlers,"keep-references","clock-type","jpa-persistence"。
例子2.4知識會話的配置
<drools:ksessionid="ksession1"type="stateful"kbase="kbase1">
<drools:configuration>
<drools:work-item-handlers>
<drools:work-item-handlername="handlername"ref="handlerid"/>
</drools:work-item-handlers>
<drools:keep-referenceenabled="true"/>
<drools:clock-typetype="REALTIME"/>
</drools:configuration>
</drools:ksession>
StatefulKnowledgeSessions(有狀態知識會話)可以被配置為JPA持久化
?
例子2.5JPA配置用于StatefulKnowledgeSessions
<beanid="ds"class="org.springframework.jdbc.datasource.DriverManagerDataSource">
<propertyname="driverClassName"value="org.h2.Driver"/>
<propertyname="url"value="jdbc:h2:tcp://localhost/DroolsFlow"/>
<propertyname="username"value="sa"/>
<propertyname="password"value=""/>
</bean>
<beanid="myEmf"class="org.springframework.orm.jpa.LocalContainerEntityManagerFactoryBean">
<propertyname="dataSource"ref="ds"/>
<propertyname="persistenceUnitName"value="org.drools.persistence.jpa.local"/>
</bean>
<beanid="txManager"class="org.springframework.orm.jpa.JpaTransactionManager">
<propertyname="entityManagerFactory"ref="myEmf"/>
</bean>
<drools:ksessionid="jpaSingleSessionCommandService"type="stateful"kbase="kbase1">
<drools:configuration>
<drools:jpa-persistence>
<drools:transaction-managerref="txManager"/>
<drools:entity-manager-factoryref="myEmf"/>
<drools:variable-persisters>
<drools:persisterfor-class="javax.persistence.Entity"implementation="org.drools.persistence.processinstance.persisters.JPAVariablePersister"/>
<drools:persisterfor-class="java.lang.String"implementation="org.drools.container.spring.beans.persistence.StringVariablePersister"/>
<drools:persisterfor-class="java.io.Serializable"implementation="org.drools.persistence.processinstance.persisters.SerializableVariablePersister"/>
</drools:variable-persisters>
</drools:jpa-persistence>
</drools:configuration>
</drools:ksession>
知識庫會話可以支持啟動批處理腳本,前面的版本使用"script"元素名,它將被更新為"batch"。下面的命令被支持:"insert-object","set-global","fire-all-rules","fire-until-halt","start-process","signal-event"??梢允褂媚涿鸅ean或命名"ref"屬性。
例子2.6啟動批處理命令
?
<drools:ksessionid="jpaSingleSessionCommandService"type="stateful"kbase="kbase1">
<drools:script>
<drools:insert-objectref="person1"/>
<drools:start-processprocess-id="procname">
<drools:parameteridentifier="varName"ref="varRef"/>
</drools:start-process>
<drools:fire-all-rules/>
</drools:script>
</drools:ksession>
?
在Spring中支持執行節點(ExecutionNodes),它們提供了一個注冊的ksessions。它可以與Camel一起提供ksessions路由。
2.1.2.3Camel
Spring可以與Camel組合,提供聲明式規則服務。一個Camel策略從Drools被添加,Drools提供魔法注入類加載器(ClassLoader),類加載器被ksession用于任何數據的格式化,它還增強了JAXB和XStream數據的格式化。假如在Jaxb情況下,它添加另外的Drools路徑信息,利用XStream注冊Drools相關聯的轉換器,并取別名。
你可以使用不同的地址,創建你需要的盡可能多的端點。需要CommandMessagBodyReader分配有效負荷給Camel處理。
例子2.8Rest端點配置
<cxf:rsServerid="rsServer"
address="/kservice/rest"
serviceClass="org.drools.jax.rs.CommandExecutorImpl">
<cxf:providers>
<beanclass="org.drools.jax.rs.CommandMessageBodyReader"/>
</cxf:providers>
</cxf:rsServer>
然后,Camel路由可以連接到CXF端點,允許你控制如數據的格式化和根據Droolsksessions執行等事情的有效負荷。Drools策略增加某些智能給路由。如果使用JAXB或XStream,它將注入定制路徑和轉換器,它也可以在服務器邊設置類加載器,基于目標ksessions的。在客戶邊,它自動解包Response(響應)對象。
?
這個例子使用了一個增強的XStream的數據格式解組有效負荷,并且根據ksession1實例執行它。"node"在這兒引用了ExecutionContext(執行上下文),它是一個注冊的ksessions上下文。
例子2.9Camel路由
<beanid="droolsPolicy"class="org.drools.camel.component.DroolsPolicy"/>
<camelContextid="camel"xmlns="http://camel.apache.org/schema/spring">
<route>
<fromuri="cxfrs://bean://rsServer"/>
<policyref="droolsPolicy">
<unmarshalref="xstream"/>
<touri="drools://node/ksession1"/>
<marshalref="xstream"/>
</policy>
</route>
</camelContext>
Drools端點"drools:node/ksession1",由執行節點名字、分隔符和可選的知識會話名字構成。如果知識會話沒有指定路由,會查找在輸入的有效負荷的實例中的"lookup"屬性,或者在頭部屬性"DroolsLookup"中去查找。
2.1.2.4Drools服務器
Spring,Camel和CXF可以被組合,用于聲明式服務,drools-server是一個.war,組合了它們與某些開箱即用的例子xml,就像一類模板。如果你正在jboss容器中使用war,,那么你需要添加這個組件,http://camel.apache.org/camel-jboss.html。該war包含了一個test.jsp,顯示一個象你開始的例子一樣的回顯。這個例子只是執行一個簡單的"echo"類型的應用程序。它發送一個消息到規則服務器,規則服務器預先增加單詞"echo"到開頭,并發送它回去。默認時,消息是"HelloWorld",使用url參數msg——test.jsp?msg="MyCustomMessage",可以傳遞不同的消息。
?
2.1.2.5知識代理增量變化支持
新版的知識庫代理在它配置中支持newInstance=false(增量變化集合構建)。
?
當設置這個屬性為false,知識庫代理使用存在的知識庫參考應用增量變化。現在知識庫代理可以用增量的方式處理監控的資源更改。更改的定義被編譯,并和原始版本比較。根據定義的類型,以不同的方式表現:
l?Rules:用于規則,代理搜索在它的屬性中的更改,左手邊和右手邊。
l?Queries:查詢總在kbase上被替代,無論它們被更改還是沒有被更改。
l?其他定義:所有其他定義總是在kbase中被替代(只要它們被更改)。我們希望在將來的版本中,為更改定義的探測增加更好的支持。
當前的實現只支持規則、查詢和函數定義的探測。類型聲明不能被探測。
2.1.2.6會話檢查與報告框架
一個用于運行時會話檢查與報告的基于框架的新的API被引入,從而更好地在調試或應用程序成型時采集數據。這個檢查框架將成為加工功能的基礎,用來幫助為每個會話的內容提供更詳細的信息。這個api是實驗性的,并不是用在drools-api中,但可自由的使用,并幫助我們改進它。
要檢查一個會話,可以使用以下api調用之一:
例子2.10創建一個會話檢查器
StatefulKnowledgeSessionksession=...
//...insertfacts,firerules,etc
SessionInspectorinspector=newSessionInspector(ksession);
StatefulKnowledgeSessionInfoinfo=inspector.getSessionInfo();
StatefulKnowledgeSessionInfo實例將包含許多在會話分析期間采集的相關數據。提供了一個簡單的例子報告模板,并且可以利用下面的api調用產生:
例子2.11產生一個報告
Stringreport=SessionReporter.generateReport("simple",info,null);
?
2.1.3Expert
2.1.3.1差異更新
傳統Rete算法用retract+assert(撤消+斷言)做一個更新,對一個給定的事實,這導致所有的局部匹配被撤銷,然而,在assert(斷言)期間,其中一些會被再次重建;因為它們在更新前為true,并且在更新后仍然為true。這導致許多不需要的對象被摧毀,并且這些行為增加了垃圾收集器的負荷?,F在的更新是一個單程,并在適當的位置檢查局部匹配,避免不必要的局部匹配被摧毀。經歷事件和實事維護的一個正規化過程也不再需要;正規化過程是我們準備著眼于激活retract(撤消)的地方,被插入的激活斷定真正被添加的東西,由真正插入的東西確定“差異”。
?
2.1.3.2Channels(通道)
退出點已經用更合適的名字Channels(通道)替代,我們覺得它更合適,因為多個規則引擎可以使用它們,并且不是切入點的精確對立面。切入點明顯與進入Rete網絡中的一個分區有關聯。
2.1.3.3現場查詢
Doorls一直有一個查詢支持,但結果是以一個可迭代的集合返回;這使監測隨著時間的變化很困難。
?
我們現在用現場查詢實現它,它與一個偵聽器相連,而不是返回一個可迭代的集合。這些現實查詢持續打開創建的一個視圖,并且為這個視圖的內容發布變化事件。所以,你現在可以執行你的查詢,利用參數,并在結果視圖中偵聽變化。
?
例子2.12實現ViewChangedEventListener
?
finalListupdated=newArrayList();
finalListremoved=newArrayList();
finalListadded=newArrayList();
?
ViewChangedEventListenerlistener=newViewChangedEventListener(){
publicvoidrowUpdated(Rowrow){
updated.add(row.get("$price"));
}
?
publicvoidrowRemoved(Rowrow){
removed.add(row.get("$price"));
}
?
publicvoidrowAdded(Rowrow){
added.add(row.get("$price"));
?
}
};
?
//OpentheLiveQuery
?
LiveQueryquery=ksession.openLiveQuery("cheeses",newObject[]{"cheddar","stilton"},listener);
...
?
...
query.dispose()//makesureyoucalldisposewhenyouwantthequerytoclose
?
?
一個Doorls博客文章包含了一個用于現場查詢的Glazed列表集成的例子
?
http://blog.athico.com/2010/07/glazed-lists-examples-for-drools-live.html(不可用)
?
[http://planet.jboss.org/view/post.seam;jsessionid=8F25E6F156E3093608A38BDCCE17369C?post=glazed_lists_examples_for_drools_live_querries]
?
2.1.3.4定時器和日歷
規則現在支持基于interval(間隔)和cron定時器,替代了過時的duration(期限)屬性。
例子2.13定時器屬性使用的例子
timer(int:<initialdelay><repeatinterval>?)
timer(int:30s)
timer(int:30s5m)
timer(cron:<cronexpression>)
timer(cron:*0/15***?)
?
Interval"int:"定時器遵守JDK語義,初始化延遲,緊跟一個可選的重復間隔。Cron"cron:"定時器遵守標準的cron表達式:
?
例子2.14一個Cron例子
rule"SendSMSevery15minutes"
timer(cron:*0/15***?)
when
$a:Alarm(on==true)
then
channels["sms"].insert(newSms($a.mobileNumber,"Thealarmisstillon");
end
當規則被引發時,現在可以控制日歷。日歷api是模擬Quartzhttp://www.quartz-scheduler.org/:
例子2.15調節一個Quartz日歷
CalendarweekDayCal=QuartzHelper.quartzCalendarAdapter(org.quartz.CalendarquartzCal)
日歷使用StatefulKnowledgeSession(有狀態知識會話)注冊:
例子2.16注冊一個日歷
ksession.getCalendars().set("weekday",weekDayCal);
它們可以同時用于普通規則和包含定時器的規則中。規則的calendar屬性可以有一個或多個逗點日歷名字:
例子2.17一起使用日歷和定時器
rule"weekdaysarehighpriority"
calendars"weekday"
timer(int:01h)
when
Alarm()
then
send("priorityhigh-wehaveanalarm);
end
?
rule"weekendarelowpriority"
calendars"weekend"
timer(int:04h)
when
Alarm()
then
send("prioritylow-wehaveanalarm);
end
2.1.3.5決策表(Excel)
2.1.3.5.1簡單模板,用于單元格內部可變長度逗點分隔的列表
在一個單元格中可以有一個逗點分隔的列表,并且用一個forall模板可以渲染它們。
例子2.18DTableforall語法
forall(<separator>?){<codesnippt>}
例子2.19DTableforall例子
forall(,){propertyName==$}
forall(&&){propertyName==$}
forall(||){propertyName==$}
forall(||){propertyNameA==$}&&forall(||){propertyNameB==$}
等等
2.1.4Flow
2.1.4.1BPMN2
正如我們早期已宣稱的一樣,Dools團隊已決定支持使用XML指定業務流程的即將到來的BPMN2.0規范。這個里程碑包含了BPMN2解析器的重大擴展,使用DroolsFlow來支持BPMN2的更多功能。更具體的有:
?
l?更廣泛的事件支持:更多的事件類型組合(開始、中間、結束)和事件觸發(例如,包括錯誤、升級、定時器、條件、信號事件),以及已包括(中斷和非中斷)邊界事件。
l?子流程參數。
l?發散的綜合性出入口
l?等等
BPMN2已被集成在完整的Dools工具鏈中,支持業務流程的整個生命周期。它包括:
?
l?能夠與我們的Eclipse工具一起使用BPMN2流程。
l?Guvnor作為流程庫。
l?基于網頁的管理,使用BPM控制臺。
l?審計和調試。
l?特殊域流程。
l?等等
因此,DroolsFlow不僅是一流的開源流程引擎,天然地支持這樣一個重要的BPMN2結構集合,而且我們的面向知識的方法,也允許你容易組合你的BPMN2流程與業務規則,以及復雜的事件處理,完全使用相同的APIs和工具。
2.1.4.2基于網頁的管理控制臺
現在也可以通過一個網頁控制臺管理DroolsFlow流程。它包括的功能有:管理你的流程實例(開始/停止/檢查),檢查你的(人的)任務列表,執行那些任務,產生報表。
?
這個控制臺實際上是HeikoBraun的工作(卓越的),他創建了一個通用的BMP控制臺,可以被用來支持多種流程語言。我們實現了必要的組件,允許這個控制臺能與DroolsFlow引擎通信。
2.1.4.3可插式可變持久化
DroolsFlow可以持久化運行流程的運行時間狀態到一個數據庫(所以它們完全不需要在內存,并且在故障情況時可以被存儲)。我們的默認持久化機制是用一個二進制對象(利用相關的元數據)存儲關聯于一個流程實例的所有運行時間信息。關聯這個流程實例(又名流程實例變量)的數據也作為這個二進制對象的一部分被存儲。然而這可以產生問題(1)在數據沒有被序列化時,(2)當用流程實例狀態的部分持久化,對象太大時,或者(3)在其他地方已經被持久化時。為此,我們實現了可插式可變持久化,用戶可以定義多少變量的值被存儲。例如,它允許你存儲個別變量的值,并且支持JPA實體被分別存儲和引用(避免狀態重復)。
2.1.4.4改進的流程實例移植
隨著時間的推移,流程可以進化。每當一個流程更新,確定已經運行的流程實例會發生什么是重要的。我們改進了我們的支持,用于移植運行的流程實例到流程定義的一個新版本。更多信息請看DroolsFlow文檔。
2.1.4.5安裝腳本
Drools構建輸出了一個安裝器,它簡化了Guvnor和gwt-控制臺的Eclipse插件的安裝。它創建了和復制了需要的jars和war,并且布置它們到JBossAS。它也包含了一個簡單的求值流程例子,你可以用它測試你的安裝。更多信息,下載Drools安裝器,請看其內部的自述文件readme。
?
2.1.5Guvnor
?
外觀已被清潔,例如少了彈出窗口。意味著用斷言和有關行為發生的信息更改之后的節省,以及如果出錯時,更好的錯誤報告。
?
2.1.5.3討論
?
注釋是在下面的“文檔”部分(當然是可選的)(并且有一個Atom供應給它們)
圖2.1實時討論
?
一個"backchannel(反向通道)"類型連接,保持了對瀏覽器的開放,允許消息推回——這意味著(在啟用時)信息實時顯示(和其他便利的事情一樣,如果某東西添加到一個列表——列表就會被更新)
?
2.1.5.4收件箱
?
收件箱功能提供了這樣的能力,跟蹤你打開或編輯的東西——這顯示在主導航器中的"Inbox"項目下。
?
?
圖2.2收件箱分類
?
?
l?最近打開的
?
點擊recentlyopened條目,會打開“最近”打開過的所有項目的一個列表(它跟蹤最近你看過的數百個項目)。
?
l?最近編輯的
?
所有你保存過的項目,或者注釋,將馬上顯示在這里。
?
l?收到的更改
?
它跟蹤“其他人”對“你”的“最近編輯”列表中的項目所做的更改。當你打開這些項目,那么它們會從這個列表中刪除(但仍然保留在你最近編輯過的列表中)
?
圖2.3收件箱項目列表。
?
2.1.5.5批量導入器
?
Guvnor導入器是一個maven構建工具,遞規你的規則目錄結構,并且構建一個導入文件,通過import/export管理功能可以手動導入它到Drools-Guvnor網頁界面。
?
2.1.5.6DroolsDoc
?
PDF文檔包含了有關包和每個DRL資產(asset)的信息。DroolsDoc作為知識包可以從"InformationandimportantURLs"下的包視圖(packageview)下載。
?
2.1.5.7更新為GWT2.0
?
GWT被更新,使DroolsGuvnor更快。
?
2.1.5.8安裝選擇器
?
安裝選擇器允許用戶選擇什么樣的資產構建,依據:
?
n?狀態(例如,開發,質量保證等)
n?分類
n?元數據
?
2.1.5.9單資產驗證
?
只要是你正在運行的資產(規則流、規則、決策表),就可以驗證。驗證發現諸如在一個規則中的沖突限制或在決策表中的多余行等問題。
?
2.1.5.10全局區
儲存在全局區的資產可以被所有包共享。
?
2.1.5.11快照之間的差異檢查
?
列出兩個快照之間的變化。
?
2.1.5.12在一個標簽中查看多個資產
?
可以在一個視圖中打開多個資產。所有的資產可以作為一個組被保存和編輯。
?
2.1.5.13From/Collect/Accumulate支持
?
指導編輯器已基本支持From,Accumulate和Collect模式。你可以添加它們中的任何一個結構作為正規模式。新的表達式構建器組件被創建,增加了對嵌套方法調用的一個變量支持。在規則的WHEN部分頂部使用了“加”按鈕,或者使用呈現在每個模式中的新的“在后面增加”按鈕,將打開彈出,添加新的條件元素到你的規則中。在可能元素的列表中的,你會發現三個新的條目:”From”,“FromAccumulate”和“FromCollect”。
?
當你添加一個新的”From”元素,你會在指導編輯器看到下面這樣圖象的東西。左邊模式的”From”條件元素是一個正規模式。你可以在這里添加你希望的任何類型的條件元素。右邊部分的”From”模式是一個表達式構建器。
?
圖2.4來自一個CE構建器
?
當你在左邊模式中使用“FromCollect”時,你可以選擇“java.util.Collection”,“java.util.List”或“java.util.Set”事實類型。這個事實類型會被自動包含在事實類型列表中。
?
右邊模式的收集條件元素可以是下面模式之一:
?
n?FactTypePattern(事實類型模式)
n?FreeFormExpression(自由表單表達式)
n?FromPattern(From模式)
n?FromCollectPattern(FromCollect模式)
n?FromAccumulatePattern(FromAccumulate模式)
?
圖2.5來自CollectCE構建器
?
當使用“FromAccumulate”時,左邊模式可以是任何事實類型模式。這個條件元素的右邊部分被劃分成兩個:
?
圖2.6來自累積CE構建器
?
左邊模式可以是任何事實類型模式。這個條件元素的右邊部分被劃分成兩個:
?
源模式:(在載圖中的,Bed$n)可以是任何事實類型、From、Collect或者Accumulate模式
?
累積函數:在這里你可發現一個標簽式面板,你可以輸入一個累積函數(在截圖中的sum()),或者你可以使用“CustomCode”創建一個在線定制函數。
?
2.1.5.14規則模板
?
規則模板可以被指導編輯器用于編輯復雜的規則,然后通過一個電子表格的表格數據隱喻輕松地編寫它。替代了一個字段的值,僅是用名為"TemplateKey"標識它,并且該key可以作為網格中的一個列。每行可以應用規則模板來產生一個規則。
?
圖2.7在'WHEN'部分增加了一個TemplateKey。
?
圖2.8"THEN"部分增加了一個TemplateKey。
?
圖2.9根據這些TemplateKey填充行。
?
圖2.10每行產生一個規則
?
2.1.5.15工作集
?
在建模規則時,用戶暴露所有的事實類型,它可能是整個的很小部分。工作集允許相關的事實類型分組在一起,并在編寫規則時,提供一個更易于管理的選擇事實類型的視圖。
?
圖2.11顯示導入的類型。
?
圖2.12創建一個動物工作集。
?
圖2.13沒有使用工作集,所有類型是可見的。
?
圖2.14選擇動物工作集。
?
圖2.15可用的類型減少了。
2.1.5.16事實約束
工作集可以與事實約束相結合,提供額外的設計時間驗證。例如,如果你依據某個人的年齡編寫一個規則,在設計時,我們可以分辨有效的范圍,并且使用它來約束作者。事實約束是工作集的一部分,并且在編輯一個規則時,你必然選擇工作集約束,那個你希望用于作為驗證處理部分的約束。
?
圖2.16選擇字段。
?
圖2.17選擇字段約束類型.
?
圖2.18一個范圍選擇的例子。
?
圖2.19選擇工作集,用于驗證年齡字段。
?
圖2.205歲是無效的。
?
2.1.5.17指導規則編輯器
?
編輯規則變得更明確。編輯器是更小“盒子”,且用一個普通文本編寫更多規則。增加了"contains"關鍵字,現在在綁定變量給限制是更容易了。
?
2.1.5.17.1模式排序
?
指導編輯器在lhs和rhs部分支持模式重排序,以及位置插入,新的模式可以以任何順序被插入(并不總是在最后)。
?
圖2.21上下移動元素。
?
圖2.22在任何位置插入元素。
?
2.1.5.18決策表(Guvnor)
?
增加了關鍵字"in"。
可以移動列,并且新行的位置可以自由選擇。
?
2.1.6Eclipse
?
2.1.6.3在大綱視圖中分組規則
?
現在你可以為議程組使用排序或分組。
?
圖2.23分組議程組
圖2.24排序議程組
2.1.6.4支持在審計視圖中拖/放文件。
現在可以拖放日志文件到審計視圖中。
2.1.7已知的問題
2.1.7.3多線程模式
使用試驗的多線程執行模式存在一個已知的問題,如下面JIRA中描述的一樣
https://jira.jboss.org/browse/JBRULES-2125
?
2.2????? 在Drools 5.0.0中值得關注的新東西
?
2.2.1??? Drools API
?Drools現在有完善的api/實現分離物,不再面向規則。當我們開始支持其他邏輯形式時,如工作流和事件處理時,這是一個重要的策略。最重要的改變是我們面向知識,而不是面向規則。drools-api模塊提供接口和工廠,并且與以前相比,我們已竭力提供更好的javadocs,帶有一些代碼片段。drools-api還有助于清楚地顯示有意作為一個用戶的api是什么,只是一個引擎的api是什么,而Drools核心和Drools編譯器沒有充分明確這點。你將使用的最普通的接口有:
?
n?org.drools.builder.KnowledgeBuilder
n?org.drools.KnowledgeBase
n?org.drools.agent.KnowledgeAgent
n?org.drools.runtime.StatefulKnowledgeSession
n?org.drools.runtime.StatelessKnowledgeSession
?
工廠類,帶有靜態方法,提供上面接口的實例。一個可插式提供者方法被用來允許提供者實現在運行時連接工廠。你將最常使用的工廠有:
?
n?org.drools.builder.KnowledgeBuilderFactory
n?org.drools.io.ResourceFactory
n?org.drools.KnowledgeBaseFactory
n?org.drools.agent.KnowledgeAgentFactory
?
例子2.20 加載一個規則資源的一個典型例子
?
KnowledgeBuilder kbuilder = KnowledgeBuilderFactory.newKnowledgeBuilder();
kbuilder.add( ResourceFactory.newUrlResource( url ), ResourceType.DRL );
if ( kbuilder.hasErrors() ) {
? System.err.println( builder.getErrors().toString() );
}????????
?
KnowledgeBase kbase = KnowledgeBaseFactory.newKnowledgeBase();
kbase.addKnowledgePackages( builder.getKnowledgePackages() );
?
StatefulKnowledgeSession ksession = knowledgeBase.newStatefulKnowledgeSession();
ksession.insert( new Fibonacci( 10 ) );
ksession.fireAllRules();
?
ksession.dispose();
?
一個典型的加載一個流程資源的例子。注意ResourceType使用相應的資源類型被改變。
?
例子 2.21一個典型的加載一個流程資源的例子。注意ResourceType使用相應的資源類型被改變。
?
KnowledgeBuilder kbuilder = KnowledgeBuilderFactory.newKnowledgeBuilder();
kbuilder.add( ResourceFactory.newUrlResource( url ),
??????????? ResourceType.DRF );
if ( kbuilder.hasErrors() ) {
? System.err.println( builder.getErrors().toString() );
}????????
?
KnowledgeBase kbase = KnowledgeBaseFactory.newKnowledgeBase();
kbase.addKnowledgePackages( builder.getKnowledgePackages() );
?
StatefulKnowledgeSession ksession = knowledgeBase.newStatefulKnowledgeSession();
ksession.startProcess( "Buy Order Process" );
?
ksession.dispose();
?
'kbuilder','kbase','ksession'是經常使用的變量標識符,用knowledge的k開頭。
?
例子 2.22 我們已統一了決策樹如何加載,現在不再需要利用電子表格編譯器預先生成一致的DRL。
?
DecisionTableConfiguration dtconf = KnowledgeBuilderFactory.newDecisionTableConfiguration();
dtconf.setInputType( DecisionTableInputType.XLS );
dtconf.setWorksheetName( "Tables_2" );
kbuilder.add( ResourceFactory.newUrlResource( "file://IntegrationExampleTest.xls" ),
??????????? ResourceType.DTABLE,
??????????? dtconf );
?
使用配置也可以配置一個KnowledgeBase,通過一個xml更改集,而不是編程方式。
?
例子2.23 一個簡單的更改集例子
?
<change-set?xmlns='http://drools.org/drools-5.0/change-set'
xmlns:xs='http://www.w3.org/2001/XMLSchema-instance'
xs:schemaLocation='http://drools.org/drools-5.0/change-set?change-set-5.0.xsd'?>
??<add>
??????<resource?source='classpath:org/domain/someRules.drl'?type='DRL'?/>
??????<resource?source='classpath:org/domain/aFlow.drf'?type='DRF'?/>
??</add>
</change-set>
?
例子 2.24 可以象其他資源類型一樣添加
?
KnowledgeBuilder kbuilder = KnowledgeBuilderFactory.newKnowledgeBuilder();
kbuilder.add( ResourceFactory.newUrlResource( url ),
??????????? ResourceType.ChangeSet );
?
KnowledgeAgent與?RuleAgent相比較,其他較大的變化是輪詢掃描現在是一個服務了。進一步說,是在代理通知與資源監視之間有一個抽象,允許使用其他輪詢機制。
?
例子 2.25 這些服務當前不再默認啟動,要啟動它們要如下這樣:
?
ResourceFactory.getResourceChangeNotifierService().start();
ResourceFactory.getResourceChangeScannerService().start();
?
增加了兩個接口,ResourceChangeNotifier和ResourceChangeMonitor。KnowledgeAgent使用ResourceChangeNotifie實現訂購資源更改通知。通過添加ResourceChangeMonitor通知ResourceChangeNotifie資源改變了。我們現在只提供一個開箱既用的的監視器, ResourceChangeScannerService,它輪詢資源的變化。然而,存在有api用于用戶添加自己的監視器,所以可以使用一個如jms這樣的基于推的監視器。
?
ResourceFactory.getResourceChangeNotifierService().addResourceChangeMonitor( myJmsMonitor);
?
2.2.2??? Drools Guvnor
?
n?新外觀的網頁工具
?圖2.25 新外觀
?
n?網頁基于決策表編輯器
圖2.26網頁基于決策表編輯器
?
n?集成的場景測試
?圖2.27 運行所有場景
?
圖2.28 運行單個場景
?
n?WebDAV文件基于接口庫
?
圖2.29? WebDAV
?
n?聲明式模擬類型(不使用pojos的類型)
圖2.30 ?聲明式模擬
?
它與"declare"語句一起工作——你現在可以在drl本身內聲明類型。然后你可以裝配它們,不必使用pojo(如果你喜歡)。然后這些類型可用于規則庫中。
?
u?細粒度安全(鎖定訪問每包或每分類應用程序)。只有分類權限的用戶具有有限的UI能力(針對企業用戶)
u?執行服務器——執行通過XML或JSON訪問規則。
u?分類規則允許你為一個分類設置“父規則”。出現在給定分類的任何規則會“繼承”指定的規則——例如,繼承條件/ LHS。分類的基本規則可以在包配置標簽上設置。RHS不被繼承,只有LHS被繼承。
u?場景運行器檢測無限循環。
u?現在可以設置在指南編輯器中的DSL句子,用于顯示作為一個下接菜單的枚舉、作為一個數據拾取器的數據、作為一個單選框的布爾值,并且使用正則表達式來校驗用戶輸入(在Guvnor中的DSL小飾件)。
u?函數可以使用文本編輯器進行編輯。
u?可以添加對象到全局集合。
u?翻譯為英語,西班牙語,漢語和日語。
2.2.3??Drools Expert
?
2.2.3.1??非對稱Rete算法實現
?
不再需要影子代理。影子代理保護引擎免受有關實事的信息變化的影響,如果發生在引擎控件的外部,它可能不會被修改或撤消。
?
2.2.3.2??包構建器現在可以構建多個命名空間
?
你不再需要對一個包命名空間構建一個PackageBuilder?。只要保持為所有命名空間增加你的DRLs,并且getPackages()為每個使用的命名空間返加一個包數組。
?
例子 2.26 獲得多個包
?
Package[] packages = pkgBuilder.getPackages();
?
2.2.3.3??規則庫連接包構建器
?
現在可以連接一個?RuleBase到一個?PackageBuilder,這意味著規則被構建,并且同時被添加到規則庫。PackageBuilder使用現行的RuleBase的Package實例作為它的資源,取消了發生在現有方法中的Package創造和融合。
?
例子 2.27 連接規則庫(RuleBase)到包構建器(PackageBuilder)
?
RuleBase ruleBase = RuleBaseFactory.newRuleBase();
PackageBuilder pkgBuilder = new PackageBuilder( ruleBase, null );
?
2.2.3.4??有狀態會話的二進制編碼
?
有狀態會話現在可以保存,并可在以后的日期中恢復。預加載數據會話現在可以被創建。對用戶對象的持久化可使用可插式策略,例如,hibernate或特征(identity)映射。
?
2.2.3.5??類型聲明
?
Drools現在支持一種新的基礎結構,稱為類型聲明。這個結構達到兩個目的:能夠聲明實事元數據,以及能夠為規則引擎動態地產生局部的新的事實類型。Guvnor模擬工具在底層使用了它。下面是該結構的一個例子:
?
例子 2.28 聲明StockTick
?
declare StockTick
? @role( event )
? @timestamp( timestampAttr )
?
? companySymbol : String
? stockPrice : double
? timestampAttr : long
end
?
2.2.3.6??聲明實事元數據
?
要聲明和關聯事實的元數據,只需要對你想聲明的每個元數據ID使用@符號。例子:
?
例子 2.29 聲明元數據
?
declare StockTick
? @role( event )
end
?
2.2.3.7??觸發Bean產生
?
要激活動態bean產生,僅為你的類型聲明添加字段和類型。
?
例子 2.30 聲明Person
?
declare Person
? name : String
? age : int
end
?
2.2.3.8??DSL的改進
?
一系列DSL的改進被實現,包括一個完善的新解析器,并且能夠為匹配的變量聲明匹配的掩碼(mask)。例如,它可限定一個電話號碼字段為2位數的國家代碼+ 3位區號+ 8位數字電話號碼,所有連接以“ - ”(破折號)連接,通過象這樣聲明DSL映射:電話號碼為{number:\d{2}-\d{3}-\d{8}},所有有效的Java正則表達式可以用于變量的掩碼中。
?
2.2.3.9??fireUntilHalt()
?
Drools現在支持fireUntilHalt()功能,它以一種被動模式啟動引擎,在那兒規則會被連續引發,直到調用了halt()。這尤其對CEP(complex event processing)場景有用,CEP場景需要俗稱的“活動查詢”。
?
2.2.3.10???規則庫分區和多線程傳播
?
Drools ReteOO算法現在支持一個選項,用于以多線程模式啟動規則庫,在那兒Drools ReteOO網絡被劃分為多個部分,然后規則被多個線程并發計算。對通常有幾個獨立規則并發運行的CEP,它也有一個要求,接近實時性能/吞吐量的要求,并且一個計算不能干擾其他的計算。
?
2.2.3.11???XSD模式支持
?
Drools現在支持XSD模式。記住雖然XSD模式以用于Drools類加載器的本地POJO類生成。在包構建器中存在有一個幫助類用于模式的產生。一旦數據模式被生成,你通常使用JAXB數據加載器插入數據。
?
2.2.3.12???數據加載器
?
Drools現在支持兩種數據加載器,Smooks和JAXB。Smooks是一個用于ETL的開源數據轉換工具,JAXB是一個標準的Sun數據映射工具。單元測試顯示Smooks和JAXB均可在這里找到。
?
2.2.3.13???類型安全配置
?
在Drools中,除了能夠通過配置文件配置選項外,也可用系統屬性配置,通過API的 setProperty()方法設置屬性,Drools-API現在支持類型安全配置。我們不希望為每個可能的配置方法增加特殊的方法,有兩個原因:它污染了API,并且每次都有一個新選項增加到Drools,API將不得不改變。而這種方式,我們遵循模塊化,類基于配置,在此處為每個可能的配置,一個新的選項類增加到了API,除了靈活之外,也維持了API的穩定。所以,現在為了設置配置選項,你只需要使用枚舉或者提供每個選項的工廠。例如,如果你希望為斷言行為"equality"?配置知識庫,并且自動從模式匹配中刪除特征(identities),你只需要使用下面的枚舉:
?
例子2.31 配置
?
KnowledgeBaseConfiguration config = KnowledgeBaseFactory.newKnowledgeBaseConfiguration();
config.setOption( AssertBehaviorOption.EQUALITY );
config.setOption( RemoveIdentitiesOption.YES );
?
對于選項,我們不需要預定義約束,或者可以假設多個值,提供一個工廠方法。例如,配置alpha值為5,只使用get()工廠方法:
?
例子 2.32 配置alpha值
?
config.setOption( AlphaThresholdOption.get(5) );
正如你所見,為每個不同的可能配置,使用了相同的setOption()方法,然而它們仍然是類型安全的。
?
2.2.3.14???新的累積函數:collectSet和collectList
?
有時候,有必要收集來自實事屬性的值的集合或列表,而不是實事本身。在這種情況下,不可能使用collect CE。所以對這種情況,現在Drools有兩個新的累積函數:collectSet用于收集值的集合(即,無重復的值),collectList用于收集值的列表(即,允許重復的值):
?
例子 2.33 新的累積函數
?
# collect the set of unique names in the working memory
$names : Set() from accumulate( Person( $n : name, $s : surname ),
??????????????????????? collectSet( $n + " " + $s ) )
?
# collect the list of alarm codes from the alarms in the working memory
$codes : List() from accumulate( Alarm( $c : code, $s : severity ),
???????????????????????? collectList( $c + $s ) )
?
2.2.3.15??用于類型聲明的新元數據:@propertyChangeSupport
?
事實實現了象定義在Javabean(tm)規范中的屬性改變的支持?,F在可以注釋,讓引擎注冊自身來偵聽事實屬性的變化。在Drools 4 API的insert()方法中使用的布爾參數已過時,并且不存在于drools-aip模塊中了。
?
例子 2.34? @propertyChangeSupport
?
?declare Person
???????? @propertyChangeSupport
end
?
2.2.3.16??批處理器
?
批處理器允許一個知識會話使用命令腳本,此外,無論是StatelessKnowledgeSession?還是?StatefulKnowledgeSession實現都可以使用CommandFactory創建這個接口命令,且使用"execute"?方法執行,如下所示:
?
例子 2.35 使用CommandFactory
?
ksession.execute( CommandFactory.newInsert( person ) );
?
盡管這樣,你通常會希望執行一個批處理命令,通過組合命令?BatchExecution可以完成它。BatchExecutionResults現在用來處理結果,某些命令可以使用"out"標識符,用它來添加結果到BatchExecutionResult。現在可以輕松地執行查詢,并把結果添加到BatchExecutionResult。這個結果進一步被限定到這個執行調用,并且通過BatchExecutionResults返回。
?
例子 2.36 ?使用BatchExecutionResult
?
List<Command> cmds = new ArrayList<Command>();
cmds.add( CommandFactory.newSetGlobal( "list1", new ArrayList(), true ) );
cmds.add( CommandFactory.newInsert( new Person( "jon", 102 ), "person" ) );
cmds.add( CommandFactory.newQuery( "Get People" "getPeople" );
?
BatchExecutionResults results = ksession.execute( CommandFactory.newBatchExecution( cmds ) );
results.getValue( "list1" ); // returns the ArrayList
results.getValue( "person" ); // returns the inserted fact Person
results.getValue( "Get People" );// returns the query as a QueryResults instance.
End
?
CommandFactory詳細描述支持的命令,它們所有都可以使用XStream和BatchExecutionHelper進行編碼??梢允褂霉艿澜M合它們來自動化會話腳本。
?
例子 2.37 使用PipelineFactory
?
Action executeResultHandler = PipelineFactory.newExecuteResultHandler();
Action assignResult = PipelineFactory.newAssignObjectAsResult();
assignResult.setReceiver( executeResultHandler );
Transformer outTransformer = PipelineFactory.newXStreamToXmlTransformer( BatchExecutionHelper.newXStreamMarshaller() );
outTransformer.setReceiver( assignResult );
KnowledgeRuntimeCommand batchExecution = PipelineFactory.newBatchExecutor();
batchExecution.setReceiver( outTransformer );
Transformer inTransformer = PipelineFactory.newXStreamFromXmlTransformer( BatchExecutionHelper.newXStreamMarshaller() );
inTransformer.setReceiver( batchExecution );
Pipeline pipeline = PipelineFactory.newStatelessKnowledgeSessionPipeline( ksession );
pipeline.setReceiver( inTransformer );
?
對一個規則集使用上面所述的,會更新一個Cheese事實的價格,下面給定的xml會插入一個使用了輸出標識符(out-identifier)的Cheese實例。
?
例子 2.38 更新Cheese實事
?
<batch-execution>
<insert?out-identifier='outStilton'>
??<org.drools.Cheese>
????<type>stilton</type>
????<price>25</price>
????<oldPrice>0</oldPrice>
??</org.drools.Cheese>
</insert>
</batch-execution>
?
然后我們會得到BatchExecutionResults:
?
例子 2.39 更新Cheese實事
<batch-execution-results>
?<result?identifier='outStilton'>
???<org.drools.Cheese>
?????<type>stilton</type>
?????<oldPrice>0</oldPrice>???????
?????<price>30</price>
???</org.drools.Cheese>
?</result>
</batch-execution-results>
?
2.2.3.17??編碼
?
MarshallerFactory被用來編碼和解碼StatefulKnowledgeSessions。最簡單的,它可以象下面這樣使用:
?
例子 2.40 使用MarshallerFactory
?
// ksession is the StatefulKnowledgeSession
// kbase is the KnowledgeBase
ByteArrayOutputStream baos = new ByteArrayOutputStream();
Marshaller marshaller = MarshallerFactory.newMarshaller( kbase );
marshaller.marshall( baos, ksession );
baos.close();
?
然而,在處理引用的用戶數據時,你需要更有彈性地使用編碼。要達成它,我們有一個ObjectMarshallingStrategy接口。我們提供了兩個實現,但是用戶可以自己實現它。提供的兩個是IdentityMarshallingStrategy和SerializeMarshallingStrategy。默認為SerializeMarshallingStrategy,如上例所示,它只在一個用戶實例上調用Serializable或Externalizable方法。而IdentityMarshallingStrategy為每個用戶對象創建了一個整數id,并存儲它們在一個映射中,該id被寫入到該流中。在解碼時,它只簡單地查看IdentityMarshallingStrategy映射,取回該實例。這意味著,如果你使用IdentityMarshallingStrategy,它對編碼實例的生命周期是有狀態的,并且會創建ids,保持它企圖編碼的所有對象的引用。
?
例子 2.41 使用IdentityMarshallingStrategy編碼
?
ByteArrayOutputStream baos = new ByteArrayOutputStream();
Marshaller marshaller = MarshallerFactory.newMarshaller( kbase, new ObjectMarshallingStrategy[] { MarshallerFactory.newIdentityMarshallingStrategy() } );
marshaller.marshall( baos, ksession );
baos.close();
?
為增加彈性,我們不能想當然地認為單策略更合適,所以我們增加了一個ObjectMarshallingStrategyAcceptor?接口,每個ObjectMarshallingStrategy都有。編碼器有一個策略鏈,并且當它企圖讀或寫一個用戶對象時,它遍歷策略,詢問它們是否承擔負責編碼用戶對象。提供了一個實現為ClassFilterAcceptor。它允許使用字符和通匹符匹配類名。默認為"*.*",所以在上面使用的IdentityMarshallingStrategy,它有一個默認的"*.*"接收器。然而,比方說,我們希望序列化所有類,一個給定的包除外,這種情況,我們會使用身份查詢,如下所示:
?
例子 2.42 ?使用身份查詢
?
ByteArrayOutputStream baos = new ByteArrayOutputStream();
ObjectMarshallingStrategyAcceptor identityAceceptor = MarshallerFactory.newClassFilterAcceptor( new String[] { "org.domain.pkg1.*" } );
ObjectMarshallingStrategy identityStratetgy = MarshallerFactory.newIdentityMarshallingStrategy( identityAceceptor );
Marshaller marshaller = MarshallerFactory.newMarshaller( kbase, new ObjectMarshallingStrategy[] { identityStratetgy, MarshallerFactory.newSerializeMarshallingStrategy() } );
marshaller.marshall( baos, ksession );
baos.close();
?
2.2.3.18??知識代理
?
KnowlegeAgent由?KnowlegeAgentFactory創建。KnowlegeAgent提供自動加載、緩存和重新加載資源,并且根據一個屬性文件配置它。當KnowlegeBase使用的資源更改時,KnowlegeAgent可以更新或重構KnowlegeBase。通過給定工廠的配置確定KnowlegeAgent的策略,但通常使用基于標準輪詢的拉策略。我們希望增加基于推的更新,并在將來的版本中重構它。下面的例子,構建了一個代理,它根據在路徑字符串中指定的文件構建了一個新的KnowledgeBase。它會每30秒拉這些文件,而不是更新存在的一個,因為?"newInstance" 設置為了"true"?(然而,目前只支持"true"?值,并且很難編碼到引擎中)。
?
例子 2.43 構建一個代理
?
// Set the interval on the ResourceChangeScannerService if you are to use it and default of 60s is not desirable. ResourceChangeScannerConfiguration sconf = ResourceFactory.getResourceChangeScannerService().newResourceChangeScannerConfiguration(); sconf.setProperty( "drools.resource.scanner.interval", ????????????????? "30" ); // set the disk scanning interval to 30s, default is 60s ResourceFactory.getResourceChangeScannerService().configure( sconf ); KnowledgeBase kbase = KnowledgeBaseFactory.newKnowledgeBase(); KnowledgeAgentConfiguration aconf = KnowledgeAgentFactory.newKnowledgeAgentConfiguration(); aconf.setProperty( "drools.agent.scanDirectories", ????????????????? "true" ); // we want to scan directories, not just files, turning this on turns on file scanning aconf.setProperty( "drools.agent.newInstance", ????????????????? "true" ); // resource changes results in a new instance of the KnowledgeBase being built, ??????????????????????????? // this cannot currently be set to false for incremental building ?? ? KnowledgeAgent kagent = KnowledgeAgentFactory.newKnowledgeAgent( "test agent", // the name of the agent ??????????????????????????????????????????????????????????????? kbase, // the KnowledgeBase to use, the Agent will also monitor any exist knowledge definitions ??????????????????????????????????????????????????????????????? aconf ); kagent.applyChangeSet( ResourceFactory.newUrlResource( url ) ); // resource to the change-set xml for the resources to add?
KnowledgeAgents可以使用一個空的 KnowledgeBase或植入的一個。如果提供了一個植入的KnowledgeBase,KnowledgeAgent會遍歷KnowledgeBase,并訂閱它發現的資源。雖然KnowledgeBuilder可以構建在一個目錄中發現的所有資源,但信息會被KnowledgeBuilder丟棄,因些那些目錄不會繼續被掃描。只有作為applyChangeSet(Resource)方法的一部分指定的目錄才會被監控。
總結
以上是生活随笔為你收集整理的Drools 5.1.1(一)的全部內容,希望文章能夠幫你解決所遇到的問題。
- 上一篇: Drools与Spring集成 登录测试
- 下一篇: Oracle查询慢的原因总结