规则引擎drools封装
一.前言
网上规则引擎drools介绍很多,并且有很多细致的说明,作者也不敢托大说自己的好用,但作者经过2个项目使用过规则引擎后,自己对规则引擎的理解并进行封装,对规则内容及如何使用,有自己的一番实践,并提供源代码,供大家参考
二.设计思路及具体代码
首先我希望是轻量级的使用drools,不希望使用太过复杂的架构,以这种思路入手,就可以与任何项目轻易融入,这样就需要能够将drools规则的来源,从规则文件(drl)中可以从maven和自己的数据库中获取,脚本是动态的,配合drools6.5支持通过maven接入的规则的API,就可以做到从任何处获取规则内容
一个工具类DroolsUtils
-
package com.vip.jie.rule.util;
-
-
import org.drools.compiler.kie.builder.impl.InternalKieModule;
-
import org.kie.api.KieServices;
-
import org.kie.api.builder.KieBuilder;
-
import org.kie.api.builder.KieFileSystem;
-
import org.kie.api.builder.ReleaseId;
-
import org.kie.api.builder.model.KieBaseModel;
-
import org.kie.api.builder.model.KieModuleModel;
-
import org.kie.api.builder.model.KieSessionModel;
-
import org.kie.api.conf.EqualityBehaviorOption;
-
import org.kie.api.conf.EventProcessingOption;
-
-
import java.io.IOException;
-
-
-
-
/**
-
* 动态生成kjar
-
* @author jie01.zhu
-
* @DateTime 2018/3/19 22:14
-
*/
-
public class DroolsUtils {
-
-
/**
-
* 创建默认的kbase和stateful的kiesession
-
*
-
* @param ks
-
* @param isdefault
-
* @return
-
*/
-
private static KieFileSystem createKieFileSystemWithKProject(KieServices ks, boolean isdefault) {
-
KieModuleModel kproj = ks.newKieModuleModel();
-
KieBaseModel kieBaseModel1 = kproj.newKieBaseModel("KBase").setDefault(isdefault)
-
.setEqualsBehavior(EqualityBehaviorOption.EQUALITY)
-
.setEventProcessingMode(EventProcessingOption.STREAM);
-
// Configure the KieSession.
-
kieBaseModel1.newKieSessionModel("KSession").setDefault(isdefault)
-
.setType(KieSessionModel.KieSessionType.STATEFUL);
-
KieFileSystem kfs = ks.newKieFileSystem();
-
kfs.writeKModuleXML(kproj.toXML());
-
return kfs;
-
}
-
-
/**
-
* 创建kjar的pom
-
*
-
* @param releaseId
-
* @param dependencies
-
* @return
-
*/
-
private static String getPom(ReleaseId releaseId, ReleaseId... dependencies) {
-
String pom = "<?xml version=\"1.0\" encoding=\"UTF-8\"?>\n"
-
+ "<project xmlns=\"http://maven.apache.org/POM/4.0.0\" xmlns:xsi=\"http://www.w3.org/2001/XMLSchema-instance\"\n"
-
+ " xsi:schemaLocation=\"http://maven.apache.org/POM/4.0.0 http://maven.apache.org/maven-v4_0_0.xsd\">\n"
-
+ " <modelVersion>4.0.0</modelVersion>\n" + "\n" + " <groupId>" + releaseId.getGroupId()
-
+ "</groupId>\n" + " <artifactId>" + releaseId.getArtifactId() + "</artifactId>\n" + " <version>"
-
+ releaseId.getVersion() + "</version>\n" + "\n";
-
if (dependencies != null && dependencies.length > 0) {
-
pom += "<dependencies>\n";
-
for (ReleaseId dep : dependencies) {
-
pom += "<dependency>\n";
-
pom += " <groupId>" + dep.getGroupId() + "</groupId>\n";
-
pom += " <artifactId>" + dep.getArtifactId() + "</artifactId>\n";
-
pom += " <version>" + dep.getVersion() + "</version>\n";
-
pom += "</dependency>\n";
-
}
-
pom += "</dependencies>\n";
-
}
-
pom += "</project>";
-
return pom;
-
}
-
-
/**
-
* 初始化一个kjar:把原有的drl包含进新建的kjar中
-
*
-
* @param ks
-
* @param releaseId
-
* @return
-
* @throws IOException
-
*/
-
public static InternalKieModule initKieJar(KieServices ks, ReleaseId releaseId) throws IOException {
-
KieFileSystem kfs = createKieFileSystemWithKProject(ks, true);
-
kfs.writePomXML(getPom(releaseId));
-
KieBuilder kieBuilder = ks.newKieBuilder(kfs);
-
if (!kieBuilder.buildAll().getResults().getMessages().isEmpty()) {
-
throw new IllegalStateException("Error creating KieBuilder.");
-
}
-
return (InternalKieModule) kieBuilder.getKieModule();
-
}
-
-
public static InternalKieModule createKieJar(KieServices ks, ReleaseId releaseId, DroolsResource droolsResource) {
-
KieFileSystem kfs = createKieFileSystemWithKProject(ks, true);
-
kfs.writePomXML(getPom(releaseId));
-
kfs.write("src/main/resources/" + droolsResource.getTargetResourceName(), droolsResource.getResource());
-
-
KieBuilder kieBuilder = ks.newKieBuilder(kfs);
-
if (!kieBuilder.getResults().getMessages().isEmpty()) {
-
throw new IllegalStateException(
-
"Error creating KieBuilder. errorMsg:" + kieBuilder.getResults().getMessages());
-
}
-
return (InternalKieModule) kieBuilder.getKieModule();
-
}
-
-
-
}
重点调用参考:
-
String fileName = "jie-" + group + "-rules";
-
/**
-
* 指定kjar包
-
*/
-
final ReleaseId releaseId = kieServices.newReleaseId("com.vip.jie", fileName, "1.0.0");
-
-
log.info("DroolsGetKieSession fileName:{}", fileName);
-
log.info("[DroolsGetKieSession] drlStr:{}", drlStr);
-
// 创建初始化的kjar
-
InternalKieModule kJar = DroolsUtils.createKieJar(kieServices, releaseId,
-
new DroolsResource(ResourceFactory.newByteArrayResource(drlStr.getBytes()),
-
fileName + ".drl"));
其次再将如何让使用者可以很灵活的接入,利用可变参数类型,将入参对象无限制传入,由规则脚本去决定入参的变化,通过此种方式可以比较好的实现业务灵活接入
如下单元测试类:
-
package com.vip.jie.rule.service.impl;
-
-
-
import com.vip.jie.rule.object.User;
-
import com.vip.jie.rule.service.RuleManager;
-
import lombok.extern.slf4j.Slf4j;
-
import org.junit.Test;
-
-
import static junit.framework.TestCase.fail;
-
-
/**
-
* 规则测试
-
* @author jie01.zhu
-
* @DateTime 2018/3/19 21:17
-
*
-
*/
-
@Slf4j
-
public class RuleManagerImplTest {
-
-
private RuleManager ruleManager = new RuleManagerImpl();
-
-
private String getRuleContent() {
-
StringBuilder stringBuilder = new StringBuilder();
-
-
stringBuilder.append("import com.vip.jie.rule.object.User;\n");
-
stringBuilder.append("rule test1 when\n");
-
stringBuilder.append("user : User(age==20)\n");
-
stringBuilder.append("then\n");
-
stringBuilder.append("user.setName(\"张三\");\n");
-
stringBuilder.append("end\n");
-
return stringBuilder.toString();
-
}
-
-
@Test
-
public void executeRule1() throws Exception {
-
-
User user = new User();
-
user.setAge(20);
-
-
//调用规则
-
ruleManager.executeRule("test1", getRuleContent(), user);
-
log.info("test result:{}", user.toString());
-
-
if (!"张三".equals(user.getName())) {
-
fail("error rule");
-
}
-
}
-
-
@Test
-
public void executeRule2() throws Exception {
-
-
User user = new User();
-
user.setAge(21);
-
-
//调用规则
-
ruleManager.executeRule("test1", getRuleContent(), user);
-
log.info("test result:{}", user.toString());
-
-
if ("张三".equals(user.getName())) {
-
fail("error rule");
-
}
-
}
-
}
三.对应示例源代码获取方式
githup:
https://github.com/jie01/drools-demo
csdn资源下载地址:
https://download.csdn.net/download/vipshop_fin_dev/10296393
还有一些关于安全性及与spring的封装思路,作者表示还会继续完善,并还不是最终版本,有需要可以持续关注-_-!
与当前文章有关联的链接
vipshop_ebs/朱杰
2018-03-19
原文地址:https://blog.csdn.net/vipshop_fin_dev/article/details/79618067
规则引擎drools封装的更多相关文章
- 开源规则引擎 drools
java语言开发的开源业务规则引擎 DROOLS(JBOSS RULES )具有一个易于访问企业策略.易于调整以及易于管理的开源业务规则引擎,符合业内标准,速度快.效率高.业务分析师或审核人员可以利用 ...
- 开源规则引擎 Drools 学习笔记 之 -- 1 cannot be cast to org.drools.compiler.kie.builder.impl.InternalKieModule
直接进入正题 我们在使用开源规则引擎 Drools 的时候, 启动的时候可能会抛出如下异常: Caused by: java.lang.ClassCastException: cn.com.cheng ...
- [Drools]JAVA规则引擎 -- Drools 2
上一篇文章 http://blog.csdn.net/quzishen/archive/2011/01/25/6163012.aspx 描述了一些常用的drools的语法标签和一个模拟实例即发送积分的 ...
- 使用规则引擎Drools计算圆周率PI
实际上是使用规则引擎能够更新工作内存区重新匹配规则实现迭代功能. 使用了策略模式实现. <规则引擎与RETE算法介绍> PPT : http://files.cnblogs.com/lov ...
- JAVA规则引擎 -- Drools
Drools是一个基于java的规则引擎,开源的,可以将复杂多变的规则从硬编码中解放出来,以规则脚本的形式存放在文件中,使得规则的变更不需要修正代码重启机器就可以立即在线上环境生效. 本文所使用的de ...
- [Drools]JAVA规则引擎 -- Drools
Drools是一个基于Java的规则引擎,开源的,可以将复杂多变的规则从硬编码中解放出来,以规则脚本的形式存放在文件中,使得规则的变更不需要修正代码重启机器就可以立即在线上环境生效. 本文所使用的de ...
- 小明历险记:规则引擎drools教程一
小明是一家互联网公司的软件工程师,他们公司为了吸引新用户经常会搞活动,小明常常为了做活动加班加点很烦躁,这不今天呀又来了一个活动需求,我们大家一起帮他看看. 小明的烦恼 活动规则是根据用户购买订单的金 ...
- 规则引擎 drools
https://www.jianshu.com/p/725811f420db 深入了解Drools 简单介绍 笔者正在做风控系统,风控系统里边存在非常多的规则(比如:age < 16 || ag ...
- 规则引擎drools的简单使用
规则引擎适用于有复杂多变的规则,如商品满减.积分赠送.考勤规则等 一.引入maven依赖 <dependency> <groupId>org.drools</groupI ...
随机推荐
- docker部署zabbix
我相信大家都已经会再物理机上跑zabbix并且监控了,那么有没有想过在docker中跑zabbix?下面咱们来看看如何在docker中搭建zabbix并且监控 部署环境 2台物理机机器: zabbix ...
- USB规格及速度
1. 速度对比 2. 硬件特性 USB2.0四线:5V,D-,D+,GND. USB3.0一般十线:5V,D-,D+,GND,SSTX+,SSTX-,SSRX+,SSRX-,P1_Drain,P2_D ...
- linux部署docker镜像
安装git yum install git 生成ssh秘钥 cat ~/.ssh/id_rsa.pub //查看是否有秘钥 ssh-keygen -t rsa -C "" //生成 ...
- Java使用枚举来消除if else(转载)
Java代码里经常出现多个if else会大大降低效率,我们可以使用枚举的方式来代替if else,示例代码如下: public enum Grade { A_10_90(90, 100, " ...
- 第08节-开源蓝牙协议栈BTStack数据处理
本篇博客根据韦东山的视频整理所得. 在上篇博客,通过阅读BTStack的源码,大体了解了其框架,对于任何一个BTStack的应用程序都有一个main函数,这个main函数是统一的.这个main函数做了 ...
- 201871010135 张玉晶 《2019面向对象程序设计(java)课程学习进度条》
<2019面向对象程序设计(java)课程学习进度条> 周次 (阅读/编写)代码行数 发布博客量/评论他人博客数量 课余学习时间(小时) 学习收获最大的程序 阅读或编译让我 第一周 25/ ...
- idea开发工具
IDEA简介 IDEA 全称 IntelliJ IDEA,是java编程语言开发的集成环境.IntelliJ在业界被公认为最好的java开发工具之一,尤其在智能代码助手.代码自动提示.重构.J2EE支 ...
- ESA2GJK1DH1K升级篇: 关于升级篇数据校验
前言 鉴于大家都希望升级的时候加入数据校验,所以就满足大家的要求. 其实我也希望自己做的足够的稳定可靠,让大家使用起来放心. 上一节测试了一节加入校验以后的操作方式,这节来详细的说一下校验部分的代码. ...
- 刷题记录and日记
- vue中使用element-ui自定义主题后,vue-cli跑不起来了
环境:vue-cli 2.x版本 自己在官网配置了主题并放到了项目中https://element.eleme.cn/#/zh-CN/theme 然后,我的脚手架在我的电脑中休息了几天,就跑不通了呢! ...