官网源码:https://github.com/j-easy/easy-rules
官网案例:https://github.com/j-easy/easy-rules/wiki/fizz-buzz
介绍:
规则引擎是为了解决业务代码和业务规则分离的引擎,是一种嵌入在应用程序中的组件,实现了将业务决策从应用程序代码中分离,其实就是将一大堆if/else进行处理,Easy Rules 所做的,它提供了Rule创建具有条件和操作的规则的抽象,以及RulesEngine通过一组规则运行以评估条件和执行操作的API

核心功能:

  1. 轻量级库和易于学习的 API
  2. 带有注解编程模型的基于 POJO 的开发
  3. 用于定义业务规则并通过 Java 轻松应用它们的有用抽象
  4. 从原始规则创建复合规则的能力
  5. 使用表达式语言(如 MVEL、SpEL 和 JEXL)定义规则的能力

一个规则由名称、描述、优先级三个属性和判断、执行两个方法组成,实现Rule接口,
和使用@Rule,@Condition,@Action,@Priority,@Fact注解的效果是一样的。

它主要包括几个主要的类或接口:Rule,RulesEngine,RuleListener,Facts
还有几个主要的注解:@Action,@Condition,@Fact,@Priority,@Rule

  1. Rule
public interface Rule extends Comparable<Rule> {/*** 默认的规则名称*/String DEFAULT_NAME = "rule";/*** 默认的规则描述*/String DEFAULT_DESCRIPTION = "description";/*** 默认的规则优先级*/int DEFAULT_PRIORITY = Integer.MAX_VALUE - 1;getter and setter.../*** 规则引擎判断条件* 如果提供的facts被应用到规则上返回true,否则返回false*/boolean evaluate(Facts facts);/*** 规则引擎判断条件返回true后,执行此方法*/void execute(Facts facts) throws Exception;}
  1. RulesEngine负责检查和开启规则,同时可以得到规则引擎的参数和规则监听器列表
public interface RulesEngine {/*** 返回规则引擎的参数*/RulesEngineParameters getParameters();/*** 返回已注册的规则监听器的列表*/List<RuleListener> getRuleListeners();/*** 在给定的因素上开启所有已注册的规则*/void fire(Rules rules, Facts facts);/*** 检查规则和因素是否符合*/Map<Rule, Boolean> check(Rules rules, Facts facts);
}
  1. RuleListener在规则执行的4个阶段加上了触发器,可以灵活地控制规则执行结果
    (定义规则监听器通过实现RuleListener接口)
public interface RuleListener {/*** 规则条件判断之前的触发器*/boolean beforeEvaluate(Rule rule, Facts facts);/*** 规则条件判断之后的触发器*/void afterEvaluate(Rule rule, Facts facts, boolean evaluationResult);/*** 规则执行之前的触发器*/void beforeExecute(Rule rule, Facts facts);/*** 规则执行成功之后的触发器*/void onSuccess(Rule rule, Facts facts);/*** 规则执行失败之后的触发器*/void onFailure(Rule rule, Facts facts, Exception exception);}
  1. Facts就是一个hashmap,通过注解@Fact(String value),其中的value是map的key,可以拿到Facts中的value
public class Facts implements Iterable<Map.Entry<String, Object>> {private Map<String, Object> facts = new HashMap<>();/*** 在工作空间放置一个因素*/public Object put(String name, Object fact) {Objects.requireNonNull(name);return facts.put(name, fact);}/*** 删除因素*/public Object remove(String name) {Objects.requireNonNull(name);return facts.remove(name);}/*** 通过name得到因素*/public Object get(String name) {Objects.requireNonNull(name);return facts.get(name);}/*** 以map形式返回因素*/public Map<String, Object> asMap() {return facts;}...
}

一. pom.xml中引入maven依赖

<!--easy rules核心库-->
<dependency><groupId>org.jeasy</groupId><artifactId>easy-rules-core</artifactId><version>4.0.0</version>
</dependency><!--规则定义文件格式,支持json,yaml等-->
<dependency><groupId>org.jeasy</groupId><artifactId>easy-rules-support</artifactId><version>4.0.0</version>
</dependency><!--支持mvel规则语法库-->
<dependency><groupId>org.jeasy</groupId><artifactId>easy-rules-mvel</artifactId><version>4.0.0</version>
</dependency>

二. 定义规则

大多数业务规则可以由以下定义表示:

  1. 名称:规则命名空间中的唯一规则名称
  2. 说明:规则的简要说明
  3. 优先级:相对于其他规则的规则优先级
  4. 事实:去匹配规则时的一组已知事实
  5. 条件:为了匹配该规则,在给定某些事实的情况下应满足的一组条件
  6. 动作:当条件满足时要执行的一组动作(可以添加/删除/修改事实)

Easy Rules为定义业务规则的每个关键点提供了抽象。

public interface Rule {/*** 改方法封装规则的条件(conditions)* @return 如果提供的事实适用于该规则返回true, 否则,返回false*/boolean evaluate(Facts facts);/*** 改方法封装规则的操作(actions)* @throws 如果在执行过程中发生错误将抛出Exception*/void execute(Facts facts) throws Exception;//Getters and setters for rule name, description and priority omitted.}

evaluate方法封装了必须求值为TRUE才能触发规则的条件。
execute方法封装了在满足规则条件时应执行的操作。条件和动作ConditionandAction接口表示。

首先,定义规则,方式有多种

方式一:注解

  1. @Condition注解指定规则条件
  2. @Fact注解指定参数
  3. @Action注解指定规则执行的动作
@Rule(name = "weather rule", description = "if it rains then take an umbrella")
public class WeatherRule {@Conditionpublic boolean itRains(@Fact("rain") boolean rain) {return rain;}@Actionpublic void takeAnUmbrella() {System.out.println("It rains, take an umbrella!");}
}

@Condition注解标记计算规则条件的方法。此方法必须是公共的,可以有一个或多个用@Fact注解的参数,并返回布尔类型。只有一个方法能用@Condition注解。

@Action注解标记要执行规则操作的方法。规则可以有多个操作。可以使用order属性按指定的顺序执行操作。默认情况下,操作的顺序为0。

方式二:链式编程

Rule rule = new RuleBuilder().name("myRule").description("myRuleDescription").priority(3).when(condition).then(action1).then(action2).build();

在这个例子中, Condition实例condition,Action实例是action1和action2。

方式三:表达式

Rule weatherRule = new MVELRule().name("weather rule").description("if it rains then take an umbrella").when("rain == true").then("System.out.println(\"It rains, take an umbrella!\");");

方式四:yml配置文件
例如:weather-rule.yml

name: "weather rule"
description: "if it rains then take an umbrella"
condition: "rain == true"
actions:- "System.out.println(\"It rains, take an umbrella!\");"
MVELRuleFactory ruleFactory = new MVELRuleFactory(new YamlRuleDefinitionReader());
Rule weatherRule = ruleFactory.createRule(new FileReader("weather-rule.yml"));

组合规则

CompositeRule由一组规则组成。这是一个典型地组合设计模式的实现。

组合规则是一个抽象概念,因为可以以不同方式触发组合规则。

Easy Rules自带三种CompositeRule实现:

UnitRuleGroup : 要么应用所有规则,要么不应用任何规则(AND逻辑)
ActivationRuleGroup : 它触发第一个适用规则,并忽略组中的其他规则(XOR逻辑)
ConditionalRuleGroup : 如果具有最高优先级的规则计算结果为true,则触发其余规则
复合规则可以从基本规则创建并注册为常规规则:

//Create a composite rule from two primitive rules
UnitRuleGroup myUnitRuleGroup = new UnitRuleGroup("myUnitRuleGroup", "unit of myRule1 and myRule2");
myUnitRuleGroup.addRule(myRule1);
myUnitRuleGroup.addRule(myRule2);//Register the composite rule as a regular rule
Rules rules = new Rules();
rules.register(myUnitRuleGroup);RulesEngine rulesEngine = new DefaultRulesEngine();
rulesEngine.fire(rules, someFacts);

每个规则都有优先级。它代表触发注册规则的默认顺序。默认情况下,较低的值表示较高的优先级。可以重写compareTo方法以提供自定义优先级策略。

定义事实
Facts API是一组事实的抽象,在这些事实上检查规则。
在内部,Facts实例持有HashMap<String,Object>,这意味着:
事实需要命名,应该有一个唯一的名称,且不能为空
任何Java对象都可以充当事实
这里有一个实例定义事实:

// define facts
Facts facts = new Facts();
facts.add("rain", true);

用@Fact注解可以将Facts注入到condition和action方法中
在下面的规则中,rain 事实被注入itRains方法的rain参数:

@Rule
class WeatherRule {@Conditionpublic boolean itRains(@Fact("rain") boolean rain) {return rain;}@Actionpublic void takeAnUmbrella(Facts facts) {System.out.println("It rains, take an umbrella!");// can add/remove/modify facts}}

Facts类型参数 被注入已知的 facts中 (像action方法takeAnUmbrella一样).

如果缺少注入的fact, 这个引擎会抛出 RuntimeException异常.
定义规则引擎
从版本3.1开始,Easy Rules提供了RulesEngine接口的两种实现:

  1. DefaultRulesEngine:根据规则的自然顺序(默认为优先级)应用规则。
  2. InferenceRulesEngine:持续对已知事实应用规则,直到不再应用规则为止。

创建一个规则引擎
要创建规则引擎,可以使用每个实现的构造函数:

RulesEngine rulesEngine = new DefaultRulesEngine();
// or
RulesEngine rulesEngine = new InferenceRulesEngine();

然后,您可以按以下方式触发注册规则:

rulesEngine.fire(rules, facts);

规则引擎参数

Easy Rules 引擎可以配置以下参数:

Parameter    Type    Required    Default
rulePriorityThreshold   int no  MaxInt
skipOnFirstAppliedRule  boolean no  false
skipOnFirstFailedRule   boolean no  false
skipOnFirstNonTriggeredRule boolean no  false

skipOnFirstAppliedRule:告诉引擎规则被触发时跳过后面的规则。
skipOnFirstFailedRule:告诉引擎在规则失败时跳过后面的规则。
skipOnFirstNonTriggeredRule:告诉引擎一个规则不会被触发跳过后面的规则。
rulePriorityThreshold:告诉引擎如果优先级超过定义的阈值,则跳过下一个规则。版本3.3已经不支持更改,默认MaxInt。
可以使用RulesEngineParameters API指定这些参数:

RulesEngineParameters parameters = new RulesEngineParameters().rulePriorityThreshold(10).skipOnFirstAppliedRule(true).skipOnFirstFailedRule(true).skipOnFirstNonTriggeredRule(true);RulesEngine rulesEngine = new DefaultRulesEngine(parameters);

如果要从引擎获取参数,可以使用以下代码段:

RulesEngineParameters parameters = myEngine.getParameters();

这允许您在创建引擎后重置引擎参数。

开始测试案例
1.创建项目(通过maven骨架创建)

mvn archetype:generate \-DarchetypeGroupId=org.jeasy \-DarchetypeArtifactId=easy-rules-archetype \-DarchetypeVersion=4.0.0



创建完成后,会默认生成一个HelloWorldRule规则

入过启动报错 Error:(26, 34) java: 程序包org.jeasy.rules.annotation不存在

File -->settings —>maven —>Runner ,勾选:Dele… 然后保存

重写启动

依赖:

测试案例一:

1.用到的实体

package org.testRule.one;/*** @author: YXY* @date: 2021/6/23 15:22* @Version 1.0*/
public class User {private Integer age;public Integer getAge() {return age;}public void setAge(Integer age) {this.age = age;}
}

2.测试类

package org.testRule.one;import org.jeasy.rules.annotation.Rule;
import org.jeasy.rules.api.Facts;
import org.jeasy.rules.api.Rules;
import org.jeasy.rules.api.RulesEngine;
import org.jeasy.rules.core.DefaultRulesEngine;
import org.jeasy.rules.mvel.MVELRule;import java.util.HashMap;
import java.util.Map;/*** @author: YXY* @date: 2021/6/23 15:21* @Version 1.0*/
public class MVELTestRule {public static void main(String[] args) {//规则引擎RulesEngine rulesEngine = new DefaultRulesEngine();//规则MVELRule ageRule = new MVELRule().name("my rule").description("test demo rule").priority(1).when("user.age > 18").then("map.put('code',200);map.put('msg','success');");Rules rules = new Rules();rules.register(ageRule);Facts facts = new Facts();User user   = new User();user.setAge(19);facts.put("user",user);Map map  = new HashMap();facts.put("map",map);rulesEngine.fire(rules,facts);System.out.println(map);}
}

3.运行结果

测试案例二:


1.定义规则

package org.testRule.tow.rules;import org.jeasy.rules.annotation.*;/*** @author: YXY* @date: 2021/6/23 15:19* @Version 1.0*/
@Rule(name = "被2整除")
public class TwoRule {@Conditionpublic boolean isTwo(@Fact("num") int num){System.out.println("---isTwo----run----");return num % 2 == 0;}@Actionpublic void action(@Fact("num") int num){System.out.println(num + " 被2整除");}@Prioritypublic int getPriority(){return 1;}}
package org.testRule.tow.rules;import org.jeasy.rules.annotation.*;/*** @author: YXY* @date: 2021/6/23 15:19* @Version 1.0*/
@Rule(name = "被3整除")
public class ThreeRule {@Condition //条件判断注解:如果return true, 执行Actionpublic boolean isThree(@Fact("num") int num){System.out.println("---isThree----run----");return num % 3 == 0;}@Actionpublic void action(@Fact("num") int num){System.out.println(num + " 被3整除");}@Priority //优先级注解:return 数值越小,优先级越高public int getPriority(){return 2;}
}
package org.testRule.tow.rules;import org.jeasy.rules.annotation.Rule;
import org.jeasy.rules.support.composite.UnitRuleGroup;/*** @author: YXY* @date: 2021/6/23 15:19* @Version 1.0*/
@Rule(name = "被2和3同时整除")
public class TwoThreeRuleUnitGroup extends UnitRuleGroup {public TwoThreeRuleUnitGroup(Object... rules) {for (Object rule : rules) {addRule(rule);}}@Overridepublic int getPriority() {return 0;}
}
package org.testRule.tow.rules;import org.jeasy.rules.annotation.*;/*** @author: YXY* @date: 2021/6/23 15:20* @Version 1.0*/
@Rule(name = "既不被2整除也不被3整除")
public class OtherRule {@Conditionpublic boolean isOther(@Fact("num") int num){System.out.println("---isOther----run----");return num % 2 != 0 && num % 3 != 0;}@Actionpublic void action(@Fact("num") int num){System.out.print(num);}@Prioritypublic int getPriority(){return 3;}
}

2.测试类

package org.testRule.tow;import org.jeasy.rules.api.Facts;
import org.jeasy.rules.api.Rules;
import org.jeasy.rules.api.RulesEngine;
import org.jeasy.rules.core.DefaultRulesEngine;
import org.testRule.tow.rules.OtherRule;
import org.testRule.tow.rules.ThreeRule;
import org.testRule.tow.rules.TwoRule;
import org.testRule.tow.rules.TwoThreeRuleUnitGroup;/*** @author: YXY* @date: 2021/6/23 15:21* @Version 1.0*/public class RuleTest {public static void main(String[] args) {RulesEngine rulesEngine = new DefaultRulesEngine();//创建规则Rules rules = new Rules();rules.register(new TwoRule());rules.register(new ThreeRule());rules.register(new TwoThreeRuleUnitGroup(new TwoRule(), new ThreeRule()));rules.register(new OtherRule());//设置真实数据Facts facts = new Facts();for (int i=1 ; i<=10 ; i++){//规则因素,对应的name,要和规则里面的@Fact 一致facts.put("num", i);//执行规则rulesEngine.fire(rules, facts);System.out.println();}}
}

3.运行结果

控制台乱码解决:

-Dfile.encoding=UTF-8


规则引擎Easy-rules相关推荐

  1. java 实现规则引擎_Java规则引擎 Easy Rules

    1.  Easy Rules 概述 Easy Rules是一个Java规则引擎,灵感来自一篇名为<Should I use a Rules Engine?>的文章 规则引擎就是提供一种可选 ...

  2. Java规则引擎easy rules

    场景 简单点描述,有点策略模式的味道,所以可以处理if-else-语句; 其核心内容还是在规则引擎,所以和Drools规则类似,目前支持MVEL和SpEL表达式,配置外置; 最后支持各种规则的组合,支 ...

  3. 规则引擎----easy rules

    一.规则引擎的作用 将复杂的if else判断剥离出来 二.使用 2.1.引入POM <!--easy rules核心库--><dependency><groupId&g ...

  4. 规则引擎Visual Rules Solution开发基础教程【连载6】--VisualRules实例一

    [b][align=center][size=x-large]VisualRules实例一[/size][/align][/b] [size=medium] 以下通过一个简单的例子,来大致说明如何利用 ...

  5. 规则引擎选型及应用 邴越 2017-04-27 16:31:17 浏览614 评论0 HTTPS 模块 配置 string exception void input 规则引擎 摘要: 规则引擎具体执

    规则引擎选型及应用 邴越 2017-04-27 16:31:17 浏览614 评论0 HTTPS 模块 配置 string exception void input 规则引擎 摘要: 规则引擎具体执行 ...

  6. springboot之ice规则引擎探索

    突然发现一个非常棒的框架,迫不及待的想要和大家分享一下 规则引擎 什么是规则引擎 规则引擎是一种工具,它使得这种计算模型编程变得更容易.它可能是一个完整的开发环境,或者一个可以在传统平台上工作的框架. ...

  7. 调研规则引擎用于八字命理

    熟悉命理书的朋友都知道,书上计划都是一些条文组成的断语,从下表可以看到,命理大师们习惯描述什么条件,会出现什么样的情况,这样看起来是不是很像规则引擎的职能呢?于是我就想调研一下java相关的规则引擎, ...

  8. 常见的规则引擎(Drools,RuleBook,Easy Rules等)对比

    参考文章: https://www.jianshu.com/p/96cd60059aae 规则引擎调研 - 人在江湖之诗和远方 - 博客园 java开源规则引擎比较_常用规则引擎比较分析_学校砍了我的 ...

  9. 【转】什么是规则引擎(Drools、OpenL Tablets、Easy Rules、RuleBook)

    什么是规则引擎(Drools.OpenL Tablets.Easy Rules.RuleBook) 发表于:2021年1月23日 分类:Drools, 规则引擎 标签:Drools, Easy-Rul ...

最新文章

  1. Activity的启动模式与flag详解
  2. 程序员应该知道的七个图形工具
  3. Maven(2)--生命周期以及插件目标
  4. python——asyncio模块实现协程、异步编程(二)
  5. python网络-多线程(22)
  6. [Java] 蓝桥杯ADV-96 算法提高 复数求和
  7. 2019.7.19刷题统计
  8. 由程序猿yyyy-MM-dd跨年Bug引发的深思
  9. 我的超长综合面经 ---- 北京大学 黄晔
  10. java网络爬虫电影数据,Java豆瓣电影爬虫——减少与数据库交互实现批量插入
  11. 解决ubuntu12.04 virtubox xp 有道词典发音问题
  12. Serverless 极致弹性解构在线游戏行业痛点
  13. 你和财务自由之间,只差洋哥的这些建议!!!
  14. 鸟哥惠新宸:PHP 7.1 的新特性我并不是很喜欢
  15. PLSQL下无法选择数据库(附PLSQL64位安装包和汉化包)
  16. WPF 不要给 Window 类设置变换矩阵(分析篇):System.InvalidOperationException: 转换不可逆。
  17. html table vtop,打造个性化的Select(可编辑)_表单特效
  18. java后台如何将rgb与16进制颜色进行转换
  19. PicPick软件免费版与正式版区别
  20. Burpsuite工具与浏览器之间设置代理、安装证书

热门文章

  1. 正则表达式的一些探索(偏JavaScript)
  2. Get JSON with the jQuery getJSON Method
  3. SVN入门:流程简介 安装配置 项目库配置 客户端 上线方案
  4. 转贴:Hyper-V的几款免费管理工具
  5. 浅谈基于Linux的Redis环境搭建
  6. 题解:一些递推的题。
  7. 处理:/var/redis/run/redis_6379.pid exists, process is already running or crashed
  8. 学号20145332 《信息安全系统设计基础》实验四 驱动程序设计
  9. 简述Docker镜像、容器、仓库概念
  10. 《Linux内核分析》实践2