drools规则引擎规则属性(八)

1,通过前面的学习,我们知道drools规则引擎的格式如下:

rule "ruleName"
    attributes
    when
        LHS
    then
        RHS
end

本章节就是针对规则体的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则当前规则无论是否匹配成功都不会触发。

定义规则文件

package rules;
import  com.dream21th.drools.study.demo5.Student;

rule "demo5_enabled_1"
    enabled false
    when
       $s:Student( age==10)
    then
       $s.setAge(20);
       update($s)
       System.out.println("触发demo5_enabled_1:年龄等于"+$s.getAge());
end

rule "demo5_enabled_2"
    enabled true
    when
       $s:Student( age==10)
    then
       $s.setAge(20);
       update($s)
       System.out.println("触发demo5_enabled_2:年龄等于"+$s.getAge());
end

定义测试类

@Test
public void test_enabled(){
    KieServices kieServices = KieServices.Factory.get();
    KieContainer kieClasspathContainer = kieServices.getKieClasspathContainer();
    //会话对象,用于和规则引擎交互
    KieSession kieSession = kieClasspathContainer.newKieSession();

    Student student= Student.builder().age(10).build();
    kieSession.insert(student);

    //激活规则引擎,如果规则匹配成功则执行规则
    kieSession.fireAllRules(new RuleNameStartsWithAgendaFilter("demo5_enabled"));

    System.out.println(student);
    //关闭会话
    kieSession.dispose();
}

测试结果

触发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属性,内容如下:

package rules;

rule "demo5-salience_1"
    salience 10
    when
        eval(true)
    then
        System.out.println("规则demo5-salience_1触发");
end

rule "demo5-salience_2"
    salience 20
    when
        eval(true)
    then
        System.out.println("规则demo5-salience_2触发");
end

rule "demo5-salience_3"
    salience 12
    when
        eval(true)
    then
        System.out.println("规则demo5-salience_3触发");
end

创建测试类

@Test
public void demo5_salience(){
    KieServices kieServices = KieServices.Factory.get();
    KieContainer kieClasspathContainer = kieServices.getKieClasspathContainer();
    //会话对象,用于和规则引擎交互
    KieSession kieSession = kieClasspathContainer.newKieSession();

    Student student= Student.builder().age(10).build();
    kieSession.insert(student);

    //激活规则引擎,如果规则匹配成功则执行规则
    kieSession.fireAllRules(new RuleNameStartsWithAgendaFilter("demo5-salience"));

    System.out.println(student);
    //关闭会话
    kieSession.dispose();
}

执行结果

规则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。测试步骤如下:

编写规则文件

package rules;
import  com.dream21th.drools.study.demo5.Student;

rule "demo5_noloop_1"
    no-loop true  //注意此处如果没有设置no_loop为true会导致死循环
    when
       $s:Student( age==10)
    then
       update($s)
       System.out.println("触发demo5_enabled_1:年龄等于"+$s.getAge());
end

编写测试方法

@Test
public void test_noloop(){
    KieServices kieServices = KieServices.Factory.get();
    KieContainer kieClasspathContainer = kieServices.getKieClasspathContainer();
    //会话对象,用于和规则引擎交互
    KieSession kieSession = kieClasspathContainer.newKieSession();

    Student student= Student.builder().age(10).build();
    kieSession.insert(student);

    //激活规则引擎,如果规则匹配成功则执行规则
    kieSession.fireAllRules(new RuleNameStartsWithAgendaFilter("demo5_noloop"));

    System.out.println(student);
    //关闭会话
    kieSession.dispose();
}

测试结果

触发demo5_noloop_1:年龄等于10
Student(name=null, result=null, age=10, sex=null, subjects=null)

注意:如果规则文件中没有添加no_loop为true,会导致死循环

 

6 activation-group属性

activation-group属性是指激活分组,取值为String类型。具有相同分组名称的规则只能有一个规则被触发。

编写规则文件

package rules;
import  com.dream21th.drools.study.demo5.Student;

rule "demo5_activationgroup_1"
    activation-group "demo5_activationgroup"
    when
       $s:Student( age==10)
    then
       System.out.println("触发demo5_activationgroup_1:年龄等于"+$s.getAge());
end

rule "demo5_activationgroup_2"
    activation-group "demo5_activationgroup"
    when
       $s:Student( age==10)
    then
       System.out.println("触发demo5_activationgroup_2:年龄等于"+$s.getAge());
end

rule "demo5_activationgroup_3"
    activation-group "demo5_activationgroup"
    when
       $s:Student( age==10)
    then
       System.out.println("触发demo5_activationgroup_3:年龄等于"+$s.getAge());
end

编写测试方法

@Test
public void test_activationgroup(){
    KieServices kieServices = KieServices.Factory.get();
    KieContainer kieClasspathContainer = kieServices.getKieClasspathContainer();
    //会话对象,用于和规则引擎交互
    KieSession kieSession = kieClasspathContainer.newKieSession();

    Student student= Student.builder().age(10).build();
    kieSession.insert(student);

    //激活规则引擎,如果规则匹配成功则执行规则
    kieSession.fireAllRules(new RuleNameStartsWithAgendaFilter("demo5_activationgroup"));

    System.out.println(student);
    //关闭会话
    kieSession.dispose();
}

测试结果

触发demo5_activationgroup_1:年龄等于10
Student(name=null, result=null, age=10, sex=null, subjects=null)

由测试结果可知,相同的规则组,相同的触发条件,只触发一条数据。

7 agenda-group属性

agenda-group属性为议程分组,属于另一种可控的规则执行方式。用户可以通过设置agenda-group来控制规则的执行,只有获取焦点的组中的规则才会被触发。

编写规则

package rules;
import  com.dream21th.drools.study.demo5.Student;

rule "demo5_agendagroup_1"
    agenda-group "demo5_agendagroup"
    when
       $s:Student( age==10)
    then
       System.out.println("触发demo5_agendagroup_1:年龄等于"+$s.getAge());
end

rule "demo5_agendagroup_2"
    agenda-group "demo5_agendagroup"
    when
       $s:Student( age==10)
    then
       System.out.println("触发demo5_agendagroup_2:年龄等于"+$s.getAge());
end

rule "demo5_agendagroup_3"
    agenda-group "demo5_agendagroup"
    when
       $s:Student( age==10)
    then
       System.out.println("触发demo5_agendagroup_3:年龄等于"+$s.getAge());
end

编写测试方法

@Test
public void test_agendagroup(){
    KieServices kieServices = KieServices.Factory.get();
    KieContainer kieClasspathContainer = kieServices.getKieClasspathContainer();
    //会话对象,用于和规则引擎交互
    KieSession kieSession = kieClasspathContainer.newKieSession();

    Student student= Student.builder().age(10).build();
    kieSession.insert(student);

    //设置焦点,对应agenda-group分组中的规则才可能被触发
    kieSession.getAgenda().getAgendaGroup("demo5_agendagroup").setFocus();

    //激活规则引擎,如果规则匹配成功则执行规则
    kieSession.fireAllRules(new RuleNameStartsWithAgendaFilter("demo5_agendagroup"));

    System.out.println(student);
    //关闭会话
    kieSession.dispose();
}

测试结果

触发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属性来控制。

编写规则:

package rules;
import  com.dream21th.drools.study.demo5.Student;

rule "demo5_agendagroup_autofocus_1"
    agenda-group "demo5_agendagroup_autofocus_1"
    when
       $s:Student( age==10)
    then
       System.out.println("触发demo5_agendagroup_autofocus_1:年龄等于"+$s.getAge());
end

rule "demo5_agendagroup_autofocus_2"
    agenda-group "demo5_agendagroup_autofocus_1"
    when
       $s:Student( age==10)
    then
       System.out.println("触发demo5_agendagroup_autofocus_2:年龄等于"+$s.getAge());
end

rule "demo5_agendagroup_autofocus_3"
    agenda-group "demo5_agendagroup_autofocus_2"
    auto-focus true
    when
       $s:Student( age==10)
    then
       System.out.println("触发demo5_agendagroup_autofocus_3:年龄等于"+$s.getAge());
end

编写测试方法

@Test
public void test_agendagroup_autofocus(){
    KieServices kieServices = KieServices.Factory.get();
    KieContainer kieClasspathContainer = kieServices.getKieClasspathContainer();
    //会话对象,用于和规则引擎交互
    KieSession kieSession = kieClasspathContainer.newKieSession();

    Student student= Student.builder().age(10).build();
    kieSession.insert(student);

    //激活规则引擎,如果规则匹配成功则执行规则
    kieSession.fireAllRules(new RuleNameStartsWithAgendaFilter("demo5_agendagroup_autofocus"));

    System.out.println(student);
    //关闭会话
    kieSession.dispose();
}

测试结果

触发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: <initial delay> <repeat interval>?)

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

方式二:timer(cron: <cron expression>)

此种方式使用标准的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

  • 0
    点赞
  • 1
    收藏
    觉得还不错? 一键收藏
  • 打赏
    打赏
  • 0
    评论

“相关推荐”对你有帮助么?

  • 非常没帮助
  • 没帮助
  • 一般
  • 有帮助
  • 非常有帮助
提交
评论
添加红包

请填写红包祝福语或标题

红包个数最小为10个

红包金额最低5元

当前余额3.43前往充值 >
需支付:10.00
成就一亿技术人!
领取后你会自动成为博主和红包主的粉丝 规则
hope_wisdom
发出的红包

打赏作者

dream21st

你的鼓励将是我创作的最大动力

¥1 ¥2 ¥4 ¥6 ¥10 ¥20
扫码支付:¥1
获取中
扫码支付

您的余额不足,请更换扫码支付或充值

打赏作者

实付
使用余额支付
点击重新获取
扫码支付
钱包余额 0

抵扣说明:

1.余额是钱包充值的虚拟货币,按照1:1的比例进行支付金额的抵扣。
2.余额无法直接购买下载,可以购买VIP、付费专栏及课程。

余额充值