当前位置: 首页 > news >正文

从零开始: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 应用程序中,并使用规则文件动态管理业务规则,实现不同客户类型的动态折扣计算。这种方式可以使得业务规则更易于维护和修改,同时与应用程序解耦,提高了灵活性和可维护性。

相关文章:

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

规则引擎作用 规则引擎主要用于将业务逻辑从应用程序代码中分离出来&#xff0c;提高系统的灵活性和可维护性。规则引擎通过预定义的规则来处理输入数据并做出相应的决策&#xff0c;从而实现业务逻辑的自动化和动态调整。 例如 门店信息校验&#xff1a;美团点评在门店信息…...

工业边缘计算网关

1 介绍 HINETG系列边缘计算网关&#xff08;Linux操作系统&#xff09;&#xff0c;是华辰智通的—款面向工业现场设备接入、数据采集、设备监控的工业级边缘计算网关。采用ARM Cortex-A7 800MHz高性能CPU,拥有以太网、串口、CAN口、IO口等丰富的接口&#xff0c;支持以太网、…...

【C++ 初阶路】--- 类和对象(末)

目录 一、const成员1.1 取地址及const取地址操作符重载 二、再谈构造函数2.1 构造函数体赋值2.2 初始化列表2.3 explicit关键字 三、static成员3.1 概念3.2 特性 四、友元4.1 友元函数4.2 友元类 五、内部类六、匿名对象 一、const成员 将const修饰的“成员函数”称之为const成…...

bable 【实用教程】

简介 bable 用于将 ES6 的语法编译为 ES5 只关心语法&#xff0c;不关心 API 是否正确。不处理模块化&#xff08;webpack 会处理&#xff09; 搭建开发环境 安装相关的包 npm i babel/cli babel/core babel/preset-env新建文件 .babelrc&#xff0c;内容为 { "presets…...

Android中使用startActivityForResult启动活动

Android中使用startActivityForResult启动活动 大家好&#xff0c;我是免费搭建查券返利机器人省钱赚佣金就用微赚淘客系统3.0的小编&#xff0c;也是冬天不穿秋裤&#xff0c;天冷也要风度的程序猿&#xff01;在本文中&#xff0c;我们将深入探讨Android开发中使用startActi…...

NineData和华为云在一起!提供一站式智能数据库DevOps平台

以GuassDB数据库为底座 NineData和华为云一起 为企业提供 一站式智能数据库DevOps平台 帮助开发者 高效、安全地完成 数据库SQL审核 访问控制、敏感数据保护等 日常数据库相关开发任务 NineData 智能数据管理平台 NineData 作为新一代的云原生智能数据管理平台&#xf…...

深入解析 Redisson分布式锁看门狗机制

一、Redisson分布式锁概述 1.1 分布式锁的意义 在分布式系统中&#xff0c;多个节点可能同时访问共享资源&#xff0c;导致数据不一致或竞态条件。分布式锁通过协调不同节点对共享资源的访问&#xff0c;确保数据的一致性和并发访问的安全性。 1.2 Redisson分布式锁的优势 …...

Apache Arrow 和数据的未来:开放标准推动人工智能发展

Apache Arrow 是一种开源列式内存格式&#xff0c;适用于平面数据和分层数据。在现代数据湖中&#xff0c;开放数据格式&#xff08;如 Apache Arrow&#xff09;位于现代对象存储的存储层中。这些格式成为对象存储中的对象。 在最新版本中&#xff0c;Apache Arrow 宣布计划从…...

Vue项目生产环境的打包优化

Vue项目生产环境的打包优化 前言 在这篇文章我们讨论Vue项目生产环境的打包优化&#xff0c;并按步骤展示实际优化过程中的修改和前后对比。 背景 刚开始的打包体积为48.71M 优化 步骤一&#xff1a;删除viser-vue viser-vue底层依赖antv/g2等库一并被删除&#xff0c;…...

oracle数据库之使用Java程序调用存储过程(二十四)

在Oracle数据库中&#xff0c;你可以使用Java程序来调用存储过程。这通常涉及几个步骤&#xff1a;首先&#xff0c;确保你的Java环境能够连接到Oracle数据库&#xff1b;其次&#xff0c;使用JDBC&#xff08;Java Database Connectivity&#xff09;来调用存储过程。 以下是…...

西电953总分第一、专业课第一考研上岸

今年上岸西电杭研院网信院网络与信息安全专业&#xff0c;总分370分&#xff0c;专业课116分&#xff0c;分别是总分第一名&#xff0c;专业课第一名&#xff0c;感谢研梦的953叶学姐&#xff0c;非常负责&#xff0c;本硕大佬学姐&#xff0c;当年密码学38分选手&#xff08;满…...

pytorch-模型训练

目录 1. 模型训练的基本步骤1.1 train、test数据下载1.2 train、test数据加载1.3 Lenet5实例化、初始化loss函数、初始化优化器1.4 开始train和test 2. 完整代码 1. 模型训练的基本步骤 以cifar10和Lenet5为例 1.1 train、test数据下载 使用torchvision中的datasets可以方便…...

Linux /proc目录总结

1、概念 在Linux系统中&#xff0c;/proc目录是一个特殊的文件系统&#xff0c;通常被称为"proc文件系统"或"procfs"。这个文件系统以文件系统的方式为内核与进程之间的通信提供了一个接口。/proc目录中的文件大多数都提供了关于系统状态的信息&#xff0…...

【JavaEE】浅谈线程(二)

线程 线程的常见属性 线程属性可以通过下面的表格查看。 •ID 是线程的唯⼀标识&#xff0c;不同线程不会重复 • 名称是各种调试⼯具⽤到&#xff08;如jconsoloe&#xff09; • 状态表示线程当前所处的⼀个情况&#xff0c;下⾯我们会进⼀步说明 • 优先级高的线程理论上来…...

爬虫:爬取知乎热榜一级评论及回答2024不包含翻页

一、先上结果&#xff08;注:本文仅为兴趣爱好探究&#xff0c;请勿进行商业利用或非法研究&#xff0c;负责后果自负&#xff0c;与作者无关&#xff09; 1、爬标题及其具体内容 2、抓标题下的对应回答 3、爬取对应一级评论 二、上流程 1、获取cookies&#xff08;相信哥哥姐姐…...

AI 编程探索- iOS动态标签控件

需求分析&#xff1a; 标签根据文字长度&#xff0c;自适应标签居中显示扩展 超过内容显示范围&#xff0c;需要换行显示&#xff0c;且保持居中显示 AI实现过程 提问&#xff1a; 回答&#xff1a; import UIKit import SnapKitclass DynamicLabelsContainerView: UIView…...

计算机网络——数据链路层(数据链路层概述及基本问题)

链路、数据链路和帧的概念 数据链路层在物理层提供服务的基础上向网络层提供服务&#xff0c;其主要作用是加强物理层传输原始比特流的功能&#xff0c;将物理层提供的可能出错的物理连接改造为逻辑上无差错的数据链路&#xff0c;使之对网络层表现为一条无差错的链路。 链路(…...

【前端】前端权限管理的实现方式:基于Vue项目的详细指南

前端权限管理的实现方式&#xff1a;基于Vue项目的详细指南 在Web开发中&#xff0c;前端权限管理是一个确保应用安全性和优化用户体验的关键部分。本文将详细介绍前端权限管理的几种实现方式&#xff0c;并通过Vue项目中的代码示例来演示具体实现方法。 前端权限管理的基本实…...

MySQL数据库基础练习系列——教务管理系统

项目名称与项目简介 教务管理系统是一个旨在帮助学校或教育机构管理教务活动的软件系统。它涵盖了学生信息管理、教师信息管理、课程管理、成绩管理以及相关的报表生成等功能。通过该系统&#xff0c;学校可以更加高效地处理教务数据&#xff0c;提升教学质量和管理水平。 1.…...

windowns server2016服务器配置php调用powerpoint COM组件

解决问题&#xff1a;windowns server2016服务器配置php调用powerpoint COM组件 环境&#xff1a; windows server2016 宝塔&#xff08;nginxmysqlphp7.2&#xff09; IIS 搭建宝塔&#xff1a; 下载地址&#xff1a;https://www.bt.cn/download/windows.html ​ 安装使用&…...

RestClient

什么是RestClient RestClient 是 Elasticsearch 官方提供的 Java 低级 REST 客户端&#xff0c;它允许HTTP与Elasticsearch 集群通信&#xff0c;而无需处理 JSON 序列化/反序列化等底层细节。它是 Elasticsearch Java API 客户端的基础。 RestClient 主要特点 轻量级&#xff…...

Mobile ALOHA全身模仿学习

一、题目 Mobile ALOHA&#xff1a;通过低成本全身远程操作学习双手移动操作 传统模仿学习&#xff08;Imitation Learning&#xff09;缺点&#xff1a;聚焦与桌面操作&#xff0c;缺乏通用任务所需的移动性和灵活性 本论文优点&#xff1a;&#xff08;1&#xff09;在ALOHA…...

Linux C语言网络编程详细入门教程:如何一步步实现TCP服务端与客户端通信

文章目录 Linux C语言网络编程详细入门教程&#xff1a;如何一步步实现TCP服务端与客户端通信前言一、网络通信基础概念二、服务端与客户端的完整流程图解三、每一步的详细讲解和代码示例1. 创建Socket&#xff08;服务端和客户端都要&#xff09;2. 绑定本地地址和端口&#x…...

技术栈RabbitMq的介绍和使用

目录 1. 什么是消息队列&#xff1f;2. 消息队列的优点3. RabbitMQ 消息队列概述4. RabbitMQ 安装5. Exchange 四种类型5.1 direct 精准匹配5.2 fanout 广播5.3 topic 正则匹配 6. RabbitMQ 队列模式6.1 简单队列模式6.2 工作队列模式6.3 发布/订阅模式6.4 路由模式6.5 主题模式…...

倒装芯片凸点成型工艺

UBM&#xff08;Under Bump Metallization&#xff09;与Bump&#xff08;焊球&#xff09;形成工艺流程。我们可以将整张流程图分为三大阶段来理解&#xff1a; &#x1f527; 一、UBM&#xff08;Under Bump Metallization&#xff09;工艺流程&#xff08;黄色区域&#xff…...

Tauri2学习笔记

教程地址&#xff1a;https://www.bilibili.com/video/BV1Ca411N7mF?spm_id_from333.788.player.switch&vd_source707ec8983cc32e6e065d5496a7f79ee6 官方指引&#xff1a;https://tauri.app/zh-cn/start/ 目前Tauri2的教程视频不多&#xff0c;我按照Tauri1的教程来学习&…...

「Java基本语法」变量的使用

变量定义 变量是程序中存储数据的容器&#xff0c;用于保存可变的数据值。在Java中&#xff0c;变量必须先声明后使用&#xff0c;声明时需指定变量的数据类型和变量名。 语法 数据类型 变量名 [ 初始值]; 示例&#xff1a;声明与初始化 public class VariableDemo {publi…...

基于Java项目的Karate API测试

Karate 实现了可以只编写Feature 文件进行测试,但是对于熟悉Java语言的开发或是测试人员,可以通过编程方式集成 Karate 丰富的自动化和数据断言功能。 本篇快速介绍在Java Maven项目中编写和运行测试的示例。 创建Maven项目 最简单的创建项目的方式就是创建一个目录,里面…...

智能体革命:企业如何构建自主决策的AI代理?

OpenAI智能代理构建实用指南详解 随着大型语言模型&#xff08;LLM&#xff09;在推理、多模态理解和工具调用能力上的进步&#xff0c;智能代理&#xff08;Agents&#xff09;成为自动化领域的新突破。与传统软件仅帮助用户自动化流程不同&#xff0c;智能代理能够自主执行工…...

华为OD机考- 简单的自动曝光/平均像素

import java.util.Arrays; import java.util.Scanner;public class DemoTest4 {public static void main(String[] args) {Scanner in new Scanner(System.in);// 注意 hasNext 和 hasNextLine 的区别while (in.hasNextLine()) { // 注意 while 处理多个 caseint[] arr Array…...