欧美bbbwbbbw肥妇,免费乱码人妻系列日韩,一级黄片

Springboot集成規(guī)則引擎Drools方式

 更新時(shí)間:2023年11月27日 16:51:26   作者:Leopard鋒  
這篇文章主要介紹了Springboot集成規(guī)則引擎Drools方式,具有很好的參考價(jià)值,希望對大家有所幫助,如有錯(cuò)誤或未考慮完全的地方,望不吝賜教

Drools 是用 Java 語言編寫的開放源碼規(guī)則引擎,使用 Rete 算法對所編寫的規(guī)則求值。

Drools 允許使用聲明方式表達(dá)業(yè)務(wù)邏輯。

可以使用非 XML 的本地語言編寫規(guī)則,從而便于學(xué)習(xí)和理解。

并且,還可以將 Java 代碼直接嵌入到規(guī)則文件中。

詳細(xì)可見開源業(yè)務(wù)規(guī)則引擎:Drools中文網(wǎng)

一、項(xiàng)目目錄結(jié)構(gòu)

二、集成drools

1、引入依賴

 
        <!--drools規(guī)則引擎-->
        <dependency>
            <groupId>org.drools</groupId>
            <artifactId>drools-core</artifactId>
            <version>7.59.0.Final</version>
        </dependency>
        <dependency>
            <groupId>org.drools</groupId>
            <artifactId>drools-compiler</artifactId>
            <version>7.59.0.Final</version>
        </dependency>
        <dependency>
            <groupId>org.drools</groupId>
            <artifactId>drools-templates</artifactId>
            <version>7.59.0.Final</version>
        </dependency>
        <dependency>
            <groupId>org.kie</groupId>
            <artifactId>kie-api</artifactId>
            <version>7.59.0.Final</version>
        </dependency>
        <dependency>
            <groupId>org.kie</groupId>
            <artifactId>kie-spring</artifactId>
            <version>7.59.0.Final</version>
        </dependency>

2、新建規(guī)則文件

rule1.drl

package com.leopard.drools
import com.leopard.drools.pojo.QueryParam
import com.leopard.drools.service.RuleEngineService
 
dialect  "java"
 
rule "boy"
    when queryParam : QueryParam(paramId != null && paramSign.equals("+"))
    then
        RuleEngineService ruleEngineService = new RuleEngineService();
        ruleEngineService.executeAddRule(queryParam);
        System.out.println("參數(shù):getParamId="+queryParam.getParamId()+";getParamSign="+queryParam.getParamSign());
end

rule2.drl

package com.leopard.drools
import com.leopard.drools.pojo.QueryParam
 
dialect  "java"
rule "girl"
    when queryParam : QueryParam(paramId != null && paramSign.equals("-"))
    then
        System.out.println(queryParam.getParamId() +  "是女孩");
end

3、創(chuàng)建KieUtils(因要做熱加載,需要重載規(guī)則文件,規(guī)則引擎容器要支持變動(dòng))

public class KieUtils {
 
    private static KieContainer kieContainer;
 
    private static KieSession kieSession;
 
    private static KModuleBeanFactoryPostProcessor kModuleBeanFactoryPostProcessor;
 
    public static KieContainer getKieContainer() {
        return kieContainer;
    }
 
    public static void setKieContainer(KieContainer kieContainer) {
        KieUtils.kieContainer = kieContainer;
        kieSession = kieContainer.newKieSession();
    }
 
    public static KieSession getKieSession() {
        return kieSession;
    }
 
    public static void setKieSession(KieSession kieSession) {
        KieUtils.kieSession = kieSession;
    }
 
    public static KieServices getKieServices() {
        return KieServices.Factory.get();
    }
 
    public static KModuleBeanFactoryPostProcessor getkModuleBeanFactoryPostProcessor() {
        return kModuleBeanFactoryPostProcessor;
    }
 
    public static void setkModuleBeanFactoryPostProcessor(KModuleBeanFactoryPostProcessor kModuleBeanFactoryPostProcessor) {
        KieUtils.kModuleBeanFactoryPostProcessor = kModuleBeanFactoryPostProcessor;
    }
}

4、添加初始化配置

 
@Slf4j
@Configuration
public class RuleEngineConfig {
 
    public static final String RULES_PATH = "droolsRule/";
    public static final String BASE_RULES_PATH = "classpath*:";
 
    private final KieServices kieServices = KieServices.Factory.get();
 
    /**
     * @return
     * @throws IOException
     * @ConditionalOnMissingBean,它是修飾bean的一個(gè)注解, 主要實(shí)現(xiàn)的是,當(dāng)你的bean被注冊之后,如果而注冊相同類型的bean,就不會(huì)成功,
     * 它會(huì)保證你的bean只有一個(gè),即你的實(shí)例只有一個(gè),當(dāng)你注冊多個(gè)相同的bean時(shí),會(huì)出現(xiàn)異常
     */
    @Bean
    @ConditionalOnMissingBean(KieFileSystem.class)
    public KieFileSystem kieFileSystem() throws IOException {
        KieFileSystem kieFileSystem = kieServices.newKieFileSystem();
        //獲取初始化規(guī)則文件所在路徑
        ResourcePatternResolver resourcePatternResolver = new PathMatchingResourcePatternResolver();
        Resource[] files = resourcePatternResolver.getResources(BASE_RULES_PATH + RULES_PATH + "*.*");
        String path = null;
        for (Resource file : files) {
            path = RULES_PATH + file.getFilename();
            log.info("path=" + path);
            //將規(guī)則文件寫規(guī)則引擎系統(tǒng)內(nèi)
            kieFileSystem.write(ResourceFactory.newClassPathResource(path, "UTF-8"));
        }
        return kieFileSystem;
    }
 
    /**
     * 創(chuàng)建KIE內(nèi)部容器
     *
     * @return
     * @throws IOException
     */
    @Bean
    @ConditionalOnMissingBean(KieContainer.class)
    public KieContainer kieContainer() throws IOException {
 
        final KieRepository kieRepository = kieServices.getRepository();
        kieRepository.addKieModule(kieRepository::getDefaultReleaseId);
        KieBuilder kieBuilder = kieServices.newKieBuilder(kieFileSystem());
        kieBuilder.buildAll();
        KieContainer kieContainer = kieServices.newKieContainer(kieRepository.getDefaultReleaseId());
        KieUtils.setKieContainer(kieContainer);
        return kieServices.newKieContainer(kieRepository.getDefaultReleaseId());
    }
 
    @Bean
    @ConditionalOnMissingBean(KieBase.class)
    public KieBase kieBase() throws IOException {
        return kieContainer().getKieBase();
    }
 
    @Bean
    @ConditionalOnMissingBean(KieSession.class)
    public KieSession kieSession() throws IOException {
        KieSession kieSession = kieContainer().newKieSession();
        KieUtils.setKieSession(kieSession);
        return kieSession;
    }
 
    @Bean
    @ConditionalOnMissingBean(KModuleBeanFactoryPostProcessor.class)
    public KModuleBeanFactoryPostProcessor kModuleBeanFactoryPostProcessor() {
        return new KModuleBeanFactoryPostProcessor();
    }
}

5、重載實(shí)現(xiàn),可通過鏈接數(shù)據(jù)庫刷新規(guī)則

@Slf4j
@Service
public class ReloadDroolsRules {
 
    @Autowired
    private KieSession kieSession;
 
    @Autowired
    private KieContainer kieContainer;
 
    /**
     * 重新加載規(guī)則
     * @param drlName   規(guī)則名稱
     * @throws Exception
     */
    public void reload(String drlName) throws Exception {
 
        KieFileSystem kfs = KieUtils.getKieServices().newKieFileSystem();
//        loadDBRules(drlName, kfs);
        loadFileRules(drlName, kfs);
        KieBuilder kieBuilder = KieUtils.getKieServices().newKieBuilder(kfs).buildAll();
        Results results = kieBuilder.getResults();
        if (results.hasMessages(Message.Level.ERROR)) {
            System.out.println(results.getMessages());
            throw new IllegalStateException("### errors ###");
        }
        KieContainer kieContainer = KieUtils.getKieServices().newKieContainer(KieUtils.getKieServices().getRepository().getDefaultReleaseId());
        KieUtils.setKieContainer(kieContainer);
        System.out.println("新規(guī)則重載成功");
    }
 
    /**
     * 重新讀取數(shù)據(jù)庫配置內(nèi)容
     * @param drlName
     * @param kfs
     * @throws IOException
     */
    private void loadDBRules(String drlName, KieFileSystem kfs) throws IOException {
        //        String path = "src/main/resources/rules/address.drl";
        String path = "src/main/resources/" + RuleEngineConfig.RULES_PATH + "/" + drlName + ".drl";
        // 從數(shù)據(jù)庫加載的規(guī)則
        kfs.write(path, "package plausibcheck.adress\n\n import com.leopard.drools.pojo.QueryParam;\n\n rule \"Postcode 6 numbers\"\n\n    when\n  then\n        System.out.println(\"打印日志:更新rules成功!\");\n end");
    }
 
    /**
     * 重新配置文件
     * @param drlName
     * @param kfs
     * @throws IOException
     */
    private void loadFileRules(String drlName, KieFileSystem kfs) throws IOException {
        // 從classess/rules加載的規(guī)則
        //獲取初始化規(guī)則文件所在路徑
        String path = null;
        for (Resource file : getRuleFiles(drlName)) {
            path = RuleEngineConfig.RULES_PATH + file.getFilename();
            log.info("path=" + path);
            //將規(guī)則文件寫規(guī)則引擎系統(tǒng)內(nèi)
            kfs.write(ResourceFactory.newClassPathResource(path, "UTF-8"));
        }
    }
 
    private Resource[] getRuleFiles(String drlName) throws IOException {
        if (StringUtils.isEmpty(drlName)) {
            ResourcePatternResolver resourcePatternResolver = new PathMatchingResourcePatternResolver();
            return resourcePatternResolver.getResources(RuleEngineConfig.BASE_RULES_PATH + RuleEngineConfig.RULES_PATH + "**/*.*");
        }
        ResourcePatternResolver resourcePatternResolver = new PathMatchingResourcePatternResolver();
        return resourcePatternResolver.getResources(RuleEngineConfig.BASE_RULES_PATH + RuleEngineConfig.RULES_PATH + "**/" + drlName + ".*");
    }
}

三、驗(yàn)證測試

1、創(chuàng)建測試實(shí)體類

@Data
public class QueryParam {
 
    private String paramId;
 
    private String paramSign;
}

2、添加規(guī)則實(shí)現(xiàn)

@Slf4j
@Service
public class RuleEngineService {
 
    /**
     * 插入規(guī)則
     *
     * @param param
     */
    public void executeAddRule(QueryParam param) {
        log.info("參數(shù)數(shù)據(jù):" + param.getParamId() + ";" + param.getParamSign());
        log.info("插入規(guī)則");
    }
 
    /**
     * 移除規(guī)則
     *
     * @param param
     */
    public void executeRemoveRule(QueryParam param) {
        log.info("參數(shù)數(shù)據(jù):" + param.getParamId() + ";" + param.getParamSign());
        log.info("移除規(guī)則");
    }
}

3、API調(diào)用實(shí)現(xiàn)

@RestController
@RequestMapping(value = "test")
public class TestController {
 
    @Autowired
    private RuleEngineService ruleEngineService;
 
    @Autowired
    private ReloadDroolsRules reloadDroolsRules;
 
    @RequestMapping("/param")
    public void param (){
        QueryParam queryParam1 = new QueryParam() ;
        queryParam1.setParamId("1");
        queryParam1.setParamSign("+");
        QueryParam queryParam2 = new QueryParam() ;
        queryParam2.setParamId("2");
        queryParam2.setParamSign("-");
        QueryParam queryParam3 = new QueryParam() ;
        queryParam3.setParamId("3");
        queryParam3.setParamSign("-");
        // 入?yún)?
        KieUtils.getKieSession().insert(queryParam2) ;
        KieUtils.getKieSession().insert(queryParam3) ;
        KieUtils.getKieSession().insert(queryParam1) ;
        KieUtils.getKieSession().insert(this.ruleEngineService) ;
        // 返參
        KieUtils.getKieSession().fireAllRules() ;
    }
 
    @RequestMapping("/reload")
    public String reload (String ruleName) throws Exception {
        // 返參
        reloadDroolsRules.reload(ruleName);
        return "新規(guī)則重載成功";
    }
 
}

運(yùn)行服務(wù),查看結(jié)果

調(diào)用 localhost:9666/api/v1/test/param

修改規(guī)則文件,調(diào)用重新加載配置 localhost:9666/api/v1/test/reload,不指定配置規(guī)則文件名,默認(rèn)重新加載全部規(guī)則,然后重新調(diào)用請求

需要注意點(diǎn):

修改規(guī)則配置,是修改加載后的文件,也就是 運(yùn)行項(xiàng)目時(shí),生成的 target目錄下加載的規(guī)則文件,而不是項(xiàng)目本身resources下的。

總結(jié)

以上為個(gè)人經(jīng)驗(yàn),希望能給大家一個(gè)參考,也希望大家多多支持腳本之家。

相關(guān)文章

  • MyBatis實(shí)現(xiàn)動(dòng)態(tài)查詢、模糊查詢功能

    MyBatis實(shí)現(xiàn)動(dòng)態(tài)查詢、模糊查詢功能

    這篇文章主要介紹了MyBatis實(shí)現(xiàn)動(dòng)態(tài)查詢、模糊查詢功能,非常不錯(cuò),具有一定的參考借鑒價(jià)值,需要的朋友可以參考下
    2018-06-06
  • Java NumberFormat格式化float類型的bug

    Java NumberFormat格式化float類型的bug

    今天小編就為大家分享一篇關(guān)于Java NumberFormat格式化float類型的bug,小編覺得內(nèi)容挺不錯(cuò)的,現(xiàn)在分享給大家,具有很好的參考價(jià)值,需要的朋友一起跟隨小編來看看吧
    2018-10-10
  • Spring @value用法示例詳解

    Spring @value用法示例詳解

    這篇文章主要介紹了Spring-@value用法詳解,為了簡化讀取properties文件中的配置值,spring支持@value注解的方式來獲取,這種方式大大簡化了項(xiàng)目配置,提高業(yè)務(wù)中的靈活性,本文通過實(shí)例代碼給大家介紹的非常詳細(xì),需要的朋友參考下吧
    2022-08-08
  • Java中的反射機(jī)制詳解

    Java中的反射機(jī)制詳解

    這篇文章主要介紹了Java中的反射機(jī)制詳解的相關(guān)資料,需要的朋友可以參考下
    2017-06-06
  • Spring?AOP的注解實(shí)現(xiàn)方式實(shí)例詳解

    Spring?AOP的注解實(shí)現(xiàn)方式實(shí)例詳解

    AOP是一種對某一類事情集中處理的思想,本文給大家介紹Spring?AOP的注解實(shí)現(xiàn)方式實(shí)例詳解,感興趣的朋友一起看看吧
    2025-04-04
  • 一文徹底弄懂Java中MultipartFile接口和File類

    一文徹底弄懂Java中MultipartFile接口和File類

    MultipartFile是一個(gè)接口,我們可以理解為是Spring?給我們綁定的一個(gè)在使用文件上傳等時(shí)簡便實(shí)現(xiàn)的口子,這篇文章主要給大家介紹了關(guān)于如何通過一文徹底弄懂Java中MultipartFile接口和File類的相關(guān)資料,需要的朋友可以參考下
    2023-11-11
  • Java設(shè)計(jì)模式:組合模式

    Java設(shè)計(jì)模式:組合模式

    這篇文章主要介紹了快速理解Java設(shè)計(jì)模式中的組合模式,具有一定參考價(jià)值,需要的朋友可以了解下,希望能夠給你帶來幫助
    2021-09-09
  • Java微信公眾平臺開發(fā)(2) 微信服務(wù)器post消息體的接收

    Java微信公眾平臺開發(fā)(2) 微信服務(wù)器post消息體的接收

    這篇文章主要為大家詳細(xì)介紹了Java微信公眾平臺開發(fā)第二步,微信服務(wù)器post消息體的接收,具有一定的參考價(jià)值,感興趣的小伙伴們可以參考一下
    2017-04-04
  • JAVA獲取rabbitmq消息總數(shù)過程詳解

    JAVA獲取rabbitmq消息總數(shù)過程詳解

    這篇文章主要介紹了JAVA獲取rabbitmq消息總數(shù)過程詳解,公司使用的是rabbitMQ,需要做監(jiān)控預(yù)警的job去監(jiān)控rabbitMQ里面的堆積消息個(gè)數(shù),如何使用rabbitMQ獲取監(jiān)控的隊(duì)列里面的隊(duì)列消息個(gè)數(shù)呢,需要的朋友可以參考下
    2019-07-07
  • Java使用OpenCV進(jìn)行圖像處理的示例代碼

    Java使用OpenCV進(jìn)行圖像處理的示例代碼

    OpenCV是一個(gè)開源的計(jì)算機(jī)視覺庫,廣泛應(yīng)用于圖像處理、機(jī)器學(xué)習(xí)和計(jì)算機(jī)視覺等領(lǐng)域,盡管OpenCV主要使用C/C++進(jìn)行開發(fā),但它也為Java提供了綁定,使得Java開發(fā)者能夠利用其強(qiáng)大的圖像處理功能,在本篇文章中,我們將詳細(xì)介紹如何在Java中使用OpenCV,需要的朋友可以參考下
    2025-03-03

最新評論