SpringBoot整合Drools
文章目录
- 关于Drools
- 整合Drools
- 一般流程
- 快速整合
关于Drools
博客: 规则引擎 Drools
上面那篇博客详细的介绍了Drools,还要语法规则,关于什么是Drools,看这篇博客完全足够了。
下面的重点是springboot整合drools
整合Drools
一般流程
创建一个springboot项目,不会创建的可以参考这篇博客:【Spring Boot】快速上手SpringBoot
引入我们的drools依赖:
<dependency><groupId>org.kie</groupId><artifactId>kie-spring</artifactId><version>7.37.0.Final</version></dependency><dependency><groupId>org.drools</groupId><artifactId>drools-compiler</artifactId><version>7.37.0.Final</version></dependency>
配合测试可能还需要引入的依赖:
<dependency><groupId>junit</groupId><artifactId>junit</artifactId><version>4.13.2</version><scope>test</scope></dependency><dependency><groupId>org.projectlombok</groupId><artifactId>lombok</artifactId><version>1.18.20</version></dependency>
- 配置好我们的工具类KieSessionUtils,后面可以直接调用即可:
package com.gaolang.utils;import org.drools.decisiontable.InputType;
import org.drools.decisiontable.SpreadsheetCompiler;
import org.kie.api.KieBase;
import org.kie.api.KieServices;
import org.kie.api.builder.*;
import org.kie.api.event.rule.DebugRuleRuntimeEventListener;
import org.kie.api.io.Resource;
import org.kie.api.io.ResourceType;
import org.kie.api.runtime.KieContainer;
import org.kie.api.runtime.KieSession;
import org.kie.api.runtime.StatelessKieSession;
import org.kie.internal.utils.KieHelper;
import org.springframework.core.io.support.PathMatchingResourcePatternResolver;import java.io.File;
import java.io.FileInputStream;
import java.io.FileNotFoundException;
import java.io.InputStream;
import java.util.List;/**** 1.维护了有状态和无状态的两种Session对象,不推荐使用get。* 2.全局的Session已经在config下的Configuration中自动装配了。* 3.无并发的情况下,使用newKieSession()既可。* @author Hong Wen 2018/04/04**/
public class KieSessionUtils {private static KieSession kieSession;private static final String RULES_PATH = "rules/";private KieSessionUtils() {}/*** @description TODO(创建包含所有规则的对象)* @throws Exception* @return KieSession*/public static KieSession getAllRules() throws Exception {try {disposeKieSession();KieServices kieServices = KieServices.Factory.get();KieFileSystem kieFileSystem = kieServices.newKieFileSystem();for (org.springframework.core.io.Resource file : new PathMatchingResourcePatternResolver().getResources("classpath*:" + RULES_PATH + "**/*.*")) {kieFileSystem.write(org.kie.internal.io.ResourceFactory.newClassPathResource(RULES_PATH + file.getFilename(), "UTF-8"));}final KieRepository kieRepository = KieServices.Factory.get().getRepository();kieRepository.addKieModule(new KieModule() {@Overridepublic ReleaseId getReleaseId() {return kieRepository.getDefaultReleaseId();}});KieBuilder kieBuilder = KieServices.Factory.get().newKieBuilder(kieFileSystem);kieBuilder.buildAll();kieSession = KieServices.Factory.get().newKieContainer(kieRepository.getDefaultReleaseId()).newKieSession().getKieBase().newKieSession();return kieSession;} catch (Exception ex) {throw ex;}}/*** @description TODO (快速新建KieSession)* @param classPath 绝对路径* @return KieSession 有状态*/public static KieSession newKieSession(String classPath) throws Exception {KieSession kieSession = getKieBase(classPath).newKieSession();kieSession.addEventListener(new DebugRuleRuntimeEventListener());return kieSession;}/*** @description TODO (快速新建StatelessKieSession)* @param classPath 绝对路径* @return StatelessKieSession 无状态*/public static StatelessKieSession newStatelessKieSession(String classPath) throws Exception {StatelessKieSession kiesession = getKieBase(classPath).newStatelessKieSession();return kiesession;}/*** @description TODO (清空对象)* @title disposeKieSession 重置KieSession* @return void*/public static void disposeKieSession() {if (kieSession != null) {kieSession.dispose();kieSession = null;}}protected static KieBase getKieBase(String classPath) throws Exception {KieServices kieServices = KieServices.Factory.get();KieFileSystem kfs = kieServices.newKieFileSystem();Resource resource = kieServices.getResources().newClassPathResource(classPath);resource.setResourceType(ResourceType.DRL);kfs.write(resource);KieBuilder kieBuilder = kieServices.newKieBuilder(kfs).buildAll();if (kieBuilder.getResults().getMessages(Message.Level.ERROR).size() > 0) {throw new Exception();}KieContainer kieContainer = kieServices.newKieContainer(kieServices.getRepository().getDefaultReleaseId());KieBase kBase = kieContainer.getKieBase();return kBase;}/*** 根据服务器真实路径下的xls文件生成drl文件内容*/public static KieSession getKieSessionFromXLS(String realPath) throws FileNotFoundException {return createKieSessionFromDRL(getDRL(realPath));}// 把xls文件解析为Stringpublic static String getDRL (String realPath) throws FileNotFoundException {File file = new File(realPath); // 例如:C:\\abc.xlsInputStream is = new FileInputStream(file);SpreadsheetCompiler compiler = new SpreadsheetCompiler();return compiler.compile(is, InputType.XLS);}// drl为含有内容的字符串public static KieSession createKieSessionFromDRL(String drl) {KieHelper kieHelper = new KieHelper();kieHelper.addContent(drl, ResourceType.DRL);Results results = kieHelper.verify();if (results.hasMessages(Message.Level.WARNING, Message.Level.ERROR)) {List<Message> messages = results.getMessages(Message.Level.WARNING, Message.Level.ERROR);for (Message message : messages) {System.out.println("Error: "+message.getText());}throw new IllegalStateException("Compilation errors were found. Check the logs.");}return kieHelper.build().newKieSession();}}
- 创建一个测试实体类,以及一个rule.drl规则文件:
@Data
public class UserInfo {private String name;private Integer age;private List<String> interests;private Map<String, String> tags;
}
关于rule.drl文件放置的位置,工具类KieSessionUtils 的getAllRules()方法会解析工程resource目录下rules文件夹下的所有drl文件,你可以放在这里。
newKieSession()里面参数是绝对路径,解析单一的drl文件,测试的rule.drl:
package rules;
dialect "java"import com.gaolang.entity.*;rule "评估用户"
when$u : UserInfo(name == "张" || name == "李")
thenSystem.err.println("用户"+$u);end
- 测试代码:
@Testpublic void test01() throws Exception {UserInfo userInfo = new UserInfo();userInfo.setName("李");KieSession kieSession = KieSessionUtils.getAllRules();kieSession.insert(userInfo);
// kieSession.getAgenda().getAgendaGroup("abc").setFocus();kieSession.fireAllRules();kieSession.dispose();}
测试的结果:它是与关系式匹配的,会看到输出:
快速整合
创建一个springboot项目,不会创建的可以参考这篇博客:【Spring Boot】快速上手SpringBoot
引入我们的drools依赖:
关于这个依赖的网址:https://github.com/hongwen1993/fast-drools-spring-boot-starter
<dependency><groupId>com.github.hongwen1993</groupId><artifactId>fast-drools-spring-boot-starter</artifactId><version>8.0.8</version></dependency>
配合测试可能还需要引入的依赖:
<dependency><groupId>junit</groupId><artifactId>junit</artifactId><version>4.13.2</version><scope>test</scope></dependency><dependency><groupId>org.projectlombok</groupId><artifactId>lombok</artifactId><version>1.18.20</version></dependency>
- 官方的配置文件,放到项目的application.properties中:
################## 必填属性 ##################
# 指定规则文件目录,会自动扫描该目录下所有规则文件,决策表,以及CSV文件
# 支持classpath资源目录,如:classpath:drools/**/*.drl
# win 系统注意使用反斜杠,如:C:\\DRL\\
# linux 系统注意使用斜杠,如:/usr/local/drl/
spring.drools.path = C:\\DRL\\
################## 可选属性 ##################
# 也可以指定全局的mode,选择stream或cloud(默认stream模式)
spring.drools.mode = stream
# 自动更新,on 或 off(默认开启)
spring.drools.auto-update = on
# 指定规则文件自动更新的周期,单位秒(默认30秒扫描偶一次)
spring.drools.update = 10
# 规则监听日志,on 或 off(默认开启)
spring.drools.listener = on
# 开启 drl 语法检查,on 或 off(默认关闭)
spring.drools.verify = off
上面配置文件的修改spring.drools.path部分
# 支持classpath资源目录,如:classpath:drools/**/*.drl
# win 系统注意使用反斜杠,如:C:\\DRL\\
# linux 系统注意使用斜杠,如:/usr/local/drl/
- 和上面相同的测试实体类和drl文件:
@Autowiredprivate KieTemplate kieTemplate;@Beforepublic void before() throws InterruptedException {Thread.sleep(1000);}@Testvoid test02() throws Exception {KieSession session = kieTemplate.getKieSession("rule01.drl");UserInfo userInfo = new UserInfo();userInfo.setName("李");session.insert(userInfo);session.fireAllRules();session.dispose();}
测试结果是相同的。
SpringBoot整合Drools相关推荐
- SpringBoot整合Drools规则引擎动态生成业务规则
最近的项目中,使用的是flowable工作流来处理业务流程,但是在业务规则的配置中,是在代码中直接固定写死的,领导说这样不好,需要规则可以动态变化,可以通过页面去动态配置改变,所以就花了几天时间去研究 ...
- SpringBoot第九篇: springboot整合Redis
这篇文章主要介绍springboot整合redis,至于没有接触过redis的同学可以看下这篇文章:5分钟带你入门Redis. 引入依赖: 在pom文件中添加redis依赖: <dependen ...
- es springboot 不设置id_原创 | 一篇解决Springboot 整合 Elasticsearch
ElasticSearch 结合业务的场景,在目前的商品体系需要构建搜索服务,主要是为了提供用户更丰富的检索场景以及高速,实时及性能稳定的搜索服务. ElasticSearch是一个基于Lucene的 ...
- springboot整合shiro使用shiro-spring-boot-web-starter
此文章仅仅说明在springboot整合shiro时的一些坑,并不是教程 增加依赖 <!-- 集成shiro依赖 --> <dependency><groupId> ...
- db2 springboot 整合_springboot的yml配置文件通过db2的方式整合mysql的教程
springboot整合MySQL很简单,多数据源就master,slave就行了,但是在整合DB2就需要另起一行,以下是同一个yml文件 先配置MySQL,代码如下 spring: datasour ...
- 九、springboot整合rabbitMQ
springboot整合rabbitMQ 简介 rabbitMQ是部署最广泛的开源消息代理. rabbitMQ轻量级,易于在内部和云中部署. 它支持多种消息传递协议. RabbitMQ可以部署在分布式 ...
- 八、springboot整合Spring Security
springboot整合Spring Security 简介 Spring Security是一个功能强大且可高度自定义的身份验证和访问控制框架.它是保护基于Spring的应用程序的事实标准. Spr ...
- 六、springboot整合swagger
六.springboot整合swagger 简介 swagger 提供最强大,最易用的工具,以充分利用OpenAPI规范. 官网 : https://swagger.io/ 准备工作 pom.xml ...
- SpringBoot整合mybatis、shiro、redis实现基于数据库的细粒度动态权限管理系统实例(转)...
SpringBoot整合mybatis.shiro.redis实现基于数据库的细粒度动态权限管理系统实例 shiro 目录(?)[+] 前言 表结构 maven配置 配置Druid 配置mybatis ...
最新文章
- linux文件移出目录命令_Linux 文件与目录管理详解
- node.js是开源的吗_为开源做贡献并不难:我为Node.js项目做贡献的旅程
- VScode+SSH Remote多级连跳配置
- NXT(未来币)(阿朵)节点钱包
- Android Binder 分析——匿名共享内存(Ashmem)
- 毕业后,两个月,第二家公司上班第一天
- 1193, Unknown system variable 'tx_isolation'
- win7怎么安装消息队列 MSMQ
- CSR8675烧录工具-全系列CSR8675/86xx一拖多量产工具csr烧录软件(支持FLASH版本和ROM版本)
- 嵌入式研发人员核心竞争力分析
- FPGA下载(kintex-7)
- html5打开新标签,[HTML5] 新标签解释及用法
- win10 git bash 设置别名
- 企业网络及应用层安全防护技术精要
- 最长单调递增子序列O(NlogN)算法
- C/C++程序员面试指南
- 一个ACM底层参赛选手的退役感言
- 分类器模型评价指标之ROC曲线
- 为什么程序员适合做自由职业者
- Camtasia2023版本软件电脑自带录屏功能使用教程