计算机系统应用教程网站

网站首页 > 技术文章 正文

开启灵活开发编码模式:规则引擎drools——规则属性

btikc 2024-11-16 17:20:35 技术文章 1 ℃ 0 评论

接下来一起去学习下drools规则属性,通过前面的学习了解了规则体相关的内容。

规则属性

  • ① 规则文件的构成

rule 定义规则体的开始,后面跟的规则名称,后面在跟的是规则的属性,前面的专题实例没有提到过属性,后面when 跟的LHS,then跟的RHS部分,end结束。

rule "ruleName"
    attributes
    when
        LHS
    then
        RHS
end

这个章节主要说的属性,attributes出现的位置就是rule 和 when之间的。

部分常用的属性

  • ② enabled属性

enabled属性对应的取值为true和false,默认值为true。用于指定当前规则是否启用,如果设置的值为false则当前规则无论是否匹配成功都不会触发。

  • ③ dialect属性

dialect属性用于指定当前规则使用的语言类型,取值为java和mvel,默认值为java。
注:mvel是一种基于java语法的表达式语言。
mvel像正则表达式一样,有直接支持集合、数组和字符串匹配的操作符。
mvel还提供了用来配置和构造字符串的模板语言。
mvel表达式内容包括属性表达式,布尔表达式,方法调用,变量赋值,函数定义等。

mvel本专题不会展开,主要是通过java的方式。

  • ④ salience属性

前面也接触到,salience属性用于指定规则的执行优先级,执行的顺序,取值类型为Integer。数值越大越优先执行。每个规则都有一个默认的执行顺序,如果不设置salience属性,规则体的执行顺序为由上到下。可以通过创建规则文件salience.drl来测试salience属性。

没有设置优先级的情况是这样执行的。

设置了优先级的情况下是这样的。数值越大,越先执行。

  • ⑤ no-loop属性

no-loop属性用于防止死循环,当规则通过update之类的函数修改了Fact对象时,可能使当前规则再次被激活从而导致死循环。取值类型为Boolean,默认值为false。

调用update方法、 insert方法、retract方法 重新匹配容易产生死循环


解决方法:通过控制台可以看到,由于我们没有设置no-loop属性的值,所以发生了死循环。接下来设置no-loop的值为true再次测试则不会发生死循环。

注意:no-loop解决不了多规则文件间的死循环。

  • ⑥ activation-group属性

激活分组,取值为String类型。具有相同分组名称的规则只能有一个规则被触发。规则分组后,只执行一个。

不加入activation-group分组的话,两个都执行

加入分组后,看看执行情况,只执行了一条

这个属性添加后只执行一条可以理解,但是为什么只执行了上面的不执行下面这个,可以这样解释,在没有设置优先级的情况下,它的执行规则是从上往下来进行执行的。

上面的两个规则因为属于同一个分组,所以只有一个触发了。同一个分组中的多个规则如果都能够匹配成功,具体哪一个最终能够被触发可以通过salience属性确定。

  • ⑦ agenda-group属性

议程分组,属于另一种可控的规则执行方式。用户可以通过设置agenda-group来控制规则的执行,只有获取焦点的组中的规则才会被触发。说白了需要在代码里面获取指定的名称的分组,这样组才能被触发。

进行分组

单元测试代码
//设置焦点,对应agenda-group分组中的规则才可能被触发
kieSession.getAgenda().getAgendaGroup(“myagendagroup_1”).setFocus();

执行结果

只有获取焦点的分组中的规则才会触发。与activation-group不同的是,activation-group定义的分组中只能够有一个规则可以被触发,而agenda-group分组中的多个规则都可以被触发。如果when不满足,就算设置了焦点也不执行。

  • ⑧ auto-focus属性

自动获取焦点,取值类型为Boolean,默认值为false。一般结合agenda-group属性使用,当一个议程分组未获取焦点时,可以设置auto-focus属性来控制。

drl文件中设置自动获取焦点的属性。

置auto-focus属性为true的规则都触发了。不用java的方式。

如果规则属于同一个组,写一个auto-focus就可以了,也就是说同一组只有有一个设置了auto-focus等于true,其他都会设置对应的焦点,不管是设置了false 还是不设置。但是可读性可能不太好,建议都写,方便阅读。

  • ⑨ timer属性

timer属性可以通过定时器的方式指定规则执行的时间,使用方式有两种:

方式一:timer (int: ?)

此种方式遵循java.util.Timer对象的使用方式,第一个参数表示几秒后执行,第二个参数表示每隔几秒执行一次,第二个参数为可选。

方式二:timer(cron: )

此种方式使用标准的unix cron表达式的使用方式来定义规则执行的时间。

规则文件编写drl

指定代码,必须修改。因为目前是通过单元测试来运行的,如果是tomcat容器就不存在这个问题了。

运行规则

  • ⑩ date-effective

属性用于指定规则的生效时间,即只有当前系统时间大于等于设置的时间或者日期规则才有可能触发。默认日期格式为:dd-MMM-yyyy。用户也可以自定义日期格式。

规则文件编写drl

java编写

上面的代码需要设置日期格式,否则我们在规则文件中写的日期格式和默认的日期格式不匹配程序会报错。

  • ? date-expires

date-expires属性用于指定规则的失效时间,即只有当前系统时间小于设置的时间或者日期规则才有可能触发。默认日期格式为:dd-MMM-yyyy。用户也可以自定义日期格式。跟上边类似,只是这个是失效时间。

java编写


上面的代码需要设置日期格式,否则我们在规则文件中写的日期格式和默认的日期格式不匹配程序会报错。

PS: drools的规则文件已经讲解完毕,只是介绍了常用的,有些特殊的在特殊场景才使用。

Tags:

本文暂时没有评论,来添加一个吧(●'◡'●)

欢迎 发表评论:

最近发表
标签列表