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属性会受到其他属性的影响,如下图所示
第一种情况:
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