当前位置:实例文章 » JAVA Web实例» [文章]springboot 自定义注解 ,实现接口限流(计数器限流)【强行喂饭版】

springboot 自定义注解 ,实现接口限流(计数器限流)【强行喂饭版】

发布人:shili8 发布时间:2025-03-15 00:21 阅读次数:0

**SpringBoot 自定义注解实现接口限流**

在实际的开发中,我们经常会遇到需要对接口进行限流的需求。例如,某个接口每天只能被访问100次,这样可以防止恶意爬虫或其他程序过度地访问我们的接口,从而保护我们的系统不被滥用。

在SpringBoot中,我们可以使用自定义注解来实现接口限流。下面我们将一步步地讲解如何创建一个自定义注解,并且使用它来实现接口限流。

###1. 创建自定义注解首先,我们需要创建一个自定义注解,用于标记需要进行限流的接口。

javaimport java.lang.annotation.Documented;
import java.lang.annotation.ElementType;
import java.lang.annotation.Retention;
import java.lang.annotation.RetentionPolicy;
import java.lang.annotation.Target;

@Target(ElementType.METHOD)
@Retention(RetentionPolicy.RUNTIME)
@Documentedpublic @interface LimitFlow {
 int count() default100; // 每次限流的次数}

在上面的代码中,我们定义了一个名为`LimitFlow`的注解,使用了`@Target(ElementType.METHOD)`来指定该注解只能用于方法上。我们还设置了`count()`属性,表示每次限流的次数,默认值是100。

###2. 创建计数器接下来,我们需要创建一个计数器来记录每个接口被访问的次数。
javaimport java.util.concurrent.ConcurrentHashMap;
import java.util.concurrent.atomic.AtomicInteger;

public class FlowCounter {
 private ConcurrentHashMap flowMap = new ConcurrentHashMap<>();

 public void addFlow(String key) {
 AtomicInteger count = flowMap.get(key);
 if (count == null) {
 count = new AtomicInteger(0);
 flowMap.putIfAbsent(key, count);
 }
 count.incrementAndGet();
 }

 public int getFlowCount(String key) {
 return flowMap.getOrDefault(key, new AtomicInteger(0)).get();
 }
}

在上面的代码中,我们定义了一个`FlowCounter`类,使用了`ConcurrentHashMap`和`AtomicInteger`来实现线程安全的计数器。

###3. 使用自定义注解现在,我们可以使用自定义注解来标记需要进行限流的接口。
java@RestController@RequestMapping("/api")
public class MyController {
 @Autowired private FlowCounter flowCounter;

 @GetMapping("/test")
 @LimitFlow(count =50) // 每次限流的次数为50 public String test() {
 return "Hello World!";
 }
}

在上面的代码中,我们使用了自定义注解`@LimitFlow`来标记`test()`方法,每次限流的次数为50。

###4. 实现限流逻辑最后,我们需要实现限流逻辑。
javaimport org.springframework.web.method.HandlerMethod;
import org.springframework.web.servlet.handler.HandlerInterceptor;

import javax.servlet. />import javax.servlet. />import java.lang.reflect.Method;

public class FlowInterceptor implements HandlerInterceptor {
 @Autowired private FlowCounter flowCounter;

 @Override public boolean preHandle(HttpServletRequest request, HttpServletResponse response, Object handler) throws Exception {
 if (handler instanceof HandlerMethod) {
 HandlerMethod method = (HandlerMethod) handler;
 Method targetMethod = method.getMethod();
 LimitFlow annotation = targetMethod.getAnnotation(LimitFlow.class);
 if (annotation != null) {
 String key = request.getRequestURI() + ":" + targetMethod.getName();
 int count = flowCounter.getFlowCount(key);
 if (count >= annotation.count()) {
 throw new RuntimeException("接口被限流!");
 }
 flowCounter.addFlow(key);
 }
 }
 return true;
 }
}

在上面的代码中,我们实现了一个`FlowInterceptor`类,用于拦截需要进行限流的请求。我们使用自定义注解`@LimitFlow`来标记需要进行限流的接口,每次限流的次数为50。

###5. 配置拦截器最后,我们需要配置拦截器。
java@Configurationpublic class WebConfig implements WebMvcConfigurer {
 @Bean public FlowInterceptor flowInterceptor() {
 return new FlowInterceptor();
 }

 @Override public void addInterceptors(InterceptorRegistry registry) {
 registry.addInterceptor(flowInterceptor()).addPathPatterns("/api/**");
 }
}

在上面的代码中,我们配置了拦截器`flowInterceptor()`,并且添加了拦截规则`/api/**`。

通过以上步骤,我们就实现了一个自定义注解来进行接口限流。

其他信息

其他资源

Top