规则引擎easyRule详解
规则引擎有许多种:Drools,Aviator,Mvel,EasyRule,这里主要讲解一下EasyRule。
easyRule集成了Mvel,而Mvel表达式非常强大,我们可以自己写一些表达式,交给mvel进行解析计算,得到这个表达式计算的值。
easyRule可大致分为三部分:规则引擎,事实,规则
<dependency><groupId>org.jeasy</groupId><artifactId>easy-rules-core</artifactId><version>4.1.0</version></dependency><dependency><groupId>org.jeasy</groupId><artifactId>easy-rules-mvel</artifactId><version>4.1.0</version></dependency>
它有两种使用方式:一种是注解,一种是api方式,这里主要介绍一下api的方式
- 规则引擎
RulesEngine rulesEngine = new DefaultRulesEngine();rulesEngine.fire(rules, facts);
从版本3.1开始,Easy Rules提供了RulesEngine接口的两种实现:
DefaultRulesEngine:根据规则的自然顺序(默认为优先级)应用规则。
InferenceRulesEngine:持续对已知事实应用规则,直到不再应用规则为止什么意思呢?来看一段代码
public static void main(String[] args) {//规则条件String condition = "name contains(\"张\")";String condition2 = "age > 10 && age <= 20";//规则引擎RulesEngine rulesEngine = new DefaultRulesEngine();Rules rules = new Rules();//具体规则,当满足condition,然后输出对应的successRule rule = new MVELRule().when(condition).then("System.out.println(\"name success\")").priority(2);Rule rule2 = new MVELRule().when(condition2).then("System.out.println(\"age success\")").priority(1);rules.register(rule);rules.register(rule2);//匹配规则的事实Facts facts = new Facts();facts.put("name","张");facts.put("age","11");rulesEngine.fire(rules,facts);}
使用DefaultRulesEngine引擎会根据规则设置的priority属性,从小到大顺序执行。
可以看到age先执行,name后执行。
使用InferenceRulesEngine引擎,会通过循环不停的通过事实去匹配规则,直到全部事实都不匹配规则才停止循环。可以看到源码中就是通过do while循环的
规则引擎也有几个参数默认都为false
- skipOnFirstAppliedRule:告诉引擎规则被触发时跳过后面的规则。
- skipOnFirstFailedRule:告诉引擎在规则失败时跳过后面的规则。
- skipOnFirstNonTriggeredRule:告诉引擎一个规则不会被触发跳过后面的规则。
- rulePriorityThreshold:告诉引擎如果优先级超过定义的阈值,则跳过下一个规则。版本3.3已经不支持更改,默认MaxInt。
通过构造函数设置进去就行了
RulesEngineParameters parameters = new RulesEngineParameters().rulePriorityThreshold(10).skipOnFirstAppliedRule(true).skipOnFirstFailedRule(true).skipOnFirstNonTriggeredRule(true);RulesEngine rulesEngine = new DefaultRulesEngine(parameters);
- 事实
事实如何理解呢?规定定义好了,为谁定义的呢?就是Facts ,规则引擎就是判断这些Facts符不符合规则。在内部,Facts实例持有HashSet<Fact<?>>,这意味着:
1.事实需要命名,应该有一个唯一的名称,且不能为空
2. 任何Java对象都可以充当事实
不好理解来看代码
//可以这样Facts facts = new Facts();facts.put("name","张");facts.put("age","11"); //也可以这样存放对象Facts facts = new Facts();Result p1 = new Result();p1.setAge(11); p1.setName("张三");Result p2 = new Result();p2.setAge(12); p2.setName("张四");//facts的key相同,后put会覆盖前一个person,因为Facts是通过HastSet来存储,并以key区分facts.put("person",p1);facts.put("person",p2);//如果是这样那么规则就必须person.xxx这样写String condition = "person.name contains(\"张\")";String condition2 = "person.age > 10 && person.age <= 20";@Dataclass Result {private String name;private Integer age;}
为了解决上面出现的覆盖问题,可以考虑下面这样的实现
public static void main(String[] args) {List<Result> list = new ArrayList<>();Result p1 = new Result();p1.setAge(11);p1.setName("张三");Result p2 = new Result();p2.setAge(12);p2.setName("张四");list.add(p1);list.add(p2);String condition = "person.name contains(\"张\")";String condition2 = "person.age > 10 && person.age <= 20";RulesEngine rulesEngine = new DefaultRulesEngine();Rules rules = new Rules();Rule rule = new MVELRule().when(condition).then("System.out.println(\"name success\")").priority(2);Rule rule2 = new MVELRule().when(condition2).then("System.out.println(\"age success\")").priority(1);rules.register(rule);rules.register(rule2);for (int i = 0; i < list.size(); i++) {Facts facts = new Facts();facts.put("person", list.get(i));rulesEngine.fire(rules, facts);}}
- 规则
上面的案例都是一个事实匹配一个规则(一个person只要满足name包含张或者age >10 && age <20其中一个条件就执行对应规则校验成功后的逻辑),那如何做到一个事实匹配多个规则呢?也就是说一个person不仅要满足name包含张且age >10 && age <20才执行成功后的逻辑,就需要使用复合规则。
UnitRuleGroup:单元规则组是作为一个单元的复合规则:要么应用所有规则,要么什么都不应用。
ActivationRuleGroup:激活规则组是一个复合规则,它触发第一个适用规则,并忽略组中的其他规则(XOR逻辑)。规则首先按照组内的自然顺序(默认优先级)进行排序。
ConditionalRuleGroup:条件规则组是一个复合规则,其中优先级最高的规则充当条件:如果优先级最高的规则求值为true,则触发其余规则。
废话不多说,上demo
public static void main(String[] args) {List<Result> list = new ArrayList<>();Result p1 = new Result();p1.setAge(11);p1.setName("张三");Result p2 = new Result();p2.setAge(12);p2.setName("李四");list.add(p1);list.add(p2);String condition = "person.name contains(\"张\")";String condition2 = "person.age > 10 && person.age <= 20";RulesEngine rulesEngine = new DefaultRulesEngine();Rules rules = new Rules();Rule rule = new MVELRule().when(condition).then("System.out.println(\"name success\")").priority(2);Rule rule2 = new MVELRule().when(condition2).then("System.out.println(\"age success\")").priority(1);// 要么应用所有规则,要么什么都不应用。UnitRuleGroup unitRuleGroup = new UnitRuleGroup();unitRuleGroup.addRule(rule); unitRuleGroup.addRule(rule2);rules.register(unitRuleGroup);for (int i = 0; i < list.size(); i++) {Facts facts = new Facts();facts.put("person", list.get(i));rulesEngine.fire(rules, facts);}}
输出结果:
可以看到 李四没有满足条件 ,其他几个复合规则,大家可自行去尝试。
以上就是easyRule的总结
参考文章:
https://zhuanlan.zhihu.com/p/91158525
https://www.jianshu.com/p/4eb762b559fd
规则引擎easyRule详解相关推荐
- 视频教程-FPS游戏逆向与安全+UE4引擎基础详解-其他
FPS游戏逆向与安全+UE4引擎基础详解 想把自己的知识传播出去,让更多人学习到 苏瑞兵 ¥188.00 立即订阅 扫码下载「CSDN程序员学院APP」,1000+技术好课免费看 APP订阅课程,领取 ...
- 表达式引擎Mvel详解与实战
前言 表达式引擎是规则引擎的一部分,是一种嵌入在应用程序中的组件,实现了逻辑判断与程序代码中分离出来,并使用预定义的语义脚本编写业务条件.接受数据输入,解释执行表达式,并返回表达式执行结果. 在前面的 ...
- 成本计算引擎动态规则解析技术详解
源宝导读:随着企业数字系统应用的越来越深入,业务计算方式也变的越来越复杂,灵活度要求也越来越高.本文将介绍通过将配置动态转换成可执行代码的方式,解决业务计算高度灵活化配置的技术方案. 一.背景 ERP ...
- Activiti工作流引擎使用详解(一)
一.IDEA安装activiti插件 在插件库中查找actiBPM,安装该插件,如果找不到该插件,请到插件库中下载该包手动安装,插件地址 http://plugins.jetbrains.com/pl ...
- ubuntu下安装三维渲染引擎OSG详解
零.前言 OpenSceneGraph是一个开源的.跨平台的三维引擎,被广泛的应用在可视化仿真.游戏.虚拟现实.三维重建等领域,采用标准C++和OpenGL编写而成,能够更加快速.便捷地创建高性能.跨 ...
- TokuDB引擎安装详解
背景 项目目前使用的Sequoiadb数据库,撑不住每小时千万的数据量了,所以领导安排研究TokuDB. 安装TokuDB引擎之前需要先安装MySQL,而且推荐的是Percona MySQL.本文选择 ...
- mysql递归查询所有上下节点_【转】MySQL之Spider存储引擎原理详解
一.概述 Spider是为MySQL/MariaDB开发的一个特殊引擎,具有内嵌分片功能.MariaDB从10.0.4开始支持Spider.作为MariaDB的一个新的主要特性.Spider的主要功能 ...
- freemaker模板引擎使用详解
目录: 一.freemaker介绍 二.freemaker的使用 正文: 一.freemaker介绍 1.1FreeMarker概述:FreeMarker是一款模板引擎,即一种基于模板和要改变的数据, ...
- mysql 储存引擎_详解mysql存储引擎的标准
浅谈选择mysql存储引擎的标准 主要存储引擎的介绍 1.InnoDB存储引擎 InnoDB是MySQL的默认事务型引擎,它被设计用来处理大量的短期(short-lived)事务.除非有非常特别的原因 ...
最新文章
- gz解压java,java 解压gz
- go语言笔记——defer作用DB资源等free或实现调试
- tensorflow tf.enable_eager_execution()(立即执行操作,不添加到稍后在“ tf.Session”中执行的图)
- TI Davinci DM6446开发攻略——开发环境搭建
- 点石关键词排名优化软件_重庆关键词优化排名
- 如何查看自己的ubutu系统是32位的还是64位的
- Linux命令替换字符串
- wpf项目无法使用针式打印机_针式打印机的常见故障和解决方法2
- 避免uicollection view被错误的移动
- VS编译错误:error C2143: 语法错误 : 缺少“;”(在“类型”的前面)
- Laravel5.3之Container源码解析
- rootkit的检测
- linux sqluldr2命令,sqluldr2 linux64
- delphi读音_用Delphi 6编程实现自动标注汉语拼音_Delphi
- PySpark | SparkSQL入门 | DataFrame入门
- 财务管理----记账凭证的输入格式设计与数据库设计
- 手写数字识别——KNN算法的应用
- 计算机考csp200分啥水平,计算机与信息工程学院成功举办第20次CCF CSP认证考试
- 问题解决“Windows Installer 程序包有问题,此安装需要的程序不能运行。请与您的支持人员或程序包开发商联系
- 链上泉城,商机赋能 | 易保全亮相商机大会,区块链应用受瞩目