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

win.hupubao.common.aop.RequestLimitAspect Maven / Gradle / Ivy

Go to download

简单封装公共工具,二维码工具,驼峰转换工具,des加解密工具,http访问工具,字符串工具,日期工具

There is a newer version: 2.0.4
Show newest version
/*
 * Copyright 2018 the original author or authors.
 *
 * 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 win.hupubao.common.aop;

import net.jodah.expiringmap.ExpirationPolicy;
import net.jodah.expiringmap.ExpiringMap;
import org.aspectj.lang.ProceedingJoinPoint;
import org.aspectj.lang.annotation.Around;
import org.aspectj.lang.annotation.Aspect;
import win.hupubao.common.annotations.RequestLimit;
import win.hupubao.common.aop.adaper.RequestLimitAdapter;
import win.hupubao.common.aop.adaper.RequestLimitHandler;
import win.hupubao.common.utils.LoggerUtils;
import win.hupubao.common.utils.StringUtils;

import javax.servlet.http.HttpServletRequest;
import java.util.concurrent.TimeUnit;

/**
 * @author ysdxz207
 * @date 2018-08-06
 * 访问频率检查
 */
@Aspect
public class RequestLimitAspect {
    private static final ExpiringMap REQUEST_MAP = ExpiringMap.builder()
            .variableExpiration()
            .expirationPolicy(ExpirationPolicy.CREATED)
            .build();

    /**
     * 需要有构造方法
     * 否则会报Caused by: java.lang.NoSuchMethodError xxx  method <init>()V not found
     */
    public RequestLimitAspect() {
    }

    @Around("execution(* *(..)) && @annotation(requestLimit)")
    public Object around(ProceedingJoinPoint proceedingJoinPoint,
                         RequestLimit requestLimit) throws Throwable {
        long limitInterval = requestLimit.interval();
        if (limitInterval > 0) {
            Object[] args = proceedingJoinPoint.getArgs();

            HttpServletRequest request = null;
            for (Object obj : args) {
                if (obj instanceof HttpServletRequest) {
                    request = (HttpServletRequest) obj;
                }
            }
            if (request == null) {
                LoggerUtils.warn(getClass(), "Method with annotation [RequestLimit] should have HttpServletRequest type parameter.");
                return proceedingJoinPoint.proceed();
            }
            String key = null;
            Class clazzAdapter = requestLimit.adapter();
            try {
                key = clazzAdapter.newInstance().getUniqueKey(request);
            } catch (InstantiationException e) {
                LoggerUtils.warn("Can not execute request limit adpter [{}].", clazzAdapter.getName());
            }

            if (StringUtils.isBlank(key)) {
                LoggerUtils.warn("Can not get request limit key by [{}], default to session id.", clazzAdapter.getName());
                key = request.getSession().getId();
            }

            long currentTime = System.currentTimeMillis();
            boolean limit = REQUEST_MAP.containsKey(key);
            long lastRequestTime = limit ? REQUEST_MAP.get(key) : 0;
            long currentInterval = currentTime - lastRequestTime;


            if (limit) {
                long limitTimeLast = limitInterval - currentInterval;
                if (requestLimit.updated()) {
                    REQUEST_MAP.put(key, currentTime, limitInterval, TimeUnit.MILLISECONDS);
                    limitTimeLast = limitInterval;
                }

                Class clazz = requestLimit.handler();
                try {

                    RequestLimitHandler requestLimitAdapter = clazz.newInstance();
                    return requestLimitAdapter.handle(limitInterval, requestLimit.updated(), limitTimeLast, args);
                } catch (InstantiationException e) {
                    LoggerUtils.warn("Can not execute request limit handler [{}].", clazz.getName());
                }

            }
            REQUEST_MAP.put(key, currentTime, limitInterval, TimeUnit.MILLISECONDS);

        }
        return proceedingJoinPoint.proceed();
    }

}




© 2015 - 2025 Weber Informatics LLC | Privacy Policy