Java + Spring Boot 后端防抖应用实例

防抖工具(适用单机部署)

DebounceUtil.java

package com.weiyu.utils;import jakarta.annotation.PostConstruct;
import jakarta.annotation.PreDestroy;
import org.springframework.stereotype.Component;import java.util.Map;
import java.util.concurrent.ConcurrentHashMap;
import java.util.concurrent.Executors;
import java.util.concurrent.ScheduledExecutorService;
import java.util.concurrent.TimeUnit;/*** 防抖工具(适用单机部署)*/
@Component
public class DebounceUtil {private final Map<String, Boolean> debounceMap = new ConcurrentHashMap<>();private ScheduledExecutorService scheduler;@PostConstructpublic void init() {scheduler = Executors.newSingleThreadScheduledExecutor();}@PreDestroypublic void destroy() {if (scheduler != null) {scheduler.shutdown();}}/*** 检查并设置防抖状态* @param key 唯一标识* @param delay 防抖时间(毫秒)* @return true 允许操作*/public boolean checkAndSet(String key, long delay) {if (debounceMap.containsKey(key)) {// 在冷却期内return false;}// 增加 keydebounceMap.put(key, true);// 延迟后移除 keyscheduler.schedule(() -> debounceMap.remove(key), delay, TimeUnit.MILLISECONDS);return true;}
}

手动防抖(临时应用)

Controller 层:WarehouseController.java

......public class WarehouseController {......// 自动注入防抖工具@Autowiredprivate DebounceUtil debounceUtil;// 查询待入库的出库明细数据@GetMapping("/ckd/queryDetailForRk")public Result<List<CkDetail>> queryCkDetailForRk(@RequestParam String ckNo) {log.info("【出库】,查询明细数据,/warehouse/ckd/queryDetailForRk,ckNo = {}", ckNo);// 防抖增加的代码//#####################################################################// 防抖唯一标识:请求路径 + 用户名(账号)String debounceKey = "/warehouse/ckd/queryDetailForRk:" + PublicUtils.getUserName();// 防抖时间:1秒long debounceTime = 1000;if (!debounceUtil.checkAndSet(debounceKey, debounceTime)) {throw new RuntimeException("操作过于频繁,请稍后再试");}//#####################################################################List<CkDetail> ckDetailList = warehouseService.queryCkDetailForRk(ckNo);return Result.success(ckDetailList);}
}

 注解防抖(项目应用)

1、增加防抖注解 @Debounce

Debounce.java

package com.weiyu.anno;import java.lang.annotation.ElementType;
import java.lang.annotation.Retention;
import java.lang.annotation.RetentionPolicy;
import java.lang.annotation.Target;/*** 防抖注解*/
@Target(ElementType.METHOD) // @Target 是元注解,指定当前注解 Debounce 可以应用的目标元素类型为方法 METHOD
@Retention(RetentionPolicy.RUNTIME) // @Retention 是元注解,指定当前注解 Debounce 的保留策略(生命周期)是 运行时仍可通过反射机制读取 RUNTIME
public @interface Debounce {// 默认防抖时间long value() default 3000;// 自定义Key(支持SpEL)String key() default "";
}

2、增加防抖切面类 AOP 

DebounceAspect.java

package com.weiyu.aop;import com.weiyu.anno.Debounce;
import com.weiyu.utils.DebounceUtil;
import org.aspectj.lang.ProceedingJoinPoint;
import org.aspectj.lang.annotation.Around;
import org.aspectj.lang.annotation.Aspect;
import org.aspectj.lang.reflect.MethodSignature;
import org.springframework.beans.factory.annotation.Autowired;
import org.springframework.stereotype.Component;/*** 防抖切面类 AOP*/
@Component
@Aspect
public class DebounceAspect {@Autowiredprivate DebounceUtil debounceUtil;/*** 切面:防抖*/@Around("@annotation(debounceAnnotation)")public Object debounce(ProceedingJoinPoint joinPoint, Debounce debounceAnnotation) throws Throwable  {// 安全保护:注解为空时直接放行if (debounceAnnotation == null) {return joinPoint.proceed();}// 从注解中获取 keyString key = debounceAnnotation.key();// 从注解中获取防抖时间long delay = debounceAnnotation.value();// 处理空 key 情况if (key == null || key.isEmpty()) {// 生成默认 key:类名 + 方法名MethodSignature signature = (MethodSignature) joinPoint.getSignature();key = signature.getDeclaringTypeName() + "#" + signature.getName();}// 防抖if (!debounceUtil.checkAndSet(key, delay)) {throw new RuntimeException("操作过于频繁,请稍后再试");}return joinPoint.proceed();}
}

Controller 层:WarehouseController.java

......public class WarehouseController {......// 自动注入防抖工具@Autowiredprivate DebounceUtil debounceUtil;// 查询待入库的出库明细数据@GetMapping("/ckd/queryDetailForRk")@Debounce(key = "/warehouse/ckd/queryDetailForRk", value = 1000)public Result<List<CkDetail>> queryCkDetailForRk(@RequestParam String ckNo) {log.info("【出库】,查询明细数据,/warehouse/ckd/queryDetailForRk,ckNo = {}", ckNo);//        // 防抖增加的代码
//        //#####################################################################
//        // 防抖唯一标识:请求路径 + 用户名(账号)
//        String debounceKey = "/warehouse/ckd/queryDetailForRk:" + PublicUtils.getUserName();
//        // 防抖时间:1秒
//        long debounceTime = 1000;
//        if (!debounceUtil.checkAndSet(debounceKey, debounceTime)) {
//            throw new RuntimeException("操作过于频繁,请稍后再试");
//        }
//        //#####################################################################List<CkDetail> ckDetailList = warehouseService.queryCkDetailForRk(ckNo);return Result.success(ckDetailList);}
}

页面应用效果

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

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

相关文章

PostgreSQL 快速入门

PostgreSQL介绍 PostgreSQL 是一个功能强大的开源关系型数据库系统&#xff0c;它使用并扩展了 SQL 语言&#xff0c;并结合了许多功能&#xff0c;可以安全地存储和扩展复杂的数据工作 PostgreSQL 因其经过验证的架构、可靠性、数据完整性、强大的功能集、可扩展性以及软件背…

CppCon 2016 学习:Out of memory? Business as usual.

当程序因为内存耗尽而抛出 std::bad_alloc 异常时&#xff0c;这并不意味着程序必须崩溃或停止运行。我们应该考虑“内存不足”作为一种可能正常出现的情况&#xff08;“Out of memory? Business as usual.”&#xff09;&#xff0c;并设计应用程序能优雅地处理这种异常。 具…

庙算兵棋推演AI开发初探(8-神经网络模型接智能体进行游戏)

前言の碎碎念 由于我做的模仿学习&#xff0c;可能由于没有完全模仿&#xff0c;可以说效果很烂……后来用强化学习优化&#xff0c;这个倒是不用自己做数据集了&#xff0c;为方便大家只搞代码&#xff0c;这里只说这部分的经历和方法。 实践基础介绍 1-动作 先介绍一个强化…

Uart_Prj02 Windows 窗口版串口_Step1

完成上位机控制台串口后&#xff0c;接下来想用C#做一个Windows 窗口版的串口。上位机编程不是很熟练&#xff0c;每天学一点做一点。 using System; using System.Collections.Generic; using System.ComponentModel; using System.Data; using System.Drawing; using System.…

自动驾驶系统研发—从工程视角看纯视觉自动驾驶的安全挑战与应对策略

🌟🌟 欢迎来到我的技术小筑,一个专为技术探索者打造的交流空间。在这里,我们不仅分享代码的智慧,还探讨技术的深度与广度。无论您是资深开发者还是技术新手,这里都有一片属于您的天空。让我们在知识的海洋中一起航行,共同成长,探索技术的无限可能。 🚀 探索专栏:学…

PostgreSQL认证怎么选?PGCP中级认证、PGCM高级认证

上图是2025年6月份最新的db-engines上的数据库排名情况&#xff0c;可以看出PostgreSQL数据库仍然呈上升趋势&#xff0c;跟排名第三的"Microsoft SQL Server"起来越接近&#xff0c;国内亦是如此&#xff0c;PostgreSQL的热潮依在&#xff0c;可见学习PostgreSQL数据…

Hive 3.x数据静态脱敏与加密

引言 在大数据时代&#xff0c;数据已成为企业和组织的核心资产。作为数据处理的重要平台&#xff0c;Hive 3.x存储着大量敏感信息&#xff0c;如用户个人身份、财务数据、商业机密等。如何确保这些数据在存储和处理过程中的安全性&#xff0c;成为数据从业者关注的焦点。数据…

CppCon 2016 学习:Lightweight Object Persistence With Modern C++

你给出的这段文字是某个演讲、论文或者技术文档的概要&#xff08;Overview&#xff09;部分&#xff0c;内容主要是关于内存分配器&#xff08;allocator&#xff09;设计以及**对象持久化&#xff08;object persistence&#xff09;**的一些思路。让我帮你逐条解析和理解&am…

IPv6中的ARP“NDP协议详解“

一、概述 在IPv4网络环境当中,我们想要与对端进行网络通信时,首先需要去解析对方的MAC地址这样我们才能封装二层数据帧,就算访问不同网络时也需要解析网关的MAC,这些都是需要我们的ARP协议来进行操作完成的,但是在我们的IPv6网络环境当中并没有ARP协议,而是通过NDP协议来完成类…

TortoiseSVN迁移到本地git

将项目从Subversion&#xff08;SVN&#xff09;迁移到Git是许多开发团队的需求&#xff0c;因为Git提供了更多的功能和灵活性。本文将详细介绍如何使用TortoiseSVN将项目迁移到本地Git仓库。 一、准备工作 安装Git&#xff1a;确保在本地机器上安装了Git。可以通过以下命令检…

高性能 Web 服务器之Tengine

一、概述 Tengine 是一个由淘宝网发起的 Web 服务器项目。它基于 Nginx 然后针对大访问量网站的需求&#xff0c;添加了很多高级功能和特性&#xff0c;从 2011 年 12 月开始&#xff0c;Tengine 正式开源。Tengine 的性能和稳定性已经100多家大型网站如淘宝网&#xff0c;天猫…

简单实现HTML在线编辑器

我们继续来看一下如何开发一个简单的html在线编辑器&#xff0c;要求很简单 能够同时编辑html&#xff0c;css&#xff0c;js代码&#xff0c;并且运行之后可以同时预览效果 一&#xff1a;前置知识 在H5中设置了一个新的标签&#xff0c;<iframe>&#xff0c; 用于在当前…

【Bluedroid】蓝牙启动之核心模块(startProfiles )初始化与功能源码解析

本文深入解析Android蓝牙协议栈中 start_profiles 函数及其调用的核心模块初始化逻辑,涵盖 BNEP、PAN、A2DP、AVRC、HID Host、BTA_AR 等关键配置文件和应用层模块。通过代码分析与流程梳理,阐述各模块如何通过全局控制块、状态机、回调机制实现功能初始化、连接管理及数据交…

RK3576 Android14 DMIC调制

一、背景 近期项目中有个DMIC调试的需求&#xff0c;搁置了较长时间&#xff0c;现今着手调试&#xff0c;遂作记录。 二、开发环境 OS&#xff1a;Android14 Platform&#xff1a;RK3576 Linux Version&#xff1a;6.1.99 SDK Version&#xff1a;android-14.0-mid-rkr6 …

使用 Prometheus 监控 Spring Boot 应用

SpringBoot+Prometheus+Grafana实现监控 逻辑如图 应用程序在生产环境中运行时,监控其运行状况是非常必要的。通过实时了解应用程序的运行状况,才能在问题出现之前得到警告,也可以通监控应用系统的运行状况,优化性能,提高运行效率。 一、监控 Spring Boot 应用 下面我们…

简易计算器 Python 实现

目录 一、代码逐步分析&#xff08;适合刚入门的朋友看&#xff09; 1.定义了一个名为simple_calculator的函数&#xff0c;封装了整个计算器的逻辑。 二、深入分析代码块&#xff0c;用更加官方的语词来说&#xff08;适合想要深入学习的朋友&#xff09; 主循环结构 退出…

开源编译器介绍

文章目录 基本构成传统编译器编译器的发展历史&#xff08;History of Compiler&#xff09;GCC 编译过程与原理&#xff08;GCC Process and Principle&#xff09;LLVM/Clang 编译过程与原理&#xff08;LLVM/Clang Process and Principle&#xff09;GCC与与 LLVM/Clang 的对…

C++ String知识点

当然可以&#xff01;下面我将以系统全面、通俗易懂、深入浅出的方式&#xff0c;为你讲解 C 中非常核心但也容易被低估的内容 —— std::string。 &#x1f31f; C std::string 全面详解 &#x1f4cc; 一、string 是什么&#xff1f; C 的 std::string 是 C 标准库中封装好…

全新NVIDIA Llama Nemotron Nano视觉语言模型在OCR基准测试中准确率夺冠

全新NVIDIA Llama Nemotron Nano视觉语言模型在OCR基准测试中准确率夺冠 PDF、图表、图形和仪表板等文档是丰富的数据源&#xff0c;当这些数据被提取和整理后&#xff0c;能够为决策制定提供有价值的洞察。从自动化财务报表处理到改进商业智能工作流程&#xff0c;智能文档处…

gradle的 build时kaptDebugKotlin 处理数据库模块

gradle的 build时输出&#xff1a; Task :app:kaptDebugKotlin 注: Processing class HDCoinBean 注: Processing class HDCurrencyBean 注: Processing class HDSelfAddCoin 注: Processing class MN 注: Creating DefaultRealmModule <—> 80% EXECUTING [7m 56s] IDLE…