easy-rule规则引擎使用

news2024/11/16 1:22:24

简介

        轻量级的规则引擎,易于学习的api

        简单来说,规则引擎就是一个函数:y=f(x1,x2,…,xn)

        将业务代码和业务规则分离,解耦业务决策和业务代码的绑定关系

入门示例

依赖引入
<dependency>
     <groupId>org.jeasy</groupId>
     <artifactId>easy-rules-core</artifactId>
     <version>4.1.0</version>
</dependency>

<!--规则定义文件格式,支持json,yaml等-->
<dependency>
  <groupId>org.jeasy</groupId>
  <artifactId>easy-rules-support</artifactId>
  <version>4.1.0</version>
</dependency>

<!--支持mvel规则语法库-->
<dependency>
  <groupId>org.jeasy</groupId>
  <artifactId>easy-rules-mvel</artifactId>
  <version>4.1.0</version>
</dependency>

<dependency>
  <groupId>org.jeasy</groupId>
  <artifactId>easy-rules-spel</artifactId>
  <version>4.1.0</version>
</dependency>
代码示例
public static void main(String[] args) {

        Rules rules = new Rules();

        Rule rule = new RuleBuilder()
                .name("test")
                .description("测试").priority(3)
                .when(facts -> facts.get("userName").equals("zhangsan"))
                .then(facts -> System.out.println("this is test action!"))
                .build();

        rules.register(rule);

        Facts facts = new Facts();
        facts.put("userName","zhangsan");

        DefaultRulesEngine defaultRulesEngine = new DefaultRulesEngine();
        defaultRulesEngine.fire(rules,facts);
    }
核心概念
规则(Rule)

        由条件和行动构成的推理语句,通俗的讲:当满足某个条件之后,需要做后续的动作(一个或多个动作),一般表示为IF <conditions> THEN <actions>, Rule表达逻辑。一个规则的IF部分称为LHS,THEN部分称为RHS。

除了以上示例方式构建Rule,还可以通过注解构建Rule:

@Rule(name = "repeatRule",description = "重复规则对消息内容去重",priority = 100)
public class RepeatRule {

    @Condition
    public boolean evaluate(@Fact("sendMessages") Set<String> sendMessages, @Fact("message") String message) {
        return sendMessages.contains(message);
    }

    @Action(order =0)
    public void execute(Facts facts) {
        //
    }

    @Action(order = 1)
    public void breakRules(Facts facts) {
        facts.put("break",true);
        facts.put("reason","repeat limit");
    }

}
事实(Facts)

        一组用户的输入数据,规则将根据输入数据判断是否满足条件,从而触发规则actions

        Facts是一组Fact集合,源码示例如下:

而Fact是一个容器,可以简单的理解成一个Map对象:

执行引擎(RulesEngine)

        引擎执行器,一般为推理引擎。Rules使用LHS与事实进行模式匹配。当匹配被找到,Rules会执行RHS即执行逻辑,同时actions经常会改变facts的状态,来推理出期望的结果。

        常用的执行引擎即:DefaultRulesEngine

结合mvel使用示例

@Test
    public void mvelExecute() {
        MVELRule repeatRule = new MVELRule().name("repeat Rule")
                .priority(100)
                .when("!sendMessages.contains(msgId)")
                .then("result.put('break',true);result.put('reason','repeat limit')");

        Rules rules = new Rules(repeatRule);

        Facts facts = new Facts();

        facts.put("msgId","123456");
        facts.put("sendMessages",new TreeSet<>());
        facts.put("msgType","interaction");
        facts.put("message","hello world");
        facts.put("result",new HashMap<>());

        DefaultRulesEngine engine = new DefaultRulesEngine();
        //CustomRuleListener customRuleListener = new CustomRuleListener();
        //engine.registerRuleListener(customRuleListener);
        engine.fire(rules,facts);
        Map<String,Object> result = (Map<String,Object>)facts.get("result");

        log.info("执行结果是:{}", JSONUtil.toJsonStr(result));
    }

MVEL可以支持表达式支持常用的逻辑符:> = < && || 等,还支持java类型api的调用

最直观的使用MVEL表达是API如下:

 @Test
    public void mvelCompileTest(){
        MyTest obj = new MyTest();
        Map<String, Object> map = new HashMap<>();
        map.put("key1", 1);
        map.put("key2", 2);

        String expression = "func(map)";
        Map<String, Object> vars = new HashMap<>();
        vars.put("map", map);

        MVEL.executeExpression(MVEL.compileExpression(expression), obj, vars);
        System.out.println(map);

    }

    public void func(Map<String, Object> map) {
        map.put("test","lisi");
    }

详细的MVEL脚本语言的使用:http://mvel.documentnode.com/

结合spel使用示例

public static void main(String[] args) {

        Rules rules = new Rules();

        SpELRule spelRule = new SpELRule().name("1")
                .description("1")
                .priority(1)
                .when("#{ ['item'].price >= 100 }")
                .then("#{ ['item'].setExpression('折扣1折\n原价为:' + ['item'].price " +
                        "+ '\n折扣后的价格为:'" +
                        " + T(java.lang.Float).parseFloat(['item'].price * 0.1+'') )  }");

        rules.register(spelRule);
        Item item = new Item(500);
        Facts facts = new Facts();
        facts.put("item", item);

        DefaultRulesEngine defaultRulesEngine = new DefaultRulesEngine();
        // 触发引擎
        defaultRulesEngine.fire(rules, facts);
        System.out.println(item.getExpression());

    }

企业级应用

如果规则引擎的使用仅仅只如以上硬编码的使用方式,还不足以体现规则引擎的强大。试看以下代码:

@Test
    public void factoryTest() throws Exception {

        ClassPathResource classPathResource = new ClassPathResource("rule.yml");
        String absolutePath = classPathResource.getAbsolutePath();

        YamlRuleDefinitionReader ymlReader = new YamlRuleDefinitionReader();
        MVELRuleFactory mvelRuleFactory = new MVELRuleFactory(ymlReader);
        Rules rules = mvelRuleFactory.createRules(new FileReader(absolutePath));

        DefaultRulesEngine rulesEngine = new DefaultRulesEngine();
        JSONObject entries = new JSONObject();
        entries.set("productId","1");
        entries.set("type","1");

        Facts facts = new Facts();
        facts.put("canteen", entries);

        rulesEngine.fire(rules, facts);
    }

yml内容如下:

---
name: "规则1"
description: "prouductId = 1 && type = 1 "
condition: "canteen.productId==1&&canteen.type==1"
priority: 1
actions:
  - "com.byd.performance.easyruledemo.four.UserInfoService.getNowTime();"
---
name: "规则2"
description: "prouductId = 1 && type = 2"
condition: "canteen.productId == 2 && canteen.type == 1"
priority: 2
actions:
  - "System.out.println(2);"

以上通过配置文件定义规则,将规则的触发决策通过文本的方式表述,解耦了业务逻辑代码和规则决策,大大的提升了该引擎的实用性。试想如下业务场景:

公司为了对产品经销商加强管理,需要制定一系列的处罚措施,当触犯某条规则时,将受到相应的惩罚措施。如果采用代码实现决策过程,需要大量的if else来完成,且当需要改变处罚措施时,需要修改代码,重新发布。

如果把决策过程由以上配置文件完成(再配合规则变动刷新等措施或者直接把规则数据由数据库存储加载),可以方便的支持需求变更(此处只是讨论决策的变动,如果需要新增加某种处罚措施也需要代码调整、发布)

源码浅析

easy-rule的源码较为简单(最主要是将触发规则(Condition)和执行逻辑(Action)解耦的思想),以下以简单的示例做源码分析:

org.jeasy.rules.core.DefaultRulesEngine#doFire

可以看出执行引擎的核心逻辑逻辑清晰、简单--就是通过循环Rule,判断是否命中规则,然后执行规则逻辑即可

其中执行引擎有4个参数可设置,分别释义如下:

skipOnFirstAppliedRule:Parameter to skip next applicable rules when a rule is applied(当第一个被命中的规则执行后,是否不执行后续规则)代码line 115就是改功能的释义

skipOnFirstNonTriggeredRule:Parameter to skip next applicable rules when a rule is non triggered(当有规则的判断逻辑未命中或判断是否命中异常,是否跳过后续规则,代码line102,line130 是逻辑释义)

isSkipOnFirstFailedRule:Parameter to skip next applicable rules when a rule has failed(当执行某个规则逻辑异常时是否跳过后续规则)

priorityThreshold:规则优先级的阈值,超过该阈值的规则不被执行,默认值是Integer.MAX_VALUE

功能展望

在上面的企业级应用中有提到过,将规则决策由代码实现转而由配置文件(或者存储于数据库)中实现,解耦了规则和执行逻辑。(执行逻辑--知识库)知识库的更新需要走发布流程。如果实现以下功能是不是能更好的发挥该框架的功能

1  解藕知识库与业务逻辑的耦合性,维护知识库来进行知识与版本的管理

2  动态增加知识库,让JVM动态加载新的知识库

3 屏蔽语言壁垒,能够让运营、产品支持在线规则配置、发布是最终要实现的重要目标。做到无需研发接入,实时发布

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

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

相关文章

3dmax渲染经常卡主?关掉光追即可流畅渲染

3ds Max是一款广泛应用于三维建模、动画和渲染的软件&#xff0c;它在影视、游戏、建筑可视化等领域具有重要地位。在3ds Max中&#xff0c;渲染技术的选择和应用直接影响到最终图像的质量和渲染效率。 但在实际使用过程中&#xff0c;由于3dsMax中有太多选项&#xff0c;很多…

一文看懂!电磁仿真软件CST Studio Suite的技术发展历程

CST工作套件室是一款功能强大、专业级别的软件包&#xff0c;用于进行微波无源器件和天线的仿真分析和设计。它支持的应用领域包括耦合器、滤波器、环流器、隔离器、谐振腔、平面结构、连接器、电磁兼容、集成电路封装以及各种类型的天线和天线阵列。该软件可以提供必要的S参数…

【C++】:vector容器的底层模拟实现迭代器失效隐藏的浅拷贝

目录 &#x1f4a1;前言一&#xff0c;构造函数1 . 强制编译器生成默认构造2 . 拷贝构造3. 用迭代器区间初始化4. 用n个val值构造5. initializer_list 的构造 二&#xff0c;析构函数三&#xff0c;关于迭代器四&#xff0c;有关数据个数与容量五&#xff0c;交换函数swap六&am…

【机器学习-k近邻算法-01】 | Scikit-Learn工具包进阶指南:机器学习sklearn.neighbors模块之k近邻算法实战

&#x1f3a9; 欢迎来到技术探索的奇幻世界&#x1f468;‍&#x1f4bb; &#x1f4dc; 个人主页&#xff1a;一伦明悦-CSDN博客 ✍&#x1f3fb; 作者简介&#xff1a; C软件开发、Python机器学习爱好者 &#x1f5e3;️ 互动与支持&#xff1a;&#x1f4ac;评论 &…

ubuntu下载离线软件包及依赖

目录 一、前言 二、正文 1.准备环境 2.开始下载 3.后续工作 三、总结 一、前言 由于给客户提供的设备机不允许上网&#xff0c;那么所有待安装的软件包及依赖库都需要提前下载好&#xff0c;然后通过局域网传过去再安装。 另外&#xff0c;软件包可能还依赖其他的库&…

AI大模型给稀土产业带来什么

近日&#xff0c;在包头市金蒙汇磁材料有限责任公司成品自动检验车间&#xff0c;三台AI大模型质检机器人正在紧张工作着&#xff0c;随着光电的闪烁&#xff0c;电子屏上不断更新着相关信息&#xff0c;一批批磁钢产品很快完成检测。 技术人员查看大模型质检设备上的检测信息 …

Jetpack架构组件_4. 数据绑定库页面传递数据

本篇介绍数据源从activity_main&#xff08;1级页面&#xff09;传递给include布局&#xff08;2级页面&#xff09;。 1.实现步骤 step1.修改build.gradle文件 修改app模块下的build.gradle文件&#xff0c;增加如下内容&#xff1a; dataBinding {enabled true} step2.创建…

WPF之TextBlock文本标签

TextBlock: 用于显示文本内容 常用属性 Text设置展示的文本fontsize设置字体大小FontWeight设置字体粗细FontFamily设置字体样式 实例 <Grid><TextBlock Text"显示文本"FontSize"10"FontWeight"Bold"Foreground"red">&l…

【机器学习300问】105、计算机视觉(CV)领域有哪些子任务?

计算机视觉作为人工智能的重要分支&#xff0c;发展至今已经在诸多领域取得显著的成果。在众多的计算机视觉任务中&#xff0c;图像分类、目标检测与定位、语义分割和实例分割是四个基本而关键的子任务&#xff0c;它们在不同的应用场景下扮演着重要角色。这四个子任务虽然各具…

Neovim 配置全面解析(下)

Neovim 配置全面解析&#xff08;下&#xff09; 原文&#xff1a;Neovim 配置全面解析&#xff08;下&#xff09; - 知乎 (zhihu.com) 环境&#xff1a;Ubuntu 20.04 宿主机&#xff1a;windows &#xff08;windows terminal&#xff09;WSL 2 NVIM&#xff1a;v 0.10.0-de…

是如何学习 Java 的?

我曾在携程旅行网做 Java 开发&#xff0c;也曾拿过阿里 P7 offer 和饿了么、美团等公司的 offer&#xff0c;这是职位都是 Java 开发岗&#xff0c;也做过 Java 面试官面试过不少同学。下面我就和大家分享一下我学习 Java的经验。 我将从 Java 基础知识、Java 框架、计算机基…

Java设计模式 _行为型模式_备忘录模式

一、备忘录模式 1、备忘录模式 备忘录模式&#xff08;Memento Pattern&#xff09;是一种行为型模式。通过保存一个对象的某个状态&#xff0c;以便在适当的时候恢复对象。 2、实现思路 &#xff08;1&#xff09;、定义记录数据的格式规范。 &#xff08;2&#xff09;、编…

计算机算法中的数字表示法——原码、反码、补码

目录 1.前言2.研究数字表示法的意义3.数字表示法3.1 无符号整数3.2 有符号数值3.3 二进制补码(Twos Complement, 2C)3.4 二进制反码(也称作 1 的补码, Ones Complement, 1C)3.5 减 1 表示法(Diminished one System, D1)3.6 原码、反码、补码总结 1.前言 昨天有粉丝让我讲解下定…

SRE视角下的DevOps构建之道

引言&#xff1a; 随着数字化时代的飞速发展&#xff0c;软件成为了企业竞争力的核心。为了更高效地交付高质量的软件&#xff0c;DevOps&#xff08;Development和Operations的组合&#xff09;作为一种文化、实践和工具集的集合&#xff0c;逐渐成为了行业内的热门话题。然而…

怎样快速查找网页代码中存在的错误?

计算机很机械&#xff0c;代码中存在微小的错误&#xff0c;计算机就得不到正确的运行结果。比如&#xff0c;一个字母的大小写、比如&#xff0c;个别地方丢掉了一个符号、、、如此等等。这就要求程序员和计算机是心灵相通的&#xff0c;不能有任何的“隔阂”。 但是&#xf…

汇智知了堂实力展示:四川农业大学Python爬虫实训圆满结束

近日&#xff0c;汇智知了堂在四川农业大学举办的为期五天的校内综合项目实训活动已圆满结束。本次实训聚焦Python爬虫技术&#xff0c;旨在提升学生的编程能力和数据分析能力&#xff0c;为学生未来的职业发展打下坚实的基础。 作为一家在IT教育行业享有盛誉的机构&#xff…

【ArcGISPro】3.1.5下载和安装教程

下载教程 arcgis下载地址&#xff1a;Трекер (rutracker.net) 点击磁力链下载弹出对应的软件进行下载 ArcGISPro3.1新特性 ArcGIS Pro 3.1是ArcGIS Pro的最新版本&#xff0c;它引入了一些新的特性和功能&#xff0c;以提高用户的工作效率和数据分析能力。以下是ArcGIS…

基于Udp(收发信息使用同一个socket)网络通信编程

想要实现网络通信那么就要有一个客户端一个服务器 客户端发送数据&#xff0c;服务器接收数据并返回数据 网络通信就是进程通信 所以我们用两个程序来分别编写客户端和服务器 服务器 1&#xff0c;设置端口号&#xff0c; 2、ip可以固定位127.0.0.1来用于本地测试&#xff0c…

dbserver 软件 展示 全部模式库

目录 1 问题2 实现 1 问题 dbserver 软件 展示 全部模式库 2 实现 以上就可以了

基于文本来推荐相似酒店

基于文本来推荐相似酒店 查看数据集基本信息 import pandas as pd import numpy as np from nltk.corpus import stopwords from sklearn.metrics.pairwise import linear_kernel from sklearn.feature_extraction.text import CountVectorizer from sklearn.feature_extrac…