成都seo网站qq,亚洲影视传媒有限公司,成都市微信网站建设公司,做国内打不开的网站在 Java Spring Boot 项目中实现防抖#xff08;Debounce#xff09;#xff0c;主要用于防止短时间内重复触发操作#xff08;如按钮重复提交、搜索框频繁请求#xff09;。以下是几种实现方案#xff1a; 方案 1#xff1a;使用 Redis 实现分布式防抖#xff08;推荐…在 Java Spring Boot 项目中实现防抖Debounce主要用于防止短时间内重复触发操作如按钮重复提交、搜索框频繁请求。以下是几种实现方案 方案 1使用 Redis 实现分布式防抖推荐
适合分布式环境利用 Redis 的原子性和过期时间特性。 添加依赖 xml 复制 下载 运行 dependencygroupIdorg.springframework.boot/groupIdartifactIdspring-boot-starter-data-redis/artifactId
/dependency 创建防抖工具类 java 复制 下载 import org.springframework.data.redis.core.RedisTemplate;
import org.springframework.data.redis.core.ValueOperations;
import java.util.concurrent.TimeUnit;Component
public class DebounceUtil {Autowiredprivate RedisTemplateString, String redisTemplate;/*** 检查是否允许操作防抖* param key 唯一标识如userId 操作类型* param expireTime 防抖时间毫秒* return true-允许操作, false-被限制*/public boolean checkAndSet(String key, long expireTime) {ValueOperationsString, String ops redisTemplate.opsForValue();// 使用 setIfAbsent 实现原子操作Boolean success ops.setIfAbsent(key, 1, expireTime, TimeUnit.MILLISECONDS);return Boolean.TRUE.equals(success);}
} 在 Controller 中使用 java 复制 下载 RestController
public class UserController {Autowiredprivate DebounceUtil debounceUtil;PostMapping(/submit)public ResponseEntityString submitOrder(RequestParam String userId) {String debounceKey order_submit: userId; // 唯一键long debounceTime 3000; // 3秒内防抖if (!debounceUtil.checkAndSet(debounceKey, debounceTime)) {return ResponseEntity.status(429).body(操作过于频繁请稍后再试);}// 正常业务逻辑return ResponseEntity.ok(提交成功);}
} 方案 2基于本地缓存单机适用
使用 ConcurrentHashMap ScheduledExecutorService 实现单机防抖。
java
复制
下载
import javax.annotation.PostConstruct;
import javax.annotation.PreDestroy;
import java.util.Map;
import java.util.concurrent.*;Component
public class LocalDebounceUtil {private final MapString, 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; // 在冷却期内}debounceMap.put(key, true);// 延迟后移除keyscheduler.schedule(() - debounceMap.remove(key), delay, TimeUnit.MILLISECONDS);return true;}
} 方案 3AOP 注解实现优雅封装
通过自定义注解统一管理防抖逻辑。 定义注解 java 复制 下载 Target(ElementType.METHOD)
Retention(RetentionPolicy.RUNTIME)
public interface Debounce {long value() default 3000; // 默认防抖时间String key() default ; // 自定义Key支持SpEL
} 实现AOP切面 java 复制 下载 Aspect
Component
public class DebounceAspect {Autowiredprivate DebounceUtil debounceUtil; // 复用前面的Redis工具类Around(annotation(debounceAnnotation))public Object debounce(ProceedingJoinPoint joinPoint, Debounce debounceAnnotation) throws Throwable {String key generateKey(joinPoint, debounceAnnotation);long expireTime debounceAnnotation.value();if (!debounceUtil.checkAndSet(key, expireTime)) {throw new RuntimeException(操作过于频繁);}return joinPoint.proceed();}private String generateKey(ProceedingJoinPoint joinPoint, Debounce annotation) {// 从注解获取key支持SpEL表达式String keyExpr annotation.key();if (!StringUtils.isEmpty(keyExpr)) {return parseSpEL(joinPoint, keyExpr);}// 默认生成方法签名作为keyMethodSignature signature (MethodSignature) joinPoint.getSignature();return signature.getMethod().toString();}private String parseSpEL(ProceedingJoinPoint joinPoint, String spEL) {// 实现SpEL解析略}
} 在Service/Controller中使用 java 复制 下载 Service
public class OrderService {Debounce(key #userId, value 5000) // 5秒防抖keyuserIdpublic void submitOrder(String userId) {// 业务逻辑}
} 关键注意事项 Key 设计原则 确保唯一性如用户ID 操作类型 分布式环境需用 Redis 等共享存储 避免 Key 冲突添加业务前缀 防抖时间选择 前端操作300ms~1000ms如搜索框 提交类操作1000ms~5000ms如订单提交 用户体验优化 返回明确错误信息HTTP 429 Too Many Requests 结合前端防抖如限制按钮点击状态 性能考虑 Redis 方案需评估连接开销 高并发场景用 setIfAbsent 保证原子性 前端辅助防抖推荐组合使用
后端防抖是最后防线前端也应做基础拦截
javascript
复制
下载
// Vue示例使用lodash
import { debounce } from lodash;export default {methods: {submitOrder: debounce(function() {axios.post(/api/submit, ...)}, 1000) // 1秒内仅触发一次}
} 总结 分布式场景Redis AOP 注解方案13 单机应用本地缓存方案2 最佳实践前后端同时实现防抖后端以 Redis 方案为主