- 引入依赖
xml
<dependency>
<groupId>org.springframework.boot</groupId>
<artifactId>spring-boot-starter-aop</artifactId>
</dependency>
<dependency>
<groupId>com.google.guava</groupId>
<artifactId>guava</artifactId>
<version>31.1-jre</version>
</dependency>
- 自定义注解
java
/**
* 限流器注解
*/
@Target(ElementType.METHOD)
@Retention(RetentionPolicy.RUNTIME)
public @interface Limiter {
int count() default 20;
int time() default 1;
}
- 定义切面
java
@Aspect
@Component
public class RateLimiterAspect {
private static final Logger LOGGER = LoggerFactory.getLogger(RateLimiterAspect.class);
private ConcurrentHashMap<String, RateLimiter> RATE_LIMITER = new ConcurrentHashMap<>();
@Before(value = "@annotation(com.shi.demo.annotation.Limiter)")
public void handleRateLimiter(JoinPoint jp) {
RateLimiter rateLimiter = null;
MethodSignature signature = (MethodSignature) jp.getSignature();
Method method = signature.getMethod();
Limiter annotation = method.getAnnotation(Limiter.class);
int count = annotation.count();
int time = annotation.time();
String className = method.getDeclaringClass().getName();
String methodName = method.getName();
String key = className + "." + methodName;
if (!RATE_LIMITER.containsKey(key)) {
rateLimiter = RateLimiter.create(count, time, TimeUnit.SECONDS);
RATE_LIMITER.put(key, rateLimiter);
}
rateLimiter = RATE_LIMITER.get(key);
if (!rateLimiter.tryAcquire()) {
throw new RuntimeException("限流了,请稍后再试");
}
}
}
- 接口上 使用注解
java
@RestController
@RequestMapping("/users")
public class UserController {
@Limiter
@GetMapping
public String get(){
return "get";
}
@Limiter(count=20,time=1)
@PostMapping
public String post(){
return "post";
}
@DeleteMapping
public String delete(){
return "delete";
}
}