mirror of
https://github.com/continew-org/continew-starter.git
synced 2025-09-09 08:57:17 +08:00
refactor(ratelimiter): 将限流相关代码从 security 模块中分离,创建独立的 ratelimiter 模块
修复部分幂等配置错误
This commit is contained in:
@@ -1,31 +0,0 @@
|
||||
<project xmlns="http://maven.apache.org/POM/4.0.0" xmlns:xsi="http://www.w3.org/2001/XMLSchema-instance"
|
||||
xsi:schemaLocation="http://maven.apache.org/POM/4.0.0 http://maven.apache.org/xsd/maven-4.0.0.xsd">
|
||||
<modelVersion>4.0.0</modelVersion>
|
||||
<parent>
|
||||
<groupId>top.continew</groupId>
|
||||
<artifactId>continew-starter-security</artifactId>
|
||||
<version>${revision}</version>
|
||||
</parent>
|
||||
|
||||
<artifactId>continew-starter-security-limiter</artifactId>
|
||||
<description>ContiNew Starter 安全模块 - 限流</description>
|
||||
|
||||
<dependencies>
|
||||
<dependency>
|
||||
<groupId>org.springframework.boot</groupId>
|
||||
<artifactId>spring-boot-starter-aop</artifactId>
|
||||
</dependency>
|
||||
|
||||
<!-- Web 模块 -->
|
||||
<dependency>
|
||||
<groupId>top.continew</groupId>
|
||||
<artifactId>continew-starter-web</artifactId>
|
||||
</dependency>
|
||||
|
||||
<!-- 缓存模块 - Redisson -->
|
||||
<dependency>
|
||||
<groupId>top.continew</groupId>
|
||||
<artifactId>continew-starter-cache-redisson</artifactId>
|
||||
</dependency>
|
||||
</dependencies>
|
||||
</project>
|
@@ -1,69 +0,0 @@
|
||||
/*
|
||||
* Copyright (c) 2022-present Charles7c Authors. All Rights Reserved.
|
||||
* <p>
|
||||
* Licensed under the GNU LESSER GENERAL PUBLIC LICENSE 3.0;
|
||||
* you may not use this file except in compliance with the License.
|
||||
* You may obtain a copy of the License at
|
||||
* <p>
|
||||
* http://www.gnu.org/licenses/lgpl.html
|
||||
* <p>
|
||||
* 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 top.continew.starter.security.limiter.annotation;
|
||||
|
||||
import top.continew.starter.security.limiter.enums.LimitType;
|
||||
|
||||
import java.lang.annotation.*;
|
||||
import java.util.concurrent.TimeUnit;
|
||||
|
||||
/**
|
||||
* 限流注解
|
||||
*
|
||||
* @author KAI
|
||||
* @since 2.2.0
|
||||
*/
|
||||
@Documented
|
||||
@Target(ElementType.METHOD)
|
||||
@Retention(RetentionPolicy.RUNTIME)
|
||||
public @interface RateLimiter {
|
||||
|
||||
/**
|
||||
* 类型
|
||||
*/
|
||||
LimitType type() default LimitType.DEFAULT;
|
||||
|
||||
/**
|
||||
* 名称
|
||||
*/
|
||||
String name() default "";
|
||||
|
||||
/**
|
||||
* 键(支持 Spring EL 表达式)
|
||||
*/
|
||||
String key() default "";
|
||||
|
||||
/**
|
||||
* 速率(指定时间间隔产生的令牌数)
|
||||
*/
|
||||
int rate() default Integer.MAX_VALUE;
|
||||
|
||||
/**
|
||||
* 速率间隔(时间间隔)
|
||||
*/
|
||||
int interval() default 0;
|
||||
|
||||
/**
|
||||
* 速率间隔时间单位(默认:毫秒)
|
||||
*/
|
||||
TimeUnit unit() default TimeUnit.MILLISECONDS;
|
||||
|
||||
/**
|
||||
* 提示信息
|
||||
*/
|
||||
String message() default "操作过于频繁,请稍后再试";
|
||||
}
|
@@ -1,36 +0,0 @@
|
||||
/*
|
||||
* Copyright (c) 2022-present Charles7c Authors. All Rights Reserved.
|
||||
* <p>
|
||||
* Licensed under the GNU LESSER GENERAL PUBLIC LICENSE 3.0;
|
||||
* you may not use this file except in compliance with the License.
|
||||
* You may obtain a copy of the License at
|
||||
* <p>
|
||||
* http://www.gnu.org/licenses/lgpl.html
|
||||
* <p>
|
||||
* 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 top.continew.starter.security.limiter.annotation;
|
||||
|
||||
import java.lang.annotation.*;
|
||||
|
||||
/**
|
||||
* 限流组注解
|
||||
*
|
||||
* @author KAI
|
||||
* @since 2.2.0
|
||||
*/
|
||||
@Documented
|
||||
@Retention(RetentionPolicy.RUNTIME)
|
||||
@Target(ElementType.METHOD)
|
||||
public @interface RateLimiters {
|
||||
|
||||
/**
|
||||
* 限流组
|
||||
*/
|
||||
RateLimiter[] value();
|
||||
}
|
@@ -1,60 +0,0 @@
|
||||
/*
|
||||
* Copyright (c) 2022-present Charles7c Authors. All Rights Reserved.
|
||||
* <p>
|
||||
* Licensed under the GNU LESSER GENERAL PUBLIC LICENSE 3.0;
|
||||
* you may not use this file except in compliance with the License.
|
||||
* You may obtain a copy of the License at
|
||||
* <p>
|
||||
* http://www.gnu.org/licenses/lgpl.html
|
||||
* <p>
|
||||
* 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 top.continew.starter.security.limiter.autoconfigure;
|
||||
|
||||
import jakarta.annotation.PostConstruct;
|
||||
import org.slf4j.Logger;
|
||||
import org.slf4j.LoggerFactory;
|
||||
import org.springframework.boot.autoconfigure.AutoConfiguration;
|
||||
import org.springframework.boot.autoconfigure.condition.ConditionalOnMissingBean;
|
||||
import org.springframework.boot.autoconfigure.condition.ConditionalOnProperty;
|
||||
import org.springframework.boot.context.properties.EnableConfigurationProperties;
|
||||
import org.springframework.context.annotation.Bean;
|
||||
import org.springframework.context.annotation.ComponentScan;
|
||||
import top.continew.starter.core.constant.PropertiesConstants;
|
||||
import top.continew.starter.security.limiter.core.DefaultRateLimiterNameGenerator;
|
||||
import top.continew.starter.security.limiter.core.RateLimiterNameGenerator;
|
||||
|
||||
/**
|
||||
* 限流器自动配置
|
||||
*
|
||||
* @author KAI
|
||||
* @author Charles7c
|
||||
* @since 2.2.0
|
||||
*/
|
||||
@AutoConfiguration
|
||||
@EnableConfigurationProperties(RateLimiterProperties.class)
|
||||
@ComponentScan({"top.continew.starter.security.limiter.core"})
|
||||
@ConditionalOnProperty(prefix = PropertiesConstants.SECURITY_LIMITER, name = PropertiesConstants.ENABLED, havingValue = "true", matchIfMissing = true)
|
||||
public class RateLimiterAutoConfiguration {
|
||||
|
||||
private static final Logger log = LoggerFactory.getLogger(RateLimiterAutoConfiguration.class);
|
||||
|
||||
/**
|
||||
* 限流器名称生成器
|
||||
*/
|
||||
@Bean
|
||||
@ConditionalOnMissingBean
|
||||
public RateLimiterNameGenerator nameGenerator() {
|
||||
return new DefaultRateLimiterNameGenerator();
|
||||
}
|
||||
|
||||
@PostConstruct
|
||||
public void postConstruct() {
|
||||
log.debug("[ContiNew Starter] - Auto Configuration 'Security-RateLimiter' completed initialization.");
|
||||
}
|
||||
}
|
@@ -1,43 +0,0 @@
|
||||
/*
|
||||
* Copyright (c) 2022-present Charles7c Authors. All Rights Reserved.
|
||||
* <p>
|
||||
* Licensed under the GNU LESSER GENERAL PUBLIC LICENSE 3.0;
|
||||
* you may not use this file except in compliance with the License.
|
||||
* You may obtain a copy of the License at
|
||||
* <p>
|
||||
* http://www.gnu.org/licenses/lgpl.html
|
||||
* <p>
|
||||
* 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 top.continew.starter.security.limiter.autoconfigure;
|
||||
|
||||
import org.springframework.boot.context.properties.ConfigurationProperties;
|
||||
import top.continew.starter.core.constant.PropertiesConstants;
|
||||
|
||||
/**
|
||||
* 限流器配置属性
|
||||
*
|
||||
* @author KAI
|
||||
* @since 2.2.0
|
||||
*/
|
||||
@ConfigurationProperties(PropertiesConstants.SECURITY_LIMITER)
|
||||
public class RateLimiterProperties {
|
||||
|
||||
/**
|
||||
* Key 前缀
|
||||
*/
|
||||
private String keyPrefix = "RateLimiter";
|
||||
|
||||
public String getKeyPrefix() {
|
||||
return keyPrefix;
|
||||
}
|
||||
|
||||
public void setKeyPrefix(String keyPrefix) {
|
||||
this.keyPrefix = keyPrefix;
|
||||
}
|
||||
}
|
@@ -1,107 +0,0 @@
|
||||
/*
|
||||
* Copyright (c) 2022-present Charles7c Authors. All Rights Reserved.
|
||||
* <p>
|
||||
* Licensed under the GNU LESSER GENERAL PUBLIC LICENSE 3.0;
|
||||
* you may not use this file except in compliance with the License.
|
||||
* You may obtain a copy of the License at
|
||||
* <p>
|
||||
* http://www.gnu.org/licenses/lgpl.html
|
||||
* <p>
|
||||
* 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 top.continew.starter.security.limiter.core;
|
||||
|
||||
import cn.hutool.core.util.ClassUtil;
|
||||
import top.continew.starter.core.constant.StringConstants;
|
||||
|
||||
import java.lang.reflect.Method;
|
||||
import java.util.concurrent.ConcurrentHashMap;
|
||||
|
||||
/**
|
||||
* 默认限流器名称生成器
|
||||
*
|
||||
* @author Charles7c
|
||||
* @since 2.2.0
|
||||
*/
|
||||
public class DefaultRateLimiterNameGenerator implements RateLimiterNameGenerator {
|
||||
|
||||
protected final ConcurrentHashMap<Method, String> nameMap = new ConcurrentHashMap<>();
|
||||
|
||||
@Override
|
||||
public String generate(Object target, Method method, Object... args) {
|
||||
return nameMap.computeIfAbsent(method, key -> {
|
||||
final StringBuilder nameSb = new StringBuilder();
|
||||
String className = method.getDeclaringClass().getName();
|
||||
nameSb.append(ClassUtil.getShortClassName(className));
|
||||
nameSb.append(StringConstants.DOT);
|
||||
nameSb.append(method.getName());
|
||||
nameSb.append(StringConstants.ROUND_BRACKET_START);
|
||||
for (Class<?> clazz : method.getParameterTypes()) {
|
||||
this.getDescriptor(nameSb, clazz);
|
||||
}
|
||||
nameSb.append(StringConstants.ROUND_BRACKET_END);
|
||||
return nameSb.toString();
|
||||
});
|
||||
}
|
||||
|
||||
/**
|
||||
* 获取指定数据类型的描述
|
||||
*
|
||||
* @param sb 名称字符串缓存
|
||||
* @param typeClass 数据类型
|
||||
*/
|
||||
private void getDescriptor(final StringBuilder sb, final Class<?> typeClass) {
|
||||
Class<?> clazz = typeClass;
|
||||
while (true) {
|
||||
if (clazz.isPrimitive()) {
|
||||
sb.append(this.getPrimitiveChar(clazz));
|
||||
return;
|
||||
} else if (clazz.isArray()) {
|
||||
sb.append(StringConstants.BRACKET_START);
|
||||
clazz = clazz.getComponentType();
|
||||
} else {
|
||||
sb.append('L');
|
||||
String name = clazz.getName();
|
||||
name = ClassUtil.getShortClassName(name);
|
||||
sb.append(name);
|
||||
sb.append(StringConstants.SEMICOLON);
|
||||
return;
|
||||
}
|
||||
}
|
||||
}
|
||||
|
||||
/**
|
||||
* 根据基本数据获取类型字符
|
||||
*
|
||||
* @param clazz 数据类型
|
||||
* @return 类型字符
|
||||
*/
|
||||
private char getPrimitiveChar(Class<?> clazz) {
|
||||
char c;
|
||||
if (clazz == Integer.TYPE) {
|
||||
c = 'I';
|
||||
} else if (clazz == Void.TYPE) {
|
||||
c = 'V';
|
||||
} else if (clazz == Boolean.TYPE) {
|
||||
c = 'Z';
|
||||
} else if (clazz == Byte.TYPE) {
|
||||
c = 'B';
|
||||
} else if (clazz == Character.TYPE) {
|
||||
c = 'C';
|
||||
} else if (clazz == Short.TYPE) {
|
||||
c = 'S';
|
||||
} else if (clazz == Double.TYPE) {
|
||||
c = 'D';
|
||||
} else if (clazz == Float.TYPE) {
|
||||
c = 'F';
|
||||
} else {
|
||||
c = 'J';
|
||||
}
|
||||
return c;
|
||||
}
|
||||
}
|
@@ -1,198 +0,0 @@
|
||||
/*
|
||||
* Copyright (c) 2022-present Charles7c Authors. All Rights Reserved.
|
||||
* <p>
|
||||
* Licensed under the GNU LESSER GENERAL PUBLIC LICENSE 3.0;
|
||||
* you may not use this file except in compliance with the License.
|
||||
* You may obtain a copy of the License at
|
||||
* <p>
|
||||
* http://www.gnu.org/licenses/lgpl.html
|
||||
* <p>
|
||||
* 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 top.continew.starter.security.limiter.core;
|
||||
|
||||
import cn.hutool.core.convert.Convert;
|
||||
import cn.hutool.core.text.CharSequenceUtil;
|
||||
import cn.hutool.core.util.ObjectUtil;
|
||||
import cn.hutool.extra.servlet.JakartaServletUtil;
|
||||
import org.aspectj.lang.JoinPoint;
|
||||
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.*;
|
||||
import org.springframework.stereotype.Component;
|
||||
import top.continew.starter.cache.redisson.util.RedisUtils;
|
||||
import top.continew.starter.core.constant.StringConstants;
|
||||
import top.continew.starter.core.util.expression.ExpressionUtils;
|
||||
import top.continew.starter.security.limiter.annotation.RateLimiter;
|
||||
import top.continew.starter.security.limiter.annotation.RateLimiters;
|
||||
import top.continew.starter.security.limiter.autoconfigure.RateLimiterProperties;
|
||||
import top.continew.starter.security.limiter.enums.LimitType;
|
||||
import top.continew.starter.security.limiter.exception.RateLimiterException;
|
||||
import top.continew.starter.web.util.SpringWebUtils;
|
||||
|
||||
import java.lang.reflect.Method;
|
||||
import java.time.Duration;
|
||||
import java.util.Objects;
|
||||
import java.util.concurrent.ConcurrentHashMap;
|
||||
|
||||
/**
|
||||
* 限流器切面
|
||||
*
|
||||
* @author KAI
|
||||
* @author Charles7c
|
||||
* @since 2.2.0
|
||||
*/
|
||||
@Aspect
|
||||
@Component
|
||||
public class RateLimiterAspect {
|
||||
|
||||
private static final ConcurrentHashMap<String, RRateLimiter> RATE_LIMITER_CACHE = new ConcurrentHashMap<>();
|
||||
private final RateLimiterProperties properties;
|
||||
private final RateLimiterNameGenerator nameGenerator;
|
||||
private final RedissonClient redissonClient;
|
||||
|
||||
public RateLimiterAspect(RateLimiterProperties properties,
|
||||
RateLimiterNameGenerator nameGenerator,
|
||||
RedissonClient redissonClient) {
|
||||
this.properties = properties;
|
||||
this.nameGenerator = nameGenerator;
|
||||
this.redissonClient = redissonClient;
|
||||
}
|
||||
|
||||
/**
|
||||
* 单个限流注解切点
|
||||
*/
|
||||
@Pointcut("@annotation(top.continew.starter.security.limiter.annotation.RateLimiter)")
|
||||
public void rateLimiterPointCut() {
|
||||
}
|
||||
|
||||
/**
|
||||
* 多个限流注解切点
|
||||
*/
|
||||
@Pointcut("@annotation(top.continew.starter.security.limiter.annotation.RateLimiters)")
|
||||
public void rateLimitersPointCut() {
|
||||
}
|
||||
|
||||
/**
|
||||
* 单限流场景
|
||||
*
|
||||
* @param joinPoint 切点
|
||||
* @param rateLimiter 限流注解
|
||||
* @return 目标方法的执行结果
|
||||
* @throws Throwable /
|
||||
*/
|
||||
@Around("@annotation(rateLimiter)")
|
||||
public Object aroundRateLimiter(ProceedingJoinPoint joinPoint, RateLimiter rateLimiter) throws Throwable {
|
||||
if (isRateLimited(joinPoint, rateLimiter)) {
|
||||
throw new RateLimiterException(rateLimiter.message());
|
||||
}
|
||||
return joinPoint.proceed();
|
||||
}
|
||||
|
||||
/**
|
||||
* 多限流场景
|
||||
*
|
||||
* @param joinPoint 切点
|
||||
* @param rateLimiters 限流组注解
|
||||
* @return 目标方法的执行结果
|
||||
* @throws Throwable /
|
||||
*/
|
||||
@Around("@annotation(rateLimiters)")
|
||||
public Object aroundRateLimiters(ProceedingJoinPoint joinPoint, RateLimiters rateLimiters) throws Throwable {
|
||||
for (RateLimiter rateLimiter : rateLimiters.value()) {
|
||||
if (isRateLimited(joinPoint, rateLimiter)) {
|
||||
throw new RateLimiterException(rateLimiter.message());
|
||||
}
|
||||
}
|
||||
return joinPoint.proceed();
|
||||
}
|
||||
|
||||
/**
|
||||
* 是否需要限流
|
||||
*
|
||||
* @param joinPoint 切点
|
||||
* @param rateLimiter 限流注解
|
||||
* @return true: 需要限流;false:不需要限流
|
||||
*/
|
||||
private boolean isRateLimited(ProceedingJoinPoint joinPoint, RateLimiter rateLimiter) {
|
||||
try {
|
||||
String cacheKey = this.getCacheKey(joinPoint, rateLimiter);
|
||||
RRateLimiter rRateLimiter = RATE_LIMITER_CACHE.computeIfAbsent(cacheKey, key -> redissonClient
|
||||
.getRateLimiter(cacheKey));
|
||||
// 限流器配置
|
||||
RateType rateType = rateLimiter.type() == LimitType.CLUSTER ? RateType.PER_CLIENT : RateType.OVERALL;
|
||||
int rate = rateLimiter.rate();
|
||||
Duration rateInterval = Duration.ofMillis(rateLimiter.unit().toMillis(rateLimiter.interval()));
|
||||
// 判断是否需要更新限流器
|
||||
if (this.isConfigurationUpdateNeeded(rRateLimiter, rateType, rate, rateInterval)) {
|
||||
// 更新限流器
|
||||
rRateLimiter.setRate(rateType, rate, rateInterval);
|
||||
}
|
||||
// 尝试获取令牌
|
||||
return !rRateLimiter.tryAcquire();
|
||||
} catch (Exception e) {
|
||||
throw new RateLimiterException("服务器限流异常,请稍候再试", e);
|
||||
}
|
||||
}
|
||||
|
||||
/**
|
||||
* 获取限流缓存 Key
|
||||
*
|
||||
* @param joinPoint 切点
|
||||
* @param rateLimiter 限流注解
|
||||
* @return 限流缓存 Key
|
||||
*/
|
||||
private String getCacheKey(JoinPoint joinPoint, RateLimiter rateLimiter) {
|
||||
Object target = joinPoint.getTarget();
|
||||
MethodSignature methodSignature = (MethodSignature)joinPoint.getSignature();
|
||||
Method method = methodSignature.getMethod();
|
||||
Object[] args = joinPoint.getArgs();
|
||||
// 获取限流名称
|
||||
String name = rateLimiter.name();
|
||||
if (CharSequenceUtil.isBlank(name)) {
|
||||
name = nameGenerator.generate(target, method, args);
|
||||
}
|
||||
// 解析限流 Key
|
||||
String key = rateLimiter.key();
|
||||
if (CharSequenceUtil.isNotBlank(key)) {
|
||||
Object eval = ExpressionUtils.eval(key, target, method, args);
|
||||
if (ObjectUtil.isNull(eval)) {
|
||||
throw new RateLimiterException("限流 Key 解析错误");
|
||||
}
|
||||
key = Convert.toStr(eval);
|
||||
}
|
||||
// 获取后缀
|
||||
String suffix = switch (rateLimiter.type()) {
|
||||
case IP -> JakartaServletUtil.getClientIP(SpringWebUtils.getRequest());
|
||||
case CLUSTER -> redissonClient.getId();
|
||||
default -> StringConstants.EMPTY;
|
||||
};
|
||||
return RedisUtils.formatKey(properties.getKeyPrefix(), name, key, suffix);
|
||||
}
|
||||
|
||||
/**
|
||||
* 判断是否需要更新限流器配置
|
||||
*
|
||||
* @param rRateLimiter 限流器
|
||||
* @param rateType 限流类型(OVERALL:全局限流;PER_CLIENT:单机限流)
|
||||
* @param rate 速率(指定时间间隔产生的令牌数)
|
||||
* @param rateInterval 速率间隔
|
||||
* @return 是否需要更新配置
|
||||
*/
|
||||
private boolean isConfigurationUpdateNeeded(RRateLimiter rRateLimiter,
|
||||
RateType rateType,
|
||||
long rate,
|
||||
Duration rateInterval) {
|
||||
RateLimiterConfig config = rRateLimiter.getConfig();
|
||||
return !Objects.equals(config.getRateType(), rateType) || !Objects.equals(config.getRate(), rate) || !Objects
|
||||
.equals(config.getRateInterval(), rateInterval.toMillis());
|
||||
}
|
||||
}
|
@@ -1,39 +0,0 @@
|
||||
/*
|
||||
* Copyright (c) 2022-present Charles7c Authors. All Rights Reserved.
|
||||
* <p>
|
||||
* Licensed under the GNU LESSER GENERAL PUBLIC LICENSE 3.0;
|
||||
* you may not use this file except in compliance with the License.
|
||||
* You may obtain a copy of the License at
|
||||
* <p>
|
||||
* http://www.gnu.org/licenses/lgpl.html
|
||||
* <p>
|
||||
* 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 top.continew.starter.security.limiter.core;
|
||||
|
||||
import java.lang.reflect.Method;
|
||||
|
||||
/**
|
||||
* 限流器名称生成器
|
||||
*
|
||||
* @author Charles7c
|
||||
* @since 2.2.0
|
||||
*/
|
||||
@FunctionalInterface
|
||||
public interface RateLimiterNameGenerator {
|
||||
|
||||
/**
|
||||
* Generate a rate limiter name for the given method and its parameters.
|
||||
*
|
||||
* @param target the target instance
|
||||
* @param method the method being called
|
||||
* @param args the method parameters (with any var-args expanded)
|
||||
* @return a generated rate limiter name
|
||||
*/
|
||||
String generate(Object target, Method method, Object... args);
|
||||
}
|
@@ -1,41 +0,0 @@
|
||||
/*
|
||||
* Copyright (c) 2022-present Charles7c Authors. All Rights Reserved.
|
||||
* <p>
|
||||
* Licensed under the GNU LESSER GENERAL PUBLIC LICENSE 3.0;
|
||||
* you may not use this file except in compliance with the License.
|
||||
* You may obtain a copy of the License at
|
||||
* <p>
|
||||
* http://www.gnu.org/licenses/lgpl.html
|
||||
* <p>
|
||||
* 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 top.continew.starter.security.limiter.enums;
|
||||
|
||||
/**
|
||||
* 限流类型
|
||||
*
|
||||
* @author KAI
|
||||
* @since 2.2.0
|
||||
*/
|
||||
public enum LimitType {
|
||||
|
||||
/**
|
||||
* 全局限流
|
||||
*/
|
||||
DEFAULT,
|
||||
|
||||
/**
|
||||
* 根据 IP 限流
|
||||
*/
|
||||
IP,
|
||||
|
||||
/**
|
||||
* 根据实例限流(支持集群多实例)
|
||||
*/
|
||||
CLUSTER
|
||||
}
|
@@ -1,36 +0,0 @@
|
||||
/*
|
||||
* Copyright (c) 2022-present Charles7c Authors. All Rights Reserved.
|
||||
* <p>
|
||||
* Licensed under the GNU LESSER GENERAL PUBLIC LICENSE 3.0;
|
||||
* you may not use this file except in compliance with the License.
|
||||
* You may obtain a copy of the License at
|
||||
* <p>
|
||||
* http://www.gnu.org/licenses/lgpl.html
|
||||
* <p>
|
||||
* 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 top.continew.starter.security.limiter.exception;
|
||||
|
||||
import top.continew.starter.core.exception.BaseException;
|
||||
|
||||
/**
|
||||
* 限流异常
|
||||
*
|
||||
* @author KAI
|
||||
* @since 2.2.0
|
||||
*/
|
||||
public class RateLimiterException extends BaseException {
|
||||
|
||||
public RateLimiterException(String message) {
|
||||
super(message);
|
||||
}
|
||||
|
||||
public RateLimiterException(String message, Throwable cause) {
|
||||
super(message, cause);
|
||||
}
|
||||
}
|
@@ -1 +0,0 @@
|
||||
top.continew.starter.security.limiter.autoconfigure.RateLimiterAutoConfiguration
|
@@ -1,7 +0,0 @@
|
||||
{
|
||||
"top.continew.starter.security.limiter.annotation.RateLimiter@key":{
|
||||
"method":{
|
||||
"parameters": true
|
||||
}
|
||||
}
|
||||
}
|
@@ -17,7 +17,6 @@
|
||||
<module>continew-starter-security-password</module>
|
||||
<module>continew-starter-security-mask</module>
|
||||
<module>continew-starter-security-crypto</module>
|
||||
<module>continew-starter-security-limiter</module>
|
||||
<module>continew-starter-security-sensitivewords</module>
|
||||
</modules>
|
||||
|
||||
|
Reference in New Issue
Block a user