diff --git a/spring-boot-demo-ratelimit-redis/src/main/java/com/xkcoding/ratelimit/redis/annotation/RateLimiter.java b/spring-boot-demo-ratelimit-redis/src/main/java/com/xkcoding/ratelimit/redis/annotation/RateLimiter.java new file mode 100644 index 0000000..dda0954 --- /dev/null +++ b/spring-boot-demo-ratelimit-redis/src/main/java/com/xkcoding/ratelimit/redis/annotation/RateLimiter.java @@ -0,0 +1,48 @@ +package com.xkcoding.ratelimit.redis.annotation; + +import org.springframework.core.annotation.AliasFor; +import org.springframework.core.annotation.AnnotationUtils; + +import java.lang.annotation.*; +import java.util.concurrent.TimeUnit; + +/** + *
+ * 限流注解,添加了 {@link AliasFor} 必须通过 {@link AnnotationUtils} 获取,才会生效 + *
+ * + * @author yangkai.shen + * @date Created in 2019/9/30 10:31 + * @see AnnotationUtils + */ +@Target(ElementType.METHOD) +@Retention(RetentionPolicy.RUNTIME) +@Documented +public @interface RateLimiter { + long DEFAULT_REQUEST = 10; + + /** + * max 最大请求数 + */ + @AliasFor("max") long value() default DEFAULT_REQUEST; + + /** + * max 最大请求数 + */ + @AliasFor("value") long max() default DEFAULT_REQUEST; + + /** + * 限流key + */ + String key() default ""; + + /** + * 超时时长,默认1分钟 + */ + long timeout() default 1; + + /** + * 超时时间单位,默认 分钟 + */ + TimeUnit timeUnit() default TimeUnit.MINUTES; +} diff --git a/spring-boot-demo-ratelimit-redis/src/main/java/com/xkcoding/ratelimit/redis/controller/TestController.java b/spring-boot-demo-ratelimit-redis/src/main/java/com/xkcoding/ratelimit/redis/controller/TestController.java new file mode 100644 index 0000000..48d57fa --- /dev/null +++ b/spring-boot-demo-ratelimit-redis/src/main/java/com/xkcoding/ratelimit/redis/controller/TestController.java @@ -0,0 +1,40 @@ +package com.xkcoding.ratelimit.redis.controller; + +import cn.hutool.core.lang.Dict; +import com.xkcoding.ratelimit.redis.annotation.RateLimiter; +import lombok.extern.slf4j.Slf4j; +import org.springframework.web.bind.annotation.GetMapping; +import org.springframework.web.bind.annotation.RestController; + +/** + *+ * 测试 + *
+ * + * @author yangkai.shen + * @date Created in 2019/9/30 10:30 + */ +@Slf4j +@RestController +public class TestController { + + @RateLimiter(value = 5) + @GetMapping("/test1") + public Dict test1() { + log.info("【test1】被执行了。。。。。"); + return Dict.create().set("msg", "hello,world!").set("description", "别想一直看到我,不信你快速刷新看看~"); + } + + @GetMapping("/test2") + public Dict test2() { + log.info("【test2】被执行了。。。。。"); + return Dict.create().set("msg", "hello,world!").set("description", "我一直都在,卟离卟弃"); + } + + @RateLimiter(value = 2) + @GetMapping("/test3") + public Dict test3() { + log.info("【test3】被执行了。。。。。"); + return Dict.create().set("msg", "hello,world!").set("description", "别想一直看到我,不信你快速刷新看看~"); + } +} diff --git a/spring-boot-demo-ratelimit-redis/src/main/java/com/xkcoding/ratelimit/redis/handler/GlobalExceptionHandler.java b/spring-boot-demo-ratelimit-redis/src/main/java/com/xkcoding/ratelimit/redis/handler/GlobalExceptionHandler.java new file mode 100644 index 0000000..30bdb31 --- /dev/null +++ b/spring-boot-demo-ratelimit-redis/src/main/java/com/xkcoding/ratelimit/redis/handler/GlobalExceptionHandler.java @@ -0,0 +1,24 @@ +package com.xkcoding.ratelimit.redis.handler; + +import cn.hutool.core.lang.Dict; +import lombok.extern.slf4j.Slf4j; +import org.springframework.web.bind.annotation.ExceptionHandler; +import org.springframework.web.bind.annotation.RestControllerAdvice; + +/** + *+ * 全局异常拦截 + *
+ * + * @author yangkai.shen + * @date Created in 2019/9/30 10:30 + */ +@Slf4j +@RestControllerAdvice +public class GlobalExceptionHandler { + + @ExceptionHandler(RuntimeException.class) + public Dict handler(RuntimeException ex) { + return Dict.create().set("msg", ex.getMessage()); + } +} diff --git a/spring-boot-demo-ratelimit-redis/src/main/resources/application.yml b/spring-boot-demo-ratelimit-redis/src/main/resources/application.yml new file mode 100644 index 0000000..af5002c --- /dev/null +++ b/spring-boot-demo-ratelimit-redis/src/main/resources/application.yml @@ -0,0 +1,4 @@ +server: + port: 8080 + servlet: + context-path: /demo