SpringBoot2整合Drools规则引擎及案例详解

作者:知了一笑 时间:2021-12-30 05:57:10 

一、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、项目结构

SpringBoot2 整合 Drools规则引擎,实现高效的业务规则

SpringBoot2整合Drools规则引擎及案例详解

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

来源:https://blog.51cto.com/14439672/2444594

标签:spring,boot,2,整合,drools,规则,引擎
0
投稿

猜你喜欢

  • Java多线程的临界资源问题解决方案

    2021-12-29 07:44:35
  • Java循环对bean的属性进行赋值的实现

    2023-01-27 10:18:05
  • Java 获取当前系统时间的三种方法

    2023-11-21 12:51:51
  • Java编程基础测试题分享

    2023-11-27 22:14:58
  • Maven setting.xml配置文件详解

    2023-06-28 00:33:41
  • java IO流文件的读写具体实例

    2023-08-21 04:44:34
  • Java 8 中 Function 接口使用方法介绍

    2022-12-08 23:54:39
  • C语言时间函数之strftime()详解

    2023-06-26 02:42:32
  • 从dubbo zookeeper注册地址提取出zookeeper地址的方法

    2023-04-29 18:51:16
  • Java中初始化List集合的八种方式汇总

    2021-09-20 22:31:54
  • c++中的malloc底层实现代码

    2023-11-02 19:49:18
  • SpringBoot基于数据库的定时任务统一管理的实现

    2023-12-10 12:57:47
  • java设计模式之外观模式学习笔记

    2022-07-02 18:48:06
  • 利用Lambda表达式创建新线程案例

    2023-08-26 23:16:00
  • Java中HashMap里面key为null存放到哪

    2023-11-10 02:46:47
  • Quarkus的Spring扩展快速改造Spring项目

    2023-11-26 03:01:58
  • 图文详解SpringBoot中Log日志的集成

    2023-05-27 09:55:13
  • 详解java.lang.reflect.Modifier.isInterface()方法

    2023-07-27 18:25:25
  • ActiveMQ安装及部署教程图解

    2023-11-17 18:01:46
  • C++实现无重复字符的最长子串

    2023-11-02 22:49:00
  • asp之家 软件编程 m.aspxhome.com