1,通过前面的学习,我们知道drools规则引擎的格式如下:
|
本章节就是针对规则体的attributes属性部分进行讲解。Drools中提供的属性如下表(部分属性):
属性名 | 说明 |
---|---|
salience | 指定规则执行优先级 |
dialect | 指定规则使用的语言类型,取值为java和mvel |
enabled | 指定规则是否启用 |
date-effective | 指定规则生效时间 |
date-expires | 指定规则失效时间 |
activation-group | 激活分组,具有相同分组名称的规则只能有一个规则触发 |
agenda-group | 议程分组,只有获取焦点的组中的规则才有可能触发 |
timer | 定时器,指定规则触发的时间 |
auto-focus | 自动获取焦点,一般结合agenda-group一起使用 |
no-loop | 防止死循环 |
2, enabled属性
enabled属性对应的取值为true和false,默认值为true。
用于指定当前规则是否启用,如果设置的值为false则当前规则无论是否匹配成功都不会触发。
定义规则文件
|
定义测试类
|
测试结果
触发demo5_enabled_2:年龄等于20 Student(name=null, result=null, age=20, sex=null, subjects=null) |
由上述执行结果可以看出,enabled属性值为false,即使满足条件也不会触发规则;
3,,dialect属性
dialect属性用于指定当前规则使用的语言类型,取值为java和mvel,默认值为java。
注:mvel是一种基于java语法的表达式语言。
mvel像正则表达式一样,有直接支持集合、数组和字符串匹配的操作符。
mvel还提供了用来配置和构造字符串的模板语言。
mvel表达式内容包括属性表达式,布尔表达式,方法调用,变量赋值,函数定义等。
4,salience属性
salience属性用于指定规则的执行优先级,取值类型为Integer。数值越大越优先执行。每个规则都有一个默认的执行顺序,如果不设置salience属性,规则体的执行顺序为由上到下。
可以通过创建规则文件salience.drl来测试salience属性,内容如下:
|
创建测试类
|
执行结果
规则demo5-salience_2触发 规则demo5-salience_3触发 规则demo5-salience_1触发 Student(name=null, result=null, age=10, sex=null, subjects=null) |
通过控制台可以看到,规则文件执行的顺序是按照我们设置的salience值由大到小顺序执行的。
建议在编写规则时使用salience属性明确指定执行优先级。
5,no-loop属性
no-loop属性用于防止死循环,当规则通过update之类的函数修改了Fact对象时,可能使当前规则再次被激活从而导致死循环。取值类型为Boolean,默认值为false。测试步骤如下:
编写规则文件
|
编写测试方法
|
测试结果
触发demo5_noloop_1:年龄等于10 Student(name=null, result=null, age=10, sex=null, subjects=null) |
注意:如果规则文件中没有添加no_loop为true,会导致死循环
6 activation-group属性
activation-group属性是指激活分组,取值为String类型。具有相同分组名称的规则只能有一个规则被触发。
编写规则文件
|
编写测试方法
|
测试结果
触发demo5_activationgroup_1:年龄等于10 Student(name=null, result=null, age=10, sex=null, subjects=null) |
由测试结果可知,相同的规则组,相同的触发条件,只触发一条数据。
7 agenda-group属性
agenda-group属性为议程分组,属于另一种可控的规则执行方式。用户可以通过设置agenda-group来控制规则的执行,只有获取焦点的组中的规则才会被触发。
编写规则
|
编写测试方法
|
测试结果
触发demo5_agendagroup_1:年龄等于10 触发demo5_agendagroup_2:年龄等于10 触发demo5_agendagroup_3:年龄等于10 Student(name=null, result=null, age=10, sex=null, subjects=null) |
通过控制台可以看到,只有获取焦点的分组中的规则才会触发。与activation-group不同的是,activation-group定义的分组中只能够有一个规则可以被触发,而agenda-group分组中的多个规则都可以被触发。
8 auto-focus属性
auto-focus属性为自动获取焦点,取值类型为Boolean,默认值为false。一般结合agenda-group属性使用,当一个议程分组未获取焦点时,可以设置auto-focus属性来控制。
编写规则:
|
编写测试方法
|
测试结果
触发demo5_agendagroup_autofocus_3:年龄等于10 Student(name=null, result=null, age=10, sex=null, subjects=null) |
由测试结果可知,代码中没有显示的调用setFocus方法,但规则文件中设置为auto-focus true 触发了
9 timer属性
timer属性可以通过定时器的方式指定规则执行的时间,使用方式有两种:
方式一:timer (int:
此种方式遵循java.util.Timer对象的使用方式,第一个参数表示几秒后执行,第二个参数表示每隔几秒执行一次,第二个参数为可选。
方式二:timer(cron:
此种方式使用标准的unix cron表达式的使用方式来定义规则执行的时间。
创建规则文件
package rules; import java.text.SimpleDateFormat import java.util.Date /* 此规则文件用于测试timer属性 */ rule "demo5_timer_1" timer (5s 2s) //含义:5秒后触发,然后每隔2秒触发一次 when then System.out.println("规则demo5_timer_1触发,触发时间为:" + new SimpleDateFormat("yyyy-MM-dd HH:mm:ss").format(new Date())); end rule "demo5_timer_2" timer (cron:0/1 * * * * ?) //含义:每隔1秒触发一次 when then System.out.println("规则demo5_timer_2触发,触发时间为:" + new SimpleDateFormat("yyyy-MM-dd HH:mm:ss").format(new Date())); end |
创建测试方法
@Test public void test_timer() throws InterruptedException { KieServices kieServices = KieServices.Factory.get(); KieContainer kieClasspathContainer = kieServices.getKieClasspathContainer(); //会话对象,用于和规则引擎交互 final KieSession kieSession = kieClasspathContainer.newKieSession(); new Thread(new Runnable() { public void run() { //启动规则引擎进行规则匹配,直到调用halt方法才结束规则引擎 kieSession.fireUntilHalt(new RuleNameStartsWithAgendaFilter("demo5_timer")); } }).start(); Thread.sleep(10000); //结束规则引擎 kieSession.halt(); kieSession.dispose(); } |
注意:单元测试的代码和以前的有所不同,因为我们规则文件中使用到了timer进行定时执行,需要程序能够持续一段时间才能够看到定时器触发的效果。
10 date-effective属性
date-effective属性用于指定规则的生效时间,即只有当前系统时间大于等于设置的时间或者日期规则才有可能触发。默认日期格式为:dd-MMM-yyyy。用户也可以自定义日期格式。
定义规则文件
package rules; import java.text.SimpleDateFormat import java.util.Date /* 此规则文件用于测试date-expires属性 */ rule "demo5_dateexpires_1" date-expires "2019-10-01 10:00" when then System.out.println("规则demo5_dateexpires_1触发"); end |
定义测试方法
@Test public void test_dateeffective(){ //设置日期格式 System.setProperty("drools.dateformat","yyyy-MM-dd HH:mm"); KieServices kieServices = KieServices.Factory.get(); KieContainer kieClasspathContainer = kieServices.getKieClasspathContainer(); KieSession kieSession = kieClasspathContainer.newKieSession(); kieSession.fireAllRules(new RuleNameStartsWithAgendaFilter("demo5_dateeffective")); kieSession.dispose(); } |
测试结果
无规则触发
注意:上面的代码需要设置日期格式,否则我们在规则文件中写的日期格式和默认的日期格式不匹配程序会报错。
11date-expires属性
date-expires属性用于指定规则的失效时间,即只有当前系统时间小于设置的时间或者日期规则才有可能触发。默认日期格式为:dd-MMM-yyyy。用户也可以自定义日期格式。
定义规则文件
package rules; import java.text.SimpleDateFormat import java.util.Date /* 此规则文件用于测试date-expires属性 */ rule "demo5_dateexpires_1" date-expires "2019-10-01 10:00" when then System.out.println("规则demo5_dateexpires_1触发"); end |
测试方法
@Test public void test_dateexpires(){ //设置日期格式 System.setProperty("drools.dateformat","yyyy-MM-dd HH:mm"); KieServices kieServices = KieServices.Factory.get(); KieContainer kieClasspathContainer = kieServices.getKieClasspathContainer(); KieSession kieSession = kieClasspathContainer.newKieSession(); kieSession.fireAllRules(new RuleNameStartsWithAgendaFilter("demo5_dateexpires")); kieSession.dispose(); } |
注意:上面的代码需要设置日期格式,否则我们在规则文件中写的日期格式和默认的日期格式不匹配程序会报错。
代码地址:https://gitee.com/dream21th/drools-study/tree/master/demo5