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

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

10年的金鳳網(wǎng)站建設(shè)經(jīng)驗(yàn),針對(duì)設(shè)計(jì)、前端、開發(fā)、售后、文案、推廣等六對(duì)一服務(wù),響應(yīng)快,48小時(shí)及時(shí)工作處理。營(yíng)銷型網(wǎng)站的優(yōu)勢(shì)是能夠根據(jù)用戶設(shè)備顯示端的尺寸不同,自動(dòng)調(diào)整金鳳建站的顯示方式,使網(wǎng)站能夠適用不同顯示終端,在瀏覽器中調(diào)整網(wǎng)站的寬度,無(wú)論在任何一種瀏覽器上瀏覽網(wǎng)站,都能展現(xiàn)優(yōu)雅布局與設(shè)計(jì),從而大程度地提升瀏覽體驗(yàn)。創(chuàng)新互聯(lián)從事“金鳳網(wǎng)站設(shè)計(jì)”,“金鳳網(wǎng)站推廣”以來,每個(gè)客戶項(xiàng)目都認(rèn)真落實(shí)執(zhí)行。

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

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

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

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

    Import:導(dǎo)入需要使用的類的包或類

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

function String hello(String applicantName) {

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

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

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

declare Cheese

        name : String

        price : int

        end

      Global:定義全局變量;

    Rule: 定義此規(guī)則的唯一標(biāo)識(shí);

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

    Then: 滿足條件時(shí)觸發(fā)的動(dòng)作,包括增、刪、改三個(gè)動(dòng)作;

    End:規(guī)則執(zhí)行結(jié)束的標(biāo)識(shí)符。

二、主要組件

第一次接觸的Drools的話對(duì)于各種配置和組件關(guān)系還是比較蒙蔽的,結(jié)合個(gè)人理解,給出一個(gè)簡(jiǎn)單的關(guān)系圖,畫的可能有失偏頗,如有不對(duì),還請(qǐng)指出:

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

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

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

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

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

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

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

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

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

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

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

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

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

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

    1)定義User對(duì)象如下:

@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("測(cè)試結(jié)束");

    then [black]

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

    then [white]

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

     end

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

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

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

    簡(jiǎn)單場(chǎng)景下,drl文件可以預(yù)先定義好,但是很多時(shí)候我們需要根據(jù)條件來生成drl文件,或者從數(shù)據(jù)庫(kù)加載文件內(nèi)容,此時(shí)就要?jiǎng)討B(tài)地生成drl文件。其流程簡(jiǎn)述為:界面配置,后臺(tái)生成drl文件,寫入規(guī)則引擎。其核心思想是:根據(jù)界面規(guī)則生成相應(yīng)的.drl文件,動(dòng)態(tài)加載進(jìn)內(nè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è)從數(shù)據(jù)庫(kù)加載的規(guī)則
        return "package adress\n\n rule \"Postcode 6 numbers\"\n\n    when\n  then\n        System.out.println(\"規(guī)則2中打印日志:我是從數(shù)據(jù)庫(kù)加載的!\");\n end";

    }

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

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

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

    參考代碼如下:

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

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

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

    這種需求也是很常見的,比如不同的產(chǎn)品在出廠時(shí),其校驗(yàn)規(guī)則肯定是不一樣的,都有其自身特有的屬性校驗(yàn)。那么,如何根據(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屬性來指定加載哪個(gè).drl文件,packages="org.some.pkg"表示ksession2只會(huì)加載org.some.pkg下的規(guī)則文件,如果沒寫,則默認(rèn)加載所有的規(guī)則文件。相應(yīng)Java代碼如下:

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

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

    此KieSession只會(huì)加載drl文件中有package org.some.pkg 聲明的規(guī)則文件。如果沒有指明kiesession名稱,則會(huì)默認(rèn)加載所有的drl文件,并且此時(shí)kmodule.xml中不能聲明任何kbase標(biāo)簽,否則報(bào)錯(cuò):

java.lang.RuntimeException: Cannot find a default KieSession

七、其他需求

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

到此,相信大家對(duì)“Drools規(guī)則引擎的作用是什么”有了更深的了解,不妨來實(shí)際操作一番吧!這里是創(chuàng)新互聯(lián)網(wǎng)站,更多相關(guān)內(nèi)容可以進(jìn)入相關(guān)頻道進(jìn)行查詢,關(guān)注我們,繼續(xù)學(xué)習(xí)!

新聞名稱:Drools規(guī)則引擎的作用是什么
網(wǎng)頁(yè)URL:http://muchs.cn/article10/pphggo.html

成都網(wǎng)站建設(shè)公司_創(chuàng)新互聯(lián),為您提供網(wǎng)站收錄云服務(wù)器、靜態(tài)網(wǎng)站、微信公眾號(hào)、動(dòng)態(tài)網(wǎng)站網(wǎng)站維護(hù)

廣告

聲明:本網(wǎng)站發(fā)布的內(nèi)容(圖片、視頻和文字)以用戶投稿、用戶轉(zhuǎn)載內(nèi)容為主,如果涉及侵權(quán)請(qǐng)盡快告知,我們將會(huì)在第一時(shí)間刪除。文章觀點(diǎn)不代表本網(wǎng)站立場(chǎng),如需處理請(qǐng)聯(lián)系客服。電話:028-86922220;郵箱:631063699@qq.com。內(nèi)容未經(jīng)允許不得轉(zhuǎn)載,或轉(zhuǎn)載時(shí)需注明來源: 創(chuàng)新互聯(lián)

網(wǎng)站優(yōu)化排名