drools規(guī)則屬性(rule attributes)的使用

一、介紹

規(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代碼


項目結(jié)構(gòu).jpg

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_1no-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_2no-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,激活的組是在棧頂贾虽。參考如下圖:

agenda-groups.jpg

參考鏈接: 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

?著作權(quán)歸作者所有,轉(zhuǎn)載或內(nèi)容合作請聯(lián)系作者
  • 序言:七十年代末茵乱,一起剝皮案震驚了整個濱河市茂洒,隨后出現(xiàn)的幾起案子,更是在濱河造成了極大的恐慌瓶竭,老刑警劉巖督勺,帶你破解...
    沈念sama閱讀 219,427評論 6 508
  • 序言:濱河連續(xù)發(fā)生了三起死亡事件渠羞,死亡現(xiàn)場離奇詭異,居然都是意外死亡智哀,警方通過查閱死者的電腦和手機(jī)次询,發(fā)現(xiàn)死者居然都...
    沈念sama閱讀 93,551評論 3 395
  • 文/潘曉璐 我一進(jìn)店門,熙熙樓的掌柜王于貴愁眉苦臉地迎上來瓷叫,“玉大人屯吊,你說我怎么就攤上這事∧〔ぃ” “怎么了盒卸?”我有些...
    開封第一講書人閱讀 165,747評論 0 356
  • 文/不壞的土叔 我叫張陵,是天一觀的道長次氨。 經(jīng)常有香客問我蔽介,道長,這世上最難降的妖魔是什么煮寡? 我笑而不...
    開封第一講書人閱讀 58,939評論 1 295
  • 正文 為了忘掉前任虹蓄,我火速辦了婚禮,結(jié)果婚禮上洲押,老公的妹妹穿的比我還像新娘武花。我一直安慰自己,他們只是感情好杈帐,可當(dāng)我...
    茶點故事閱讀 67,955評論 6 392
  • 文/花漫 我一把揭開白布。 她就那樣靜靜地躺著专钉,像睡著了一般挑童。 火紅的嫁衣襯著肌膚如雪。 梳的紋絲不亂的頭發(fā)上跃须,一...
    開封第一講書人閱讀 51,737評論 1 305
  • 那天站叼,我揣著相機(jī)與錄音,去河邊找鬼菇民。 笑死尽楔,一個胖子當(dāng)著我的面吹牛,可吹牛的內(nèi)容都是我干的第练。 我是一名探鬼主播阔馋,決...
    沈念sama閱讀 40,448評論 3 420
  • 文/蒼蘭香墨 我猛地睜開眼,長吁一口氣:“原來是場噩夢啊……” “哼娇掏!你這毒婦竟也來了呕寝?” 一聲冷哼從身側(cè)響起,我...
    開封第一講書人閱讀 39,352評論 0 276
  • 序言:老撾萬榮一對情侶失蹤婴梧,失蹤者是張志新(化名)和其女友劉穎下梢,沒想到半個月后客蹋,有當(dāng)?shù)厝嗽跇淞掷锇l(fā)現(xiàn)了一具尸體,經(jīng)...
    沈念sama閱讀 45,834評論 1 317
  • 正文 獨居荒郊野嶺守林人離奇死亡孽江,尸身上長有42處帶血的膿包…… 初始之章·張勛 以下內(nèi)容為張勛視角 年9月15日...
    茶點故事閱讀 37,992評論 3 338
  • 正文 我和宋清朗相戀三年讶坯,在試婚紗的時候發(fā)現(xiàn)自己被綠了。 大學(xué)時的朋友給我發(fā)了我未婚夫和他白月光在一起吃飯的照片岗屏。...
    茶點故事閱讀 40,133評論 1 351
  • 序言:一個原本活蹦亂跳的男人離奇死亡辆琅,死狀恐怖,靈堂內(nèi)的尸體忽然破棺而出担汤,到底是詐尸還是另有隱情涎跨,我是刑警寧澤,帶...
    沈念sama閱讀 35,815評論 5 346
  • 正文 年R本政府宣布崭歧,位于F島的核電站隅很,受9級特大地震影響,放射性物質(zhì)發(fā)生泄漏率碾。R本人自食惡果不足惜叔营,卻給世界環(huán)境...
    茶點故事閱讀 41,477評論 3 331
  • 文/蒙蒙 一、第九天 我趴在偏房一處隱蔽的房頂上張望所宰。 院中可真熱鬧绒尊,春花似錦、人聲如沸仔粥。這莊子的主人今日做“春日...
    開封第一講書人閱讀 32,022評論 0 22
  • 文/蒼蘭香墨 我抬頭看了看天上的太陽躯泰。三九已至谭羔,卻和暖如春,著一層夾襖步出監(jiān)牢的瞬間麦向,已是汗流浹背瘟裸。 一陣腳步聲響...
    開封第一講書人閱讀 33,147評論 1 272
  • 我被黑心中介騙來泰國打工, 沒想到剛下飛機(jī)就差點兒被人妖公主榨干…… 1. 我叫王不留诵竭,地道東北人话告。 一個月前我還...
    沈念sama閱讀 48,398評論 3 373
  • 正文 我出身青樓,卻偏偏與公主長得像卵慰,于是被迫代替她去往敵國和親沙郭。 傳聞我的和親對象是個殘疾皇子,可洞房花燭夜當(dāng)晚...
    茶點故事閱讀 45,077評論 2 355

推薦閱讀更多精彩內(nèi)容

  • 概述(Overview) 以.drl為擴(kuò)展名的文件呵燕,是Drools中的規(guī)則文件棠绘,規(guī)則文件的編寫,遵循Drools規(guī)...
    老羊_肖恩閱讀 41,773評論 4 31
  • 對于Drools Rule的理解 一個規(guī)則可以包含三個部分: 屬性部分:定義當(dāng)前規(guī)則執(zhí)行的一些屬性等,比如是否可被...
    RyanLee_閱讀 6,829評論 0 8
  • Drools規(guī)則文件——語法屬性 salience 功能:設(shè)置規(guī)制執(zhí)行的優(yōu)先級值:數(shù)字(數(shù)字越大執(zhí)行優(yōu)先級越高)...
    天堂的碼頭閱讀 3,164評論 0 2
  • Drools是一款基于Java的開源規(guī)則引擎 實現(xiàn)了將業(yè)務(wù)決策從應(yīng)用程序中分離出來氧苍。 優(yōu)點: 1夜矗、簡化系統(tǒng)架構(gòu),優(yōu)...
    生活的探路者閱讀 11,058評論 0 5
  • 深入了解Drools 簡單介紹 筆者正在做風(fēng)控系統(tǒng)让虐,風(fēng)控系統(tǒng)里邊存在非常多的規(guī)則(比如:age < 16 || a...
    duval閱讀 22,399評論 2 19