Skip to content
体验新版
项目
组织
正在加载...
登录
切换导航
打开侧边栏
希川
container-mini
提交
f30bb862
C
container-mini
项目概览
希川
/
container-mini
通知
6
Star
1
Fork
0
代码
文件
提交
分支
Tags
贡献者
分支图
Diff
Issue
0
列表
看板
标记
里程碑
合并请求
0
DevOps
流水线
流水线任务
计划
Wiki
0
Wiki
分析
仓库
DevOps
项目成员
Pages
C
container-mini
项目概览
项目概览
详情
发布
仓库
仓库
文件
提交
分支
标签
贡献者
分支图
比较
Issue
0
Issue
0
列表
看板
标记
里程碑
合并请求
0
合并请求
0
Pages
DevOps
DevOps
流水线
流水线任务
计划
分析
分析
仓库分析
DevOps
Wiki
0
Wiki
成员
成员
收起侧边栏
关闭侧边栏
动态
分支图
创建新Issue
流水线任务
提交
Issue看板
前往新版Gitcode,体验更适合开发者的 AI 搜索 >>
提交
f30bb862
编写于
11月 17, 2021
作者:
希川
浏览文件
操作
浏览文件
下载
电子邮件补丁
差异文件
<feat>: 添加限流器支持功能,基于 guava 的 RateLimiter 实现
上级
d74b86b5
变更
8
隐藏空白更改
内联
并排
Showing
8 changed file
with
145 addition
and
1 deletion
+145
-1
pom.xml
pom.xml
+7
-0
src/main/java/cn/noexception/ratelimiter/Constants.java
src/main/java/cn/noexception/ratelimiter/Constants.java
+17
-0
src/main/java/cn/noexception/ratelimiter/DoRateLimiterPoint.java
...n/java/cn/noexception/ratelimiter/DoRateLimiterPoint.java
+39
-0
src/main/java/cn/noexception/ratelimiter/annotation/DoRateLimiter.java
.../cn/noexception/ratelimiter/annotation/DoRateLimiter.java
+21
-0
src/main/java/cn/noexception/ratelimiter/valve/IValveService.java
.../java/cn/noexception/ratelimiter/valve/IValveService.java
+16
-0
src/main/java/cn/noexception/ratelimiter/valve/impl/RateLimiterValve.java
.../noexception/ratelimiter/valve/impl/RateLimiterValve.java
+41
-0
src/test/java/cn/noexception/test/AopTest.java
src/test/java/cn/noexception/test/AopTest.java
+2
-1
src/test/java/cn/noexception/test/bean/UserService.java
src/test/java/cn/noexception/test/bean/UserService.java
+2
-0
未找到文件。
pom.xml
浏览文件 @
f30bb862
...
...
@@ -75,6 +75,13 @@
<version>
4.7
</version>
<scope>
test
</scope>
</dependency>
<dependency>
<groupId>
com.google.guava
</groupId>
<artifactId>
guava
</artifactId>
<version>
18.0
</version>
</dependency>
</dependencies>
<build>
...
...
src/main/java/cn/noexception/ratelimiter/Constants.java
0 → 100644
浏览文件 @
f30bb862
package
cn.noexception.ratelimiter
;
import
com.google.common.util.concurrent.RateLimiter
;
import
java.util.Collections
;
import
java.util.HashMap
;
import
java.util.Map
;
/**
* Constants
*
* @author 吕滔
* @Date 2021/11/16 14:47
*/
public
class
Constants
{
public
static
Map
<
String
,
RateLimiter
>
rateLimiterMap
=
Collections
.
synchronizedMap
(
new
HashMap
<
String
,
RateLimiter
>());
}
src/main/java/cn/noexception/ratelimiter/DoRateLimiterPoint.java
0 → 100644
浏览文件 @
f30bb862
package
cn.noexception.ratelimiter
;
import
cn.noexception.container.factory.stereotype.Cube
;
import
cn.noexception.ratelimiter.annotation.DoRateLimiter
;
import
cn.noexception.ratelimiter.valve.IValveService
;
import
cn.noexception.ratelimiter.valve.impl.RateLimiterValve
;
import
org.aspectj.lang.JoinPoint
;
import
org.aspectj.lang.ProceedingJoinPoint
;
import
org.aspectj.lang.Signature
;
import
org.aspectj.lang.annotation.Around
;
import
org.aspectj.lang.annotation.Pointcut
;
import
org.aspectj.lang.reflect.MethodSignature
;
import
java.lang.reflect.Method
;
/**
* DoRateLimiterPoint
*
* @author 吕滔
* @Date 2021/11/16 14:19
*/
@Cube
public
class
DoRateLimiterPoint
{
@Pointcut
(
"@annotation(cn.noexception.ratelimiter.annotation.DoRateLimiter)"
)
public
void
aopPoint
()
{
}
@Around
(
"aopPoint() && @annotation(doRateLimiter)"
)
public
Object
doRouter
(
ProceedingJoinPoint
jp
,
DoRateLimiter
doRateLimiter
)
throws
Throwable
{
IValveService
valveService
=
new
RateLimiterValve
();
return
valveService
.
accept
(
jp
,
getMethod
(
jp
),
doRateLimiter
,
jp
.
getArgs
());
}
private
Method
getMethod
(
JoinPoint
joinPoint
)
throws
NoSuchMethodException
{
Signature
sig
=
joinPoint
.
getSignature
();
MethodSignature
methodSignature
=
(
MethodSignature
)
sig
;
return
joinPoint
.
getTarget
().
getClass
().
getMethod
(
methodSignature
.
getName
(),
methodSignature
.
getParameterTypes
());
}
}
src/main/java/cn/noexception/ratelimiter/annotation/DoRateLimiter.java
0 → 100644
浏览文件 @
f30bb862
package
cn.noexception.ratelimiter.annotation
;
import
java.lang.annotation.ElementType
;
import
java.lang.annotation.Retention
;
import
java.lang.annotation.RetentionPolicy
;
import
java.lang.annotation.Target
;
/**
* DoRateLimiter
* 自定义限流器注解
*
* @author 吕滔
* @Date 2021/11/16 14:19
*/
@Retention
(
RetentionPolicy
.
RUNTIME
)
@Target
({
ElementType
.
METHOD
})
public
@interface
DoRateLimiter
{
double
rate
()
default
1
;
// 限流许可量
String
returnJson
()
default
""
;
// 返回结果信息
}
src/main/java/cn/noexception/ratelimiter/valve/IValveService.java
0 → 100644
浏览文件 @
f30bb862
package
cn.noexception.ratelimiter.valve
;
import
cn.noexception.ratelimiter.annotation.DoRateLimiter
;
import
org.aspectj.lang.ProceedingJoinPoint
;
import
java.lang.reflect.Method
;
/**
* IValveService
*
* @author 吕滔
* @Date 2021/11/16 14:22
*/
public
interface
IValveService
{
Object
accept
(
ProceedingJoinPoint
jp
,
Method
method
,
DoRateLimiter
doRateLimiter
,
Object
[]
args
)
throws
Throwable
;
}
src/main/java/cn/noexception/ratelimiter/valve/impl/RateLimiterValve.java
0 → 100644
浏览文件 @
f30bb862
package
cn.noexception.ratelimiter.valve.impl
;
import
cn.hutool.json.JSONUtil
;
import
cn.noexception.ratelimiter.Constants
;
import
cn.noexception.ratelimiter.annotation.DoRateLimiter
;
import
cn.noexception.ratelimiter.valve.IValveService
;
import
com.google.common.util.concurrent.RateLimiter
;
import
org.aspectj.lang.ProceedingJoinPoint
;
import
java.lang.reflect.Method
;
/**
* RateLimiterValve
* 限流调用服务包装
*
* @author 吕滔
* @Date 2021/11/16 14:22
*/
public
class
RateLimiterValve
implements
IValveService
{
@Override
public
Object
accept
(
ProceedingJoinPoint
jp
,
Method
method
,
DoRateLimiter
doRateLimiter
,
Object
[]
args
)
throws
Throwable
{
// 判断是否开启限流器
if
(
0
==
doRateLimiter
.
rate
())
return
jp
.
proceed
();
String
clazzName
=
jp
.
getTarget
().
getClass
().
getName
();
String
methodName
=
method
.
getName
();
String
key
=
clazzName
+
"."
+
methodName
;
if
(
null
==
Constants
.
rateLimiterMap
.
get
(
key
))
{
Constants
.
rateLimiterMap
.
put
(
key
,
RateLimiter
.
create
(
doRateLimiter
.
rate
()));
}
RateLimiter
rateLimiter
=
Constants
.
rateLimiterMap
.
get
(
key
);
if
(
rateLimiter
.
tryAcquire
())
{
return
jp
.
proceed
();
}
return
JSONUtil
.
parse
(
doRateLimiter
.
returnJson
()).
toBean
(
method
.
getReturnType
());
}
}
src/test/java/cn/noexception/test/AopTest.java
浏览文件 @
f30bb862
...
...
@@ -121,7 +121,8 @@ public class AopTest {
public
void
test_inject
()
{
ClassPathXmlApplicationContext
applicationContext
=
new
ClassPathXmlApplicationContext
(
"classpath:spring-inject.xml"
);
IUserService
userService
=
applicationContext
.
getBean
(
"userService"
,
IUserService
.
class
);
System
.
out
.
println
(
"测试结果:"
+
userService
.
queryUserInfo
());
System
.
out
.
println
(
"测试结果1:"
+
userService
.
queryUserInfo
());
System
.
out
.
println
(
"测试结果2:"
+
userService
.
queryUserInfo
());
}
...
...
src/test/java/cn/noexception/test/bean/UserService.java
浏览文件 @
f30bb862
...
...
@@ -3,6 +3,7 @@ package cn.noexception.test.bean;
import
cn.noexception.container.factory.annotation.Inject
;
import
cn.noexception.container.factory.annotation.InputValue
;
import
cn.noexception.container.factory.stereotype.Cube
;
import
cn.noexception.ratelimiter.annotation.DoRateLimiter
;
import
java.util.Random
;
...
...
@@ -21,6 +22,7 @@ public class UserService implements IUserService {
@Inject
private
UserDao
userDao
;
@DoRateLimiter
(
rate
=
1
,
returnJson
=
"{\"code\":\"1111\",\"info\":\"调用方法超过最大次数,限流返回!\"}"
)
@Override
public
String
queryUserInfo
()
{
try
{
...
...
编辑
预览
Markdown
is supported
0%
请重试
或
添加新附件
.
添加附件
取消
You are about to add
0
people
to the discussion. Proceed with caution.
先完成此消息的编辑!
取消
想要评论请
注册
或
登录