Drools中Fact的等价模式有哪些具体应用场景?

2026-05-25 18:191阅读0评论SEO问题
  • 内容介绍
  • 文章标签
  • 相关推荐

本文共计1696个文字,预计阅读时间需要7分钟。

Drools中Fact的等价模式有哪些具体应用场景?

一、equality modes 介绍 + 在 drools 中存在以下 2 种 equality modes:

1.identity 模式:identity

- 这是默认的情况。drools 引擎使用 IdentityHashMap 保存所有插入到工作内存中的 Fact 对象。 - 对于每次插入的同一个Fact对象,实际上都是一个新的对象实例。

一、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="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。

Drools中Fact的等价模式有哪些具体应用场景?

<kmodule xmlns="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个方法,所以返回的是同一个。

六、完整代码

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

七、参考链接

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

标签:equalitymodes

本文共计1696个文字,预计阅读时间需要7分钟。

Drools中Fact的等价模式有哪些具体应用场景?

一、equality modes 介绍 + 在 drools 中存在以下 2 种 equality modes:

1.identity 模式:identity

- 这是默认的情况。drools 引擎使用 IdentityHashMap 保存所有插入到工作内存中的 Fact 对象。 - 对于每次插入的同一个Fact对象,实际上都是一个新的对象实例。

一、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="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。

Drools中Fact的等价模式有哪些具体应用场景?

<kmodule xmlns="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个方法,所以返回的是同一个。

六、完整代码

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

七、参考链接

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

标签:equalitymodes