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/**`。
通过以上步骤,我们就实现了一个自定义注解来进行接口限流。

 粤公网安备 44011102002787号
 粤公网安备 44011102002787号