zoukankan      html  css  js  c++  java
  • SpringBoot2 整合 Drools规则引擎,实现高效的业务规则

    本文源码:GitHub·点这里 || GitEE·点这里

    一、Drools引擎简介

    1、基础简介

    Drools是一个基于java的规则引擎,开源的,可以将复杂多变的规则从硬编码中解放出来,以规则脚本的形式存放在文件中,使得规则的变更不需要修正代码重启机器就可以立即在线上环境生效。具有易于访问企业策略、易于调整以及易于管理的特点,作为开源业务规则引擎,符合业内标准,速度快、效率高。

    2、规则语法

    (1)、演示drl文件格式

    package droolRule ;
    import org.slf4j.Logger
    import org.slf4j.LoggerFactory ;
    dialect  "java"
    rule "paramcheck1"
        when 
        then
            final Logger LOGGER = LoggerFactory.getLogger("param-check-one 规则引擎") ;
            LOGGER.info("参数");
    end
    

    (2)、语法说明

    · 文件格式
    可以 .drl、xml文件,也可以Java代码块硬编码;
    · package
    规则文件中,package是必须定义的,必须放在规则文件第一行;
    · import
    规则文件使用到的外部变量,可以是一个类,也可以是类中的可访问的静态方法;
    · rule
    定义一个规则。paramcheck1规则名。规则通常包含三个部分:属性、条件、结果;
    

    二、整合SpringBoot框架

    1、项目结构

    2、核心依赖

    <!--drools规则引擎-->
    <dependency>
        <groupId>org.drools</groupId>
        <artifactId>drools-core</artifactId>
        <version>7.6.0.Final</version>
    </dependency>
    <dependency>
        <groupId>org.drools</groupId>
        <artifactId>drools-compiler</artifactId>
        <version>7.6.0.Final</version>
    </dependency>
    <dependency>
        <groupId>org.drools</groupId>
        <artifactId>drools-templates</artifactId>
        <version>7.6.0.Final</version>
    </dependency>
    <dependency>
        <groupId>org.kie</groupId>
        <artifactId>kie-api</artifactId>
        <version>7.6.0.Final</version>
    </dependency>
    <dependency>
        <groupId>org.kie</groupId>
        <artifactId>kie-spring</artifactId>
        <version>7.6.0.Final</version>
    </dependency>
    

    3、配置文件

    @Configuration
    public class RuleEngineConfig {
        private static final Logger LOGGER = LoggerFactory.getLogger(RuleEngineConfig.class) ;
        private static final String RULES_PATH = "droolRule/";
        private final KieServices kieServices = KieServices.Factory.get();
        @Bean
        public KieFileSystem kieFileSystem() throws IOException {
            KieFileSystem kieFileSystem = kieServices.newKieFileSystem();
            ResourcePatternResolver resourcePatternResolver = new PathMatchingResourcePatternResolver();
            Resource[] files = resourcePatternResolver.getResources("classpath*:" + RULES_PATH + "*.*");
            String path = null;
            for (Resource file : files) {
                path = RULES_PATH + file.getFilename();
                LOGGER.info("path="+path);
                kieFileSystem.write(ResourceFactory.newClassPathResource(path, "UTF-8"));
            }
            return kieFileSystem;
        }
        @Bean
        public KieContainer kieContainer() throws IOException {
            KieRepository kieRepository = kieServices.getRepository();
            kieRepository.addKieModule(kieRepository::getDefaultReleaseId);
            KieBuilder kieBuilder = kieServices.newKieBuilder(kieFileSystem());
            kieBuilder.buildAll();
            return kieServices.newKieContainer(kieRepository.getDefaultReleaseId());
        }
        @Bean
        public KieBase kieBase() throws IOException {
            return kieContainer().getKieBase();
        }
        @Bean
        public KieSession kieSession() throws IOException {
            return kieContainer().newKieSession();
        }
        @Bean
        public KModuleBeanFactoryPostProcessor kiePostProcessor() {
            return new KModuleBeanFactoryPostProcessor();
        }
    }
    

    这样环境整合就完成了。

    三、演示案例

    1、规则文件

    • 规则一
    dialect  "java"
    rule "paramcheck1"
        salience 99
        when queryParam : QueryParam(paramId != null && paramSign.equals("+"))
            resultParam : RuleResult()
        then
            final Logger LOGGER = LoggerFactory.getLogger("param-check-one 规则引擎") ;
            LOGGER.info("参数:getParamId="+queryParam.getParamId()+";getParamSign="+queryParam.getParamSign());
            RuleEngineServiceImpl ruleEngineService = new RuleEngineServiceImpl() ;
            ruleEngineService.executeAddRule(queryParam);
            resultParam.setPostCodeResult(true);
    end
    
    • 规则二
    dialect  "java"
    rule "paramcheck2"
        salience 88
        when queryParam : QueryParam(paramId != null && paramSign.equals("-"))
            resultParam : RuleResult()
        then
            final Logger LOGGER = LoggerFactory.getLogger("param-check-two 规则引擎") ;
            LOGGER.info("参数:getParamId="+queryParam.getParamId()+";getParamSign="+queryParam.getParamSign());
            RuleEngineServiceImpl ruleEngineService = new RuleEngineServiceImpl() ;
            ruleEngineService.executeRemoveRule(queryParam);
            resultParam.setPostCodeResult(true);
    end
    

    规则说明:

    A、salience 的值越大,越优先执行;

    B、规则流程:如果paramId不为null,参数标识是+号,执行添加规则,-号,执行移除规则操作。

    2、规则执行代码

    @Service
    public class RuleEngineServiceImpl implements RuleEngineService {
        private static final Logger LOGGER = LoggerFactory.getLogger(RuleEngineServiceImpl.class) ;
        @Override
        public void executeAddRule(QueryParam param) {
            LOGGER.info("参数数据:"+param.getParamId()+";"+param.getParamSign());
            ParamInfo paramInfo = new ParamInfo() ;
            paramInfo.setId(param.getParamId());
            paramInfo.setParamSign(param.getParamSign());
            paramInfo.setCreateTime(new Date());
            paramInfo.setUpdateTime(new Date());
            ParamInfoService paramInfoService = (ParamInfoService)SpringContextUtil.getBean("paramInfoService") ;
            paramInfoService.insertParam(paramInfo);
        }
        @Override
        public void executeRemoveRule(QueryParam param) {
            LOGGER.info("参数数据:"+param.getParamId()+";"+param.getParamSign());
            ParamInfoService paramInfoService = (ParamInfoService)SpringContextUtil.getBean("paramInfoService") ;
            ParamInfo paramInfo = paramInfoService.selectById(param.getParamId());
            if (paramInfo != null){
                paramInfoService.removeById(param.getParamId()) ;
            }
        }
    }
    

    3、规则调用接口

    @RestController
    @RequestMapping("/rule")
    public class RuleController {
        @Resource
        private KieSession kieSession;
        @Resource
        private RuleEngineService ruleEngineService ;
        @RequestMapping("/param")
        public void param (){
            QueryParam queryParam1 = new QueryParam() ;
            queryParam1.setParamId("1");
            queryParam1.setParamSign("+");
            QueryParam queryParam2 = new QueryParam() ;
            queryParam2.setParamId("2");
            queryParam2.setParamSign("-");
            // 入参
            kieSession.insert(queryParam1) ;
            kieSession.insert(queryParam2) ;
            kieSession.insert(this.ruleEngineService) ;
            // 返参
            RuleResult resultParam = new RuleResult() ;
            kieSession.insert(resultParam) ;
            kieSession.fireAllRules() ;
        }
    }
    

    这样,完整的案例就结束了。

    四、源代码地址

    GitHub·地址
    https://github.com/cicadasmile/middle-ware-parent
    GitEE·地址
    https://gitee.com/cicadasmile/middle-ware-parent
    

  • 相关阅读:
    Leetcode NO.110 Balanced Binary Tree 平衡二叉树
    Leetcode NO.226 Invert Binary Tree 翻转二叉树
    Leetcode NO.215 Kth Largest Element In An Array 数组中的第K个最大元素
    根据特征的浏览器判断
    Cygwin在打开在当前目录
    【转帖】科学对待 健康养猫 打造快乐孕妇
    解决chrome浏览器安装扩展、应用程序一直处在“检查中”的问题
    对【SQL SERVER 分布式事务解决方案】的心得补充
    关于“点击这里继续访问您选择的百度XXX”
    VBA一例:如何保持文本框焦点
  • 原文地址:https://www.cnblogs.com/cicada-smile/p/11632629.html
Copyright © 2011-2022 走看看