溫馨提示×

溫馨提示×

您好,登錄后才能下訂單哦!

密碼登錄×
登錄注冊×
其他方式登錄
點擊 登錄注冊 即表示同意《億速云用戶服務條款》

Drools規(guī)則引擎的作用是什么

發(fā)布時間:2021-06-24 14:53:12 來源:億速云 閱讀:1124 作者:chen 欄目:大數(shù)據(jù)

本篇內容主要講解“Drools規(guī)則引擎的作用是什么”,感興趣的朋友不妨來看看。本文介紹的方法操作簡單快捷,實用性強。下面就讓小編來帶大家學習“Drools規(guī)則引擎的作用是什么”吧!

   一、規(guī)則描述及判定

        規(guī)則約束和判定都是通過DRL(Drools Rule Language)文件完成,一個文件可包含一條或者多條規(guī)則。典型描述規(guī)則如下格式:

Drools規(guī)則引擎的作用是什么

    Package:包是Drools中相關資產的文件夾,如數(shù)據(jù)對象、DRL文件、決策表和其他資產類型。主要充當每個規(guī)則組的惟一名稱空間,必須位于文件的頂部,和Java中的編寫的相關的類的路徑無關,保證唯一即可。

    Import:導入需要使用的類的包或類

    Function:函數(shù)定義,如:

function String hello(String applicantName) {

            return "Hello " + applicantName + "!"; }

    Query: 可以根據(jù)規(guī)則名稱在引擎中查詢符合條件的結果對象;

    Declare:可以聲明一個類,與使用java 定義的類具有同樣的功能。如:

declare Cheese

        name : String

        price : int

        end

      Global:定義全局變量;

    Rule: 定義此規(guī)則的唯一標識;

    When: 條件判定,如Person( age == 50 ),在Person對象中,滿足age屬性等于50;

    Then: 滿足條件時觸發(fā)的動作,包括增、刪、改三個動作;

    End:規(guī)則執(zhí)行結束的標識符。

二、主要組件

第一次接觸的Drools的話對于各種配置和組件關系還是比較蒙蔽的,結合個人理解,給出一個簡單的關系圖,畫的可能有失偏頗,如有不對,還請指出:

Drools規(guī)則引擎的作用是什么

    kmodule.xml:定義在/META-INF/kmodule.xml,配置一個或多個Kiebase,每個Kiebase可配置多個KieSession。通常可以運行時根據(jù)項目需求動態(tài)生成KieBases 和 KieSessions,依賴于KieFileSystem提供各種方法。動態(tài)創(chuàng)建kmodule.xml的內容并加入到KieFileSystem。

Drools規(guī)則引擎的作用是什么

    KieBase:在項目的KIE模塊描述符文件(kmodule .xml)中定義的存儲庫,它包含Drools中的所有內容,但不包含任何運行時數(shù)據(jù),可通過KieContainer獲得:KieBase kBase = kContainer.getKieBase();

    KieServices:接口,可以訪問所有的創(chuàng)建和運行時對象,如日志,資源,環(huán)境,容器等。其中有的方法分為兩大類:getX()和newX(),其中,get只會返回一個對應單例對象的引用,new則會重新創(chuàng)建一個對象。

    KieContainer: 裝載與引擎相關的組件,通過KieServices.Factory.get()方式獲得,為其他Kie工具提供服務。KieContainer可以通過ReleaseId,Artifact,Version參數(shù)獲得另外一個KieContainer:

Drools規(guī)則引擎的作用是什么

    KieSession:在Drools中,KIE會話存儲并執(zhí)行運行時數(shù)據(jù)。如果在項目的KIE模塊描述符文件(kmodu .xml)中定義了KIE會話,則可以從KIE基礎創(chuàng)建KIE會話,或者直接從KIE容器創(chuàng)建,可細分有狀態(tài)和無狀態(tài)連接。

    .drl文件:可以動態(tài)的添加,KieResources 提供了多種工廠方式以轉化為InputStream, URL, File, String

Drools規(guī)則引擎的作用是什么

    創(chuàng)建.drl文件后,重新加載:

Drools規(guī)則引擎的作用是什么

三、嵌套規(guī)則判定

    嵌套規(guī)則,也可以理解為多重條件判定,這個Drools可以做的很好,主要是了解其drl文件的語法規(guī)則,則能夠很好的處理復雜的邏輯判斷,如嵌套對象、集合等常見需求,下面簡單的給個示例:

    1)定義User對象如下:

@Data 
public class User {

    private String name;

    private Integer age;

    private Pet pet;}

    2)定義Pet如下:

@Data

public class Pet {

    private String name;

    private String color;}

    3)定義規(guī)則如下:

rule "nested multiple condition"

    when

        $user : User(age>15 && age<60)

        $pet : Pet() from $user.pet

        if($pet.getColor()=="black") do[black]

        if($pet.getColor()=="white") break[white]

    then

        System.out.print("測試結束");

    then [black]

        System.out.println("pet color is balck");

    then [white]

        System.out.print("pet color is white");

     end

    4)執(zhí)行邏輯為:

Drools規(guī)則引擎的作用是什么

四、動態(tài)生成drl文件

    簡單場景下,drl文件可以預先定義好,但是很多時候我們需要根據(jù)條件來生成drl文件,或者從數(shù)據(jù)庫加載文件內容,此時就要動態(tài)地生成drl文件。其流程簡述為:界面配置,后臺生成drl文件,寫入規(guī)則引擎。其核心思想是:根據(jù)界面規(guī)則生成相應的.drl文件,動態(tài)加載進內存再由引擎判定。代碼參考如下:

public void reload() throws UnsupportedEncodingException {
        KieServices kieServices = getKieServices();
        KieFileSystem kfs = kieServices.newKieFileSystem();
        kfs.write("src/main/resources/rules/temp.drl", loadRules());
        KieBuilder kieBuilder = kieServices.newKieBuilder(kfs).buildAll();
        Results results = kieBuilder.getResults();
        if (results.hasMessages(Message.Level.ERROR)) {
            System.out.println(results.getMessages());
            throw new IllegalStateException("### errors ###");
        }
    }

    private String loadRules() {
        // 假設從數(shù)據(jù)庫加載的規(guī)則
        return "package adress\n\n rule \"Postcode 6 numbers\"\n\n    when\n  then\n        System.out.println(\"規(guī)則2中打印日志:我是從數(shù)據(jù)庫加載的!\");\n end";

    }

五、動態(tài)加載規(guī)則

    更為普遍地使用場景是:規(guī)則可以動態(tài)生成(如上所述),規(guī)則可以動態(tài)加載進引擎,根據(jù)條件加載指定地規(guī)則。這又如何實現(xiàn)呢?

    在Drools中,KieContainer是引擎執(zhí)行時的核心工具,一個container會加載kmodule.xml中的所有資源。因此,可以將不同的kmodule.xml加載進不同的container,那么就可以根據(jù)參數(shù)選擇container,從而觸發(fā)此container中的引擎。注意,drl文件和kmodule.xml不是一對一的關系,但是drl文件的包名和kmodule.xml中package屬性是對應的,詳見下節(jié)討論。為保證項目結構清晰,便于管理,一般可以kmodule.xml對應一個drl文件。

    參考代碼如下:

private KieContainer getContainer(String domain) {
        KieServices kieServices = KieServices.Factory.get();
        KieFileSystem kfs = kieServices.newKieFileSystem();
        //內部方法,生成kmodule.xml文件,返回此xml文件中KieSession名稱,下次可根據(jù)此sessionName從kieContainer中生成獲得對應的session
        sessionName = generateXML(domain, kieServices, kfs);
        //寫入drl文件并加載進
        kfs.write("src/main/resources/rules/temp.drl", loadRules());
        KieBuilder kieBuilder = kieServices.newKieBuilder(kfs).buildAll();
        
        //生成裝載此xml文件的容器
        KieContainer kieContainer = 
        kieServices.newKieContainer(kieServices.getRepository().getDefaultReleaseId());
        //建立對應關系并緩存起來此規(guī)則
        cache.put(domain,kieContainer);
        return kieContainer;
    }

//訪問資源
 @ResponseBody
    @RequestMapping("dynamic/{domain}")
    public String resource(@PathVariable String domain) {
        String res="你不是第一次訪問,直接加載相關資源";
        KieContainer kieContainer = cache.get(domain);
        if (null == kieContainer) {
            res="你是第一次訪問,生成相關資源";
            kieContainer=getContainer(domain);
        }
        //根據(jù)之前生成的sessionName獲取kieSession,然后規(guī)則校驗
        final KieSession kieSession = kieContainer.newKieSession(sessionName);
        kieSession.insert(new Address());
        kieSession.fireAllRules();
        kieSession.dispose();
        return res;
    }

六、加載指定的規(guī)則的文件

    這種需求也是很常見的,比如不同的產品在出廠時,其校驗規(guī)則肯定是不一樣的,都有其自身特有的屬性校驗。那么,如何根據(jù)不同的參數(shù)來使用不同規(guī)則呢?如下kmodule.xml文件:

<kmodule xmlns="http://www.drools.org/xsd/kmodule">

  <kbase name="kbase1">
    <ksession name="ksession1"/>
  </kbase>

  <kbase name="kbase2" packages="org.some.pkg">
    <ksession name="ksession2"/>
  </kbase>
</kmodule>

    可以根據(jù)kmodule.xml中不同的package屬性來指定加載哪個.drl文件,packages="org.some.pkg"表示ksession2只會加載org.some.pkg下的規(guī)則文件,如果沒寫,則默認加載所有的規(guī)則文件。相應Java代碼如下:

KieContainer kc =KieServices.Factory.get().getKieClasspathContainer();

KieSession kieSession = kc.newKieSession("ksession2");

    此KieSession只會加載drl文件中有package org.some.pkg 聲明的規(guī)則文件。如果沒有指明kiesession名稱,則會默認加載所有的drl文件,并且此時kmodule.xml中不能聲明任何kbase標簽,否則報錯:

java.lang.RuntimeException: Cannot find a default KieSession

七、其他需求

    規(guī)則的判定順序可以使用屬性Salience:定義規(guī)則優(yōu)先級的整數(shù)。值越大,優(yōu)先級越高,如salience 10

到此,相信大家對“Drools規(guī)則引擎的作用是什么”有了更深的了解,不妨來實際操作一番吧!這里是億速云網站,更多相關內容可以進入相關頻道進行查詢,關注我們,繼續(xù)學習!

向AI問一下細節(jié)

免責聲明:本站發(fā)布的內容(圖片、視頻和文字)以原創(chuàng)、轉載和分享為主,文章觀點不代表本網站立場,如果涉及侵權請聯(lián)系站長郵箱:is@yisu.com進行舉報,并提供相關證據(jù),一經查實,將立刻刪除涉嫌侵權內容。

AI