一、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中插入一个新的对象,只有这个对象不存在(根据对象的hashcodeequals判断)才会返回一个新的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方法。

  1. 多次向工作内存中插入对象,看产生的结果。
  2. 插入同一个对象看获取到的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对象,那么就输出这个对象的nameage的值。

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 因为这种模式下,是需要根据对象的equalshashcode方法进行比较,而Person对象重写了这2个方法,所以返回的是同一个。

六、完整代码

https://gitee.com/huan1993/spring-cloud-parent/tree/master/drools/drools-fact-equality-modes

七、参考链接

1、https://docs.drools.org/7.69.0.Final/drools-docs/html_single/index.html#fact-equality-modes-con_decision-engine

drools中Fact的equality modes的更多相关文章

  1. drools中的条件 when

    目录 1.介绍 2.语法结构 3.模式例子 3.1 单个对象匹配 3.2 匹配任何对象 3.3 带条件匹配 3.3.1 注意事项 3.4 嵌套属性的匹配 3.4.1 访问单个嵌套属性 3.4.2 访问 ...

  2. drools中query的使用

    一.背景 我们知道在drools中是存在工作内存的,我们的Fact对象会加入到工作内存中,同时我们自己也可以在drl文件中使用insert/modify/update/delete等方法,修改工作内存 ...

  3. 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. ...

  4. drools规则引擎中易混淆语法分析_相互触发导致死循环分析

    整理了下最近在项目中使用drools出现的问题,幸好都在开发与测试阶段解决了,未波及到prod. 首先看这样两条规则: /** * 规则1_set默认利率a */ rule "rate_de ...

  5. 【java规则引擎】之Drools引擎中模拟ReteooStatefulSession内部设计结构

    该片文章只是抽取drools中java代码实现的一些代码结构,帮助我们理解drools是如何实现rete算法的. 该部分只是抽取ReteooStatefulSession工作过程中的代码架构 利用了多 ...

  6. Drools文档(八) 规则语言参考

    规则语言参考 概述 Drools有一个"本地"的规则语言.这种格式在标点符号上非常轻,并且通过"扩展器"支持自然语言和领域特定的语言,使语言能够变形到您的问题领 ...

  7. Drools 7.4.1.Final参考手册(八) 规则语言参考

    规则语言参考 概述 Drools有一个“本地”的规则语言.这种格式在标点符号上非常轻,并且通过“扩展器”支持自然语言和领域特定的语言,使语言能够变形到您的问题领域.本章主要与本机规则格式一致.用于表示 ...

  8. Drools环境搭建(转)

    Eclipse3.5安装Drools5.2.0.Final插件 到Drools下载页面(现在是http://www.jboss.org/drools/downloads.html) -下载并解压Dro ...

  9. JAVA规则引擎 -- Drools

    Drools是一个基于java的规则引擎,开源的,可以将复杂多变的规则从硬编码中解放出来,以规则脚本的形式存放在文件中,使得规则的变更不需要修正代码重启机器就可以立即在线上环境生效. 本文所使用的de ...

随机推荐

  1. 从零开始画自己的DAG作业依赖图(四)--节点连线优化版

    概述 上个版本简单的连线在一些复杂场景,尤其层级比较多,连线跨层级比较多的情况下,会出现线条会穿过矩形的情况,这一讲就是在这个基础上,去优化这个连线. 场景分析 在下面几种情况下,简单版本的画法已经没 ...

  2. 从kill-chain的角度检测APT攻击

    前言 最近一直在考虑如何结合kill chain检测APT攻击.出发点是因为尽管APT是一种特殊.高级攻击手段,但是它还是会具有攻击的common feature,只要可以把握住共同特征,就能进行检测 ...

  3. SQList基础+ListView基本使用

    今日所学: SQList基础语法 SDList下载地址 SQLite Download Page SQList安装教程SQLite的安装与基本操作 - 极客开发者-博客 ListView用法 没遇到什 ...

  4. Java 将Map按Value值降序排列

    1 /** 2 * 将集合按照降序排列-FLOAT 3 * @param nowPartTwoData 4 * @return 5 */ 6 private static List<Map.En ...

  5. Android 接入腾讯IM即时通信(详细图文)

    原文地址:Android 接入腾讯IM即时通信(详细图文) | Stars-One的杂货小窝 腾讯云IM官网文档上提供了带UI模块和不带UI模块的,本文是基于带UI模块进行了Module封装,可以方便 ...

  6. Unable to configure HTTPS endpoint. No server certificate was specified, and the default developer certificate could not be found 解决办法

    问题 每次vs重启都提示安装证书,即使执行dotnet dev-certs https --clean,dotnet dev-certs https -t然后重启vs也不行. 环境 win10, vs ...

  7. spring-注入list集合对象(值是对象)

    1.创建stu类 public class Stu { // //1.数组类型 // private String[] courses; // // //2.list集合属性 // private L ...

  8. Intellij IDEA中查看字节码

    首先安装插件,这俩都勾上 Intellij IDEA 直接集成了一个工具菜单,可以直接查看字节码,打开 ByteCode 插件窗口方法如下:

  9. 帝国cms 7.5版列表页分页样式修改笔记

    最近在用帝国改版我的个人博客站点,这个也是我第一次尝试用帝国来做博客,之前用过wordpress,每用一个新的程序,都会有些新的收获,也会学到一些新的东西. 在改用帝国之前,我也在网上大概了解了一下, ...

  10. form表单请求

    form 表单的acton属性指向url:端口号/(服务器get,post的参数), meyhod='get'/'post'  请求方式,必须要加上name属性. <form action=&q ...