Drools入门之global全局变量
全局变量是一个很有用的元素节点,它是通过关键字global class(对象类型)name组成的。class可以是任意的,能为规则提供操作数据或服务等功能,特别是在规则RHS部分中使用程序提供的服务功能,如在RHS部分添加日志功能、修改数据表、发送E-mail等。
global全局变量与Fact(事实)对象不同,不会因为值变化而影响到规则的再次激活。
接下来,我们看一个例子。
public class RulesHello {
public static void main(String[] args) {
KieServices kieService = KieServices.Factory.get();
KieContainer kieContainer = kieService.getKieClasspathContainer();
KieSession kieSession = kieContainer.newKieSession("testGlobal");
kieSession.setGlobal("count",2017);
int count = kieSession.fireAllRules();
System.out.println("kieSession getGlobal:" + kieSession.getGlobal("count"));
System.out.println("总共执行了"+count+"条规则");
kieSession.dispose();
}
}
<kbase name="global" packages="rules.isGlobal">
<ksession name="testGlobal"/>
</kbase>
package rules.isGlobal;
dialect "mvel"
import com.domain.Person
global java.lang.Integer count
rule "global1"
when
then
System.out.println("global1 修改之前---->"+count);
count = 10;
System.out.println("global1 修改之后---->"+count);
end
rule "global2"
when
then
System.out.println("global2 直接输出---->"+count);
end
rule "global3"
when
$total : Double() from
accumulate(Person(),
init(Double totls = 0.0),
action(
System.out.println("global3 LHS修改之前---->"+count);
count=20;
totls+=1;
System.out.println("global3 LHS修改之后---->"+count);
),
reverse( totls-=1;),
result( totls )
)
then
System.out.println("global3 RHS修改之前---->"+count);
count = 90;
System.out.println("global3 RHS修改之后---->" + count);
end
这个例子中,有三条规则,第一条规则在RHS中对全局变量进行修改,分别在修改前后,输出了全局变量的值。第二条规则没有修改全局变量,直接进行了输出,第三条规则的LHS中用到了内置函数,后面会介绍,主要是在LHS的修改前后输出了值,以及RHS修改前后输出了值。
我们来看一下日志
global1 修改之前---->2017
global1 修改之后---->10
global2 直接输出---->2017
global3 RHS修改之前---->2017
global3 RHS修改之后---->90
kieSession getGlobal:2017
总共执行了3条规则
通过控制台的输出结果可以看出,当前规则体中修改的值包装类的全局变量只会影响到当前规则体。
如果多个package使用相同标识声明的全局变量,那么它们的类型必须是相同的,并且它们所有引用都是相同的全局变量。
全局变量定义成常量或包装类型时,该值对整个规则而言是不变的。但并不提倡用于数据共享。原因是针对不同类型全局变量中的内容也可能会发生变化。全局变量如果定义成集合类或JavaBean时,在规则体RHS部分中进行修改,则规则库或Java代码中的值都会发生变化。这证明了全局变量并非不可变的值,但也正是这一点会引发出一个问题,如果在多个地方使用并修改了全局变量,就可能会导致最终结果并不是设计师所想的。
使用全局变量时应注意点以下几点。
(1)常量值是不能改变的。
(2)包装类是不能改变的。
(3)类似JavaBean、List类的操作是可以改变内容的,但内存地址不会变。
Drools入门之global全局变量
https://www.zhaojun.inkhttps://www.zhaojun.ink/archives/drools-global