refactor(ratelimiter): 将限流相关代码从 security 模块中分离,创建独立的 ratelimiter 模块

修复部分幂等配置错误
This commit is contained in:
2025-03-17 21:53:26 +08:00
parent 27a71cf076
commit 2b3de0c67e
20 changed files with 90 additions and 70 deletions

View File

@@ -49,11 +49,6 @@ public class PropertiesConstants {
*/ */
public static final String SECURITY_CRYPTO = SECURITY + StringConstants.DOT + "crypto"; public static final String SECURITY_CRYPTO = SECURITY + StringConstants.DOT + "crypto";
/**
* 限流器配置
*/
public static final String SECURITY_LIMITER = SECURITY + StringConstants.DOT + "limiter";
/** /**
* 敏感词配置 * 敏感词配置
*/ */
@@ -139,10 +134,15 @@ public class PropertiesConstants {
*/ */
public static final String TENANT = CONTINEW_STARTER + StringConstants.DOT + "tenant"; public static final String TENANT = CONTINEW_STARTER + StringConstants.DOT + "tenant";
/**
* 限流配置
*/
public static final String RATE_LIMITER = CONTINEW_STARTER + StringConstants.DOT + "rate-limiter";
/** /**
* 幂等配置 * 幂等配置
*/ */
public static final String IDEMPOTENT = "idempotent"; public static final String IDEMPOTENT = CONTINEW_STARTER + StringConstants.DOT + "idempotent";
private PropertiesConstants() { private PropertiesConstants() {
} }

View File

@@ -538,6 +538,20 @@
<version>${revision}</version> <version>${revision}</version>
</dependency> </dependency>
<!-- 幂等模块 -->
<dependency>
<groupId>top.continew</groupId>
<artifactId>continew-starter-idempotent</artifactId>
<version>${revision}</version>
</dependency>
<!-- 限流模块 -->
<dependency>
<groupId>top.continew</groupId>
<artifactId>continew-starter-ratelimiter</artifactId>
<version>${revision}</version>
</dependency>
<!-- 日志模块 - 基于拦截器实现Spring Boot Actuator HttpTrace 增强版) --> <!-- 日志模块 - 基于拦截器实现Spring Boot Actuator HttpTrace 增强版) -->
<dependency> <dependency>
<groupId>top.continew</groupId> <groupId>top.continew</groupId>
@@ -566,6 +580,13 @@
<version>${revision}</version> <version>${revision}</version>
</dependency> </dependency>
<!-- 安全模块 - 敏感词 -->
<dependency>
<groupId>top.continew</groupId>
<artifactId>continew-starter-security-sensitivewords</artifactId>
<version>${revision}</version>
</dependency>
<!-- 安全模块 - 加密 --> <!-- 安全模块 - 加密 -->
<dependency> <dependency>
<groupId>top.continew</groupId> <groupId>top.continew</groupId>
@@ -587,20 +608,6 @@
<version>${revision}</version> <version>${revision}</version>
</dependency> </dependency>
<!-- 安全模块 - 限流 -->
<dependency>
<groupId>top.continew</groupId>
<artifactId>continew-starter-security-limiter</artifactId>
<version>${revision}</version>
</dependency>
<!-- 安全模块 - 敏感词 -->
<dependency>
<groupId>top.continew</groupId>
<artifactId>continew-starter-security-sensitivewords</artifactId>
<version>${revision}</version>
</dependency>
<!-- API 文档模块 --> <!-- API 文档模块 -->
<dependency> <dependency>
<groupId>top.continew</groupId> <groupId>top.continew</groupId>

View File

@@ -26,6 +26,7 @@ import org.springframework.boot.autoconfigure.condition.ConditionalOnProperty;
import org.springframework.boot.context.properties.EnableConfigurationProperties; import org.springframework.boot.context.properties.EnableConfigurationProperties;
import org.springframework.context.annotation.Bean; import org.springframework.context.annotation.Bean;
import org.springframework.core.ResolvableType; import org.springframework.core.ResolvableType;
import top.continew.starter.cache.redisson.autoconfigure.RedissonAutoConfiguration;
import top.continew.starter.core.constant.PropertiesConstants; import top.continew.starter.core.constant.PropertiesConstants;
import top.continew.starter.idempotent.aop.IdempotentAspect; import top.continew.starter.idempotent.aop.IdempotentAspect;
import top.continew.starter.idempotent.generator.IdempotentNameGenerator; import top.continew.starter.idempotent.generator.IdempotentNameGenerator;
@@ -37,7 +38,7 @@ import top.continew.starter.idempotent.generator.IdempotentNameGenerator;
* @author Charles7c * @author Charles7c
* @since 2.10.0 * @since 2.10.0
*/ */
@AutoConfiguration @AutoConfiguration(after = RedissonAutoConfiguration.class)
@EnableConfigurationProperties(IdempotentProperties.class) @EnableConfigurationProperties(IdempotentProperties.class)
@ConditionalOnProperty(prefix = PropertiesConstants.IDEMPOTENT, name = PropertiesConstants.ENABLED, havingValue = "true", matchIfMissing = true) @ConditionalOnProperty(prefix = PropertiesConstants.IDEMPOTENT, name = PropertiesConstants.ENABLED, havingValue = "true", matchIfMissing = true)
public class IdempotentAutoConfiguration { public class IdempotentAutoConfiguration {

View File

@@ -0,0 +1,7 @@
{
"top.continew.starter.idempotent.annotation.Idempotent@key":{
"method":{
"parameters": true
}
}
}

View File

@@ -3,19 +3,14 @@
<modelVersion>4.0.0</modelVersion> <modelVersion>4.0.0</modelVersion>
<parent> <parent>
<groupId>top.continew</groupId> <groupId>top.continew</groupId>
<artifactId>continew-starter-security</artifactId> <artifactId>continew-starter</artifactId>
<version>${revision}</version> <version>${revision}</version>
</parent> </parent>
<artifactId>continew-starter-security-limiter</artifactId> <artifactId>continew-starter-ratelimiter</artifactId>
<description>ContiNew Starter 安全模块 - 限流</description> <description>ContiNew Starter 限流模块</description>
<dependencies> <dependencies>
<dependency>
<groupId>org.springframework.boot</groupId>
<artifactId>spring-boot-starter-aop</artifactId>
</dependency>
<!-- Web 模块 --> <!-- Web 模块 -->
<dependency> <dependency>
<groupId>top.continew</groupId> <groupId>top.continew</groupId>

View File

@@ -14,9 +14,9 @@
* limitations under the License. * limitations under the License.
*/ */
package top.continew.starter.security.limiter.annotation; package top.continew.starter.ratelimiter.annotation;
import top.continew.starter.security.limiter.enums.LimitType; import top.continew.starter.ratelimiter.enums.LimitType;
import java.lang.annotation.*; import java.lang.annotation.*;
import java.util.concurrent.TimeUnit; import java.util.concurrent.TimeUnit;

View File

@@ -14,7 +14,7 @@
* limitations under the License. * limitations under the License.
*/ */
package top.continew.starter.security.limiter.annotation; package top.continew.starter.ratelimiter.annotation;
import java.lang.annotation.*; import java.lang.annotation.*;

View File

@@ -14,7 +14,7 @@
* limitations under the License. * limitations under the License.
*/ */
package top.continew.starter.security.limiter.core; package top.continew.starter.ratelimiter.aop;
import cn.hutool.core.convert.Convert; import cn.hutool.core.convert.Convert;
import cn.hutool.core.text.CharSequenceUtil; import cn.hutool.core.text.CharSequenceUtil;
@@ -27,15 +27,15 @@ import org.aspectj.lang.annotation.Aspect;
import org.aspectj.lang.annotation.Pointcut; import org.aspectj.lang.annotation.Pointcut;
import org.aspectj.lang.reflect.MethodSignature; import org.aspectj.lang.reflect.MethodSignature;
import org.redisson.api.*; import org.redisson.api.*;
import org.springframework.stereotype.Component;
import top.continew.starter.cache.redisson.util.RedisUtils; import top.continew.starter.cache.redisson.util.RedisUtils;
import top.continew.starter.core.constant.StringConstants; import top.continew.starter.core.constant.StringConstants;
import top.continew.starter.core.util.expression.ExpressionUtils; import top.continew.starter.core.util.expression.ExpressionUtils;
import top.continew.starter.security.limiter.annotation.RateLimiter; import top.continew.starter.ratelimiter.annotation.RateLimiter;
import top.continew.starter.security.limiter.annotation.RateLimiters; import top.continew.starter.ratelimiter.annotation.RateLimiters;
import top.continew.starter.security.limiter.autoconfigure.RateLimiterProperties; import top.continew.starter.ratelimiter.autoconfigure.RateLimiterProperties;
import top.continew.starter.security.limiter.enums.LimitType; import top.continew.starter.ratelimiter.generator.RateLimiterNameGenerator;
import top.continew.starter.security.limiter.exception.RateLimiterException; import top.continew.starter.ratelimiter.enums.LimitType;
import top.continew.starter.ratelimiter.exception.RateLimiterException;
import top.continew.starter.web.util.SpringWebUtils; import top.continew.starter.web.util.SpringWebUtils;
import java.lang.reflect.Method; import java.lang.reflect.Method;
@@ -51,7 +51,6 @@ import java.util.concurrent.ConcurrentHashMap;
* @since 2.2.0 * @since 2.2.0
*/ */
@Aspect @Aspect
@Component
public class RateLimiterAspect { public class RateLimiterAspect {
private static final ConcurrentHashMap<String, RRateLimiter> RATE_LIMITER_CACHE = new ConcurrentHashMap<>(); private static final ConcurrentHashMap<String, RRateLimiter> RATE_LIMITER_CACHE = new ConcurrentHashMap<>();
@@ -70,14 +69,14 @@ public class RateLimiterAspect {
/** /**
* 单个限流注解切点 * 单个限流注解切点
*/ */
@Pointcut("@annotation(top.continew.starter.security.limiter.annotation.RateLimiter)") @Pointcut("@annotation(top.continew.starter.ratelimiter.annotation.RateLimiter)")
public void rateLimiterPointCut() { public void rateLimiterPointCut() {
} }
/** /**
* 多个限流注解切点 * 多个限流注解切点
*/ */
@Pointcut("@annotation(top.continew.starter.security.limiter.annotation.RateLimiters)") @Pointcut("@annotation(top.continew.starter.ratelimiter.annotation.RateLimiters)")
public void rateLimitersPointCut() { public void rateLimitersPointCut() {
} }
@@ -144,23 +143,23 @@ public class RateLimiterAspect {
} }
/** /**
* 获取限流缓存 Key * 获取缓存 Key
* *
* @param joinPoint 切点 * @param joinPoint 切点
* @param rateLimiter 限流注解 * @param rateLimiter 限流注解
* @return 限流缓存 Key * @return 缓存 Key
*/ */
private String getCacheKey(JoinPoint joinPoint, RateLimiter rateLimiter) { private String getCacheKey(JoinPoint joinPoint, RateLimiter rateLimiter) {
Object target = joinPoint.getTarget(); Object target = joinPoint.getTarget();
MethodSignature methodSignature = (MethodSignature)joinPoint.getSignature(); MethodSignature methodSignature = (MethodSignature)joinPoint.getSignature();
Method method = methodSignature.getMethod(); Method method = methodSignature.getMethod();
Object[] args = joinPoint.getArgs(); Object[] args = joinPoint.getArgs();
// 获取限流名称 // 获取名称
String name = rateLimiter.name(); String name = rateLimiter.name();
if (CharSequenceUtil.isBlank(name)) { if (CharSequenceUtil.isBlank(name)) {
name = nameGenerator.generate(target, method, args); name = nameGenerator.generate(target, method, args);
} }
// 解析限流 Key // 解析 Key
String key = rateLimiter.key(); String key = rateLimiter.key();
if (CharSequenceUtil.isNotBlank(key)) { if (CharSequenceUtil.isNotBlank(key)) {
Object eval = ExpressionUtils.eval(key, target, method, args); Object eval = ExpressionUtils.eval(key, target, method, args);

View File

@@ -14,9 +14,10 @@
* limitations under the License. * limitations under the License.
*/ */
package top.continew.starter.security.limiter.autoconfigure; package top.continew.starter.ratelimiter.autoconfigure;
import jakarta.annotation.PostConstruct; import jakarta.annotation.PostConstruct;
import org.redisson.api.RedissonClient;
import org.slf4j.Logger; import org.slf4j.Logger;
import org.slf4j.LoggerFactory; import org.slf4j.LoggerFactory;
import org.springframework.boot.autoconfigure.AutoConfiguration; import org.springframework.boot.autoconfigure.AutoConfiguration;
@@ -24,10 +25,11 @@ import org.springframework.boot.autoconfigure.condition.ConditionalOnMissingBean
import org.springframework.boot.autoconfigure.condition.ConditionalOnProperty; import org.springframework.boot.autoconfigure.condition.ConditionalOnProperty;
import org.springframework.boot.context.properties.EnableConfigurationProperties; import org.springframework.boot.context.properties.EnableConfigurationProperties;
import org.springframework.context.annotation.Bean; import org.springframework.context.annotation.Bean;
import org.springframework.context.annotation.ComponentScan; import top.continew.starter.cache.redisson.autoconfigure.RedissonAutoConfiguration;
import top.continew.starter.core.constant.PropertiesConstants; import top.continew.starter.core.constant.PropertiesConstants;
import top.continew.starter.security.limiter.core.DefaultRateLimiterNameGenerator; import top.continew.starter.ratelimiter.aop.RateLimiterAspect;
import top.continew.starter.security.limiter.core.RateLimiterNameGenerator; import top.continew.starter.ratelimiter.generator.DefaultRateLimiterNameGenerator;
import top.continew.starter.ratelimiter.generator.RateLimiterNameGenerator;
/** /**
* 限流器自动配置 * 限流器自动配置
@@ -36,14 +38,23 @@ import top.continew.starter.security.limiter.core.RateLimiterNameGenerator;
* @author Charles7c * @author Charles7c
* @since 2.2.0 * @since 2.2.0
*/ */
@AutoConfiguration @AutoConfiguration(after = RedissonAutoConfiguration.class)
@EnableConfigurationProperties(RateLimiterProperties.class) @EnableConfigurationProperties(RateLimiterProperties.class)
@ComponentScan({"top.continew.starter.security.limiter.core"}) @ConditionalOnProperty(prefix = PropertiesConstants.RATE_LIMITER, name = PropertiesConstants.ENABLED, havingValue = "true", matchIfMissing = true)
@ConditionalOnProperty(prefix = PropertiesConstants.SECURITY_LIMITER, name = PropertiesConstants.ENABLED, havingValue = "true", matchIfMissing = true)
public class RateLimiterAutoConfiguration { public class RateLimiterAutoConfiguration {
private static final Logger log = LoggerFactory.getLogger(RateLimiterAutoConfiguration.class); private static final Logger log = LoggerFactory.getLogger(RateLimiterAutoConfiguration.class);
/**
* 限流器切面
*/
@Bean
public RateLimiterAspect rateLimiterAspect(RateLimiterProperties properties,
RateLimiterNameGenerator rateLimiterNameGenerator,
RedissonClient redissonClient) {
return new RateLimiterAspect(properties, rateLimiterNameGenerator, redissonClient);
}
/** /**
* 限流器名称生成器 * 限流器名称生成器
*/ */
@@ -55,6 +66,6 @@ public class RateLimiterAutoConfiguration {
@PostConstruct @PostConstruct
public void postConstruct() { public void postConstruct() {
log.debug("[ContiNew Starter] - Auto Configuration 'Security-RateLimiter' completed initialization."); log.debug("[ContiNew Starter] - Auto Configuration 'RateLimiter' completed initialization.");
} }
} }

View File

@@ -14,7 +14,7 @@
* limitations under the License. * limitations under the License.
*/ */
package top.continew.starter.security.limiter.autoconfigure; package top.continew.starter.ratelimiter.autoconfigure;
import org.springframework.boot.context.properties.ConfigurationProperties; import org.springframework.boot.context.properties.ConfigurationProperties;
import top.continew.starter.core.constant.PropertiesConstants; import top.continew.starter.core.constant.PropertiesConstants;
@@ -25,7 +25,7 @@ import top.continew.starter.core.constant.PropertiesConstants;
* @author KAI * @author KAI
* @since 2.2.0 * @since 2.2.0
*/ */
@ConfigurationProperties(PropertiesConstants.SECURITY_LIMITER) @ConfigurationProperties(PropertiesConstants.RATE_LIMITER)
public class RateLimiterProperties { public class RateLimiterProperties {
/** /**

View File

@@ -14,7 +14,7 @@
* limitations under the License. * limitations under the License.
*/ */
package top.continew.starter.security.limiter.enums; package top.continew.starter.ratelimiter.enums;
/** /**
* 限流类型 * 限流类型

View File

@@ -14,7 +14,7 @@
* limitations under the License. * limitations under the License.
*/ */
package top.continew.starter.security.limiter.exception; package top.continew.starter.ratelimiter.exception;
import top.continew.starter.core.exception.BaseException; import top.continew.starter.core.exception.BaseException;

View File

@@ -14,7 +14,7 @@
* limitations under the License. * limitations under the License.
*/ */
package top.continew.starter.security.limiter.core; package top.continew.starter.ratelimiter.generator;
import cn.hutool.core.util.ClassUtil; import cn.hutool.core.util.ClassUtil;
import top.continew.starter.core.constant.StringConstants; import top.continew.starter.core.constant.StringConstants;

View File

@@ -14,7 +14,7 @@
* limitations under the License. * limitations under the License.
*/ */
package top.continew.starter.security.limiter.core; package top.continew.starter.ratelimiter.generator;
import java.lang.reflect.Method; import java.lang.reflect.Method;

View File

@@ -0,0 +1 @@
top.continew.starter.ratelimiter.autoconfigure.RateLimiterAutoConfiguration

View File

@@ -0,0 +1,7 @@
{
"top.continew.starter.ratelimiter.annotation.RateLimiter@key":{
"method":{
"parameters": true
}
}
}

View File

@@ -1 +0,0 @@
top.continew.starter.security.limiter.autoconfigure.RateLimiterAutoConfiguration

View File

@@ -1,7 +0,0 @@
{
"top.continew.starter.security.limiter.annotation.RateLimiter@key":{
"method":{
"parameters": true
}
}
}

View File

@@ -17,7 +17,6 @@
<module>continew-starter-security-password</module> <module>continew-starter-security-password</module>
<module>continew-starter-security-mask</module> <module>continew-starter-security-mask</module>
<module>continew-starter-security-crypto</module> <module>continew-starter-security-crypto</module>
<module>continew-starter-security-limiter</module>
<module>continew-starter-security-sensitivewords</module> <module>continew-starter-security-sensitivewords</module>
</modules> </modules>

View File

@@ -71,8 +71,9 @@
<module>continew-starter-data</module> <module>continew-starter-data</module>
<module>continew-starter-auth</module> <module>continew-starter-auth</module>
<module>continew-starter-messaging</module> <module>continew-starter-messaging</module>
<module>continew-starter-extension</module> <module>continew-starter-ratelimiter</module>
<module>continew-starter-idempotent</module> <module>continew-starter-idempotent</module>
<module>continew-starter-extension</module>
</modules> </modules>
<build> <build>