Easy Rules规则引擎(1-基础篇)

目录

  • 一、序言
  • 二、Easy Rules介绍
  • 三、定义规则(Rules)
    • 1、规则介绍
    • 2、编程式规则定义
    • 3、声明式规则定义
  • 四、定义事实(Facts)
  • 五、定义规则引擎(Rules Engine)
    • 1、规则引擎介绍
    • 2、InferenceRulesEngine规则引擎示例
      • (1) 定义触发条件
      • (2) 定义规则触发后的执行行为
      • (3) 测试用例

一、序言

最近团队在做一些VisaMaster卡的交易风控,运营团队提供了一些交易风控的规则,比如针对卡号MCC设置单笔交易限额,24小时交易限额,72小时交易限额等等,还有触发风控规则是否拦截交易还是只发告警邮件等等等。

虽然写各种条件判断也能实现,但是随着后面规则增加,维护成本也会越来越高,所以想尝试引入规则引擎,同时考虑到开发和学习成本,还是决定学习轻量级的Easy Rules


二、Easy Rules介绍

Easy Rules是一个Java规则引擎,它提供了规则抽象,通过触发条件和触发后的行为去创建规则。还提供了规则引擎API,通过这些API可以基于一系列的规则去判断规则是否触发,以及触发后执行什么动作。

核心特性:

  • 轻量级Java库,易于学习的API。
  • 注解式编程模型实现基于POJO开发。
  • 通过抽象定义业务规则并且轻松应用规则。
  • 支持通过简单规则可以创建组合规则。
  • 支持通过表达式语言(MVEL、SPEL和JEXL)定义规则。

相关依赖如下:

<!--Easy Rule-->
<!--核心库--><dependency><groupId>org.jeasy</groupId><artifactId>easy-rules-core</artifactId><version>4.1.0</version></dependency><!--组合规则支持--><dependency><groupId>org.jeasy</groupId><artifactId>easy-rules-support</artifactId><version>4.1.0</version></dependency><!--SPEL表达式语言支持--><dependency><groupId>org.jeasy</groupId><artifactId>easy-rules-spel</artifactId><version>4.1.0</version>
</dependency><!--MVEL表达式语言支持-->
<dependency><groupId>org.jeasy</groupId><artifactId>easy-rules-mvel</artifactId><version>4.1.0</version>
</dependency>

三、定义规则(Rules)

1、规则介绍

大多数的业务规则可以通过如下定义来描述:

  • Name:唯一的规则名称。
  • Description:简单规则描述。
  • Priority:规则执行优先级。
  • Facts:触发规则时的一系列事实。
  • Condition:给定事实后,应该被满足的一系列条件。
  • Actions:条件满足时应该执行的一系列行为。

Easy Rules中的规则由Rule接口来代表,如下:

public interface Rule extends Comparable<Rule> {/*** 判断规则是否应该被触发,true-是,false-否*/boolean evaluate(Facts facts);/*** 规则触发后执行的行为* @throws Exception 执行时触发的异常*/void execute(Facts facts) throws Exception;
}

2、编程式规则定义

import org.jeasy.rules.api.Facts;
import org.jeasy.rules.api.Rule;
import org.jeasy.rules.api.Rules;
import org.jeasy.rules.api.RulesEngine;
import org.jeasy.rules.core.DefaultRulesEngine;/*** 编程式规则定义* @author Nick Liu* @date 2023/8/3*/
public class ProgrammaticHelloWorldRule implements Rule {@Overridepublic boolean evaluate(Facts facts) {return facts.get("enabled");}@Overridepublic void execute(Facts facts) throws Exception {System.out.println("Hello World");}@Overridepublic int compareTo(Rule o) {return 0;}public static void main(String[] args) {// 定义事实Facts facts = new Facts();facts.put("enabled", true);// 注册编程式规则Rules rules = new Rules();rules.register(new ProgrammaticHelloWorldRule());// 使用默认规则引擎根据事实触发规则RulesEngine rulesEngine = new DefaultRulesEngine();rulesEngine.fire(rules, facts);}
}

备注:运行程序控制台会输出Hello World

3、声明式规则定义

import org.jeasy.rules.annotation.Action;
import org.jeasy.rules.annotation.Condition;
import org.jeasy.rules.annotation.Fact;
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;/*** 声明式规则定义* @author Nick Liu* @date 2023/8/3*/
@Rule(name = "Hello world rule", description = "Always say hello world")
public class DeclarativeHelloWorldRule {@Conditionpublic boolean when(@Fact("enabled") boolean enabled) {return enabled;}@Action(order = 1)public void then(@Fact("enabled") boolean enabled) throws Exception {System.out.println("Hello World");}@Action(order = 2)public void finalAction(Facts facts) throws Exception {System.out.println("Final Hello World");}public static void main(String[] args) {Facts facts = new Facts();facts.put("enabled", true);Rules rules = new Rules();rules.register(new DeclarativeHelloWorldRule());RulesEngine rulesEngine = new DefaultRulesEngine();rulesEngine.fire(rules, facts);}
}

控制台运行结果如下:

Hello World
Final Hello World

四、定义事实(Facts)

在Easy Rules中,事实由Fact类来定义,如下:

public class Fact<T> {private final String name;private final T value;
}

事实有namevalue两个属性,两者都不能为空,且name属性值充当命名空间的角色需要唯一。

下面是定义事实的例子:

  • 第1种方式
Fact<String> fact = new Fact("foo", "bar");
Facts facts = new Facts();
facts.add(fact);
  • 第2种方式
Facts facts = new Facts();
facts.put("foo", "bar");

备注:两者方式都定义了一个namefoovaluebar的事实实例,第二种方式更加简洁。


五、定义规则引擎(Rules Engine)

1、规则引擎介绍

Easy Rules提供了两种规则引擎的实现:

  • DefaultRulesEngine:默认规则引擎,根据规则的自然顺序(默认为优先级)应用规则。
  • InferenceRulesEngine:推理规则引擎,持续性应用单条规则,直到规则触发条件不满足。

Easy Rules规则引擎支持下面参数配置:

参数名称参数类型必选默认值
rulePriorityThresholdintInteger.MAX_VALUE
skipOnFirstAppliedRulebooleanfalse
skipOnFirstFailedRulebooleanfalse
skipOnFirstNonTriggeredRulebooleanfalse
  • skipOnFirstAppliedRule: 当规则被触发并且成功执行行为后是否跳过下条规则。
  • skipOnFirstFailedRule : 当判断规则是否触发抛出异常或者触发成功但行为执行后抛出异常是否跳过下条规则。
  • skipOnFirstNonTriggeredRule : 当规则未被触发是否跳过下条规则。
  • rulePriorityThreshold : 如果规则优先级超过默认阈值,则跳过下条规则。

参数配置示例如下:

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

通过下面的代码可以获取规则引擎参数:

RulesEngineParameters parameters = myEngine.getParameters();

2、InferenceRulesEngine规则引擎示例

DefaultRulesEngine默认规则引擎的使用示例前面已经有提到过,下面我们看下InferenceRulesEngine推理规则引擎的代码示例。

(1) 定义触发条件

import org.jeasy.rules.api.Condition;
import org.jeasy.rules.api.Facts;/*** @author Nick Liu* @date 2023/8/5*/
public class HighTemperatureCondition implements Condition {@Overridepublic boolean evaluate(Facts facts) {int temperature = facts.get("temperature");return temperature > 25;}
}

(2) 定义规则触发后的执行行为

import org.jeasy.rules.api.Action;
import org.jeasy.rules.api.Facts;/*** @author Nick Liu* @date 2023/8/5*/
public class DecreaseTemperatureAction implements Action {@Overridepublic void execute(Facts facts) throws Exception {int temperature = facts.get("temperature");System.out.printf("Current temperature: %d, It's hot! cooling air...%n", temperature);facts.put("temperature", temperature - 1);}
}

(3) 测试用例

import org.jeasy.rules.api.Facts;
import org.jeasy.rules.api.Rule;
import org.jeasy.rules.api.Rules;
import org.jeasy.rules.api.RulesEngine;
import org.jeasy.rules.core.InferenceRulesEngine;
import org.jeasy.rules.core.RuleBuilder;/*** @author Nick Liu* @date 2023/8/5*/
public class AirConditionLauncher {public static void main(String[] args) {Facts facts = new Facts();facts.put("temperature", 30);// 通过规则构建API定义规则Rule rule = new RuleBuilder().name("Air Condition Rule").when(new HighTemperatureCondition()).then(new DecreaseTemperatureAction()).build();Rules rules = new Rules();rules.register(rule);// 基于事实重复应用规则的推理规则引擎,直到规则不再满足RulesEngine rulesEngine = new InferenceRulesEngine();rulesEngine.fire(rules, facts);}
}

控制台输出结果如下:

Current temperature: 30, It's hot! cooling air...
Current temperature: 29, It's hot! cooling air...
Current temperature: 28, It's hot! cooling air...
Current temperature: 27, It's hot! cooling air...
Current temperature: 26, It's hot! cooling air...

备注:可以看到定义的规则会持续触发,直到temperature的值为25。

在这里插入图片描述

本文来自互联网用户投稿,该文观点仅代表作者本人,不代表本站立场。本站仅提供信息存储空间服务,不拥有所有权,不承担相关法律责任。如若转载,请注明出处:http://www.mzph.cn/news/33586.shtml

如若内容造成侵权/违法违规/事实不符,请联系多彩编程网进行投诉反馈email:809451989@qq.com,一经查实,立即删除!

相关文章

【CSH 入门基础 5 -- csh 文件监控脚本实现】

文章目录 背景CSHLL 代码实现cshell 中 unset 的介绍bash 中监控文件的方法 背景 由于开发代码是在外网编译&#xff0c;而镜像的烧写是在内网中的EDA工具中进行的&#xff0c;所以就需要先将代码在外网编译好后&#xff0c;再通过FTP工具将镜像传输到内网中&#xff0c;然后在…

【手动配置ip地址后,电脑仍自动分配ip的问题】

现象 手动给电脑分配了一个ipv4地址&#xff0c;但是电脑会自动分配一个169开头的ipv4&#xff0c;导致虽然可以上网&#xff0c;但访问不了局域网内其他的设备&#xff08;我配置的另一个网关&#xff0c;所以可以上网&#xff09; 原因 ip地址冲突了&#xff0c;把电脑的i…

3.3 Postman基础

1. Postman概述 Postman是一个接口测试工具&#xff0c;Postman相当于一个客户端&#xff0c;可以模拟用户发起的各类HTTP请求&#xff0c;将请求数据发送至服务端&#xff0c;获取对应的响应结果。 Postman版本&#xff1a;Postman-win64-9.15.2-Setup.exe。 2. Postman的参…

uniapp 左右滑动切换页面并切换tab

实现效果如图 要实现底部内部的左右滑动切换带动上方tab栏的切换&#xff0c;并且下方内容要实现纵向滚动 &#xff0c;所以需要swiper&#xff0c;swiper-item,scroll-view组合使用 tab栏部分 <view class"tabs"><view class"tab_item" v-for&…

Matlab时频工具箱tftb下载及安装

Matlab 时频工具箱下载及安装 首先下载安装包安装包地址如下 链接: https://tftb.nongnu.org/ 点击下面的download 跳转到如下界面&#xff0c;选择下面的安装包下载 下载之后得到一个压缩包 然后找到Matlab的安装目录&#xff0c;右键桌面图标&#xff0c;打开文件所在位置…

39.输出二叉树的右视图

题目&#xff1a;请根据二叉树的前序遍历&#xff0c;中序遍历恢复二叉树&#xff0c;并打印出二叉树的右视图 思路&#xff1a;先根据前序遍历和中序遍历&#xff0c;得到二叉树。根据先序顺序得到根&#xff0c;再根据根得到其在中序遍历中的位置&#xff0c;然后得到左右子…

Spring中的Websocket身份验证和授权

目录 一、需要了解的事项二、依赖三、WebSocket 配置3.1 、简单的消息代理3.2 、Spring安全配置 一、需要了解的事项 http和WebSocket的安全链和安全配置是完全独立的。SpringAuthenticationProvider根本不参与 Websocket 身份验证。将要给出的示例中&#xff0c;身份验证不会…

网络编程小项目-tftp下载

tftp下载模型 TFTP通信过程总结 服务器在69号端口等待客户端的请求服务器若批准此请求&#xff0c;则使用 临时端口 与客户端进行通信。每个数据包的编号都有变化&#xff08;从1开始&#xff09;每个数据包都要得到ACK的确认&#xff0c;如果出现超时&#xff0c;则需要重新发…

SSL握手协议相关概念

下图为握手协议的流程图&#xff0c;具体的解释参考博客&#xff1a; 【下】安全HTTPS-全面详解对称加密&#xff0c;非对称加密&#xff0c;数字签名&#xff0c;数字证书和HTTPS_tenfyguo的博客-CSDN博客 下面梳理一下SSL协议中的一些细节。首先是相关名词&#xff1a;证书、…

Programming abstractions in C阅读笔记:p84-p87

《Programming Abstractions In C》学习第43天&#xff0c;p84-p87总结。 一、技术总结 1.record record也称为structure&#xff08;结构体&#xff09;&#xff0c;是一种数据结构。record里面的成员称为record的field。对于record&#xff0c;需要其基本用法&#xff1a;定义…

nodejs+vue+elementui健身俱乐部网站rix1z

为设计一个安全便捷&#xff0c;并且使用户更好获取本健身俱乐部管理信息&#xff0c;本文主要有安全、简洁为理念&#xff0c;实现用户快捷寻找健身课程、健身器材、会员卡信息、新闻公告等信息&#xff0c;从而解决健身俱乐部管理信息复杂难辨的问题。该系统以vue架构技术为基…

AI绘画(1)stable diffusion安装教程

1、引言 stable diffusion 是一款免费开源的AI绘画工具&#xff0c;它能够帮助任何人轻松地进行绘画创作。不论你是有绘画基础还是完全没有经验&#xff0c;stable diffusion 都能让你在数字画布上释放创造力。 stable diffusion 提供了丰富多样的绘画工具和选项&#xff0c;…

浅谈Python中的内存管理 程序的内存布局

Python中的内存管理 Python 的内存管理是通过私有堆空间来实现的。这个私有堆内存中存储了所有 Python 对象和数据结构。Python 的解释器自身则拥有对堆空间的访问权&#xff0c;程序员不能直接访问这个私有堆&#xff0c;但可以通过解释器的 API 来进行某些操作。 以下是 Py…

Windows Server 2019安装使用PostgreSQL 15

主要是参考这篇文章来做的&#xff1a; Windows11安装配置PostgreSQL&#xff08;图文详细教程&#xff09;_win11安装postgres 并管理工具_return strxi的博客-CSDN博客 1. 下载的是postgresql 15.3 windows x64-86版本 Community DL Page 2. 安装时一定要右击安装exe文件…

【MySQL--->数据库基础】

文章目录 [TOC](文章目录) 一、基本概念二、实际应用中的数据库三、mysql的架构四、mysql语句分类五、存储引擎查看 一、基本概念 mysql本质是一个CS模式的网络服务,mysql是客户端,mysqld是服务端,提供高效的数据存取方案.数据库系统简单来说是一个数据集合加上管理这个数据集…

Spring AoP 详解

目录 一、概述二、Spring AOP 和 AspectJ AOP 的区别三、AspectJ 定义的通知类型四、多个切面的执行顺序控制方法 一、概述 AOP(Aspect-Oriented Programming:面向切面编程)能够将那些与业务无关&#xff0c;却为业务模块所共同调用的逻辑或责任&#xff08;例如事务处理、日志…

Camunda 7.x 系列【10】使用 Rest API 运行流程实例

有道无术,术尚可求,有术无道,止于术。 本系列Spring Boot 版本 2.7.9 本系列Camunda 版本 7.19.0 源码地址:https://gitee.com/pearl-organization/camunda-study-demo 文章目录 1. 前言2. 官方接口文档3. 本地接口文档3.1 Postman3.2 Camunda Platform Run Swagger3.3 S…

Python之一:基础信息

#查看pip版本&#xff0c;cmd命令窗口&#xff08;注意环境变量%PYTHON_HOME%\scripts&#xff0c;是否在path中&#xff09; pip --version #安装pip&#xff0c;cmd命令窗口 python -m pip install pip #查看已安装模块&#xff0c;cmd命令窗口 python -m pydoc modules #查看…

贪心算法:基础入门篇

贪心算法&#xff1a;基础入门篇 文章目录&#xff1a; 贪心算法&#xff1a;基础入门篇一、认识贪心算法二、常见贪心问题2.1 纸牌问题2.2 背包问题&#xff08;基础版&#xff09;2.3 简单数学证明问题 三、总结 一、认识贪心算法 在求最优解的问题中&#xff0c;以某种贪心…

cookie是什么?

cookie是什么&#xff1f; Cookie实际上是一小段的文本信息。 http协议本身是无状态的。无状态是指Web浏览器与Web服务器之间不需要建立持久的连接&#xff0c;这意味着当一个客户端向服务器端发出请求&#xff0c;然后Web服务器返回响应&#xff08;Response&#xff09;&…