Drools入门之规则属性

no-loop

默认值:false

类型:Boolean

属性说明:防止死循环,当规则通过update之类的函数修改了Fact对象时,可能使规则再次被激活,从而导致死循环。将no-loop设置为true的目的是避免当前规则then部分被修改后的事实对象再次被激活,从而防止死循环的发生,即执行下面的规则

例子:

    rule "test007"
                    when
                        $p:Person(age == "20")
                    then
                        $p.setAge(20);
                        update($p)
                        System.out.println("不设置no-loop");
                    end

执行日志

不设置no-loop
不设置no-loop
不设置no-loop
不设置no-loop
不设置no-loop

设置no-loop

    rule "test007"
                    no-loop true
                    when
                        $p:Person(age == "20")
                    then
                        $p.setAge(20);
                        update($p)
                        System.out.println("不设置no-loop");
                    end

执行日志

不设置no-loop

当一个规则文件中,一个Fact(事实)对象通过Drools函数被修改,规则体将被再次激活。也就是说,在RHS部分使用了与update相类似的语法(insert同理),变更了Fact对象在规则中的内容,就会导致规则重新被激活和匹配。再次激活的前提条件是被修改的事实对象与规则LHS部分的约束条件是包含关系。一个规则事实对象的变更会影响其他规则的结果,这一点在对象引用章节中有过简单说明。

ruleflow-group

默认值:N/A

类型:String

属性说明:ruleflow-group分为rule、flow和group3个部分,分别代表规则、流程、分组,即常说的规则流。

lock-on-active

默认值:false

类型:Boolean

属性说明:lock-on-active是指“锁定活跃”。既然它是规则体的属性,那一定是锁定规则的,而且是锁定活跃的规则。简单地说,当规则体设置该属性为true时,则当前只会被触发一次。当ruleflow-group或agenda-group再次被激活时,即使在规则体中设置了lock-on-active为true,该规则体也不能再次被激活,即无论如何更新规则事实对象,当前规则也只能被触发一次。这是no-loop的升级版,一个更强大的解决死循环的属性。

salience

默认值:0

类型:integer

属性说明:规则体被执行的顺序,每一个规则都有一个默认的执行顺序,如果不设置salience属性,规则体的执行顺序为由上到下。salience值可以是一个整数,但也可以是一个负数,其值越大,执行顺序越高,排名越靠前。Drools还支持动态配置优先级。

动态配置

rule "test009"
        salience (Math.random() * 10 + 1)
        when
        then
         System.out.println("ggg");
 end

enabled

默认值:true

类型:Boolean

属性说明:指规则是否可以被执行,若规则体设置为enabled false,则规则体将视为永久不被激活。

dialect

可能值:Java或Mvel。类型:String。属性说明:用来定义规则中要使用的语言类型,支持Mvel和Java两种类型的语言,默认情况下是由包指定的。Java语言在特殊情况下会用到,如Accumulate、引用Java中的语法等

date-effective

默认值:N/A

类型:String、日期、时间

属性说明:只有当前系统时间大于等于设置的时间或日期,规则才会被激活。在没有设置该属性的情况下,规则体不受时间限制。date-effective的值是一个日期型的字符串,默认情况下,date-effective可接受的日期格式为“dd-MMM-yyyy”,例如,设置2018年08月07日的date-effective为date-effective "07-August-2018"

如果需要精确到时分秒,可以通过设置drools的日期格式化来完成任意格式的时间设定,而不是使用默认的格式。在调用代码之前设置日期格式化格式

System.setProperty("drools.dateformat", "yyyy-MM-dd HH:mm");

在规则文件中就可以按照上面设定的格式来传入日期:

date-effective "2017-07-20 16:31"

date-expires

默认值:N/A

类型:String、日期、时间

属性说明:date-expires属性与date-effective属性是相反的,即只有当前系统时间小于设置的时间或日期,规则才会被激活。在没有设置该属性的情况下,规则体不受时间限制。date-expires的值为一个日期型的字符串,默认情况下,date-expires可接受的日期格式为“dd-MMM-yyyy”。例如,设置2018年08月07日的date-effective值为“date-expires"07-August-2018"”。

duration

默认值:无

类型:long

属性说明:表示定时器,如果当前规则LHS部分为true,那么规则继续执行;如果该属性已经被弃用,那么通过新的属性timer来控制。

activation-group

默认值:N/A

类型:String

属性说明:activation-group是指激活分组,通过字符串定义分组名称,具有相同组名称的规则体有且只有一个规则被激活,其他规则体的LHS部分仍然为true也不会再被执行。该属性受salience属性的影响,如当前规则文件中的其他规则未设计该属性,则视为规则处于被激活状态,并不受该属性的影响。

agenda-group

默认值:无,需要通过Java设置

类型:String

属性说明:agenda-group是议程分组,属于另一种可控的规则执行方式,是指用户可以通过配置agenda-group的参数来控制规则的执行,而且只有获取焦点的规则才会被激活。

package rules.attribute;
dialect  "mvel"

rule "testGroup1"
    agenda-group "ag1"
    when
        eval(true)
    then
    System.out.println("group1:ag1");
end

rule "testGroup2"
    agenda-group "ag2"
    when
        eval(true)
    then
    System.out.println("group2:ag2");
end

rule "testGroup3"
    agenda-group "ag1"
    when
        eval(true)
    then
    System.out.println("group3:ag1");
end
public class RulesHello {
    public static void main(String[] args) {
        KieServices kieService = KieServices.Factory.get();
        KieContainer kieContainer = kieService.getKieClasspathContainer();
        KieSession kieSession = kieContainer.newKieSession("testAttribute");
        kieSession.getAgenda().getAgendaGroup("ag1").setFocus();
        int count = kieSession.fireAllRules();
        System.out.println("总共执行了"+count+"条规则");
        kieSession.dispose();
    }
}

执行结果

group1:ag1
group3:ag1
总共执行了2条规则

Java代码中指定getAgendaGroup()的参数时,如果参数值不存在或未指定,则设置了agenda-group属性的规则体将无法再获取焦点,这是有风险的。

实际应用中的agenda-group可以与auto-focus属性一起使用。如果将某个规则体的auto-focus属性设置为true,那么即使该规则设置了agenda-group属性,也不需要在Java代码中设置。

agenda-group属性会受到其他属性的影响,如下图所示

image-20220620100913013

第一种情况:

kieSession.getAgenda().getAgendaGroup("ag3").setFocus();
rule "testActive1"
    agenda-group "ag3"
    activation-group "agag"
    when
        eval(true)
    then
    System.out.println("testActive1:ag3");
end

rule "testActive2"
    agenda-group "ag3"
    activation-group "agag"
    when
        eval(true)
    then
    System.out.println("testActive2:ag3");
end

执行结果

testActive1:ag3
总共执行了1条规则

第二种情况

kieSession.getAgenda().getAgendaGroup("ag5").setFocus();
rule "testActive3"
    agenda-group "ag4"
    activation-group "agag1"
    when
        eval(true)
    then
    System.out.println("testActive3:ag4");
end

rule "testActive4"
    agenda-group "ag5"
    activation-group "agag1"
    when
        eval(true)
    then
    System.out.println("testActive4:ag5");
end
testActive4:ag5
总共执行了1条规则

第三种情况

kieSession.getAgenda().getAgendaGroup("ag6").setFocus();
rule "testActive5"
    agenda-group "ag6"
    activation-group "agag2"
    when
        eval(true)
    then
    System.out.println("testActive5:ag6");
end

rule "testActive6"
    agenda-group "ag6"
    activation-group "agag3"
    when
        eval(true)
    then
    System.out.println("testActive6:ag6");
end
testActive5:ag6
testActive6:ag6
总共执行了2条规则

第四种情况

kieSession.getAgenda().getAgendaGroup("ag10").setFocus();
rule "testActive7"
    agenda-group "ag6"
    activation-group "agag4"
    when
        eval(true)
    then
    System.out.println("testActive7:ag6");
end

rule "testActive8"
    agenda-group "ag7"
    activation-group "agag5"
    auto-focus true
    when
        eval(true)
    then
    System.out.println("testActive8:ag7");
end
testActive8:ag7
总共执行了1条规则

auto-focus

默认值:true

类型:Boolean

属性说明:auto-focus属性为自动获取焦点,即当前规则是否被激活。如果一个规则被执行,那么认为auto-focus为true;如果单独设置,一般结合agenda-group(在介绍agenda-group时有测试用例),当一个议程组未获取焦点时,可以设置auto-focus来控制。

timer

默认值:无

类型:与Java定时器参数类型相似

属性说明:timer属性是一个定时器,用来控制规则的执行时间,主要有两种写法。

第一种写法的代码为:

timer ( int: <initial delay> <repeat interval>? )
timer ( int: 30s )
timer ( int: 30s 5m )

第二种写法为:

timer ( cron: <cron expression> )
timer ( cron:* 0/15 * * * ? )

还可以设置开始时间和结束时间

timer (int: 30s 10s; start=3-JAN-2018, end=5-JAN-2018)

定时器功能还可以通过变量进行赋值,但需要用到declare声明。例如:

declare Bean
    delay   : String = "30s"
    period  : long = 60000
end

rule "Expression timer"
    timer( expr: $d, $p )
when
    Bean( $d : delay, $p : period )
then
end

Drools入门之规则属性
https://www.zhaojun.inkhttps://www.zhaojun.ink/archives/drools-rule-attribute
作者
卑微幻想家
发布于
2022-06-23
许可协议