规则属性是用来控制规则执行的重要工具,在前面举出的关于规则的例子当中,已经接触了如控制规则执行优先级的 salience,和是否允许规则执行一次的 no-loop。在目前 的
Drools5 当中,规则的属性共有 13 个,
它们分别是:
activation-group、agenda-group、 auto-focus、date-effective、date-expires、dialect、duration、enabled、lock-on-active、no-loop、 ruleflow-group、salience、when
这些属性分别适用于不同的场景,下面我们就来分别介绍 这些属性的含义及用法。
salience
作用是用来设置规则执行的优先级, salience 属性的值是一个数字,数字越大执行优先级越高,同时它的值可以是一个负数。默认情况下,规则的 salience 默认值为 0,所以如果我们不手动设置规则的 salience 属性,那么它的执行顺序是随机的。
no-loop
在一个规则当中如果条件满足就对 Working Memory 当中的某个 Fact 对象进行了修改, 比如使用 update 将其更新到当前的 Working Memory 当中,这时引擎会再次检查所有的规则是否满足条件,如果满足会再次执行,可能出现死循环的。如何避免这种情况呢,这时可以引入 no-loop 属性来解决这个问题。no-loop 属性的作用 是用来控制已经执行过的规则在条件再次满足时是否再次执行,no-loop 属性的值是一个布尔型,默认情况下规则的 no-loop 属性的值为 false,如果 no-loop 属性值为 true,那么就表示该规则只会被引擎检查一次,如果满足条件就执行规则的 RHS 部分,注意:如果引擎内部因为对 Fact 更新引起引擎再次启动检查规则,那么它会忽略掉所有的 no-loop 属性设置为 true 的规则。
例如以下写法
date-effective
该属性是用来控制规则只有在到达后才会触发,在规则运行时,引擎会自动拿当前操作系统的时候与date-effective设置的时间值进行比对,只有
当系统时间
>=
date-effective设置的时间值时,规则才会触发执行,否则执行将不执行。
在没有设置该属性的情况下,规则随时可以触发,没有这种限制。
date-effective 的值为一个日期型的字符串,默认情况下,date-effective 可接受的日期格式为“dd-MMM-yyyy”,例如 2009 年 9 月 25 日在设置为 date-effective 的值时,
如果的操作系统为英文的,那么应该写成“25-Sep-2009”;如果是中文操作系统“25-九月-2009" 举例说明: 注当前日期是
所以该规则不会被触发。
结果
date-expires
该属性的作用与 date-effective 属性恰恰相反(注:当前系统时间<date-expires 值), date-expires 的作用是用来设置规则的有 效期,引擎在执行规则的时候,会检查规则有没有 date-expires 属性,如果有的话,那么会将这个属性的值与当前系统时间进行比对,如果
大于系统时间,
那么规则就执行,否则就不执行。该属性的值同样也是一个日期类型,默认格式也是“dd-MMM-yyyy”,具体用法与 date-effective 属性相同。
如何写成java 传统的日期格式呢
System.setProperty("drools.dateformat", "yyyy-MM-dd HH:mm:ss"); 时分秒可加可不加
但要注意的是,在进行规则引擎格式化日期的时候,最好是将其写在初始化kie相关代码之前 例如
enabled
enabled 属性比较简单,它是用来定义一个规则是否可用的。该属性的值是一个布尔值, 默认该属性的值为 true,表示规则是可用的,如果手工为一个规则添加一个enabled 属性, 并且
设置其 enabled属性值为 false,那么引擎就
不会执行该规则。
dialect
该属性用来定义规则当中要使用的语言类型,在drools5与drools6.4版本中,支持两种类型的语言mvel 和 java,官方举例也是按这两种类型的语言举例说明的。默认情况下,如果没有手工设置规则的 dialect,那么使用的 java 语言,用的不多。作为了解
duration
对于一个规则来说,如果设置了该属性,那么
规则将在该属性指定的值
之后
在另外一个线程里触发。该属性对应的值为一个长整型,单位是毫秒 通过mian方法测试 现在已经过期了,在定时器章节中有详细的说明http://blog.csdn.net/u013115157/article/details/52486944
lock-on-active
当在规则上使用
ruleflow-group属性或
agenda-group属性的时候,
将lock-on-action属性的值设置为 true,
可能避免因某些 Fact 对象被修改而使已经执行过的规则再次被激活执行。 可以看出该属性与 no-loop 属性有相似之处,no-loop 属性是为了避免 Fact 修改或调用 了 insert、retract、update 之类而导致规则再次激活执行,这里的lock-on-action 属性也是起这个作用,lock-on-active 是 no-loop 的
增强版属性,它主要作用在使用ruleflow-group属性或agenda-group属性的时候。lock-on-active 属性默认值为 false。
activation-group
该属性的
作用是将若干个规则划分成一个组,用一个字符串来给这个组命名,这样在执行的时候,具有相同 activation-group 属性的规则中只要有一个会被执行,其它的规则都将不再执行。也就是说,在一组具有相同 activation-group属性的规则当中,只有一个规则会被执行,其它规则都将不会被执行。当然对于具有相同activation-group属性的规则当中究 竟哪一个会先执行,则可以用salience之类属性来实现。
agenda-group
规则的调用与执行是通过 StatelessSession 或
ksession
来实现的
,一般的顺序是创建一个StatelessSession 或
ksession
,将各种经过编译的规则的
package添加到session当中
,接下来将规则当中可能用到的Global对象和Fact对象插入到Session当中,最后调用 fireAllRules 方法来触发、执行规则。在没有调用最后一步 fireAllRules 方法之前,所有的规则及插入的 Fact 对象都存放在一个名叫
Agenda 表的对象当中
,这个Agenda 表中每一个规则及与其匹配相关业务数据叫做Activation,在调用 fireAllRules 方法后,这些 Activation会依次执行,这些位于Agenda表中的Activation的执行顺序在没有设置相关用来控制顺序的属性时(比如 salience 属性),它的执行顺序是随机的,不确定的。
Agenda Group是用来在Agenda的基础之上,对现在的规则进行再次分组,具体的分组方法可以采用为规则添加 agenda-group 属性来实现
agenda-group 属性的值也是一个字符串,通过这个字符串,可以将规则分为若干个 Agenda Group,默认情况下,引擎在调用这些设置了 agenda-group 属性的规则的时候需要显示的
指定某个 Agenda Group 得到 Focus(焦点),这样位于该 Agenda Group 当中的规则会才触发执行,否则将不执行。
例如: java代码
Drl代码
结果如我们想像的一样。。 会输出rule2的结果。因为rule1没有获取到焦点。所以不会输出rule1的结果
实际应用当中
agenda-group 可以和 auto-focus 属性一起使用,这样就不会在代码当中显示的为某个 Agenda Group 设置 Focus 了。一旦将某个规则的 auto-focus 属性设置为 true,那么即使该规则设置了 agenda-group 属性,我们也不需要在代码当中显示的设置 Agenda Group 的 Focus 了。
注:当加入
activation-group时同一组的Focus相同时,只会执行其中一个。执行方式从上至下。
同一组的Fouus不同时,只会执行其中一个。执行方式是最后一个获取焦点的规则
不同组的Focus相同时,会执行多个规则,但只要获取Focus的才会执行
不同组的Focus不同时,会执行多个,但执行方式是从最后一个获取焦点的规则开始
例如
则输出的结果是
auto-focus
前面我们也提到 auto-focus 属性,它的作用是用来在已设置了 agenda-group 的规则上设置该规则是否可以自动读取 Focus,如果该属性设置为true,那么在引擎执行时,就不需要显示的为某个 Agenda Group 设置 Focus,否则需要。
但将
auto-focus 设置成true 再通过agenda-group 指定Focus 则 agenda-group 不生效
如果在规则中加入
activation-group时则会进行分组,但结果会根据
auto-focus及when条件进行判定。
对于规则的执行的控制,还可以使用 Agenda Filter 来实现。在 Drools 当中,提供了一 个名为 org.drools.runtime.rule.AgendaFilter 的 Agenda Filter 接口,用户可以实现该接口,通过规则当中的某些属性来控制规则要不要执行。org.drools.runtime.rule.AgendaFilter 接口只有 一个方法需要实现
方法体如下:
public boolean accept(Match match);
在该方法当中提供了一个
Match 参数,通过该参数我们可以得到当前正在执行的规 则对象或其它一些属性,该方法要返回一个布尔值,该布尔值就决定了要不要执行当前这个规则,返回 true 就执行规则,否则就不执行。
具体java代码代码
drl文件
查看输出结果
ruleflow-group
在使用规则流的时候要用到 ruleflow-group属性,该属性的值为一个字符串,作用是用来将规则划分为一个个的组,然后在规则流当中通过使用 ruleflow-group 属性的值,从而使用对应的规则,该属性会通过流程的走向确定要执行哪一条规则。在规则流中有具体的说明
详细的语言 请参考:http://blog.csdn.net/u013115157/article/details/52487726
下面是小编的微信转帐二维码,小编再次谢谢读者的支持,小编会更努力的
----请看下方↓↓↓↓↓↓↓
百度搜索 Drools从入门到精通:可下载开源全套Drools教程
深度Drools教程不段更新中:
更多Drools实战陆续发布中………
扫描下方二维码关注公众号 ↓↓↓↓↓↓↓↓↓↓