溫馨提示×

您好,登錄后才能下訂單哦!

密碼登錄×
登錄注冊(cè)×
其他方式登錄
點(diǎn)擊 登錄注冊(cè) 即表示同意《億速云用戶服務(wù)條款》

spring如何實(shí)現(xiàn)重復(fù)注解和aop攔截

發(fā)布時(shí)間:2021-08-26 10:43:33 來(lái)源:億速云 閱讀:487 作者:小新 欄目:開(kāi)發(fā)技術(shù)

這篇文章給大家分享的是有關(guān)spring如何實(shí)現(xiàn)重復(fù)注解和aop攔截的內(nèi)容。小編覺(jué)得挺實(shí)用的,因此分享給大家做個(gè)參考,一起跟隨小編過(guò)來(lái)看看吧。

前言:

  1:jdk1.8開(kāi)始支持重復(fù)注解@Repeatable實(shí)現(xiàn)

  2:aop攔截需要攔截當(dāng)前注解和@Repeatable指向的包裝注解才可以完全攔截到,因?yàn)椋?.當(dāng)在在方法上只有一個(gè)注解時(shí),aop攔截認(rèn)為是非包裝類型注解。2.當(dāng)方法上有多個(gè)重復(fù)注解時(shí),aop攔截認(rèn)為是包裝類型注解。 

重復(fù)注解實(shí)現(xiàn)方式(RequestLimit為原始注解,RequestLimitPack為包裝注解):

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 {

    /**
     * 最大次數(shù),比如 每分鐘100次、每小時(shí)500次、每天1000次
     */
    int maxTimes();

    /**
     * 頻率更新時(shí)間,比如 60:每分鐘、  3600:每小時(shí)、  86400:每天
     **/
    int seconds();

    @Target({ElementType.METHOD})
    @Retention(RetentionPolicy.RUNTIME)
    @interface RequestLimitPack {
        RequestLimit[] value();
    }
}

重復(fù)注解效果:

spring如何實(shí)現(xiàn)重復(fù)注解和aop攔截 

aop攔截(設(shè)置了兩處@Around):

@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)) {
            // 繼續(xù)執(zhí)行方法
            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;
            }
        }
        //沒(méi)問(wèn)題則繼續(xù)執(zhí)行
        return joinPoint.proceed();
    }


    public static ResultInfo checkFrequency(RequestLimit requestLimit, boolean isInnerApi) {
     //代碼忽略......
    }

}

感謝各位的閱讀!關(guān)于“spring如何實(shí)現(xiàn)重復(fù)注解和aop攔截”這篇文章就分享到這里了,希望以上內(nèi)容可以對(duì)大家有一定的幫助,讓大家可以學(xué)到更多知識(shí),如果覺(jué)得文章不錯(cuò),可以把它分享出去讓更多的人看到吧!

向AI問(wèn)一下細(xì)節(jié)

免責(zé)聲明:本站發(fā)布的內(nèi)容(圖片、視頻和文字)以原創(chuàng)、轉(zhuǎn)載和分享為主,文章觀點(diǎn)不代表本網(wǎng)站立場(chǎng),如果涉及侵權(quán)請(qǐng)聯(lián)系站長(zhǎng)郵箱:is@yisu.com進(jìn)行舉報(bào),并提供相關(guān)證據(jù),一經(jīng)查實(shí),將立刻刪除涉嫌侵權(quán)內(nèi)容。

AI