Drools规则属性

本文详细介绍了Drools规则引擎中的几个关键属性,如enable/enabled控制规则启用,dialect选择语言类型,salience设置执行优先级,no-loop防止死循环,以及activation-group、agenda-group和auto-focus用于规则分组和执行控制。还涵盖了timer和日期有效/过期属性,展示了如何配置定时规则和时间触发规则的执行。

摘要生成于 C知道 ,由 DeepSeek-R1 满血版支持, 前往体验 >

1、enable属性

enabled属性对应的取值为true和false,默认值为true。

用于指定当前规则是否启用,如果设置的值为false则当前规则无论是否匹配成功都不会触发。

rule "rule_comparison_notMemberOf"
    //指定当前规则不可用,当前规则无论是否匹配成功都不会执行
    enabled false
    when
        ComparisonOperatorEntity(names not memberOf list)
    then
        System.out.println("规则rule_comparison_notMemberOf触发");
end

2、dialect属性

dialect属性用于指定当前规则使用的语言类型,取值为java和mvel,默认值为java。

注:mvel是一种基于java语法的表达式语言。

mvel像正则表达式一样,有直接支持集合、数组和字符串匹配的操作符。

mvel还提供了用来配置和构造字符串的模板语言。

mvel表达式内容包括属性表达式,布尔表达式,方法调用,变量赋值,函数定义等。

3、salience属性

salience属性用于指定规则的执行优先级,取值类型为Integer。数值越大越优先执行。每个规则都有一个默认的执行顺序,如果不设置salience属性,规则体的执行顺序为由上到下。

可以通过创建规则文件salience.drl来测试salience属性,内容如下:

//当前规则文件用于测试执行优先级
package testsalience
 
//定义一个规则
rule "rule_1"
    salience 10
    when
        eval(true)//返回true,即当前规则匹配成功
    then
        System.out.println("规则:rule_1触发了、、、");
end
 
//定义第二个规则
rule "rule_2"
    salience  12
    when
        eval(true)//返回true,即当前规则匹配成功
    then
        System.out.println("规则:rule_2触发了、、、");
end
 
//定义第三个规则
rule "rule_3"
    salience 11
    when
        eval(true)//返回true,即当前规则匹配成功
    then
        System.out.println("规则:rule3触发了、、、");
end
通过控制台可以看到,规则文件执行的顺序是按照我们设置的salience值由大到小顺序执行的。

建议在编写规则时使用salience属性明确指定执行优先级。

4、no-loop属性

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

第一步:编写规则文件/resource/rules/noloop.drl

package testnoloop
import com.itheima.drools.entity.Student
/*
    此规则文件用于测试no-loop属性
*/
rule "rule_noloop"
        no-loop true
    when
        $student:Student(age == 50)
    then
        update($student);//注意此处执行update会导致当前规则重新被激活
        System.out.println("规则rule_noloop触发");
end

第二步:测试.........

5、activation-group属性

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

第一步:编写规则文件/resources/rules/activationgroup.drl

//当前规则文件用于测试activation-group属性
package testactivationgroup
 
rule "rule_activationgroup_1"
    activation-group "mygroup"  //对于同一个组内的规则,只能有一个触发
    salience 5
    when
        //如果条件不写,默认为true,表示规则匹配成功
    then
        System.out.println("规则: rule_activationgroup_1触发了、、、、");
end
 
rule "rule_activationgroup_2"
    activation-group "mygroup"
    salience 10
    when
        //如果条件不写,默认为true,表示规则匹配成功
    then
        System.out.println("规则: rule_activationgroup_2触发了、、、、");
end

第二步:编写单元测试

KieServices kieServices = KieServices.Factory.get();
KieContainer kieClasspathContainer = kieServices.getKieClasspathContainer();
KieSession kieSession = kieClasspathContainer.newKieSession();
kieSession.fireAllRules();
kieSession.dispose();

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

6、agenda-group属性

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

第一步:创建规则文件/resources/rules/agendagroup.drl

package testagendagroup
/*
    此规则文件用于测试agenda-group属性
*/
rule "rule_agendagroup_1"
    agenda-group "myagendagroup_1"
    when
    then
        System.out.println("规则rule_agendagroup_1触发");
end
 
rule "rule_agendagroup_2"
    agenda-group "myagendagroup_1"
    when
    then
        System.out.println("规则rule_agendagroup_2触发");
end
//========================================================
rule "rule_agendagroup_3"
    agenda-group "myagendagroup_2"
    when
    then
        System.out.println("规则rule_agendagroup_3触发");
end
 
rule "rule_agendagroup_4"
    agenda-group "myagendagroup_2"
    when
    then
        System.out.println("规则rule_agendagroup_4触发");
end

第二步:测试类

        @Test
        public void test5()
        {
            KieServices kieServices = KieServices.Factory.get();
            //获得Kie容器对象
            //默认自动加载 META-INF/kmodule.xml
            //从KieServices中获得KieContainer实例,其会加载kmodule.xml文件并load规则文件
            KieContainer kieContainer = kieServices.getKieClasspathContainer();
            //从Kie容器对象中获取会话对象
            KieSession session = kieContainer.newKieSession();
 
            //设置焦点,对应agenda-group分组中的规则才可能被触发
            session.getAgenda().getAgendaGroup("myagendagroup_2").setFocus();
 
            session.fireAllRules();
 
            session.dispose();
 
        }

7、auto-focus属性

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

第一步:修改/resources/rules/agendagroup.drl文件内容如下

package testagendagroup
/*
    此规则文件用于测试agenda-group属性
*/
rule "rule_agendagroup_1"
    agenda-group "myagendagroup_1"
    auto-focus true  //auto-focus属性用于指定当前所属组自动获取焦点
    when
    then
        System.out.println("规则rule_agendagroup_1触发");
end
 
rule "rule_agendagroup_2"
    agenda-group "myagendagroup_1"
    when
    then
        System.out.println("规则rule_agendagroup_2触发");
end
//========================================================
rule "rule_agendagroup_3"
    agenda-group "myagendagroup_2"
    when
    then
        System.out.println("规则rule_agendagroup_3触发");
end
 
rule "rule_agendagroup_4"
    agenda-group "myagendagroup_2"
    when
    then
        System.out.println("规则rule_agendagroup_4触发");
end

8、timer属性

方式1:

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

//当前规则文件用于测试timer属性
package testtimer
 
//timer第一种使用方式
rule "rule_timer_1"
    timer(3s 2s) //当前timer属性用于指定规则触发的时间,当前表达式表示3s后触发,每隔2s触发一次
    when
    then
    System.out.println("规则:rule_timer_1触发了、、、");
end
        @Test
        public void test5() throws InterruptedException
        {
            KieServices kieServices = KieServices.Factory.get();
            //获得Kie容器对象
            //默认自动加载 META-INF/kmodule.xml
            //从KieServices中获得KieContainer实例,其会加载kmodule.xml文件并load规则文件
            KieContainer kieContainer = kieServices.getKieClasspathContainer();
            //从Kie容器对象中获取会话对象
            final KieSession session = kieContainer.newKieSession();
 
            new Thread(new Runnable()
            {
                public void run()
                {
                    //启动规则引擎进行规则匹配,直到调用halt方法才结束规则引擎
                    session.fireUntilHalt();
                }
            }).start();
 
            Thread.sleep(10000);
 
            //结束规则引擎
            session.halt();
 
            session.dispose();
 
        }

方式2:

timer(cron: <cron expression>)

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

第一步:创建规则文件/resources/rules/timer.drl

package testtimer
import java.text.SimpleDateFormat
import java.util.Date
/*
    此规则文件用于测试timer属性
*/
​
rule "rule_timer_1"
    timer (5s 2s) //含义:5秒后触发,然后每隔2秒触发一次
    when
    then
        System.out.println("规则rule_timer_1触发,触发时间为:" + 
                         new SimpleDateFormat("yyyy-MM-dd HH:mm:ss").format(new Date()));
end
​
rule "rule_timer_2"
    timer (cron:0/1 * * * * ?) //含义:每隔1秒触发一次
    when
    then
        System.out.println("规则rule_timer_2触发,触发时间为:" + 
                         new SimpleDateFormat("yyyy-MM-dd HH:mm:ss").format(new Date()));
end

第二步:编写单元测试

KieServices kieServices = KieServices.Factory.get();
KieContainer kieClasspathContainer = kieServices.getKieClasspathContainer();
final KieSession kieSession = kieClasspathContainer.newKieSession();
​
new Thread(new Runnable() {
    public void run() {
        //启动规则引擎进行规则匹配,直到调用halt方法才结束规则引擎
        kieSession.fireUntilHalt();
    }
}).start();
​
Thread.sleep(10000);
//结束规则引擎
kieSession.halt();
kieSession.dispose();

注意:单元测试的代码和以前的有所不同,因为我们规则文件中使用到了timer进行定时执行,需要程序能够持续一段时间才能够看到定时器触发的效果。

9、date-effective属性

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

第一步:编写规则文件/resources/rules/dateeffective.drl

package testdateeffective
/*
    此规则文件用于测试date-effective属性
*/
rule "rule_dateeffective_1"
    date-effective "2020-10-01 10:00"
    when
    then
        System.out.println("规则rule_dateeffective_1触发");
end

第二步:编写单元测试

//设置日期格式
System.setProperty("drools.dateformat","yyyy-MM-dd HH:mm");
KieServices kieServices = KieServices.Factory.get();
KieContainer kieClasspathContainer = kieServices.getKieClasspathContainer();
KieSession kieSession = kieClasspathContainer.newKieSession();
kieSession.fireAllRules();
kieSession.dispose();

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

10、date-expires属性

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

第一步:编写规则文件/resource/rules/dateexpires.drl

package testdateexpires
/*
    此规则文件用于测试date-expires属性
*/
​
rule "rule_dateexpires_1"
    date-expires "2019-10-01 10:00"
    when
    then
        System.out.println("规则rule_dateexpires_1触发");
end

第二步:编写单元测试

//设置日期格式
System.setProperty("drools.dateformat","yyyy-MM-dd HH:mm");
KieServices kieServices = KieServices.Factory.get();
KieContainer kieClasspathContainer = kieServices.getKieClasspathContainer();
KieSession kieSession = kieClasspathContainer.newKieSession();
kieSession.fireAllRules();
kieSession.dispose();

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

### 凌霄飞控 GPIO 的使用方法及配置 凌霄飞控是一款基于开源硬件设计的飞行控制器,其核心功能之一是对无人机或其他设备进行精确控制。GPIO(General Purpose Input/Output)作为通用输入输出接口,在嵌入式开发中具有重要作用,可以用于传感器读取、信号传输以及外设控制等功能。 以下是关于凌霄飞控 GPIO 配置和使用的详细介绍: #### 1. GPIO 基础概念 GPIO 是一种可编程的数字接口,能够被设置为输入模式或输出模式。通过软件定义,它可以实现多种用途,例如触发中断、驱动 LED 或者与其他外部设备通信。对于凌霄飞控而言,GPIO 接口通常由底层固件管理,并可以通过特定命令或者脚本进行访问[^2]。 #### 2. 查看可用的 GPIO 引脚 在使用前,需确认哪些引脚支持 GPIO 功能并获取它们的具体编号。这一步可通过查阅官方文档完成,也可以运行以下命令来查看当前系统的 GPIO 状态: ```bash gpio readall ``` 上述命令会显示所有 GPIO 引脚的状态及其对应的物理位置[^3]。 #### 3. 设置 GPIO 方向 (Input/Output) 要操作某个具体的 GPIO 引脚,首先需要指定它的方向——即它是用来接收数据还是发送数据。此过程涉及两个主要文件路径 `/sys/class/gpio/export` 和 `/sys/class/gpio/unexport` 来启用或禁用选定的引脚号 `N`: - **导出目标引脚**: ```bash echo N > /sys/class/gpio/export ``` - **设定为输入或输出**: 输入模式: ```bash echo in > /sys/class/gpio/gpioN/direction ``` 输出模式: ```bash echo out > /sys/class/gpio/gpioN/direction ``` 以上步骤完成后即可对该引脚执行进一步的操作[^4]。 #### 4. 控制 GPIO 数据流 一旦设置了正确的方向之后就可以开始实际的数据交互了。如果之前已经把某根针脚配置成了输出,则可以直接改变它上面电压高低电平;如果是当作输入则可以从那里读回实时状态值。 - 写入高/低电平时: ```bash echo 1 > /sys/class/gpio/gpioN/value # 设定 HIGH Level echo 0 > /sys/class/gpio/gpioN/value # 设定 LOW Level ``` - 获取当前电平: ```bash cat /sys/class/gpio/gpioN/value # 返回 '0' 表示 LOW, '1' 表示 HIGH ``` 这些基本指令允许开发者轻松地测试他们的电路板上的任何逻辑开关行为或是简单LED闪烁效果演示程序等等[^5]。 #### 5. 编程实例 - Python 脚本控制 GPIO 除了直接利用 shell 命令之外还可以借助高级语言如Python来进行更复杂的自动化任务处理。下面给出一段简单的例子展示如何开启关闭一个连接到第7号管脚(Pin7)的小灯泡。 ```python import RPi.GPIO as GPIO from time import sleep pin_number = 7 # 定义所要用到的实际Pin Number GPIO.setmode(GPIO.BOARD) # 使用BOARD编号方式 GPIO.setup(pin_number, GPIO.OUT) try: while True: print("Turning ON the Light...") GPIO.output(pin_number, GPIO.HIGH) # Turn On The Bulb sleep(1) # Wait For One Second print("Turning OFF the Light...") GPIO.output(pin_number, GPIO.LOW) # Turn Off The Bulb Again. sleep(1) # Another Delay Of A Single Sec. except KeyboardInterrupt: # If Ctrl+C is pressed... pass # Do Nothing Special Here finally: # Clean Up Resources Before Exit GPIO.cleanup() # Reset All Pins Back To Default State. ``` 该段代码片段展示了怎样周期性的点亮熄灭一个关联至第七个接头处发光二极体(LED),并且当按下键盘组合键Ctrl-C终止进程的时候还会自动清理释放掉占用资源确保下次重新启动不会遇到冲突情况发生[^6]。 ---
评论
添加红包

请填写红包祝福语或标题

红包个数最小为10个

红包金额最低5元

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

打赏作者

烈火138

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

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

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

打赏作者

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

抵扣说明:

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

余额充值