SpringBoot整合 drools規則引擎 系列教程(一)快速集成上手

SpringBoot整合 drools規則引擎 系列教程(二)Drools規則語法 & LHS 條件java

教程代碼已提交到ytooo-drools,歡迎stargit

1. Drools簡介

什麼是規則引擎

  規則引擎由推理引擎發展而來,是一種嵌入在應用程序中的組件,
實現了將業務決策從應用程序代碼中分離出來,並使用預約義的語義模塊編寫業務決策。
接受數據輸入,解釋業務規則,並根據業務規則作出業務決策。github

  簡單來講包括像表單驗證和動態表達式引擎這樣的簡單系統均可以稱之爲規則引擎。web

爲何使用規則引擎?

  複雜企業級項目的開發以及其中隨外部條件不斷變化的業務規則(business logic),
迫切須要分離商業決策者的商業決策邏輯和應用開發者的技術決策,
並把這些商業決策放在中心數據庫或其餘統一的地方,讓它們能在運行時(即商務時間)
能夠動態地管理和修改從而提供軟件系統的柔性和適應性。規則引擎正是應用於上述動態環境中的一種解決方法。算法

  企業管理者對企業級IT系統的開發有着以下的要求:
爲提升效率,管理流程必須自動化,即便現代商業規則異常複雜;
市場要求業務規則常常變化,IT系統必須依據業務規則的變化快速、低成本的更新;
爲了快速、低成本的更新,業務人員應能直接管理IT系統中的規則,不須要程序開發人員參與。spring

規則引擎優勢

  • 聲明式編程
  • 邏輯與數據分離
  • 速度及可測量性
  • 知識集中化
  • 工具集成
  • 解釋機制
  • 易懂的規則

如何使用

開發人員在程序中使用規則引擎基本遵循如下5個典型的步驟:
  • 建立規則引擎對象;
  • 向引擎中加載規則集或更換規則集;
  • 向引擎提交須要被規則集處理的數據對象集合;
  • 命令引擎執行;
  • 導出引擎執行結果,從引擎中撤出處理過的數據。

使用了規則引擎以後,許多涉及業務邏輯的程序代碼基本被這五個典型步驟數據庫

drools

  Drools 是用 Java 語言編寫的具備一個易於訪問企業策略、易於調整以及易於管理的開源業務規則引擎
,其基於CHARLES FORGY'S的RETE算法
符合業內標準,速度快且效率高。 業務分析師人員或審覈人員能夠利用它輕鬆查看業務規則,
檢驗已編碼的規則執行了所需的業務規則。編程

2. 使用IDEA建立簡單的SpringBoot項目

新建springboot項目:

avatar

配置項目信息:

avatar

配置爲web項目:

avatar

3. 添加drools相關pom依賴

<properties>
    <java.version>1.8</java.version>
    <drools.version>7.14.0.Final</drools.version>
</properties>
<dependencies>
<!-- drools依賴 -->
    <dependency>
        <groupId>org.drools</groupId>
        <artifactId>drools-core</artifactId>
        <version>${drools.version}</version>
    </dependency>
    <dependency>
        <groupId>org.drools</groupId>
        <artifactId>drools-compiler</artifactId>
        <version>${drools.version}</version>
    </dependency>
    <!-- 決策表 -->
    <dependency>
        <groupId>org.drools</groupId>
        <artifactId>drools-decisiontables</artifactId>
        <version>${drools.version}</version>
    </dependency>
    <!-- 模板 -->
    <dependency>
        <groupId>org.drools</groupId>
        <artifactId>drools-templates</artifactId>
        <version>${drools.version}</version>
    </dependency>
    
    <dependency>
        <groupId>org.kie</groupId>
        <artifactId>kie-api</artifactId>
        <version>${drools.version}</version>
    </dependency>
</dependencies>

4. 建立KieSession Bean 使其被spring管理

@Configuration
public class KiaSessionConfig {
    @Bean
    public KieSession getSession() {
        KieServices ks = KieServices.Factory.get();
        KieContainer kContainer = ks.getKieClasspathContainer();
        return kContainer.newKieSession("ksession-rules");
    }
}

5. 建立drl規則文件

建立 kmodule.xml配置文件來指定規則文件.drl所在路徑,使用packages屬性來指定規則描述文件在項目中的位置(相對於resources)

<kmodule xmlns="http://jboss.org/kie/6.0.0/kmodule">
    <kbase name="rules" packages="rules">
        <ksession name="ksession-rules"/>
    </kbase>
</kmodule>

建立規則

1. people.drl
package com.ytooo.bean
import com.ytooo.bean.People
dialect  "java"

rule "man"
    when
        $p : People(sex == 1 && drlType == "people")
    then
        System.out.println($p.getName() + "是男孩");
end
2. people2.drl
package com.ytooo.bean
import com.ytooo.bean.People
dialect  "java"

rule "girl"
    when
        $p : People(sex == 0 && drlType == "people")
    then
        System.out.println($p.getName() + "是女孩");
end

drools中,規則是使用對象來匹配規則的,如上面兩個規則文件,在java中執行People對象的規則時,兩種規則都會觸發segmentfault

6. 建立實體對象People

package com.ytooo.bean;
import lombok.Data;

/**
 * Created by Youdmeng on 2020/1/7 0007.
 */
@Data
public class People {

    private int sex;

    private String name;

    private String drlType;

    public People(int sex, String name, String drlType) {
        this.sex = sex;
        this.name = name;
        this.drlType = drlType;
    }

    public People() {
    }
}

7. 建立測試方法

package com.ytooo;

import com.ytooo.bean.People;
import org.junit.jupiter.api.Test;
import org.junit.runner.RunWith;
import org.kie.api.runtime.KieSession;
import org.springframework.beans.factory.annotation.Autowired;
import org.springframework.boot.test.context.SpringBootTest;
import org.springframework.test.context.junit4.SpringRunner;

@SpringBootTest
@RunWith(SpringRunner.class)
class DroolsApplicationTests {

    @Autowired
    private KieSession session;

    @Test
    public void people() {
    
        People people = new People();
        people.setName("達");
        people.setSex(1);
        people.setDrlType("people");
        session.insert(people);//插入
        session.fireAllRules();//執行規則
    }
    @AfterEach
    public void runDispose() {
        session.dispose();//釋放資源
    }
}
  • 當入參爲sex爲1時,程序運行結果:
達是男孩
  • 當入參爲sex爲0時,程序運行結果:
達是女孩

當傳入其餘對象時,則不會觸發以上任何規則

package com.ytooo.bean;
import lombok.Data;

/**
 * Created by Youdmeng on 2020/1/7 0007.
 */
@Data
public class Cat {
    private int sex;

    private String name;
}
新增test方法
@Test
    public void cat() {
        Cat cat = new Cat();
        cat.setName("金");
        cat.setSex(1);
        session.insert(cat);//插入
        session.fireAllRules();//執行規則
    }

傳入sex爲1或0,都沒有結果輸出api

注:

相同.drl文件中能夠繼承多組規則如:

package com.ytooo.bean
import com.ytooo.bean.People
dialect  "java"

rule "man"
    when
        $p : People(sex == 1 && drlType == "people")
    then
        System.out.println($p.getName() + "是男孩");
end
rule "cat"
    when
        $c : Cat(sex == 1 && $c.getName().equals("金"))
    then
        System.out.println($c.getName() + "是公的");
end

教程代碼已提交到ytooo-drools,歡迎star

SpringBoot整合 drools規則引擎 系列教程(二)Drools規則語法 & LHS 條件

相關文章
相關標籤/搜索