一、介紹
規(guī)則屬性
是您可以添加到業(yè)務(wù)規(guī)則以修改規(guī)則行為
的附加規(guī)范。 在 DRL
文件中引矩,您通常在規(guī)則條件和操作的上方定義規(guī)則屬性,多個屬性位于單獨的行中
侵浸,格式如下:
rule "rule_name"
// Attribute
// Attribute
when
// Conditions
then
// Actions
end
二旺韭、常見的規(guī)則屬性
規(guī)則屬性 | 解釋 | 舉例 |
---|---|---|
salience |
定義規(guī)則優(yōu)先級 ,是一個整數(shù)掏觉。當(dāng)在激活隊列中排序 時区端,salience的值越大 ,優(yōu)先級越高 澳腹。 |
salience 99 |
enabled | 定義規(guī)則是否啟用. true 啟用织盼,false 禁用,默認(rèn)值是true
|
enabled true |
date-effective | 包含時間和日期的字符串酱塔,當(dāng)當(dāng)前時間大于date-effective 時沥邻,該規(guī)則才會被激活。這個時間格式可以修改羊娃,見下方具體的用法
|
date-effective "4-5月-2022" |
date-expires | 設(shè)置規(guī)則的過期時間唐全,時間格式和上方一樣。 | date-expires "4-5月-2022" |
no-loop | 布爾值蕊玷,默認(rèn)值為false , 定義當(dāng)當(dāng)前規(guī)則規(guī)則的結(jié)果 修改了fact 對象時邮利,是否可以再次執(zhí)行該規(guī)則。true: 不可以垃帅, false: 可以延届,可能會導(dǎo)致死循環(huán)。指的是當(dāng)前規(guī)則的修改挺智,如果別的規(guī)則修改了祷愉,還會導(dǎo)致該規(guī)則的觸發(fā) |
no-loop true |
agenda-group |
Agenda groups 允許您對agenda 進(jìn)行分區(qū)窗宦,以提供對規(guī)則組的更多執(zhí)行控制赦颇。 只有獲得焦點的議程組中的規(guī)則才能被激活二鳄。 ,但是這個里面有個特例 ,如果某個規(guī)則沒有配置 agenda-group媒怯,但是它模式匹配成功了订讼,那么會被分到默認(rèn)的組(main ),這個main 組的規(guī)則也會執(zhí)行扇苞。 |
agenda-group "GroupName" |
auto-focus | 布爾值欺殿,僅適用于Agenda-Group 內(nèi)的規(guī)則。當(dāng)值為true 時鳖敷,下次激活該規(guī)則時脖苏,會將焦點自動給這個Agenda group
|
auto-focus true |
activation-group | 表示該組下的規(guī)則只有一個規(guī)則 會被執(zhí)行,該組下其余激活的規(guī)則會被取消執(zhí)行定踱。 但是別的組激活的規(guī)則可能會被執(zhí)行棍潘。 |
activation-group "GroupName" |
duration | long類型的值,如果在這個時間之后規(guī)則還成立 崖媚,那么執(zhí)行該規(guī)則 |
duration 1000 |
timer | 一個字符串亦歉,標(biāo)識用于調(diào)度規(guī)則的 int(間隔)或 cron 計時器定義。 | Example: timer ( cron:* 0/15 * * * ? ) (every 15 minutes) |
calendar | 定義Quartz calendar用于調(diào)度規(guī)則畅哑。 | |
lock-on-active | 一個布爾值肴楷,僅適用于規(guī)則流組或議程組中的規(guī)則。 選擇該選項后荠呐,下次規(guī)則的規(guī)則流組變?yōu)榛顒訝顟B(tài)或規(guī)則的議程組獲得焦點時赛蔫,規(guī)則無法再次激活,直到規(guī)則流組不再處于活動狀態(tài)或議程組失去焦點泥张。 這是 no-loop 屬性的更強(qiáng)版本呵恢,因為匹配規(guī)則的激活被丟棄,無論更新的來源如何(不僅是規(guī)則本身)圾结。 此屬性非常適合計算規(guī)則瑰剃,其中您有許多修改事實的規(guī)則并且您不希望任何規(guī)則重新匹配和再次觸發(fā)。 | lock-on-active true |
dialect | 將 JAVA 或 MVEL 標(biāo)識為用于規(guī)則中的代碼表達(dá)式的語言的字符串筝野。 默認(rèn)情況下晌姚,該規(guī)則使用在包級別指定的方言。 此處指定的任何方言都會覆蓋該規(guī)則的包方言設(shè)置歇竟。 | dialect "JAVA" |
三挥唠、部分規(guī)則屬性案例
此處編寫出規(guī)則文件和部分核心Java代碼
1、salience
定義規(guī)則執(zhí)行的優(yōu)先級焕议,salience的值越大宝磨,優(yōu)先級越高
1、規(guī)則文件的編寫
rule "salience_rule_1"
salience 4
when
then
System.out.println("rule 1");
end
rule "salience_rule_2"
salience 3
when
then
System.out.println("rule 2");
end
// 此處優(yōu)先級的值是動態(tài)獲取來的
rule "salience_rule_3"
salience $dynamicSalience
when
$dynamicSalience: Integer()
then
System.out.println("rule 3");
end
注意:
我們的salience_rule_3
的優(yōu)先級的值是動態(tài)
來的,即是從工作內(nèi)存中獲取的唤锉。
2世囊、java代碼編寫
public class DroolsSalienceApplication {
public static void main(String[] args) {
KieServices kieServices = KieServices.get();
KieContainer kieContainer = kieServices.getKieClasspathContainer();
KieSession kieSession = kieContainer.newKieSession("rule-attributes-ksession");
// 向工作內(nèi)存中插入一個Integer值,salience_rule_3 需要用到這個優(yōu)先級
kieSession.insert(10);
// 只匹配規(guī)則名稱是已 salience_ 開頭的規(guī)則窿祥,忽略其余的規(guī)則
kieSession.fireAllRules(new RuleNameStartsWithAgendaFilter("salience_"));
kieSession.dispose();
}
}
kieSession.insert(10);
此處向工作內(nèi)存中插入一個值株憾,將會匹配到salience_rule_3
,然后動態(tài)修改它的優(yōu)先級晒衩。
3嗤瞎、運行結(jié)果
rule 3
rule 1
rule 2
因為 salience
的值越大優(yōu)先級越高,所以是這個順序听系。
2贝奇、enabled
定義規(guī)則是否啟用,true
啟用 false
禁用
1靠胜、規(guī)則文件編寫
package rules
rule "enabled_rule_1"
// 禁用此規(guī)則
enabled false
when
then
System.out.println("enabled_rule_1");
end
rule "enabled_rule_2"
// 啟用此規(guī)則掉瞳,默認(rèn)就是啟用
enabled true
when
then
System.out.println("enabled_rule_2");
end
enabled_rule_2
這個規(guī)則需要運行,enabled_rule_1
這個規(guī)則不能運行髓帽。
2菠赚、java代碼編寫
/**
* 測試規(guī)則的啟用和禁用
*/
public class DroolsEnabledApplication {
public static void main(String[] args) {
KieServices kieServices = KieServices.get();
KieContainer kieContainer = kieServices.getKieClasspathContainer();
KieSession kieSession = kieContainer.newKieSession("rule-attributes-ksession");
// 只匹配規(guī)則名稱是已 enabled_ 開頭的規(guī)則,忽略其余的規(guī)則
kieSession.fireAllRules(new RuleNameStartsWithAgendaFilter("enabled_"));
kieSession.dispose();
}
}
沒有需要注意的地方
3郑藏、運行結(jié)果
enabled_rule_2
可以看到只有規(guī)則enabled_rule_2
輸出了結(jié)果衡查,而enabled_rule_1
被禁用了。
3必盖、date-effective
定義規(guī)則什么時候啟用拌牲,只有當(dāng)前時間>
規(guī)則時間才會啟用。需要注意默認(rèn)的時間格式
歌粥,可以通過java代碼進(jìn)行修改塌忽。
1、規(guī)則文件編寫
package rules
import java.text.SimpleDateFormat
import java.util.Date
// 規(guī)則一:輸出當(dāng)前時間
rule "date_effective_rule_1"
when
then
System.out.println("當(dāng)前時間:" + new SimpleDateFormat("yyyy-MM-dd HH:mm:ss").format(new Date()));
end
// 規(guī)則二: 該規(guī)則會在2022-05-18 10:54:26之后被激活
rule "date_effective_rule_2"
date-effective "2022-05-18 10:54:26"
when
then
System.out.println("date_effective_rule_2執(zhí)行了,規(guī)則允許被執(zhí)行的時間應(yīng)該在2022-05-18 10:54:26之后");
end
// 規(guī)則三: 該規(guī)則會在2023-05-18 10:54:26之后被激活
rule "date_effective_rule_3"
date-effective "2023-05-18 10:54:26"
when
then
System.out.println("date_effective_rule_3會在時間到了2023-05-18 10:54:26才激活");
end
規(guī)則一:輸出當(dāng)前時間
規(guī)則二: 該規(guī)則會在2022-05-18 10:54:26之后被激活
規(guī)則三: 該規(guī)則會在2023-05-18 10:54:26之后被激活
2失驶、java代碼編寫
/**
* 測試規(guī)則在執(zhí)行的時間之后才能執(zhí)行
*/
public class DroolsDateEffectiveApplication {
public static void main(String[] args) {
// 設(shè)置日期格式土居,否則可能會報錯(Wrong date-effective value: Invalid date input format: [2022-05-18 10:54:26] it should follow: [d-MMM-yyyy]]])
System.setProperty("drools.dateformat", "yyyy-MM-dd HH:mm:ss");
KieServices kieServices = KieServices.get();
KieContainer kieContainer = kieServices.getKieClasspathContainer();
KieSession kieSession = kieContainer.newKieSession("rule-attributes-ksession");
// 只匹配規(guī)則名稱是已 date_effective_ 開頭的規(guī)則,忽略其余的規(guī)則
kieSession.fireAllRules(new RuleNameStartsWithAgendaFilter("date_effective_"));
kieSession.dispose();
}
}
需要注意System.setProperty("drools.dateformat", "yyyy-MM-dd HH:mm:ss");
這句嬉探,這個修改drools中的日期格式擦耀,因為規(guī)則中寫的日期格式為date-effective "2023-05-18 10:54:26"
而默認(rèn)的格式為d-MMM-yyyy
,不修會報錯涩堤。
3眷蜓、運行結(jié)果
當(dāng)前時間:2022-05-18 10:59:38
date_effective_rule_2執(zhí)行了,規(guī)則允許被執(zhí)行的時間應(yīng)該在2022-05-18 10:54:26之后
可以看到規(guī)則二執(zhí)行了,規(guī)則三沒有執(zhí)行胎围,因為規(guī)則三需要時間到達(dá)了2023-05-18 10:54:26
才執(zhí)行吁系,而當(dāng)前時間不符合德召。
4、注意事項
如果出現(xiàn)了Wrong date-effective value: Invalid date input format: [2022-05-18 10:54:26] it should follow: [d-MMM-yyyy]]]
這個錯誤該怎么解決了汽纤,這是因為日期格式不正確上岗。需要在java代碼中進(jìn)行如下設(shè)置System.setProperty("drools.dateformat", "yyyy-MM-dd HH:mm:ss")
4、date-expires
定義規(guī)則的過期時間冒版,即規(guī)則到了該時間之后就不可使用了液茎。和date-effective
的用法類似逞姿,此處就不演示了辞嗡。
5、no-loop
定義當(dāng)當(dāng)前規(guī)則
的結(jié)果修改了fact
對象時滞造,是否可以再次執(zhí)行該規(guī)則续室。可以防止死循環(huán)
1、規(guī)則文件編寫
package rules
import java.util.concurrent.TimeUnit
import java.text.SimpleDateFormat
import java.util.Date
rule "no_loop_rule_1"
no-loop true
when
$i: Integer(intValue() < 20)
then
modify($i){
}
System.out.println(new SimpleDateFormat("yyyy-MM-dd HH:mm:ss").format(new Date()) + " no_loop_rule_1 i=" + $i);
end
rule "no_loop_rule_2"
no-loop false
when
$i: Integer(intValue() < 20)
then
modify($i){
}
TimeUnit.SECONDS.sleep(1);
System.out.println(new SimpleDateFormat("yyyy-MM-dd HH:mm:ss").format(new Date()) + " no_loop_rule_2 i=" + $i);
end
解釋:
no_loop_rule_1
:no-loop true
表示如果當(dāng)前規(guī)則的RHS
部分谒养,對Fact對象進(jìn)行了修改挺狰,則不會再次觸發(fā)該規(guī)則。那如果是no_loop_rule_2
修改了买窟,會導(dǎo)致該規(guī)則的觸發(fā)嗎丰泊?答案是
會觸發(fā),如果我不想被觸發(fā)呢始绍?那么使用lock-on-active
可以實現(xiàn)瞳购。
no_loop_rule_2
:no-loop false
表示如果當(dāng)前規(guī)則的RHS
部分,對Fact對象進(jìn)行了修改亏推,那么還會再次匹配這個規(guī)則学赛。
2、java代碼編寫
/**
* 測試規(guī)則是否可以再次被執(zhí)行
*/
public class DroolsNoLoopApplication {
public static void main(String[] args) throws InterruptedException {
System.setProperty("drools.dateformat", "yyyy-MM-dd HH:mm:ss");
KieServices kieServices = KieServices.get();
KieContainer kieContainer = kieServices.getKieClasspathContainer();
KieSession kieSession = kieContainer.newKieSession("rule-attributes-ksession");
kieSession.insert(10);
// 只匹配規(guī)則名稱是已 no_loop_ 開頭的規(guī)則吞杭,忽略其余的規(guī)則
kieSession.fireAllRules(new RuleNameStartsWithAgendaFilter("no_loop_"));
// 睡眠5s盏浇,使規(guī)則文件中的規(guī)則執(zhí)行完
TimeUnit.SECONDS.sleep(5);
kieSession.dispose();
}
}
此處 java 代碼,睡眠了5s芽狗,是為了讓規(guī)則執(zhí)行绢掰。
3、運行結(jié)果
2022-05-18 11:42:29 no_loop_rule_1 i=10
2022-05-18 11:42:31 no_loop_rule_2 i=10
2022-05-18 11:42:31 no_loop_rule_1 i=10
2022-05-18 11:42:32 no_loop_rule_2 i=10
解釋:
2022-05-18 11:42:29 no_loop_rule_1 i=10
: no_loop_rule_1被觸發(fā)童擎,由于RHS部分使用了modify
修改了規(guī)則內(nèi)存中的對象滴劲,但是該規(guī)則存在 no-loop true 的屬性,所以該規(guī)則沒有再次被觸發(fā)柔昼,即只輸出了一次哑芹。
2022-05-18 11:42:30 no_loop_rule_2 i=10 2022-05-18 11:42:30 no_loop_rule_1 i=10
此時規(guī)則 no_loop_rule_2 執(zhí)行了,由于該規(guī)則的 no-loop 為 false 并且使用了 modify 方法捕透,所以該規(guī)則多次被觸發(fā)了聪姿,從結(jié)果上看碴萧,貌似規(guī)則 no_loop_rule_1 又再次被觸發(fā)了,不是應(yīng)該不被觸發(fā)嗎末购,因為設(shè)置了no-loop true破喻?因為這是no_loop_rule_2導(dǎo)致no_loop_rule_1觸發(fā)的,而no_loop只對自身的RHS修改有效盟榴。
疑問:
那如果將 no-loop
換成lock-on-active
結(jié)果會一樣嗎曹质?可以自己嘗試一下看看結(jié)果。
6擎场、agenda-group
將被模式匹配成功后的規(guī)則羽德,進(jìn)行分組,只有獲得焦點的組
迅办,才可以執(zhí)行規(guī)則宅静。但是這個里面有個特列,如果某個規(guī)則在模式匹配站欺,匹配成功了姨夹,但是沒有配置agenda-group,那么它會被分配到main
組矾策,這個main
組的規(guī)則總是執(zhí)行的磷账。
agenda-group
的數(shù)據(jù)結(jié)構(gòu)就類似stack
,激活的組是在棧頂贾虽。參考如下圖:
參考鏈接: https://stackoverflow.com/questions/6870192/understanding-agenda-group-in-drools
1逃糟、規(guī)則文件編寫
package rules
/**
agenda-group 的數(shù)據(jù)結(jié)構(gòu)類似與棧,激活的組會被放置在棧頂榄鉴,
`main`是默認(rèn)組履磨,總是存在的,即沒有配置agenda-group的就是`main`庆尘,
`main`總是會執(zhí)行的剃诅。
*/
rule "agenda_group_001_rule_1"
agenda-group "group-001"
when
then
System.out.println("agenda_group_001_rule_1");
end
rule "agenda_group_001_rule_2"
agenda-group "group-001"
when
then
System.out.println("agenda_group_001_rule_2");
end
rule "agenda_group_002_rule_3"
agenda-group "group-002"
when
then
System.out.println("agenda_group_002_rule_3");
end
rule "agenda_group_no_group_rule_4"
when
then
System.out.println("agenda_group_no_group_rule_4");
end
注意: 此處其實是 存在 3個組的,agenda_group_no_group_rule_4
如果模式匹配成功后會被分配到main
組驶忌,main
總是會被執(zhí)行的矛辕。
2、java代碼編寫
/**
* 測試規(guī)則分組
*/
public class DroolsAgendaGroupApplication {
public static void main(String[] args) {
// 設(shè)置日期格式付魔,否則可能會報錯(Wrong date-effective value: Invalid date input format: [2022-05-18 10:54:26] it should follow: [d-MMM-yyyy]]])
System.setProperty("drools.dateformat", "yyyy-MM-dd HH:mm:ss");
KieServices kieServices = KieServices.get();
KieContainer kieContainer = kieServices.getKieClasspathContainer();
KieSession kieSession = kieContainer.newKieSession("rule-attributes-ksession");
// 激活組
kieSession.getAgenda().getAgendaGroup("group-001").setFocus();
// 只匹配規(guī)則名稱是已 agenda_group_ 開頭的規(guī)則聊品,忽略其余的規(guī)則
kieSession.fireAllRules(new RuleNameStartsWithAgendaFilter("agenda_group_"));
kieSession.dispose();
}
}
激活group-001
分組。
3几苍、運行結(jié)果
agenda_group_001_rule_1
agenda_group_001_rule_2
agenda_group_no_group_rule_4
解釋:
agenda_group_no_group_rule_4
為什么會被輸出呢翻屈?它沒有定義agenda-group
啊,而且我們激活的也是group-001
分組妻坝,它不應(yīng)該輸出啊伸眶。這是應(yīng)為這個規(guī)則模式匹配成功后被分配到了默認(rèn)的main
組惊窖,而main
組一定會被執(zhí)行的。
7厘贼、auto-focus
設(shè)置某個agenda-group
默認(rèn)獲取到焦點界酒,和在java代碼中使用kieSession.getAgenda().getAgendaGroup("group-001").setFocus();
或在drl文件中使用drools.setFocus(..)
一樣。
8嘴秸、activation-group
處于該分組中激活的規(guī)則演痒,同一個組下谤辜,只有一個規(guī)則可以執(zhí)行
幔翰,其余的會被取消執(zhí)行哮奇。但是別的組中激活的規(guī)則還是可以執(zhí)行的。
1岩四、規(guī)則文件編寫
package rules
rule "activation_group_001_rule_1"
activation-group "group-001"
salience 1
when
then
System.out.println("activation_group_001_rule_1");
end
rule "activation_group_001_rule_2"
activation-group "group-001"
salience 2
when
then
System.out.println("activation_group_001_rule_2");
end
rule "activation_group_002_rule_3"
activation-group "group-002"
when
then
System.out.println("activation_group_002_rule_3");
end
rule "activation_group_no_group_rule_4"
when
then
System.out.println("activation_group_no_group_rule_4");
end
activation-group "group-001"
此處對這個組的規(guī)則指定了優(yōu)先級哭尝,優(yōu)先級高的先執(zhí)行,執(zhí)行完之后剖煌,該組別的規(guī)則不執(zhí)行。
2逝淹、java代碼編寫
public class DroolsActivationGroupApplication {
public static void main(String[] args) {
System.setProperty("drools.dateformat", "yyyy-MM-dd HH:mm:ss");
KieServices kieServices = KieServices.get();
KieContainer kieContainer = kieServices.getKieClasspathContainer();
KieSession kieSession = kieContainer.newKieSession("rule-attributes-ksession");
// 只匹配規(guī)則名稱是已 activation_group_ 開頭的規(guī)則耕姊,忽略其余的規(guī)則
kieSession.fireAllRules(new RuleNameStartsWithAgendaFilter("activation_group_"));
kieSession.dispose();
}
}
3、運行結(jié)果
activation_group_001_rule_2
activation_group_002_rule_3
activation_group_no_group_rule_4
可以看到分組group-001
中有2個規(guī)則栅葡,但是只執(zhí)行了一個規(guī)則茉兰。
9、duration
long類型的值欣簇,單位毫秒规脸,如果在這個時間之后規(guī)則還成立
,那么執(zhí)行該規(guī)則熊咽。
1莫鸭、規(guī)則文件編寫
package rules
import java.text.SimpleDateFormat
import java.util.Date
rule "duration_rule_1"
// 延遲1s后執(zhí)行規(guī)則
duration 1000
when
$i: Integer(intValue() < 10)
then
System.out.println(Thread.currentThread().getName() + ": " +
new SimpleDateFormat("yyyy-MM-dd HH:mm:ss").format(new Date())+
" duration_rule_1 $i:"+$i);
end
定義規(guī)則延遲1s
后進(jìn)行執(zhí)行。
2横殴、java代碼編寫
/**
* 在多少毫秒后被因,如果條件還成立,則觸發(fā)該規(guī)則
*/
public class DroolsDurationApplication {
public static void main(String[] args) throws InterruptedException {
System.setProperty("drools.dateformat", "yyyy-MM-dd HH:mm:ss");
KieServices kieServices = KieServices.get();
KieContainer kieContainer = kieServices.getKieClasspathContainer();
KieSession kieSession = kieContainer.newKieSession("rule-attributes-ksession");
FactHandle factHandle = kieSession.insert(3);
// 只匹配規(guī)則名稱是已 duration_ 開頭的規(guī)則衫仑,忽略其余的規(guī)則
new Thread(() -> {
// 調(diào)用此方法會阻塞調(diào)用線程梨与,直到 `kieSession.halt();`的調(diào)用
System.out.println("當(dāng)前時間:" + new SimpleDateFormat("yyyy-MM-dd HH:mm:ss").format(new Date()));
kieSession.fireUntilHalt(new RuleNameStartsWithAgendaFilter("duration_"));
}, "fire-thread").start();
// 如果修改這個值,使得規(guī)則的條件不成立文狱,看規(guī)則是否還執(zhí)行
kieSession.update(factHandle, 4);
TimeUnit.SECONDS.sleep(2);
kieSession.halt();
kieSession.dispose();
}
}
注意:
1粥鞋、我們調(diào)用出發(fā)所有規(guī)則執(zhí)行的方法不在是fireAllRules
而是fireUntilHalt
。
2瞄崇、fireUntilHalt
的調(diào)用會阻塞線程呻粹,直到調(diào)用halt
方法到踏,因此fireUntilHalt
需要放置到另外的線程中調(diào)用。而且我們觀察規(guī)則的執(zhí)行尚猿,也是在這個線程中調(diào)用的窝稿。
3、運行結(jié)果
當(dāng)前時間:2022-05-18 14:13:36
fire-thread: 2022-05-18 14:13:37 duration_rule_1 $i:4
可以看到凿掂,延遲1s
后規(guī)則執(zhí)行了伴榔。
4、疑問
如果我們在1s
鐘之內(nèi)庄萎,將規(guī)則的條件修改成不成立踪少,那么規(guī)則還執(zhí)行嗎?答案:
不執(zhí)行糠涛。
10援奢、lock-on-active
和rule flow groups or agenda groups
配合使用。
需求:
我們有2個規(guī)則忍捡,并且同屬于一個組集漾,規(guī)則二執(zhí)行完之后,工作內(nèi)存中的Fact對象的值發(fā)生了變化砸脊,導(dǎo)致規(guī)則一滿足執(zhí)行的條件具篇,而規(guī)則一已經(jīng)執(zhí)行一遍了,此處需要阻止規(guī)則二的觸發(fā)導(dǎo)致規(guī)則一的出觸發(fā)凌埂。使用lock-on-active
即可實現(xiàn)驱显。
1、規(guī)則文件編寫
package rules
import com.huan.drools.lockonactive.Person
rule "lock_on_active_rule_01"
agenda-group "group-001"
lock-on-active true
when
$p: Person(age < 18)
then
System.out.println("lock_on_active_rule_01: 用戶:[" + $p.getName() + "]當(dāng)前的年齡是:[" + $p.getAge() + "]");
end
rule "lock_on_active_rule_02"
agenda-group "group-001"
when
$p: Person(name == "張三")
then
modify($p){
setAge(15)
}
System.out.println("lock_on_active_rule_02: 用戶:[" + $p.getName() + "]當(dāng)前的年齡是:[" + $p.getAge() + "]");
end
規(guī)則lock_on_active_rule_01
加了lock-on-active true
屬性后瞳抓,規(guī)則lock_on_active_rule_02
修改Fact
導(dǎo)致規(guī)則lock_on_active_rule_01
的條件成立埃疫,此時規(guī)則也是不會執(zhí)行的。
2孩哑、java代碼編寫
/**
* 一個簡單的實體類
*
* @author huan.fu
* @date 2022/5/18 - 14:34
*/
@Getter
@Setter
@AllArgsConstructor
public class Person {
private String name;
private Integer age;
}
public class DroolsLockOnActiveApplication {
public static void main(String[] args) {
System.setProperty("drools.dateformat", "yyyy-MM-dd HH:mm:ss");
KieServices kieServices = KieServices.get();
KieContainer kieContainer = kieServices.getKieClasspathContainer();
KieSession kieSession = kieContainer.newKieSession("rule-attributes-ksession");
// 激活組
kieSession.getAgenda().getAgendaGroup("group-001").setFocus();
Person person = new Person("張三", 20);
kieSession.insert(person);
// 只匹配規(guī)則名稱是已 lock_on_active_ 開頭的規(guī)則栓霜,忽略其余的規(guī)則
kieSession.fireAllRules(new RuleNameStartsWithAgendaFilter("lock_on_active_"));
kieSession.dispose();
}
}
3、運行結(jié)果
lock_on_active_rule_02: 用戶:[張三]當(dāng)前的年齡是:[15]
可以看到只有規(guī)則二執(zhí)行了臭笆,說明阻止了規(guī)則一的執(zhí)行叙淌。
四、完整代碼
https://gitee.com/huan1993/spring-cloud-parent/tree/master/drools/drools-drl-rule-attributes
五愁铺、參考鏈接
1鹰霍、https://docs.drools.org/7.69.0.Final/drools-docs/html_single/index.html#rules-attributes-ref_drl-rules
2、 https://stackoverflow.com/questions/6870192/understanding-agenda-group-in-drools