1. 首先,我们需要引入 Hutool 和 AOP 的依赖。
<dependency>
    <groupId>cn.hutool</groupId>
    <artifactId>hutool-all</artifactId>
    <version>5.7.10</version>
</dependency>
<dependency>
    <groupId>org.springframework.boot</groupId>
    <artifactId>spring-boot-starter-aop</artifactId>
</dependency>
  1. 定义一个注解 @RateLimit,用于标记需要限流的方法。
@Target(ElementType.METHOD)
@Retention(RetentionPolicy.RUNTIME)
public @interface RateLimit {
    int limit() default 10; // 限流次数,默认为 10 次
    long time() default 60; // 限流时间,默认为 60 秒
}
  1. 在 AOP 中实现对 @RateLimit 注解的解析,并进行限流。
@Aspect
@Component
public class RateLimitAspect {
    private static final Map<String, AccessCounter> COUNTER_MAP = new ConcurrentHashMap<>();

    @Around("@annotation(rateLimit)")
    public Object around(ProceedingJoinPoint point, RateLimit rateLimit) throws Throwable {
        String methodName = point.getSignature().toShortString();
        AccessCounter counter = COUNTER_MAP.get(methodName);
        if (counter == null) {
            counter = new AccessCounter(rateLimit.limit(), rateLimit.time());
            COUNTER_MAP.put(methodName, counter);
        }
        if (counter.tryAcquire()) {
            return point.proceed();
        } else {
            throw new RuntimeException("接口访问频率超过限制!");
        }
    }

    private static class AccessCounter {
        private final int limit;
        private final long timeWindow;
        private final Queue<Long> timestamps;

        public AccessCounter(int limit, long timeWindow) {
            this.limit = limit;
            this.timeWindow = timeWindow * 1000;
            this.timestamps = new LinkedList<>();
        }

        public boolean tryAcquire() {
            long now = System.currentTimeMillis();
            while (!timestamps.isEmpty() && timestamps.peek() < now - timeWindow) {
                timestamps.poll();
            }
            if (timestamps.size() < limit) {
                timestamps.offer(now);
                return true;
            } else {
                return false;
            }
        }
    }
}
  1. 在需要进行限流的接口方法上加上 @RateLimit 注解即可。
@RestController
public class TestController {
    @RateLimit(limit = 5, time = 60)
    @GetMapping("/test")
    public String test() {
        return "Hello World!";
    }
}

以上就是 Java 使用 Hutool + 自定义注解 + Spring AOP 实现对接口限流的方法。

Java 使用 Hutool + 自定义注解 + Spring AOP 实现接口限流

原文地址: https://www.cveoy.top/t/topic/njqD 著作权归作者所有。请勿转载和采集!

免费AI点我,无需注册和登录