目录
规则属性 attributes
前面我们已经知道了规则体的构成如下:
rule "ruleName"
attributes
when
LHS
then
RHS
end
Drools中提供的属性如下表(部分属性):
enabled属性
enabled属性对应的取值为true和false,默认值为true。
用于指定当前规则是否启用,如果设置的值为false则当前规则无论是否匹配成功都不会触发
package rules
import com.mashibing.drools.entity.AttributesEnabledEntity
/*
用于测试Drools 属性:enabled
*/
//测试enabled
rule "rule_attributes_enabled"
enabled false
when
AttributesEnabledEntity(num > 10)
then
System.out.println("规则rule_attributes_enabled触发");
end
dialect属性
dialect属性用于指定当前规则使用的语言类型,取值为java和mvel,默认值为java。
注:mvel是一种基于java语法的表达式语言。
虽然mvel吸收了大量的java语法,但作为一个表达式语言,还是有着很多重要的不同之处,以达到更高的效率,比如:mvel像正则表达式一样,有直接支持集合、数组和字符串匹配的操作符。
除了表达式语言外,mvel还提供了用来配置和构造字符串的模板语言。
mvel2.x表达式包含以下部分的内容:属性表达式,布尔表达式,方法调用,变量赋值,函数定义
salience属性
salience属性用于指定规则的执行优先级,取值类型为Integer。数值越大越优先执行。每个规则都有一个默认的执行顺序,如果不设置salience属性,规则体的执行顺序为由上到下。
drl文件内容如下:
package rules
import com.mashibing.drools.entity.AttributesSalienceEntity
/*
用于测试Drools 属性:salience
*/
rule "rule_attributes_salience_1"
when
AttributesSalienceEntity(flag == true)
then
System.out.println("规则 rule_attributes_salience_1 触发");
end
rule "rule_attributes_salience_2"
when
AttributesSalienceEntity(flag == true)
then
System.out.println("规则 rule_attributes_salience_2 触发");
end
rule "rule_attributes_salience_3"
when
AttributesSalienceEntity(flag == true)
then
System.out.println("规则 rule_attributes_salience_3 触发");
end
通过控制台可以看到,由于以上三个规则没有设置salience属性,所以执行的顺序是按照规则文件中规则的顺序由上到下执行的。接下来我们修改一下文件内容:
package rules
import com.mashibing.drools.entity.AttributesSalienceEntity
/*
用于测试Drools 属性:salience
*/
rule "rule_attributes_salience_1"
salience 10
when
AttributesSalienceEntity(flag == true)
then
System.out.println("规则 rule_attributes_salience_1 触发");
end
rule "rule_attributes_salience_2"
salience 20
when
AttributesSalienceEntity(flag == true)
then
System.out.println("规则 rule_attributes_salience_2 触发");
end
rule "rule_attributes_salience_3"
salience 1
when
AttributesSalienceEntity(flag == true)
then
System.out.println("规则 rule_attributes_salience_3 触发");
end
通过控制台可以看到,规则文件执行的顺序是按照我们设置的salience值由大到小顺序执行的。
建议在编写规则时使用salience属性明确指定执行优先级。
no-loop属性
no-loop属性用于防止死循环,当规则通过update之类的函数修改了Fact对象时,可能使当前规则再次被激活从而导致死循环。取值类型为Boolean,默认值为false。测试步骤如下:
第一步:编写规则文件
package rules
import com.mashibing.drools.entity.AttributesNoLoopEntity
/*
用于测试Drools 属性:no-loop
*/
rule "rule_attributes_noloop"
//no-loop true
when
$attributesNoLoopEntity:AttributesNoLoopEntity(num > 1)
then
update($attributesNoLoopEntity)
System.out.println("规则 rule_attributes_noloop 触发");
end
第二步:编写单元测试
@Test
public void test(){
KieSession kieSession = kieBase.newKieSession();
AttributesNoLoopEntity attributesNoLoopEntity = new AttributesNoLoopEntity();
attributesNoLoopEntity.setNum(20);
kieSession.insert(attributesNoLoopEntity);
kieSession.fireAllRules();
kieSession.dispose();
}
通过控制台可以看到,由于我们没有设置no-loop属性的值,所以发生了死循环。接下来设置no-loop的值为true再次测试则不会发生死循环。
lock-on-active属性
lock-on-active这个属性,可以限制当前规则只会被执行一次,包括当前规则的重复执行不是本身触发的。取值类型为Boolean,默认值为false。测试步骤如下:
第一步:编写规则文件
```java
package rules
import com.mashibing.drools.entity.AttributesLockOnActiveEntity
/*
用于测试Drools 属性:lock-on-active
*/
rule "rule_attributes_lock_on_active_1"
no-loop true
when
$attributesLockOnActiveEntity:AttributesLockOnActiveEntity(num > 1)
then
update($attributesLockOnActiveEntity)
System.out.println("规则 rule_attributes_lock_on_active_1 触发");
end
rule "rule_attributes_lock_on_active_2"
no-loop true
lock-on-active true
when
$attributesLockOnActiveEntity:AttributesLockOnActiveEntity(num > 1)
then
update($attributesLockOnActiveEntity)
System.out.println("规则 rule_attributes_lock_on_active_2 触发");
end
```
第二步:编写单元测试
```java
@Test
public void test(){
KieSession kieSession = kieBase.newKieSession();
AttributesLockOnActiveEntity attributesLockOnActiveEntity = new AttributesLockOnActiveEntity();
attributesLockOnActiveEntity.setNum(20);
kieSession.insert(attributesLockOnActiveEntity);
kieSession.fireAllRules();
kieSession.dispose();
}
```
no-loop的作用是限制因为modify等更新操作导致规则重复执行,但是有一个限定条件,是当前规则中进行更新导致当前规则重复执行。而不是防止其他规则更新相同的fact对象,导致当前规则更新,lock-on-active可以看作是no-loop的加强版,不仅能限制自己的更新,还能限制别人的更新造成的死循环。
activation-group属性
activation-group属性是指激活分组,取值为String类型。具有相同分组名称的规则只能有一个规则被触发。
第一步:编写规则文件
```java
package rules
import com.mashibing.drools.entity.AttributesActivationGroupEntity
/*
用于测试Drools 属性: activation-group
*/
rule "rule_attributes_activation_group_1"
activation-group "customGroup"
when
$attributesActivationGroupEntity:AttributesActivationGroupEntity(num > 1)
then
System.out.println("规则 rule_attributes_activation_group_1 触发");
end
rule "rule_attributes_activation_group_2"
activation-group "customGroup"
when
$attributesActivationGroupEntity:AttributesActivationGroupEntity(num > 1)
then
System.out.println("规则 rule_attributes_activation_group_2 触发");
end
```
第二步:编写单元测试
```java
@Test
public void test(){
KieSession kieSession = kieBase.newKieSession();
AttributesActivationGroupEntity attributesActivationGroupEntity = new AttributesActivationGroupEntity();
attributesActivationGroupEntity.setNum(20);
kieSession.insert(attributesActivationGroupEntity);
kieSession.fireAllRules();
kieSession.dispose();
}
```
通过控制台可以发现,上面的两个规则因为属于同一个分组,所以只有一个触发了。同一个分组中的多个规则如果都能够匹配成功,具体哪一个最终能够被触发可以通过salience属性确定。
agenda-group属性
agenda-group属性为议程分组,属于另一种可控的规则执行方式。用户可以通过设置agenda-group来控制规则的执行,只有获取焦点的组中的规则才会被触发。
第一步:编写规则文件
```java
package rules
import com.mashibing.drools.entity.AttributesAgendaGroupEntity
/*
用于测试Drools 属性: agenda-group
*/
rule "rule_attributes_agenda_group_1"
agenda-group "customAgendaGroup1"
when
$attributesAgendaGroupEntity:AttributesAgendaGroupEntity(num > 1)
then
System.out.println("规则 rule_attributes_agenda_group_1 触发");
end
rule "rule_attributes_agenda_group_2"
agenda-group "customAgendaGroup1"
when
$attributesAgendaGroupEntity:AttributesAgendaGroupEntity(num > 1)
then
System.out.println("规则 rule_attributes_agenda_group_2 触发");
end
rule "rule_attributes_activation_group_3"
agenda-group "customAgendaGroup2"
when
$attributesAgendaGroupEntity:AttributesAgendaGroupEntity(num > 1)
then
System.out.println("规则 rule_attributes_activation_group_3 触发");
end
rule "rule_attributes_agenda_group_4"
agenda-group "customAgendaGroup2"
when
$attributesAgendaGroupEntity:AttributesAgendaGroupEntity(num > 1)
then
System.out.println("规则 rule_attributes_agenda_group_4 触发");
end
```
第二步:编写单元测试
``