理论
FACT对象
Fact 是指在Drools 规则应用当中,将一个普通的JavaBean 插入到规则的WorkingMemory当中后的对象。规则可以对Fact 对象进行任意的读写操作,当一个JavaBean 插入到WorkingMemory 当中变成Fact 之后,Fact 对象不是对原来的JavaBean 对象进行Clon,而是原来JavaBean 对象的引用。规则在进行计算的时候需要用到应用系统当中的数据,这些数据设置在Fact 对象当中,然后将其插入到规则的WorkingMemory 当中,这样在规则当中就可以通过对Fact 对象数据的读写,从而实现对应用数据的读写操作。一个Fact 对象通常是一个具有getter 和setter 方法的POJO 对象,通过这些getter 和setter 方法可以方便的实现对Fact 对象的读写操作,所以我们可以简单的把Fact 对象理解为规则与应用系统数据交互的桥梁或通道。
Drools 语法
规则文件可以使用 .drl文件,也可以是xml文件,这里我们使用drl文件
规则文件
package
对一个规则文件而言,package是必须定义的,必须放在规则文件第一行,package的名字是随意的,不必必须对应物理路径,跟java的package的概念不同,这里只是逻辑上的一种区分
import
导入规则文件需要使用到的外部规则文件或者变量,这里的使用方法跟java相同,但是不同于java的是,这里的import导入的不仅仅可以是一个类,也可以是这个类中的某一个可访问的静态方法
rule
rule "name"
attributes
when
LHS
then
RHS
end
一个规则,指定当(when)一系列特定的条件发生时(左手边LHS),然后(then)做出一系列相应的动作(右手边RHS)
attributes
no-loop: 定义当前的规则是否不允许多次循环执行,默认是false;当前的规则只要满足条件,可以无限次执行。什么情况下会出现一条规则执行过一次又被多次重复执行呢?drools提供了一些api,可以对当前传入workingMemory中的Fact对象进行修改或者个数的增减,比如上述的update方法,就是将当前的workingMemory中的Message类型的Fact对象进行属性更新,这种操作会触发规则的重新匹配执行,可以理解为Fact对象更新了,所以规则需要重新匹配一遍,那么疑问是之前规则执行过并且修改过的那些Fact对象的属性的数据会不会被重置?结果是不会,已经修改过了就不会被重置,update之后,之前的修改都会生效。当然对Fact对象数据的修改并不是一定需要调用update才可以生效,简单的使用set方法设置就可以完成,这里类似于java的引用调用,所以何时使用update是一个需要仔细考虑的问题,一旦不慎,极有可能会造成规则的死循环。上述的no-loop true,即设置当前的规则,只执行一次,如果本身的RHS部分有update等触发规则重新执行的操作,也不要再次执行当前规则。
但是其他的规则会被重新执行,岂不是也会有可能造成多次重复执行,数据紊乱甚至死循环?答案是使用其他的标签限制,也是可以控制的:lock-on-active true
lock-on-active:lock-on-active true 通过这个标签,可以控制当前的规则只会被执行一次,因为一个规则的重复执行不一定是本身触发的,也可能是其他规则触发的,所以这个是no-loop的加强版
date-expires:设置规则的过期时间,默认的时间格式:“日-月-年”
date-effective:设置规则的生效时间,时间格式同上。
duration:规则定时,duration 3000,3秒后执行规则
salience:优先级,数值越大越先执行,这个可以控制规则的执行顺序。