深入淺析drools中Fact的equality?modes
一、equality modes介紹
在drools
中存在如下2種equality modes。
1、identity模式
identity
:這是默認的情況。drools引擎使用IdentityHashMap
保存所有插入到工作內(nèi)存中的Fact
對象。對于每次插入一個新的對象,則會返回一個新的FactHandle
對象。如果是重復(fù)插入對象,則返回已經(jīng)存在的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
。即工作內(nèi)存中會存在2個Person
對象。
2、equality模式
equality
:drools引擎使用HashMap
保存所有插入到工作內(nèi)存中的Fact
對象。在這種模式下,如果向drools中插入一個新的對象,只有這個對象不存在(根據(jù)對象的hashcode
和equals
判斷)才會返回一個新的FactHandle
否則返回已經(jīng)存在的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
。即工作內(nèi)存中會存在1個Person
對象。
二、需求
我們存在一個Person
對象,存在如下3個屬性name,age和address
,其中重寫對象的name和age
的hashcode和equals方法。
- 多次向工作內(nèi)存中插入對象,看產(chǎn)生的結(jié)果。
- 插入同一個對象看獲取到的FactHandle對象是否是同一個。
三、如何設(shè)置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
屬性來配置。
其余的配置方法,參考下圖:
四、編碼實現(xiàn)
1、項目結(jié)構(gòu)圖
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、編寫一個規(guī)則文件
package rules import com.huan.drools.Person // 定義規(guī)則 rule "rule_01" when $p: Person() then System.out.println(Thread.currentThread().getName() + " name:"+$p.getName()+" age:"+$p.getAge()); end
規(guī)則文件中的內(nèi)容很簡單,只要工作內(nèi)存中存在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、運行結(jié)果
具體的解釋見上圖中的說明。
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、運行結(jié)果
五、結(jié)論
針對如下代碼,看看在不同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
方法進行重寫了,根據(jù)構(gòu)造方法的前2個參數(shù)。
1、identity模式下
factHandle1 != factHandle2
因為p1和p2是2個不同的對象。factHandle2 == factHandle3
因為是p2重復(fù)加入工作內(nèi)存,這個時候工作內(nèi)存中已經(jīng)存在了,所以返回之前關(guān)聯(lián)的FactHandle
2、equality模式下
factHandle1 == factHandle2 == factHandle3
因為這種模式下,是需要根據(jù)對象的equals
和hashcode
方法進行比較,而Person
對象重寫了這2個方法,所以返回的是同一個。
六、完整代碼
https://gitee.com/huan1993/spring-cloud-parent/tree/master/drools/drools-fact-equality-modes
七、參考鏈接
到此這篇關(guān)于drools中Fact的equality modes的文章就介紹到這了,更多相關(guān)drools equality modes內(nèi)容請搜索腳本之家以前的文章或繼續(xù)瀏覽下面的相關(guān)文章希望大家以后多多支持腳本之家!
相關(guān)文章
Java ConcurrentModificationException異常解決案例詳解
這篇文章主要介紹了Java ConcurrentModificationException異常解決案例詳解,本篇文章通過簡要的案例,講解了該項技術(shù)的了解與使用,以下就是詳細內(nèi)容,需要的朋友可以參考下2021-09-09SpringBoot集成JPA持久層框架,簡化數(shù)據(jù)庫操作
JPA(Java Persistence API)意即Java持久化API,是Sun官方在JDK5.0后提出的Java持久化規(guī)范。主要是為了簡化持久層開發(fā)以及整合ORM技術(shù),結(jié)束Hibernate、TopLink、JDO等ORM框架各自為營的局面。JPA是在吸收現(xiàn)有ORM框架的基礎(chǔ)上發(fā)展而來,易于使用,伸縮性強。2021-06-06springboot2啟動時執(zhí)行,初始化(或定時任務(wù))servletContext問題
這篇文章主要介紹了springboot2啟動時執(zhí)行,初始化(或定時任務(wù))servletContext問題,具有很好的參考價值,希望對大家有所幫助。如有錯誤或未考慮完全的地方,望不吝賜教2023-01-01Java 數(shù)據(jù)庫連接(JDBC)的相關(guān)總結(jié)
這篇文章主要介紹了Java 數(shù)據(jù)庫連接(JDBC)的相關(guān)總結(jié),幫助大家更好的理解和學(xué)習(xí)使用Java,感興趣的朋友可以了解下2021-03-03