Java 注解实现请求次数限流:完整方案及代码示例

本文将介绍如何使用 Java 注解来实现同一用户请求次数限流,并在限流时返回请求失败的信息。我们将提供完整代码示例和详细解释,帮助您快速上手并应用到实际项目中。

1. 定义限流注解

首先,定义一个名为 'Limit' 的注解,用于标记需要进行限流的方法:

@Retention(RetentionPolicy.RUNTIME)
@Target(ElementType.METHOD)
public @interface Limit {
    int value(); // 限流次数
    long expireTime(); // 限流时间,单位秒
}
  • @Retention(RetentionPolicy.RUNTIME):注解将保留到运行时,以便在运行时进行反射操作。
  • @Target(ElementType.METHOD):注解只能用于方法上。
  • value:表示限流次数。
  • expireTime:表示限流时间,单位为秒。

2. 创建限流切面类

接下来,创建名为 'LimitAspect' 的切面类,用于在方法执行前检查请求次数是否超过限制:

@Aspect
@Component
public class LimitAspect {
    private RedisTemplate<String, String> redisTemplate;

    @Autowired
    public LimitAspect(RedisTemplate<String, String> redisTemplate) {
        this.redisTemplate = redisTemplate;
    }

    @Around("execution(* *(..)) && @annotation(limit)")
    public Object limit(ProceedingJoinPoint joinPoint, Limit limit) throws Throwable {
        String methodName = joinPoint.getSignature().getName();
        String key = methodName + ':' + System.currentTimeMillis() / 1000 / limit.expireTime();
        long count = redisTemplate.opsForValue().increment(key, 1);
        redisTemplate.expire(key, limit.expireTime(), TimeUnit.SECONDS);
        if (count > limit.value()) {
            throw new RuntimeException("请求过于频繁,请稍后再试!");
        }
        return joinPoint.proceed();
    }
}
  • @Aspect:标识这是一个切面类。
  • @Component:标识这是一个 Spring Bean。
  • @Around("execution(* *(..)) && @annotation(limit)"):使用 @Around 注解定义切点,匹配所有方法,并且必须带有 @Limit 注解。
  • limit:方法参数,用于获取 @Limit 注解的配置信息。
  • 在方法中,使用 RedisTemplate 获取并递增请求次数,并设置过期时间。
  • 如果请求次数超过限制,则抛出 RuntimeException 异常。

3. 配置 Redis

在 Spring Boot 应用中,需要使用 Redis 作为存储限流次数的数据源。在 application.properties 文件中配置 Redis 连接信息:

spring.redis.host=localhost
spring.redis.port=6379

4. 开启切面自动代理

在启动类中添加 @EnableAspectJAutoProxy 注解开启切面自动代理:

@SpringBootApplication
@EnableAspectJAutoProxy
public class Application {
    public static void main(String[] args) {
        SpringApplication.run(Application.class, args);
    }
}

5. 使用限流注解

最后,在需要进行限流的方法上添加 @Limit 注解即可:

@Limit(value = 5, expireTime = 60)
@GetMapping("/hello")
public String hello() {
    return "Hello, World!";
}
  • value 设置为 5,表示每分钟最多允许 5 次请求。
  • expireTime 设置为 60,表示限流时间为 60 秒。

总结

以上代码示例演示了如何使用 Java 注解来实现同一用户请求次数限流的功能。通过自定义注解、切面和 Redis,我们可以方便地控制请求频率,避免服务器过载。您可以在此基础上进行扩展,根据实际需求实现更复杂的限流策略。


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

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