目錄
- 5. 規則屬性
- 5.1 enabled屬性
- 5.2 dialect屬性
- 5.3 salience屬性
- 5.4 no-loop屬性
- 5.5 activation-group屬性
- 5.6 agenda-group屬性
- 5.7 auto-focus屬性
- 5.8 timer屬性
- 5.9 date-effective屬性
- 5.10 date-expires屬性
5. 規則屬性
前面我們已經知道了規則體的構成如下:
rule "ruleName"
attributes
when
LHS
then
RHS
end
本章節就是針對規則體的attributes屬性部分進行講解,Drools中提供的屬性如下表(部分屬性):
| 屬性名 | 說明 |
|---|---|
| salience | 指定規則執行優先級 |
| dialect | 指定規則使用的語言型別,取值為java和mvel |
| enabled | 指定規則是否啟用 |
| date-effective | 指定規則生效時間 |
| date-expires | 指定規則失效時間 |
| activation-group | 激活分組,具有相同分組名稱的規則只能有一個規則觸發 |
| agenda-group | 議程分組,只有獲取焦點的組中的規則才有可能觸發 |
| timer | 定時器,指定規則觸發的時間 |
| auto-focus | 自動獲取焦點,一般結合agenda-group一起使用 |
| no-loop | 防止死回圈 |
5.1 enabled屬性
enabled屬性對應的取值為true和false,默認值為true,
用于指定當前規則是否啟用,如果設定的值為false則當前規則無論是否匹配成功都不會觸發,
rule "rule_comparison_notMemberOf"
//指定當前規則不可用,當前規則無論是否匹配成功都不會執行
enabled false
when
ComparisonOperatorEntity(names not memberOf list)
then
System.out.println("規則rule_comparison_notMemberOf觸發");
end
5.2 dialect屬性
dialect屬性用于指定當前規則使用的語言型別,取值為java和mvel,默認值為java,
注:mvel是一種基于java語法的運算式語言,
mvel像正則運算式一樣,有直接支持集合、陣列和字串匹配的運算子,
mvel還提供了用來配置和構造字串的模板語言,
mvel運算式內容包括屬性運算式,布爾運算式,方法呼叫,變數賦值,函式定義等,
5.3 salience屬性
salience屬性用于指定規則的執行優先級,取值型別為Integer,數值越大越優先執行,每個規則都有一個默認的執行順序,如果不設定salience屬性,規則體的執行順序為由上到下,
可以通過創建規則檔案salience.drl來測驗salience屬性,內容如下:
package test.salience
rule "rule_1"
when
eval(true)
then
System.out.println("規則rule_1觸發");
end
rule "rule_2"
when
eval(true)
then
System.out.println("規則rule_2觸發");
end
rule "rule_3"
when
eval(true)
then
System.out.println("規則rule_3觸發");
end
通過控制臺可以看到,由于以上三個規則沒有設定salience屬性,所以執行的順序是按照規則檔案中規則的順序由上到下執行的,接下來我們修改一下檔案內容:
package testsalience
rule "rule_1"
salience 9
when
eval(true)
then
System.out.println("規則rule_1觸發");
end
rule "rule_2"
salience 10
when
eval(true)
then
System.out.println("規則rule_2觸發");
end
rule "rule_3"
salience 8
when
eval(true)
then
System.out.println("規則rule_3觸發");
end
通過控制臺可以看到,規則檔案執行的順序是按照我們設定的salience值由大到小順序執行的,
建議在撰寫規則時使用salience屬性明確指定執行優先級,
5.4 no-loop屬性
no-loop屬性用于防止死回圈,當規則通過update之類的函式修改了Fact物件時,可能使當前規則再次被激活從而導致死回圈,取值型別為Boolean,默認值為false,測驗步驟如下:
第一步:撰寫規則檔案/resource/rules/noloop.drl
package testnoloop
import com.itheima.drools.entity.Student
/*
此規則檔案用于測驗no-loop屬性
*/
rule "rule_noloop"
when
// no-loop true
$student:Student(age == 25)
then
update($student);//注意此處執行update會導致當前規則重新被激活
System.out.println("規則rule_noloop觸發");
end
第二步:撰寫單元測驗
KieServices kieServices = KieServices.Factory.get();
KieContainer kieClasspathContainer = kieServices.getKieClasspathContainer();
KieSession kieSession = kieClasspathContainer.newKieSession();
Student student = new Student();
student.setAge(25);
//將資料提供給規則引擎,規則引擎會根據提供的資料進行規則匹配,如果規則匹配成功則執行規則
kieSession.insert(student);
kieSession.fireAllRules();
kieSession.dispose();
通過控制臺可以看到,由于我們沒有設定no-loop屬性的值,所以發生了死回圈,接下來設定no-loop的值為true再次測驗則不會發生死回圈,
5.5 activation-group屬性
activation-group屬性是指激活分組,取值為String型別,具有相同分組名稱的規則只能有一個規則被觸發,
第一步:撰寫規則檔案/resources/rules/activationgroup.drl
package testactivationgroup
/*
此規則檔案用于測驗activation-group屬性
*/
rule "rule_activationgroup_1"
activation-group "mygroup"
when
then
System.out.println("規則rule_activationgroup_1觸發");
end
rule "rule_activationgroup_2"
activation-group "mygroup"
when
then
System.out.println("規則rule_activationgroup_2觸發");
end
第二步:撰寫單元測驗
KieServices kieServices = KieServices.Factory.get();
KieContainer kieClasspathContainer = kieServices.getKieClasspathContainer();
KieSession kieSession = kieClasspathContainer.newKieSession();
kieSession.fireAllRules();
kieSession.dispose();
通過控制臺可以發現,上面的兩個規則因為屬于同一個分組,所以只有一個觸發了,同一個分組中的多個規則如果都能夠匹配成功,具體哪一個最終能夠被觸發可以通過salience屬性確定,
5.6 agenda-group屬性
agenda-group屬性為議程分組,屬于另一種可控的規則執行方式,用戶可以通過設定agenda-group來控制規則的執行,只有獲取焦點的組中的規則才會被觸發,
第一步:創建規則檔案/resources/rules/agendagroup.drl
package testagendagroup
/*
此規則檔案用于測驗agenda-group屬性
*/
rule "rule_agendagroup_1"
agenda-group "myagendagroup_1"
when
then
System.out.println("規則rule_agendagroup_1觸發");
end
rule "rule_agendagroup_2"
agenda-group "myagendagroup_1"
when
then
System.out.println("規則rule_agendagroup_2觸發");
end
//========================================================
rule "rule_agendagroup_3"
agenda-group "myagendagroup_2"
when
then
System.out.println("規則rule_agendagroup_3觸發");
end
rule "rule_agendagroup_4"
agenda-group "myagendagroup_2"
when
then
System.out.println("規則rule_agendagroup_4觸發");
end
第二步:撰寫單元測驗
KieServices kieServices = KieServices.Factory.get();
KieContainer kieClasspathContainer = kieServices.getKieClasspathContainer();
KieSession kieSession = kieClasspathContainer.newKieSession();
//設定焦點,對應agenda-group分組中的規則才可能被觸發
kieSession.getAgenda().getAgendaGroup("myagendagroup_1").setFocus();
kieSession.fireAllRules();
kieSession.dispose();
通過控制臺可以看到,只有獲取焦點的分組中的規則才會觸發,與activation-group不同的是,activation-group定義的分組中只能夠有一個規則可以被觸發,而agenda-group分組中的多個規則都可以被觸發,
5.7 auto-focus屬性
auto-focus屬性為自動獲取焦點,取值型別為Boolean,默認值為false,一般結合agenda-group屬性使用,當一個議程分組未獲取焦點時,可以設定auto-focus屬性來控制,
第一步:修改/resources/rules/agendagroup.drl檔案內容如下
package testagendagroup
rule "rule_agendagroup_1"
agenda-group "myagendagroup_1"
when
then
System.out.println("規則rule_agendagroup_1觸發");
end
rule "rule_agendagroup_2"
agenda-group "myagendagroup_1"
when
then
System.out.println("規則rule_agendagroup_2觸發");
end
//========================================================
rule "rule_agendagroup_3"
agenda-group "myagendagroup_2"
auto-focus true //自動獲取焦點
when
then
System.out.println("規則rule_agendagroup_3觸發");
end
rule "rule_agendagroup_4"
agenda-group "myagendagroup_2"
auto-focus true //自動獲取焦點
when
then
System.out.println("規則rule_agendagroup_4觸發");
end
第二步:撰寫單元測驗
KieServices kieServices = KieServices.Factory.get();
KieContainer kieClasspathContainer = kieServices.getKieClasspathContainer();
KieSession kieSession = kieClasspathContainer.newKieSession();
kieSession.fireAllRules();
kieSession.dispose();
通過控制臺可以看到,設定auto-focus屬性為true的規則都觸發了,
5.8 timer屬性
timer屬性可以通過定時器的方式指定規則執行的時間,使用方式有兩種:
方式一:timer (int: <initial delay> <repeat interval>?)
此種方式遵循java.util.Timer物件的使用方式,第一個引數表示幾秒后執行,第二個引數表示每隔幾秒執行一次,第二個引數為可選,
方式二:timer(cron: <cron expression>)
此種方式使用標準的unix cron運算式的使用方式來定義規則執行的時間,
第一步:創建規則檔案/resources/rules/timer.drl
package testtimer
import java.text.SimpleDateFormat
import java.util.Date
/*
此規則檔案用于測驗timer屬性
*/
rule "rule_timer_1"
timer (5s 2s) //含義:5秒后觸發,然后每隔2秒觸發一次
when
then
System.out.println("規則rule_timer_1觸發,觸發時間為:" +
new SimpleDateFormat("yyyy-MM-dd HH:mm:ss").format(new Date()));
end
rule "rule_timer_2"
timer (cron:0/1 * * * * ?) //含義:每隔1秒觸發一次
when
then
System.out.println("規則rule_timer_2觸發,觸發時間為:" +
new SimpleDateFormat("yyyy-MM-dd HH:mm:ss").format(new Date()));
end
第二步:撰寫單元測驗
KieServices kieServices = KieServices.Factory.get();
KieContainer kieClasspathContainer = kieServices.getKieClasspathContainer();
final KieSession kieSession = kieClasspathContainer.newKieSession();
new Thread(new Runnable() {
public void run() {
//啟動規則引擎進行規則匹配,直到呼叫halt方法才結束規則引擎
kieSession.fireUntilHalt();
}
}).start();
Thread.sleep(10000);
//結束規則引擎
kieSession.halt();
kieSession.dispose();
注意:單元測驗的代碼和以前的有所不同,因為我們規則檔案中使用到了timer進行定時執行,需要程式能夠持續一段時間才能夠看到定時器觸發的效果,
5.9 date-effective屬性
date-effective屬性用于指定規則的生效時間,即只有當前系統時間大于等于設定的時間或者日期規則才有可能觸發,默認日期格式為:dd-MMM-yyyy,用戶也可以自定義日期格式,
第一步:撰寫規則檔案/resources/rules/dateeffective.drl
package testdateeffective
/*
此規則檔案用于測驗date-effective屬性
*/
rule "rule_dateeffective_1"
date-effective "2022-11-13 11:36:49"
when
then
System.out.println("規則rule_dateeffective_1觸發");
end
第二步:撰寫單元測驗
//設定日期格式
System.setProperty("drools.dateformat","yyyy-MM-dd HH:mm");
KieServices kieServices = KieServices.Factory.get();
KieContainer kieClasspathContainer = kieServices.getKieClasspathContainer();
KieSession kieSession = kieClasspathContainer.newKieSession();
kieSession.fireAllRules();
kieSession.dispose();
注意:上面的代碼需要設定日期格式,否則我們在規則檔案中寫的日期格式和默認的日期格式不匹配程式會報錯,
5.10 date-expires屬性
date-expires屬性用于指定規則的失效時間,即只有當前系統時間小于設定的時間或者日期規則才有可能觸發,默認日期格式為:dd-MMM-yyyy,用戶也可以自定義日期格式,
第一步:撰寫規則檔案/resource/rules/dateexpires.drl
package testdateexpires
/*
此規則檔案用于測驗date-expires屬性
*/
rule "rule_dateexpires_1"
date-expires "2023-11-13 11:41:40"
when
then
System.out.println("規則rule_dateexpires_1觸發");
end
第二步:撰寫單元測驗
//設定日期格式
System.setProperty("drools.dateformat","yyyy-MM-dd HH:mm");
KieServices kieServices = KieServices.Factory.get();
KieContainer kieClasspathContainer = kieServices.getKieClasspathContainer();
KieSession kieSession = kieClasspathContainer.newKieSession();
kieSession.fireAllRules();
kieSession.dispose();
注意:上面的代碼需要設定日期格式,否則我們在規則檔案中寫的日期格式和默認的日期格式不匹配程式會報錯,
轉載請註明出處,本文鏈接:https://www.uj5u.com/houduan/538307.html
標籤:Java
