package com.imyeyu.spring.annotation; import jakarta.servlet.http.HttpServletRequest; import jakarta.servlet.http.HttpServletResponse; import lombok.NoArgsConstructor; import org.springframework.lang.NonNull; import org.springframework.web.method.HandlerMethod; import org.springframework.web.servlet.HandlerInterceptor; /** * 抽象访问频率限制,具体子类实现 * * @author 夜雨 * @version 2021-08-16 18:07 */ @NoArgsConstructor public abstract class RequestRateLimitAbstractInterceptor implements HandlerInterceptor { /** * 构建接口标识 * * @param handlerMethod 方法信息 * @return 接口标识 */ protected String buildId(HandlerMethod handlerMethod) { return handlerMethod.getMethod().getDeclaringClass().getSimpleName() + "." + handlerMethod.getMethod().getName(); } /** * 处理前 * * @param req 请求 * @param resp 返回 * @param handler 处理方法 * @return true 为通过 */ @Override public boolean preHandle(@NonNull HttpServletRequest req, @NonNull HttpServletResponse resp, @NonNull Object handler) { // 方法注解 if (handler instanceof HandlerMethod handlerMethod) { RequestRateLimit requestRateLimit = handlerMethod.getMethodAnnotation(RequestRateLimit.class); if (requestRateLimit == null) { return true; } // 频率限制 return beforeRun(req, resp, buildId(handlerMethod), requestRateLimit.lifeCycle(), requestRateLimit.value()); } return true; } /** * 接口访问前触发 * * @param req 请求 * @param resp 返回 * @param id 方法 * @param cycle 生命周期 * @param limit 访问限制 * @return true 为通过 */ public abstract boolean beforeRun(HttpServletRequest req, HttpServletResponse resp, String id, int cycle, int limit); }