All Downloads are FREE. Search and download functionalities are using the official Maven repository.

com.lwohvye.beans.aspect.LimitAspect Maven / Gradle / Ivy

/*
 *  Copyright 2019-2020 Zheng Jie
 *
 *  Licensed under the Apache License, Version 2.0 (the "License");
 *  you may not use this file except in compliance with the License.
 *  You may obtain a copy of the License at
 *
 *  http://www.apache.org/licenses/LICENSE-2.0
 *
 *  Unless required by applicable law or agreed to in writing, software
 *  distributed under the License is distributed on an "AS IS" BASIS,
 *  WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied.
 *  See the License for the specific language governing permissions and
 *  limitations under the License.
 */
package com.lwohvye.beans.aspect;

import com.lwohvye.core.annotation.Limit;
import com.lwohvye.core.enums.LimitType;
import com.lwohvye.core.exception.BadRequestException;
import com.lwohvye.core.utils.RequestHolder;
import com.lwohvye.core.utils.StringUtils;
import lombok.RequiredArgsConstructor;
import org.aspectj.lang.ProceedingJoinPoint;
import org.aspectj.lang.annotation.Around;
import org.aspectj.lang.annotation.Aspect;
import org.aspectj.lang.annotation.Pointcut;
import org.aspectj.lang.reflect.MethodSignature;
import org.redisson.api.RateIntervalUnit;
import org.redisson.api.RateType;
import org.redisson.api.RedissonClient;
import org.slf4j.Logger;
import org.slf4j.LoggerFactory;
import org.springframework.boot.autoconfigure.condition.ConditionalOnWebApplication;
import org.springframework.stereotype.Component;

/**
 * @author /
 */
@Aspect
@Component
@RequiredArgsConstructor
@ConditionalOnWebApplication(type = ConditionalOnWebApplication.Type.SERVLET) // 在Spring为Web服务时生效
public class LimitAspect {

    private static final Logger logger = LoggerFactory.getLogger(LimitAspect.class);

    private final RedissonClient redissonClient;

    @Pointcut("@annotation(com.lwohvye.core.annotation.Limit)")
    public void pointcut() {
    }

    @Around("pointcut()")
    public Object around(ProceedingJoinPoint joinPoint) throws Throwable {
        var request = RequestHolder.getHttpServletRequest();
        var signature = (MethodSignature) joinPoint.getSignature();
        var signatureMethod = signature.getMethod();
        Limit limit = signatureMethod.getAnnotation(Limit.class);
        var limitType = limit.limitType();
        var key = limit.key();
        if (StringUtils.isBlank(key)) {
            if (limitType == LimitType.IP) {
                key = StringUtils.getIp(request);
            } else {
                key = signatureMethod.getName();
            }
        }

        var rateLimiter = redissonClient.getRateLimiter(key);

        rateLimiter.trySetRate(RateType.OVERALL, limit.count(), limit.period(), RateIntervalUnit.SECONDS);
        if (rateLimiter.tryAcquire(1)) {
            logger.info("key {},availablePermits {}", limit.key(), rateLimiter.availablePermits());
            return joinPoint.proceed();
        } else {
            throw new BadRequestException(limit.name() + " -> 访问次数受限制");
        }
    }
}




© 2015 - 2025 Weber Informatics LLC | Privacy Policy