前言:
1:jdk1.8開始支持重復注解@Repeatable實現
2:aop攔截需要攔截當前注解和@Repeatable指向的包裝注解才可以完全攔截到,因為:1.當在在方法上只有一個注解時,aop攔截認為是非包裝類型注解。2.當方法上有多個重復注解時,aop攔截認為是包裝類型注解。
重復注解實現方式(RequestLimit為原始注解,RequestLimitPack為包裝注解):
1
2
3
4
5
6
7
8
9
10
11
12
13
14
15
16
17
18
19
20
21
22
23
24
25
26
27
28
29
30
31
32
|
import java.lang.annotation.ElementType; import java.lang.annotation.Repeatable; import java.lang.annotation.Retention; import java.lang.annotation.RetentionPolicy; import java.lang.annotation.Target; /** * 接口限流 * * @author wulm */ @Repeatable (RequestLimit.RequestLimitPack. class ) @Target ({ElementType.METHOD}) @Retention (RetentionPolicy.RUNTIME) public @interface RequestLimit { /** * 最大次數,比如 每分鐘100次、每小時500次、每天1000次 */ int maxTimes(); /** * 頻率更新時間,比如 60:每分鐘、 3600:每小時、 86400:每天 **/ int seconds(); @Target ({ElementType.METHOD}) @Retention (RetentionPolicy.RUNTIME) @interface RequestLimitPack { RequestLimit[] value(); } } |
重復注解效果:
aop攔截(設置了兩處@Around):
1
2
3
4
5
6
7
8
9
10
11
12
13
14
15
16
17
18
19
20
21
22
23
24
25
26
27
28
29
30
31
32
33
34
35
36
37
38
39
40
41
42
43
44
45
46
47
48
49
50
51
52
53
54
55
56
57
58
|
@Aspect @Configuration public class RequestLimitAop { private static final Logger LOGGER = LoggerFactory.getLogger(RequestLimitAop. class ); public static final String REDIS_SPLIT_STR = "#" ; public static final String SUB_MODULE = "API" ; @Pointcut (value = "@annotation(com.zxy.product.hr.sync.web.config.annotation.RequestLimit)" ) public void pointcut() { } @Pointcut (value = "@annotation(com.zxy.product.hr.sync.web.config.annotation.RequestLimit" + ".RequestLimitPack)" ) public void pointcutRequestLimitOuts() { } @Around (value = "pointcut()" ) public Object around(ProceedingJoinPoint joinPoint) throws Throwable { // 獲取攔截的方法名 MethodSignature msig = (MethodSignature) joinPoint.getSignature(); // 獲取到注解 RequestLimit requestLimit = msig.getMethod().getAnnotation(RequestLimit. class ); ResultInfo resultInfo = checkFrequency(requestLimit, false ); if (ResultInfo.isSuccess(resultInfo)) { // 繼續執行方法 return joinPoint.proceed(); } else { return resultInfo; } } @Around (value = "pointcutRequestLimitOuts()" ) public Object aroundRequestLimitOuts(ProceedingJoinPoint joinPoint) throws Throwable { // 獲取攔截的方法名 MethodSignature msig = (MethodSignature) joinPoint.getSignature(); // 獲取到注解 RequestLimit.RequestLimitPack requestLimitPack = msig.getMethod() .getAnnotation(RequestLimit.RequestLimitPack. class ); for (RequestLimit requestLimit : requestLimitPack.value()) { ResultInfo resultInfo = checkFrequency(requestLimit, false ); if (!ResultInfo.isSuccess(resultInfo)) { //失敗立即返回 return resultInfo; } } //沒問題則繼續執行 return joinPoint.proceed(); } public static ResultInfo checkFrequency(RequestLimit requestLimit, boolean isInnerApi) { //代碼忽略...... } } |
到此這篇關于spring 重復注解和aop攔截的實現示例的文章就介紹到這了,更多相關spring 重復注解和aop攔截內容請搜索服務器之家以前的文章或繼續瀏覽下面的相關文章希望大家以后多多支持服務器之家!
原文鏈接:https://www.cnblogs.com/wulm/p/14386372.html