drools中Fact的equality modes
一、equality modes介绍
在drools中存在如下2种equality modes。
1、identity模式
identity:这是默认的情况。drools引擎使用IdentityHashMap保存所有插入到工作内存中的Fact对象。对于每次插入一个新的对象,则会返回一个新的FactHandle对象。如果是重复插入对象,则返回已经存在的FactHandle对象。
举例:
Person p1 = new Person("zhangsan", 20, "湖北罗田");
Person p2 = new Person("zhangsan", 20, "湖北黄冈罗田");
FactHandle factHandle1 = kieSession.insert(p1);
FactHandle factHandle2 = kieSession.insert(p2);
FactHandle factHandle3 = kieSession.insert(p2);
针对以上例子, factHandle1 != factHandle2但是 factHandle2 == factHandle3。即工作内存中会存在2个Person对象。
2、equality模式
equality:drools引擎使用HashMap保存所有插入到工作内存中的Fact对象。在这种模式下,如果向drools中插入一个新的对象,只有这个对象不存在(根据对象的hashcode和equals判断)才会返回一个新的FactHandle否则返回已经存在的FactHandle。
举例:
// 重写了Person对象的hashcode和equals方法
Person p1 = new Person("zhangsan", 20, "湖北罗田");
Person p2 = new Person("zhangsan", 20, "湖北黄冈罗田");
FactHandle factHandle1 = kieSession.insert(p1);
FactHandle factHandle2 = kieSession.insert(p2);
FactHandle factHandle3 = kieSession.insert(p2);
针对以上例子, factHandle1 == factHandle2但是 factHandle2 == factHandle3。即工作内存中会存在1个Person对象。
二、需求
我们存在一个Person对象,存在如下3个属性name,age和address,其中重写对象的name和age的hashcode和equals方法。
- 多次向工作内存中插入对象,看产生的结果。
- 插入同一个对象看获取到的FactHandle对象是否是同一个。
三、如何设置fact对象的equality行为
此处介绍一个通过kmodule.xml配置的方法
<kmodule xmlns="http://www.drools.org/xsd/kmodule">
<kbase name="kbase-identity" packages="rules" default="false" equalsBehavior="identity">
<ksession name="ksession-01" default="false" type="stateful"/>
</kbase>
<kbase name="kbase-equality" packages="rules" default="false" equalsBehavior="equality">
<ksession name="ksession-02" default="false" type="stateful"/>
</kbase>
</kmodule>
通过上方的代码可知是通过配置kbase下的equalsBehavior属性来配置。
其余的配置方法,参考下图:

四、编码实现
1、项目结构图

2、倒入jar包
<dependencyManagement>
<dependencies>
<dependency>
<groupId>org.drools</groupId>
<artifactId>drools-bom</artifactId>
<type>pom</type>
<version>7.69.0.Final</version>
<scope>import</scope>
</dependency>
</dependencies>
</dependencyManagement>
<dependencies>
<dependency>
<groupId>org.drools</groupId>
<artifactId>drools-compiler</artifactId>
</dependency>
<dependency>
<groupId>org.drools</groupId>
<artifactId>drools-mvel</artifactId>
</dependency>
<dependency>
<groupId>ch.qos.logback</groupId>
<artifactId>logback-classic</artifactId>
<version>1.2.11</version>
</dependency>
</dependencies>
3、编写Person对象
public class Person {
private String name;
private Integer age;
private String address;
public Person(String name, Integer age, String address) {
this.name = name;
this.age = age;
this.address = address;
}
public String getName() {
return name;
}
public void setName(String name) {
this.name = name;
}
public Integer getAge() {
return age;
}
public void setAge(Integer age) {
this.age = age;
}
public String getAddress() {
return address;
}
public void setAddress(String address) {
this.address = address;
}
@Override
public boolean equals(Object o) {
if (this == o) return true;
if (o == null || getClass() != o.getClass()) return false;
Person person = (Person) o;
return Objects.equals(name, person.name) && Objects.equals(age, person.age);
}
@Override
public int hashCode() {
return Objects.hash(name, age);
}
}
注意:
此对象需要重写hashcode和equals方法。
4、编写kmodule.xml文件
在此配置文件中,需要在kbase上指定equalsBehavior,用来确定Fact对象的equality modes。
<kmodule xmlns="http://www.drools.org/xsd/kmodule">
<kbase name="kbase-identity" packages="rules" default="false" equalsBehavior="identity">
<ksession name="ksession-01" default="false" type="stateful"/>
</kbase>
<kbase name="kbase-equality" packages="rules" default="false" equalsBehavior="equality">
<ksession name="ksession-02" default="false" type="stateful"/>
</kbase>
</kmodule>
注意:
需要看2个equalsBehavior的取值
5、编写一个规则文件
package rules
import com.huan.drools.Person
// 定义规则
rule "rule_01"
when
$p: Person()
then
System.out.println(Thread.currentThread().getName() + " name:"+$p.getName()+" age:"+$p.getAge());
end
规则文件中的内容很简单,只要工作内存中存在Person对象,那么就输出这个对象的name和age的值。
6、identity模式测试
1、编写测试代码
public class DroolsApplication {
public static void main(String[] args) {
equalsBehaviorIdentity();
}
private static void equalsBehaviorIdentity() {
KieServices kieServices = KieServices.get();
KieContainer kieContainer = kieServices.getKieClasspathContainer();
// 注意此处的 ksession-01
KieSession kieSession = kieContainer.newKieSession("ksession-01");
kieSession.addEventListener(new DebugRuleRuntimeEventListener());
Person p1 = new Person("zhangsan", 20, "湖北罗田");
Person p2 = new Person("zhangsan", 20, "湖北黄冈罗田");
FactHandle factHandle1 = kieSession.insert(p1);
FactHandle factHandle2 = kieSession.insert(p2);
FactHandle factHandle3 = kieSession.insert(p2);
kieSession.fireAllRules();
kieSession.dispose();
}
}
2、运行结果

具体的解释见上图中的说明。
7、equality模式测试
1、编写测试代码
public class DroolsApplication {
public static void main(String[] args) {
equalsBehaviorEquality();
}
private static void equalsBehaviorEquality() {
KieServices kieServices = KieServices.get();
KieContainer kieContainer = kieServices.getKieClasspathContainer();
KieSession kieSession = kieContainer.newKieSession("ksession-02");
kieSession.addEventListener(new DebugRuleRuntimeEventListener());
Person p1 = new Person("zhangsan", 20, "湖北罗田");
Person p2 = new Person("zhangsan", 20, "湖北黄冈罗田");
FactHandle factHandle1 = kieSession.insert(p1);
FactHandle factHandle2 = kieSession.insert(p2);
FactHandle factHandle3 = kieSession.insert(p2);
kieSession.fireAllRules();
kieSession.dispose();
}
}
2、运行结果

五、结论
针对如下代码,看看在不同equality modes下的行为
Person p1 = new Person("zhangsan", 20, "湖北罗田");
Person p2 = new Person("zhangsan", 20, "湖北黄冈罗田");
FactHandle factHandle1 = kieSession.insert(p1);
FactHandle factHandle2 = kieSession.insert(p2);
FactHandle factHandle3 = kieSession.insert(p2);
Person对象的hashcode和equals方法进行重写了,根据构造方法的前2个参数。
1、identity模式下
factHandle1 != factHandle2 因为p1和p2是2个不同的对象。
factHandle2 == factHandle3 因为是p2重复加入工作内存,这个时候工作内存中已经存在了,所以返回之前关联的FactHandle
2、equality模式下
factHandle1 == factHandle2 == factHandle3 因为这种模式下,是需要根据对象的equals和hashcode方法进行比较,而Person对象重写了这2个方法,所以返回的是同一个。
六、完整代码
https://gitee.com/huan1993/spring-cloud-parent/tree/master/drools/drools-fact-equality-modes
七、参考链接
drools中Fact的equality modes的更多相关文章
- drools中的条件 when
目录 1.介绍 2.语法结构 3.模式例子 3.1 单个对象匹配 3.2 匹配任何对象 3.3 带条件匹配 3.3.1 注意事项 3.4 嵌套属性的匹配 3.4.1 访问单个嵌套属性 3.4.2 访问 ...
- drools中query的使用
一.背景 我们知道在drools中是存在工作内存的,我们的Fact对象会加入到工作内存中,同时我们自己也可以在drl文件中使用insert/modify/update/delete等方法,修改工作内存 ...
- drools中then部分的写法
目录 1.背景 2.支持的方法 2.1 insert 插入对象到工作内存中 2.1.1 需求 2.1.2 drl文件编写 2.1.3 部分java代码编写 2.1.4 运行结果 2.1.5 结论 2. ...
- drools规则引擎中易混淆语法分析_相互触发导致死循环分析
整理了下最近在项目中使用drools出现的问题,幸好都在开发与测试阶段解决了,未波及到prod. 首先看这样两条规则: /** * 规则1_set默认利率a */ rule "rate_de ...
- 【java规则引擎】之Drools引擎中模拟ReteooStatefulSession内部设计结构
该片文章只是抽取drools中java代码实现的一些代码结构,帮助我们理解drools是如何实现rete算法的. 该部分只是抽取ReteooStatefulSession工作过程中的代码架构 利用了多 ...
- Drools文档(八) 规则语言参考
规则语言参考 概述 Drools有一个"本地"的规则语言.这种格式在标点符号上非常轻,并且通过"扩展器"支持自然语言和领域特定的语言,使语言能够变形到您的问题领 ...
- Drools 7.4.1.Final参考手册(八) 规则语言参考
规则语言参考 概述 Drools有一个“本地”的规则语言.这种格式在标点符号上非常轻,并且通过“扩展器”支持自然语言和领域特定的语言,使语言能够变形到您的问题领域.本章主要与本机规则格式一致.用于表示 ...
- Drools环境搭建(转)
Eclipse3.5安装Drools5.2.0.Final插件 到Drools下载页面(现在是http://www.jboss.org/drools/downloads.html) -下载并解压Dro ...
- JAVA规则引擎 -- Drools
Drools是一个基于java的规则引擎,开源的,可以将复杂多变的规则从硬编码中解放出来,以规则脚本的形式存放在文件中,使得规则的变更不需要修正代码重启机器就可以立即在线上环境生效. 本文所使用的de ...
随机推荐
- 【推理引擎】如何在 ONNXRuntime 中添加新的算子
如果模型中有些算子不被ONNX算子库支持,我们就需要利用ONNXRuntime提供的API手动添加新算子.在官方文档中已经对如何添加定制算子进行了介绍(https://onnxruntime.ai/d ...
- C语言形参和实参的区别(非常详细)
如果把函数比喻成一台机器,那么参数就是原材料,返回值就是最终产品:从一定程度上讲,函数的作用就是根据不同的参数产生不同的返回值.这一节我们先来讲解C语言函数的参数,下一节再讲解C语言函数的返回值.C语 ...
- 要多简单就有多简单的H5拍照加水印
来一个简单粗暴的gif演示图 先来html 内容 <video id="video" width="320" height="240" ...
- D3.js中国地图下钻
使用d3.js实现中国地图及中国地图下钻到省市区 在可视化开发中,地图是很重要的一个环节,很多时候需要展现的不仅是国家地图,还需要能从国家进入到省市,看到区这样的下钻过程,今天我们就来实现这个效果. ...
- 聊聊 DisplayObject 的x/y/regX/regY/rotation/scale/skew 属性
首先要指出的是:DisplayObject 实例的属性<x, y> 与 graphics.draw*(x, y, ...) 的参数<x, y>没有关系. 在原生的 Canvas ...
- CSS - 定位属性position使用详解(static、relative、fixed、absolute)
position 属性介绍 (1)position 属性自 CSS2 起就有了,该属性规定元素的定位类型.所有主流浏览器都支持 position 属性. (2)position 的可选值有四个:sta ...
- python-班级人员信息统计
输入a,b班的名单,并进行如下统计. 输入格式: 第1行::a班名单,一串字符串,每个字符代表一个学生,无空格,可能有重复字符.第2行::b班名单,一串字符串,每个学生名称以1个或多个空格分隔,可能有 ...
- String能变化吗?和StringBuffer的区别是什么
[新手可忽略不影响继续学习]看 过上面例子的童鞋一定会觉得很奇怪,s = s + s1.charAt(i); 马克-to-win, s不是老在变化吗?其实s = "";时,虚拟机会 ...
- 小程序colorui框架引入与使用
colorui是UI框架: 超好用的一款 小程序二维码体验: : 引入方式: 1.先去下载colorui https://github.com/weilanwl/ColorUI 把col ...
- jupyter notebook 调用.py文件
方法1.利用 %run xx.py 直接运行得出结果. 方法2:利用 %load xx.py 载入代码再点击Run运行,这种方法的好处是可以方便修改代码. 说明: Jupyter Notebook中以 ...