Spring Boot 中实现防抖的几种方案,拒绝重复提交

在 Spring Boot 中实现接口防抖(debouncing)可以防止频繁的请求触发操作,例如重复点击按钮或频繁请求接口。防抖技术通常用于限制某个操作在一定时间内只能执行一次。

在 Spring Boot 中实现防抖有多种方法,下面提供了几种常见的方法:

1. 使用 @Scheduled 注解定时任务(适用于后台任务)

这种方法适用于需要在后台任务中进行防抖的场景。例如,定时处理数据,避免频繁操作。

import org.springframework.scheduling.annotation.Scheduled;
import org.springframework.stereotype.Service;

import java.util.concurrent.ConcurrentHashMap;

@Service
public 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;

@Service
public 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;

@Service
public 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;

@Service
public 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
@EnableCaching
public class CacheConfig {

    @Bean
    public CacheManager cacheManager() {
        return new ConcurrentMapCacheManager("debounceCache");
    }
}

选择合适的方法

  • 定时任务 适合于周期性处理请求。
  • 异步处理 适合于后台任务和并发处理。
  • RateLimiter 适合于控制请求速率,避免过于频繁的请求。
  • 缓存机制 适合于简单的防抖需求,特别是请求的去重。
评论
添加红包

请填写红包祝福语或标题

红包个数最小为10个

红包金额最低5元

当前余额3.43前往充值 >
需支付:10.00
成就一亿技术人!
领取后你会自动成为博主和红包主的粉丝 规则
hope_wisdom
发出的红包
实付
使用余额支付
点击重新获取
扫码支付
钱包余额 0

抵扣说明:

1.余额是钱包充值的虚拟货币,按照1:1的比例进行支付金额的抵扣。
2.余额无法直接购买下载,可以购买VIP、付费专栏及课程。

余额充值