从零开始:Spring Boot 中使用 Drools 规则引擎的完整指南

规则引擎作用

规则引擎主要用于将业务逻辑从应用程序代码中分离出来,提高系统的灵活性和可维护性。规则引擎通过预定义的规则来处理输入数据并做出相应的决策,从而实现业务逻辑的自动化和动态调整。

例如
  • 门店信息校验:美团点评在门店信息校验过程中使用规则引擎,对门店信息进行质量控制。规则包括分支条件、简单计算规则和业务定制计算规则等。通过规则引擎,门店信息校验过程变得更加高效和准确。

业务场景说明

不同会员的折扣率不同
在这里插入图片描述

代码结构

在这里插入图片描述

集成 Drools(即规则引擎)到 Spring Boot 可以帮助你实现业务规则的动态管理和执行。下面我来简要说明一下业务场景和代码实现的步骤:

1. 添加依赖

首先,需要在 pom.xml 文件中添加 Drools 的依赖:

 <!-- drools规则引擎 --><dependency><groupId>org.drools</groupId><artifactId>drools-compiler</artifactId><version>7.6.0.Final</version></dependency>
2. 创建规则文件

在项目的src/main/resources目录下创建一个名为rules的文件夹,并在其中创建一个名为sample.drl的规则文件:

package com.song;
import com.song.rulesobj.Customerrule "ORDINARY-Customers"
whencustomer: Customer(type == "ORDINARY")
thencustomer.setDiscount(0.9*customer.getOriginalPrice()); // 9折  普通会员
endrule "VIP-Customers"
whencustomer: Customer(type == "VIP")
thencustomer.setDiscount(0.6*customer.getOriginalPrice()); // 6折 VIP会员
endrule "SVIP-Customers"
whencustomer: Customer(type == "SVIP")
thencustomer.setDiscount(0.4*customer.getOriginalPrice()); // 4折 SVIP会员
end
3. 定义实体类

创建一个简单的实体类 Customer,用于表示客户信息:

package com.song.rulesobj;import lombok.Data;@Data
public class Customer {/*** 客户类型*/private String type;/*** 客户订单价格*/private Double  originalPrice; // 订单原始价格,即优惠前的价格/*** 优惠后最终结算价格*/private Double discount;
}
4. 配置 Drools 规则引擎

在 Spring Boot 应用程序中配置 Drools 规则引擎的 bean:

package com.song.conf;import com.song.bean.DiscountBean;
import org.kie.api.KieServices;
import org.kie.api.builder.KieBuilder;
import org.kie.api.builder.KieFileSystem;
import org.kie.api.builder.KieRepository;
import org.kie.api.runtime.KieContainer;
import org.kie.api.runtime.KieSession;
import org.springframework.context.annotation.Bean;
import org.springframework.context.annotation.Configuration;@Configuration
public class DroolsConfig {@Beanpublic KieContainer kieContainer() {KieServices kieServices = KieServices.Factory.get();KieRepository kieRepository = kieServices.getRepository();KieFileSystem kieFileSystem = kieServices.newKieFileSystem();kieFileSystem.write(kieServices.getResources().newClassPathResource("rules/sample.drl"));KieBuilder kieBuilder = kieServices.newKieBuilder(kieFileSystem);kieBuilder.buildAll();return kieServices.newKieContainer(kieRepository.getDefaultReleaseId());}@Beanpublic KieSession kieSession() {return kieContainer().newKieSession();}@Beanpublic DiscountBean discountBean() {return new  DiscountBean(kieSession());}}
5. 应用规则引擎

在业务代码中使用注入的 KieSession 执行规则:

/******************************************************************************** Package: com.song.bean* Type:    DiscountService* Date:    2024-06-28 13:45** Copyright (c) 2024 LTD All Rights Reserved.** You may not use this file except in compliance with the License.*******************************************************************************/
package com.song.bean;import com.song.rulesobj.Customer;
import org.kie.api.runtime.KieSession;/*** 功能描述: 规则处理器封装** @author Songxianyang* @date 2024-06-28 13:45*/
public class DiscountBean {private KieSession kieSession;public DiscountBean(KieSession kieSession) {this.kieSession = kieSession;}public void applyDiscount(Customer customer) {kieSession.insert(customer); // 插入客户对象到规则引擎中kieSession.fireAllRules(); // 执行规则// 客户对象已经被更新,包含了计算出的折扣System.out.println("客户订单价格"+customer.getOriginalPrice()+"客户折扣类型: " + customer.getType() + ", 优惠后最终结算价格: " + customer.getDiscount());}}
6. 测试规则引擎

编写一个简单的测试类来验证规则引擎是否按预期工作:

package com.song.web;import com.song.bean.DiscountBean;
import com.song.common.annotation.ResponseInfoSkin;
import com.song.rulesobj.Customer;
import io.swagger.annotations.Api;
import io.swagger.annotations.ApiOperation;
import org.kie.api.runtime.KieContainer;
import org.kie.api.runtime.KieSession;
import org.springframework.beans.factory.annotation.Autowired;
import org.springframework.web.bind.annotation.GetMapping;
import org.springframework.web.bind.annotation.PostMapping;
import org.springframework.web.bind.annotation.RequestBody;
import org.springframework.web.bind.annotation.RestController;@RestController
@Api(tags = "规则引擎")
@ResponseInfoSkin
public class DemoController {@Autowiredprivate DiscountBean discountBean;@PostMapping("/discount")@ApiOperation("打折")public Double discount(@RequestBody Customer customer) {// 规则处理器封装discountBean.applyDiscount(customer);return customer.getDiscount();}
}
测试截图

在这里插入图片描述
在这里插入图片描述

总结

通过上述步骤,你可以将 Drools 规则引擎集成到 Spring Boot 应用程序中,并使用规则文件动态管理业务规则,实现不同客户类型的动态折扣计算。这种方式可以使得业务规则更易于维护和修改,同时与应用程序解耦,提高了灵活性和可维护性。

源码

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

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

相关文章

Websocket在Java中的实践——握手拦截器

大纲 依赖握手拦截器消息处理测试参考资料 在《Websocket在Java中的实践——最小可行案例》一文中&#xff0c;我们看到如何用最简单的方式实现Websocket通信。本文中&#xff0c;我们将介绍如何在握手前后进行干涉&#xff0c;以定制一些特殊需求。 在《Websocket在Java中的实…

.net 项目中配置 Swagger

一、前言 二、Swagger 三、.net 项目中添加Swagger 1、准备工作 &#xff08;1&#xff09;.net项目 &#xff08;2&#xff09;SwaggerController &#xff08;3&#xff09;XML文档注释 2、安装Swagger包 3、 添加配置swagger中间件 &#xff08;1&#xff09;添加S…

Dijkstra算法C代码

一个带权图n个点m条边&#xff0c;求起点到终点的最短距离 先定义一个邻接矩阵graph&#xff0c;graph[i][j]表示从i到j的距离&#xff0c;i到j没有路就表示为无穷 然后定义一个visit数组&#xff0c;visit[i]表示i结点是否被访问 然后定义一个dist数组&#xff0c;dist[i]表…

计算机等级考试二级Java-第二篇:基本数据类型

1.运算符的优先级以及复杂表达式 优先级运算符结合性1( ) [ ]  .从左到右2!  ~    –从右到左3*  /  %从左到右4  -从左到右5<<  >>  >>>从左到右6<  <  >  >  instanceof从左到右7  !从左到右8&从左到右9^从左到右10|从…

常微分方程算法之编程示例四(龙格-库塔法)

目录 一、算例一 1.1 研究问题 1.2 C++代码 1.3 计算结果 二、算例二 2.1 研究问题 2.2 C++代码 2.3 计算结果 一、算例一 本节我们采用龙格-库塔法(Runge-Kutta法)求解算例。 龙格-库塔法的原理及推导请参考: 常微分方程算法之龙格-库塔法(Runge-Kutta法)…

「51媒体」浙江地区媒体邀约

传媒如春雨&#xff0c;润物细无声&#xff0c;大家好&#xff0c;我是51媒体网胡老师。 媒体宣传加速季&#xff0c;100万补贴享不停&#xff0c;一手媒体资源&#xff0c;全国100城线下落地执行。详情请联系胡老师。 浙江地区的媒体邀约资源丰富多样&#xff0c;涵盖了电视台…

EXCEL 复制后转置粘贴

nodepad 转置参考&#xff1a; https://editor.csdn.net/md/?articleId140014651 1. WPS复制后转置粘贴 复制-》右键-》顶部第一行-》粘贴行列转置&#xff0c;如下图&#xff1a; 2. Excel office365 本地版 2. Excel office365 在线版

Shell编程之正则表达式与文本处理器

正则表达式 正则表达式概述 1. 正则表达式的定义 正则表达式又称正规表达式、常规表达式。在代码中常简写为regex 、regexp 或 RE 。 正则表达式是使用单个字符串来描述、匹配一系列符合某个句法规则的字符串&#xff0c;简单来说&#xff0c;是一种匹配字符串的方法&…

Linux操作系统--软件包管理(保姆级教程)

RPM软件包的管理 大多数linux的发行版本都是某种打包系统。软件包可以用来发布应用软件&#xff0c;有时还可以发布配置文件。他们比传统结构的.tar和.gz存档文件有几个优势。如它们能让安装过程尽可能成为不可分割的原子操作。 软件包的安装程序会备份它们改动过的文件。如果…

华为昇腾NPU实战:LLM ChatGLM2模型推理体验

参考&#xff1a;https://gitee.com/mindspore/mindformers/blob/dev/docs/model_cards/glm2.md#chatglm2-6b 1、安装环境&#xff1a; 昇腾NPU卡对应英伟达GPU卡&#xff0c;CANN对应CUDA底层&#xff1b; mindspore对应pytorch&#xff1b;mindformers对应transformers 本…

【笔记】Spring Cloud Gateway 实现 gRPC 代理

Spring Cloud Gateway 在 3.1.x 版本中增加了针对 gRPC 的网关代理功能支持,本片文章描述一下如何实现相关支持.本文主要基于 Spring Cloud Gateway 的 官方文档 进行一个实践练习。有兴趣的可以翻看官方文档。 由于 Grpc 是基于 HTTP2 协议进行传输的&#xff0c;因此 Srping …

新手教程系列 -- SQLAlchemy对同一张表联表两次

在开发过程中&#xff0c;我们经常会遇到对同一张表进行多次联表查询的需求。比如在查询航线时&#xff0c;我们希望将起飞和降落的机场名称代入结果中。为了实现这一目标&#xff0c;机场名称统一存放在 AirPort 表中。下面&#xff0c;我们将介绍如何通过 SQLAlchemy 实现这一…

财务RPA与数字化转型——财务RPA如何促进企业的数字化转型

在数字化时代&#xff0c;企业面临着推动创新、提高效率的巨大挑战。RPA财务机器人作为智慧财务不可或缺的新动能&#xff0c;不仅能够优化财务流程&#xff0c;还能够在整个企业中引领数字化变革。本文金智维将深入探讨财务RPA如何成为企业数字化转型的战略利器&#xff0c;为…

visual studio 2022配置和使用jsoncpp

下载 jsoncpp下载位置&#xff1a; GitHub - open-source-parsers/jsoncpp: A C library for interacting with JSON. 编译库 1、下载完成之后解压 2、在解压文件的makefiles文件下有个vs71&#xff0c;在vs71中有visual studio项目&#xff0c;不过这里的项目是visual stud…

-bash: /snap/bin/docker: 没有那个文件或目录

-bash: /snap/bin/docker: 没有那个文件或目录 解决办法 export PATH$PATH:/usr/bin/docker然后&#xff0c;重新加载配置文件 source ~/.bashrc

AI是如何与快充技术结合的?

针对AI技术在快充领域的运用&#xff0c;我们可以进一步深入探讨AI如何与快充技术结合&#xff0c;提升充电效率和用户体验。以下是一些具体的AI技术在快充领域的应用场景&#xff1a; 一、智能充电算法 学习充电模式&#xff1a;AI算法可以学习用户的充电习惯&#xff0c;比…

浅谈API生态建设:API安全策略的6项原则

API作为连接系统与应用的桥梁&#xff0c;在助力实现高效业务流程的同时&#xff0c;也不可避免出现资产管理困难、敏感数据泄漏风险骤增等安全问题。前段时间&#xff0c;安全公司Fastly公布了一项重磅调查报告&#xff0c;报告中显示95%的企业在过去1年中遭遇过API安全问题。…

模型预测控制:设定点跟踪(Set Point Tracking)

模型预测控制&#xff1a;设定点跟踪&#xff08;Set Point Tracking&#xff09; 模型预测控制&#xff08;Model Predictive Control, MPC&#xff09;不仅可以用于系统稳定性问题&#xff0c;还可以用于设定点跟踪问题&#xff08;Set Point Tracking&#xff09;&#xff…

计算机网络 —— 路由协议:RIP、OSPF、BGP、MPLS

路由协议 1. 定义2. IGP2.1 RIP2.2 OSPF 3. BGP4. MPLS 1. 定义 互联网中需要通过路由将数据发送至目标主机。 路由器根据**路由控制表(RoutingTable)**转发数据包&#xff0c;它根据所收到的数据包中目标主机的IP地址与路由控制表的比较得出下一个应该接收的路由器。 &…

前端通过ResizeObserver来监听dom大小动态渲染echarts

export const GlobalResizeObserver (function () {const ATTR_NAME global-resizeobserver-keyconst attrValueToCallback {}function antiShake(fn, delay, immediate false) {let timer null//不能用箭头函数return function () {//在时间内重复调用的时候需要清空之前…