757 字
4 分钟
Spring Boot 中实现防抖的几种方案,拒绝重复提交
AI 摘要
本文介绍Spring Boot中实现接口防抖以防止重复提交的几种常见方案。包括使用@Scheduled
注解定时任务处理后台防抖,利用@Async
异步处理减少处理频率,借助Google Guava的RateLimiter
控制请求速率,以及通过缓存机制(如Spring Cache)实现防抖,并分析各方案适用场景。
在 Spring Boot 中实现接口防抖(debouncing)可以防止频繁的请求触发操作,例如重复点击按钮或频繁请求接口。防抖技术通常用于限制某个操作在一定时间内只能执行一次。
在 Spring Boot 中实现防抖有多种方法,下面提供了几种常见的方法:
1. 使用 @Scheduled
注解定时任务(适用于后台任务)
这种方法适用于需要在后台任务中进行防抖的场景。例如,定时处理数据,避免频繁操作。
import org.springframework.scheduling.annotation.Scheduled;import org.springframework.stereotype.Service;
import java.util.concurrent.ConcurrentHashMap;
@Servicepublic class DebounceService {
private final ConcurrentHashMap<String, Long> lastExecution = new ConcurrentHashMap<>();
// 假设防抖时间为 1 秒 private final long DEBOUNCE_TIME = 1000L;
public boolean shouldProcess(String key) { long currentTime = System.currentTimeMillis(); long lastTime = lastExecution.getOrDefault(key, 0L);
if (currentTime - lastTime > DEBOUNCE_TIME) { lastExecution.put(key, currentTime); return true; } return false; }
@Scheduled(fixedDelay = 1000) // 定时执行任务 public void processDebouncedRequests() { // 在这里处理被防抖的请求 }}
2. 使用 @Async
异步处理
异步方法可以配合防抖逻辑来减少处理频率。确保启用了 Spring 的异步支持(@EnableAsync
)。
import org.springframework.beans.factory.annotation.Autowired;import org.springframework.scheduling.annotation.Async;import org.springframework.stereotype.Service;
import java.util.concurrent.ConcurrentHashMap;
@Servicepublic class DebounceService {
private final ConcurrentHashMap<String, Long> lastExecution = new ConcurrentHashMap<>(); private final long DEBOUNCE_TIME = 1000L;
@Autowired private SomeOtherService someOtherService; // 假设你有另一个服务需要异步处理
public void processRequest(String key) { if (shouldProcess(key)) { // 执行异步任务 executeAsyncTask(key); } }
private boolean shouldProcess(String key) { long currentTime = System.currentTimeMillis(); long lastTime = lastExecution.getOrDefault(key, 0L);
if (currentTime - lastTime > DEBOUNCE_TIME) { lastExecution.put(key, currentTime); return true; } return false; }
@Async public void executeAsyncTask(String key) { // 异步处理逻辑 someOtherService.process(key); }}
3. 使用 RateLimiter
控制请求频率(如 Google Guava 的 RateLimiter
)
RateLimiter
可以控制请求的速率,适合于防抖的场景。
import com.google.common.util.concurrent.RateLimiter;import org.springframework.stereotype.Service;
@Servicepublic class DebounceService {
// 创建一个 RateLimiter,每秒允许处理 1 个请求 private final RateLimiter rateLimiter = RateLimiter.create(1.0);
public void processRequest(String request) { if (rateLimiter.tryAcquire()) { // 处理请求 handleRequest(request); } else { // 请求被抑制 System.out.println("Request suppressed: " + request); } }
private void handleRequest(String request) { // 处理请求的逻辑 }}
4. 使用缓存机制(例如 Spring Cache)
可以利用缓存机制来实现防抖。假设防抖的时间为 1 秒钟。
import org.springframework.cache.annotation.Cacheable;import org.springframework.stereotype.Service;
@Servicepublic class DebounceService {
@Cacheable(value = "debounceCache", key = "#request", cacheManager = "cacheManager") public void processRequest(String request) { // 处理请求的逻辑 }}
配置缓存管理器
import org.springframework.cache.CacheManager;import org.springframework.cache.annotation.EnableCaching;import org.springframework.cache.concurrent.ConcurrentMapCacheManager;import org.springframework.context.annotation.Bean;import org.springframework.context.annotation.Configuration;
@Configuration@EnableCachingpublic class CacheConfig {
@Bean public CacheManager cacheManager() { return new ConcurrentMapCacheManager("debounceCache"); }}
选择合适的方法
- 定时任务 适合于周期性处理请求。
- 异步处理 适合于后台任务和并发处理。
- RateLimiter 适合于控制请求速率,避免过于频繁的请求。
- 缓存机制 适合于简单的防抖需求,特别是请求的去重。
Spring Boot 中实现防抖的几种方案,拒绝重复提交
https://fuwari.vercel.app/posts/code/实现防抖/