pbootcms网站模板|日韩1区2区|织梦模板||网站源码|日韩1区2区|jquery建站特效-html5模板网

drools的簡單入門案例場景分析

drools是一款由JBoss組織提供的基于Java語言開發(fā)的開源規(guī)則引擎,可以將復(fù)雜且多變的業(yè)務(wù)規(guī)則從硬編碼中解放出來,這篇文章主要介紹了drools的簡單入門案例,需要的朋友可以參考下

一、背景

最近在學(xué)習(xí)規(guī)則引擎drools,此處簡單記錄一下drools的入門案例。

1.Drools介紹

drools是一款由JBoss組織提供的基于Java語言開發(fā)的開源規(guī)則引擎,可以將復(fù)雜且多變的業(yè)務(wù)規(guī)則從硬編碼中解放出來,以規(guī)則腳本的形式存放在文件或特定的存儲介質(zhì)中(例如存放在數(shù)據(jù)庫中),使得業(yè)務(wù)規(guī)則的變更不需要修改項(xiàng)目代碼、重啟服務(wù)器就可以在線上環(huán)境立即生效。

drools官網(wǎng)地址:https://drools.org/

drools源碼下載地址:https://github.com/kiegroup/drools
-----------------------------------
Drools:概述和入門案例:

二、為什么要學(xué)習(xí)drools

假設(shè)我們存在如下場景:
在我們到商店購買衣服的時(shí)候,經(jīng)常會發(fā)生這樣的事情,購買1件不打折,購買2件打0.98折,購買3件級以上打0.85折。
那么我們在代碼中如果要實(shí)現(xiàn)上述功能,是不是就需要編寫if ... else語句,假設(shè)后期規(guī)則變了,是不是就需要修改這些if ... else語句,然后程序重新部署。這樣是可以實(shí)現(xiàn),但是不夠優(yōu)雅。那么我們是否可以將這些業(yè)務(wù)規(guī)則寫入到規(guī)則文件中,以后規(guī)則變更直接修改規(guī)則文件即可?而drools就可以實(shí)現(xiàn)這個(gè)功能。

三、實(shí)現(xiàn)上方這個(gè)簡單的打折案例

1、引入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>

2、編寫kmodule.xml配置文件

此配置文件需要放置在resources/META-INF目錄下。

<kmodule xmlns="http://www.drools.org/xsd/kmodule">
    <!--
        kbase 可以存在多個(gè)
        name: 指定kbase的名字,需要是唯一的
        packages: 包名,可以理解為到src/main/resources目錄下查找這個(gè)包名下的規(guī)則文件,多個(gè)包使用逗號分割
        default: 當(dāng)前kbase是否是默認(rèn)的kbase
    -->
    <kbase name="shop-kabse" packages="com.huan.shop" default="false">
        <!--
            ksession 可以存在多個(gè)
            name: 指定ksession 的名字,需要唯一
            defalut: 當(dāng)前ksession在這個(gè)kbase下是否是默認(rèn)的
            type: 指定當(dāng)前ksession是否是有狀態(tài)的 stateless表示是無狀態(tài)的
        -->
        <ksession name="shop-ksession" default="false" type="stateless"/>
        <ksession name="shop-ksession-stateful" default="false" type="stateful"/>
    </kbase>
</kmodule>

此處我們需要關(guān)注一下 kbasepackage的值,這個(gè)值需要和規(guī)則文件中的package值一致,否則會找不到規(guī)則,具體看下方。

3、編寫規(guī)則文件

1、規(guī)則文件的語法

包名,必須放置在第一行
package
// 引入Java中的類,需要些全限定名
import
// 定義function ,可選
function  // Optional
// 定義 query ,可選
query  // Optional
declare   // Optional
global   // Optional
// rule 關(guān)鍵字 "rule name" 規(guī)則的名字
rule "rule name"
    // Attributes 屬性可選
    when  // 關(guān)鍵字
        // Conditions  條件,可為空
    then
        // Actions // 匹配后執(zhí)行的結(jié)果
end // 關(guān)鍵字

2、編寫規(guī)則文件

規(guī)則文件的名字無所謂,比如: book-discount.drl

// 包名,必須防止到第一行,這個(gè)名字需要和 kbase中package屬性的值一致
package com.huan.shop
/**
 * 倒入類
 */
import com.huan.drools.CustomerOrder
// 定義規(guī)則
rule "shop-rule-01"
    when
        // 模式匹配:到工作內(nèi)存中查找CustomerOrder,并且這個(gè)對象的purchaseQuantity值需要是1,
        // 如果條件成立,$order是綁定變量名,一般以$開頭,和fact對象區(qū)分開
        $order:CustomerOrder(purchaseQuantity == 1)
    then
        System.out.println("匹配規(guī)則 shop-rule-01");
        // 賦值,此處賦值后,在Java代碼中獲取獲取到賦值后的值
        $order.setDiscount(1D);
end
rule "shop-rule-02"
    when
        $order:CustomerOrder(purchaseQuantity == 2)
    then
        System.out.println("匹配規(guī)則 shop-rule-02");
        $order.setDiscount(0.98);
end
rule "shop-rule-03"
    when
        $order:CustomerOrder(purchaseQuantity >= 3)
    then
        System.out.println("匹配規(guī)則 shop-rule-03");
        $order.setDiscount(0.85);
end

3、解釋一下包名

如果 shop-discount.drl的包名修改為com.huan.shop1則會提示如下警告:

12:43:01.589 [main] WARN org.drools.compiler.kie.builder.impl.KieBuilderImpl - File 'com/huan/shop/shop-discount.drl' is in folder 'com/huan/shop' but declares package 'com.huan.shop1'. It is advised to have a correspondance between package and folder names.

四、編寫Java代碼

1、編寫一個(gè)訂單對象

此對象保存的是用戶購買了幾件衣服和對應(yīng)的折扣。

/**
 * 客戶購買衣服的訂單,省略 getter 和 setter 方法
 *
 * @author huan.fu
 * @date 2022/5/12 - 11:27
 */
public class CustomerOrder {
    /**
     * 購買了幾件衣服
     */
    private Integer purchaseQuantity;
    /**
     * 最終打多少折
     */
    private Double discount;
    public CustomerOrder(Integer purchaseQuantity) {
        this.purchaseQuantity = purchaseQuantity;
    }
}

2、編寫測試代碼

1、無狀態(tài)測試方法statelessSessionTest規(guī)則規(guī)則2,即最終打0.98折。
2、有狀態(tài)測試方法statefulSessionTest規(guī)則規(guī)則3,即最終打0.85折。

package com.huan.drools;
import org.kie.api.KieServices;
import org.kie.api.event.rule.DebugRuleRuntimeEventListener;
import org.kie.api.runtime.KieContainer;
import org.kie.api.runtime.KieSession;
import org.kie.api.runtime.StatelessKieSession;
/**
 * drools 測試類
 */
public class DroolsApplication {
    public static void main(String[] args) throws InterruptedException {
        // 無狀態(tài)session測試
        statelessSessionTest();
        // 有狀態(tài)session測試
        statefulSessionTest();
    }
    private static void statelessSessionTest() {
        // 獲取kie services
        KieServices kieServices = KieServices.get();
        // 獲取kie容器對象
        KieContainer kieContainer = kieServices.getKieClasspathContainer();
        // 獲取kie session , 此處獲取的是無狀態(tài)的session,因?yàn)?<ksession name="shop-ksession" default="false" type="stateless"/>
        // 中type="stateless"就是無狀態(tài)的session
        StatelessKieSession kieSession = kieContainer.newStatelessKieSession("shop-ksession");
        // 創(chuàng)建一個(gè)對象,可以理解為 Fact對象,即事實(shí)對象
        CustomerOrder customerOrder = new CustomerOrder(2);
        // 添加監(jiān)聽器,便于觀察日志
        kieSession.addEventListener(new DebugRuleRuntimeEventListener());
        // 無狀態(tài)的session只需要執(zhí)行 execute 方法即可。
        kieSession.execute(customerOrder);
        System.err.println("通過規(guī)則后,獲取到的折扣為:" + customerOrder.getDiscount());
    }
    private static void statefulSessionTest() {
        // 獲取kie services
        KieServices kieServices = KieServices.get();
        // 獲取kie容器對象
        KieContainer kieContainer = kieServices.getKieClasspathContainer();
        // 獲取kie session , 此處獲取的是有狀態(tài)的session
        KieSession kieSession = kieContainer.newKieSession("shop-ksession-stateful");
        // 創(chuàng)建一個(gè)對象,可以理解為 Fact對象,即事實(shí)對象
        CustomerOrder customerOrder = new CustomerOrder(3);
        // 添加監(jiān)聽器,便于觀察日志
        kieSession.addEventListener(new DebugRuleRuntimeEventListener());
        // 將customerOrder對象加入到工作內(nèi)存中
        kieSession.insert(customerOrder);
        // 觸發(fā)所有的規(guī)則,如果只想觸發(fā)指定的規(guī)則,則使用fireAllRules(AgendaFilter agendaFilter)方法
        kieSession.fireAllRules();
        // 有狀態(tài)的session一定需要調(diào)用dispose方法
        kieSession.dispose();
        System.err.println("通過規(guī)則后,獲取到的折扣為:" + customerOrder.getDiscount());
    }
}

此處需要注意有狀態(tài)session無狀態(tài)session寫法的區(qū)別。

五、測試結(jié)果

到此,我們使用drools實(shí)現(xiàn)的一個(gè)簡單的案例就實(shí)現(xiàn)了。

六、drools引擎的基本組件

1、Rules:我們自己定義的業(yè)務(wù)規(guī)則,比如我們自己寫的規(guī)則文件。所有規(guī)則必須至少包含觸發(fā)規(guī)則的條件和規(guī)則規(guī)定的操作。
2、Production memory:規(guī)則存儲在 Drools 引擎中的位置。
3、Facts:輸入或更改到 Drools 引擎中的數(shù)據(jù),Drools 引擎匹配規(guī)則條件以執(zhí)行適用規(guī)則。在規(guī)則中修改了Fact對象的值,真實(shí)的JavaBean的數(shù)據(jù)也會發(fā)生改變。
比如:當(dāng)我們調(diào)用ksession.insert(對象),那么插入的這個(gè)對象就可以理解成Facts對象。
4、Working memory:facts 在 Drools 引擎中存儲的位置。
5、Pattern matcher:匹配器,將Rule Base中所有的規(guī)則與Working memory中的Fact對象進(jìn)行模式匹配,匹配成功的規(guī)則將被激活并放入到Agenda中。
6、Agenda:議程,執(zhí)行Agenda中被激活的排好序的規(guī)則。

七、完整代碼

https://gitee.com/huan1993/spring-cloud-parent/tree/master/drools/drools-quickstart

八、參考文檔

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

到此這篇關(guān)于drools的簡單入門案例的文章就介紹到這了,更多相關(guān)drools入門案例內(nèi)容請搜索html5模板網(wǎng)以前的文章希望大家以后多多支持html5模板網(wǎng)!

【網(wǎng)站聲明】本站部分內(nèi)容來源于互聯(lián)網(wǎng),旨在幫助大家更快的解決問題,如果有圖片或者內(nèi)容侵犯了您的權(quán)益,請聯(lián)系我們刪除處理,感謝您的支持!

相關(guān)文檔推薦

主站蜘蛛池模板: 物和码官网,物和码,免费一物一码数字化营销SaaS平台 | 伶俐嫂培训学校_月嫂培训班在哪里报名学费是多少_月嫂免费政府培训中心推荐 | 测试治具|过炉治具|过锡炉治具|工装夹具|测试夹具|允睿自动化设备 | 氢氧化钙设备_厂家-淄博工贸有限公司 | ISO9001认证咨询_iso9001企业认证代理机构_14001|18001|16949|50430认证-艾世欧认证网 | 石磨面粉机|石磨面粉机械|石磨面粉机组|石磨面粉成套设备-河南成立粮油机械有限公司 | 27PR跨境电商导航 | 专注外贸跨境电商| 【德信自动化】点胶机_全自动点胶机_自动点胶机厂家_塑料热压机_自动螺丝机-深圳市德信自动化设备有限公司 | 外贮压-柜式-悬挂式-七氟丙烷-灭火器-灭火系统-药剂-价格-厂家-IG541-混合气体-贮压-非贮压-超细干粉-自动-灭火装置-气体灭火设备-探火管灭火厂家-东莞汇建消防科技有限公司 | 铁艺,仿竹,竹节,护栏,围栏,篱笆,栅栏,栏杆,护栏网,网围栏,厂家 - 河北稳重金属丝网制品有限公司 山东太阳能路灯厂家-庭院灯生产厂家-济南晟启灯饰有限公司 | 范秘书_懂你的范文小秘书| 臻知网大型互动问答社区-你的问题将在这里得到解答!-无锡据风网络科技有限公司 | 点焊机-缝焊机-闪光对焊机-电阻焊设备生产厂家-上海骏腾发智能设备有限公司 | 优宝-汽车润滑脂-轴承润滑脂-高温齿轮润滑油脂厂家 | 电销卡_北京电销卡_包月电话卡-豪付网络 | 泵阀展|阀门展|水泵展|流体机械展 -2025上海国际泵管阀展览会flowtech china | 座椅式升降机_无障碍升降平台_残疾人升降平台-南京明顺机械设备有限公司 | 干式变压器厂_干式变压器厂家_scb11/scb13/scb10/scb14/scb18干式变压器生产厂家-山东科锐变压器有限公司 | 电脑知识|软件|系统|数据库|服务器|编程开发|网络运营|知识问答|技术教程文章 - 好吧啦网 | 复盛空压机配件-空气压缩机-复盛空压机(华北)总代理 | 数码听觉统合训练系统-儿童感觉-早期言语评估与训练系统-北京鑫泰盛世科技发展有限公司 | 超声骨密度仪,双能X射线骨密度仪【起草单位】,骨密度检测仪厂家 - 品源医疗(江苏)有限公司 | 培训中心-海南香蕉蛋糕加盟店技术翰香原中心官网总部 | 双工位钻铣攻牙机-转换工作台钻攻中心-钻铣攻牙机一体机-浙江利硕自动化设备有限公司 | 印刷人才网 印刷、包装、造纸,中国80%的印刷企业人才招聘选印刷人才网! | 消防泵-XBD单级卧式/立式消防泵-上海塑泉泵阀(集团)有限公司 | 中天寰创-内蒙古钢结构厂家|门式刚架|钢结构桁架|钢结构框架|包头钢结构煤棚 | 卧涛科技有限公司科技项目申报公司|高新技术企业申报|专利申请 | SRRC认证_电磁兼容_EMC测试整改_FCC认证_SDOC认证-深圳市环测威检测技术有限公司 | 脑钠肽-白介素4|白介素8试剂盒-研域(上海)化学试剂有限公司 | 奶茶加盟,奶茶加盟店连锁品牌-甜啦啦官网 | 大功率金属激光焊接机价格_不锈钢汽车配件|光纤自动激光焊接机设备-东莞市正信激光科技有限公司 定制奶茶纸杯_定制豆浆杯_广东纸杯厂_[绿保佳]一家专业生产纸杯碗的厂家 | 光纤测温-荧光光纤测温系统-福州华光天锐光电科技有限公司 | PVC快速门-硬质快速门-洁净室快速门品牌厂家-苏州西朗门业 | 骨灰存放架|骨灰盒寄存架|骨灰架厂家|智慧殡葬|公墓陵园管理系统|网上祭奠|告别厅智能化-厦门慈愿科技 | 郑州律师咨询-郑州律师事务所_河南锦盾律师事务所 | 锌合金压铸-铝合金压铸厂-压铸模具-冷挤压-誉格精密压铸 | 玻璃瓶厂家_酱菜瓶厂家_饮料瓶厂家_酒瓶厂家_玻璃杯厂家_徐州东明玻璃制品有限公司 | 武汉宣传片制作-视频拍摄-企业宣传片公司-武汉红年影视 | 广西资质代办_建筑资质代办_南宁资质代办理_新办、增项、升级-正明集团 | 软文发布-新闻发布推广平台-代写文章-网络广告营销-自助发稿公司媒介星 |