Spring 中AOP注解@Aspect的实用方法

增加注解

@Target(ElementType.METHOD)
@Retention(RetentionPolicy.RUNTIME)
public @interface RataLimit {
    /**
     * 时间间隔内允许通过的请求数
     **/
    int count() default 120;

    /**
     * 时间间隔,单位秒
     **/
    int intervalInSeconds() default 60;

    /**
     * 限流规则,默认使用请求方法+请求IP限流
     **/
    String rule() default "";
}

使用注解

    @PostMapping("/logout")
    @RataLimit(count = 100, intervalInSeconds = 3600)
    public ResultDTO<String> logout(){
        userServiceImpl.logout();
        return ResultDTO.newSuccessResult();
    }

@Aspect的实现

@Aspect
@Component
public class RateLimitAspect {
    private static final ThorExtLogger logger = ThorExtLogger.create(RateLimitAspect.class);

    private static final String REDIS_RATE_LIMIT_TEMPLATE = BaseConstant.STR_PLACEHOLDER_CHARACTER
        .concat(BaseConstant.REDIS_SPLITTING_CHARACTER)
        .concat(BaseConstant.STR_PLACEHOLDER_CHARACTER);

    @Autowired
    private CacheRepository cacheRepository;

    @Pointcut(value = "@annotation(com.duxiaoman.pay.epic.spfront.annotation.RataLimit)")
    //这里表示所用使用rateLimit注解的方法,注意PointCut切入点只能是方法
    public void pointcut() {
    }

    @Before("pointcut() && @annotation(rataLimit)")
    //@Before方法中pointcut()代表的是对拦截到方法执行的逻辑而@annotation(rataLimit)表示可以在下面的方法中获取到你在方法上使用RateLimit的参数
    public void before(JoinPoint joinPoint, RataLimit rataLimit) throws Throwable {
      //JoinPoint joinPoint:

//JoinPoint 是 Spring AOP 提供的一个接口,它提供了有关当前被拦截的方法的信息。通过 JoinPoint,你可以获取被拦截方法的签名、参数、类实例等。
//常用的方法:
//joinPoint.getSignature():获取被拦截方法的签名(方法名称、返回类型等)。
//joinPoint.getArgs():获取被拦截方法的参数。
//joinPoint.getTarget():获取执行方法的目标对象(即当前类的实例)。
        logger.info("Enter rateLimitAspect @Before method.");
        String method = joinPoint.getSignature().getName();
        String ipAddress = HttpRequestUtil.getRemoteRealIpAddr(ServletUtils.getRequest());
        String rule = rateLimit.rule();
        String redisKey = MessageFormatter.format(REDIS_RATE_LIMIT_TEMPLATE, method, ipAddress).getMessage();

        String key = StringUtils.isNotBlank(rule) ? rule : redisKey;
        /** 请求次数限制 **/
        int permitsInterval = rataLimit.count();
        /** 时间间隔 **/
        int interval = rataLimit.intervalInSeconds();
        logger.info("RateLimitAspect @Before method output count: {}, intervalInSeconds: {}, rule: {}",
            permitsInterval, interval, rule);
        boolean isPermit = cacheRepository.checkAndIncrementThreshold(key, permitsInterval, interval);
        /** 指定时间间隔内,超过最大频率限制,进行限流 **/
        if (!isPermit) {
            logger.error("RateLimitAspect @Before method output. Call proxy method {} reaches {} maximum current limit",
                method, permitsInterval);
            throw new CommonException(ErrorCodeEnum.IP_REQUEST_UP_LIMIT_ERROR);
        }
        logger.info("Exit from rateLimitAspect @Before method.");
    }
}
评论 1
添加红包

请填写红包祝福语或标题

红包个数最小为10个

红包金额最低5元

当前余额3.43前往充值 >
需支付:10.00
成就一亿技术人!
领取后你会自动成为博主和红包主的粉丝 规则
hope_wisdom
发出的红包
实付
使用余额支付
点击重新获取
扫码支付
钱包余额 0

抵扣说明:

1.余额是钱包充值的虚拟货币,按照1:1的比例进行支付金额的抵扣。
2.余额无法直接购买下载,可以购买VIP、付费专栏及课程。

余额充值