diff --git a/continew-starter-core/src/main/java/top/continew/starter/core/constant/PropertiesConstants.java b/continew-starter-core/src/main/java/top/continew/starter/core/constant/PropertiesConstants.java
index a40318c3..c99f5e1e 100644
--- a/continew-starter-core/src/main/java/top/continew/starter/core/constant/PropertiesConstants.java
+++ b/continew-starter-core/src/main/java/top/continew/starter/core/constant/PropertiesConstants.java
@@ -139,6 +139,11 @@ public class PropertiesConstants {
*/
public static final String TENANT = CONTINEW_STARTER + StringConstants.DOT + "tenant";
+ /**
+ * 幂等配置
+ */
+ public static final String IDEMPOTENT = "idempotent";
+
private PropertiesConstants() {
}
}
diff --git a/continew-starter-idempotent/pom.xml b/continew-starter-idempotent/pom.xml
index e29bcb4f..3e908fa0 100644
--- a/continew-starter-idempotent/pom.xml
+++ b/continew-starter-idempotent/pom.xml
@@ -13,45 +13,15 @@
+ * 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 + *
+ * http://www.gnu.org/licenses/lgpl.html + *
+ * 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.idempotent.aop; + +import cn.hutool.core.convert.Convert; +import cn.hutool.core.text.CharSequenceUtil; +import cn.hutool.core.util.ObjectUtil; +import org.aspectj.lang.ProceedingJoinPoint; +import org.aspectj.lang.annotation.Around; +import org.aspectj.lang.annotation.Aspect; +import org.aspectj.lang.reflect.MethodSignature; +import top.continew.starter.cache.redisson.util.RedisUtils; +import top.continew.starter.core.util.expression.ExpressionUtils; +import top.continew.starter.idempotent.annotation.Idempotent; +import top.continew.starter.idempotent.autoconfigure.IdempotentProperties; +import top.continew.starter.idempotent.exception.IdempotentException; +import top.continew.starter.idempotent.generator.IdempotentNameGenerator; + +import java.lang.reflect.Method; +import java.time.Duration; + +/** + * 幂等切面 + * + * @author loach + * @author Charles7c + * @since 2.10.0 + */ +@Aspect +public class IdempotentAspect { + + private final IdempotentProperties properties; + private final IdempotentNameGenerator nameGenerator; + + public IdempotentAspect(IdempotentProperties properties, IdempotentNameGenerator nameGenerator) { + this.properties = properties; + this.nameGenerator = nameGenerator; + } + + /** + * 幂等处理 + * + * @param joinPoint 切点 + * @param idempotent 幂等注解 + * @return 目标方法的执行结果 + * @throws Throwable / + */ + @Around("@annotation(idempotent)") + public Object around(ProceedingJoinPoint joinPoint, Idempotent idempotent) throws Throwable { + String cacheKey = this.getCacheKey(joinPoint, idempotent); + // 如果键已存在,则抛出异常 + if (!RedisUtils.setIfAbsent(cacheKey, Duration.ofMillis(idempotent.unit().toMillis(idempotent.timeout())))) { + throw new IdempotentException(idempotent.message()); + } + // 执行目标方法 + try { + return joinPoint.proceed(); + } catch (Throwable e) { + // 删除键 + RedisUtils.delete(cacheKey); + throw e; + } + } + + /** + * 获取缓存 Key + * + * @param joinPoint 切点 + * @param idempotent 幂等注解 + * @return 缓存 Key + */ + private String getCacheKey(ProceedingJoinPoint joinPoint, Idempotent idempotent) { + Object target = joinPoint.getTarget(); + MethodSignature methodSignature = (MethodSignature)joinPoint.getSignature(); + Method method = methodSignature.getMethod(); + Object[] args = joinPoint.getArgs(); + // 获取名称 + String name = idempotent.name(); + if (CharSequenceUtil.isBlank(name)) { + name = nameGenerator.generate(target, method, args); + } + // 解析 Key + String key = idempotent.key(); + if (CharSequenceUtil.isNotBlank(key)) { + Object eval = ExpressionUtils.eval(key, target, method, args); + if (ObjectUtil.isNull(eval)) { + throw new IdempotentException("幂等 Key 解析错误"); + } + key = Convert.toStr(eval); + } + return RedisUtils.formatKey(properties.getKeyPrefix(), name, key); + } +} \ No newline at end of file diff --git a/continew-starter-idempotent/src/main/java/top/continew/starter/idempotent/aspect/IdempotentAspect.java b/continew-starter-idempotent/src/main/java/top/continew/starter/idempotent/aspect/IdempotentAspect.java deleted file mode 100644 index 72dcb16a..00000000 --- a/continew-starter-idempotent/src/main/java/top/continew/starter/idempotent/aspect/IdempotentAspect.java +++ /dev/null @@ -1,71 +0,0 @@ -/* - * Copyright (c) 2022-present Charles7c Authors. All Rights Reserved. - *
- * 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 - *
- * http://www.gnu.org/licenses/lgpl.html - *
- * 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.idempotent.aspect; - -import jakarta.servlet.http.HttpServletRequest; -import org.aspectj.lang.ProceedingJoinPoint; -import org.aspectj.lang.annotation.Around; -import org.aspectj.lang.annotation.Aspect; -import org.springframework.web.context.request.RequestContextHolder; -import org.springframework.web.context.request.ServletRequestAttributes; -import top.continew.starter.idempotent.annotation.Idempotent; -import top.continew.starter.idempotent.service.IdempotentService; -import top.continew.starter.idempotent.util.IdempotentKeyGenerator; - -/** - * 注解切面 - * - * @version 1.0 - * @Author loach - * @Date 2025-03-07 19:27 - * @Package top.continew.starter.idempotent.aspect.IdempotentAspect - */ -@Aspect -public class IdempotentAspect { - - private final IdempotentService idempotentService; - - public IdempotentAspect(IdempotentService idempotentService) { - this.idempotentService = idempotentService; - } - - /** - * AspectJ 环绕通知 - * - * @param joinPoint 切点 - * @param idempotent 注解 - * @return - * @throws Throwable - */ - @Around("@annotation(idempotent)") - public Object around(ProceedingJoinPoint joinPoint, Idempotent idempotent) throws Throwable { - HttpServletRequest request = ((ServletRequestAttributes)RequestContextHolder.getRequestAttributes()) - .getRequest(); - String key = IdempotentKeyGenerator.generateKey(idempotent.prefix(), joinPoint, request); - - try { - if (!idempotentService.checkAndLock(key, idempotent.timeout())) { - throw new RuntimeException(idempotent.message()); - } - return joinPoint.proceed(); - } catch (Exception e) { - throw new RuntimeException(e); - } finally { - idempotentService.unlock(key); - } - } -} \ No newline at end of file diff --git a/continew-starter-idempotent/src/main/java/top/continew/starter/idempotent/autoconfigure/IdempotentAutoConfiguration.java b/continew-starter-idempotent/src/main/java/top/continew/starter/idempotent/autoconfigure/IdempotentAutoConfiguration.java new file mode 100644 index 00000000..401541f2 --- /dev/null +++ b/continew-starter-idempotent/src/main/java/top/continew/starter/idempotent/autoconfigure/IdempotentAutoConfiguration.java @@ -0,0 +1,73 @@ +/* + * Copyright (c) 2022-present Charles7c Authors. All Rights Reserved. + *
+ * 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 + *
+ * http://www.gnu.org/licenses/lgpl.html + *
+ * 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.idempotent.autoconfigure; + +import jakarta.annotation.PostConstruct; +import org.slf4j.Logger; +import org.slf4j.LoggerFactory; +import org.springframework.beans.factory.NoSuchBeanDefinitionException; +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.core.ResolvableType; +import top.continew.starter.core.constant.PropertiesConstants; +import top.continew.starter.idempotent.aop.IdempotentAspect; +import top.continew.starter.idempotent.generator.IdempotentNameGenerator; + +/** + * 幂等自动配置 + * + * @author loach + * @author Charles7c + * @since 2.10.0 + */ +@AutoConfiguration +@EnableConfigurationProperties(IdempotentProperties.class) +@ConditionalOnProperty(prefix = PropertiesConstants.IDEMPOTENT, name = PropertiesConstants.ENABLED, havingValue = "true", matchIfMissing = true) +public class IdempotentAutoConfiguration { + + private static final Logger log = LoggerFactory.getLogger(IdempotentAutoConfiguration.class); + + /** + * 幂等切面 + */ + @Bean + public IdempotentAspect idempotentAspect(IdempotentProperties properties, + IdempotentNameGenerator idempotentNameGenerator) { + return new IdempotentAspect(properties, idempotentNameGenerator); + } + + /** + * 幂等名称生成器 + */ + @Bean + @ConditionalOnMissingBean + public IdempotentNameGenerator idempotentNameGenerator() { + if (log.isErrorEnabled()) { + log.error("Consider defining a bean of type '{}' in your configuration.", ResolvableType + .forClass(IdempotentNameGenerator.class)); + } + throw new NoSuchBeanDefinitionException(IdempotentNameGenerator.class); + } + + @PostConstruct + public void postConstruct() { + log.debug("[ContiNew Starter] - Auto Configuration 'Idempotent' completed initialization."); + } +} \ No newline at end of file diff --git a/continew-starter-idempotent/src/main/java/top/continew/starter/idempotent/autoconfigure/IdempotentProperties.java b/continew-starter-idempotent/src/main/java/top/continew/starter/idempotent/autoconfigure/IdempotentProperties.java new file mode 100644 index 00000000..c8245abb --- /dev/null +++ b/continew-starter-idempotent/src/main/java/top/continew/starter/idempotent/autoconfigure/IdempotentProperties.java @@ -0,0 +1,44 @@ +/* + * Copyright (c) 2022-present Charles7c Authors. All Rights Reserved. + *
+ * 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 + *
+ * http://www.gnu.org/licenses/lgpl.html + *
+ * 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.idempotent.autoconfigure; + +import org.springframework.boot.context.properties.ConfigurationProperties; +import top.continew.starter.core.constant.PropertiesConstants; + +/** + * 幂等配置属性 + * + * @author loach + * @author Charles7c + * @since 2.10.0 + */ +@ConfigurationProperties(PropertiesConstants.IDEMPOTENT) +public class IdempotentProperties { + + /** + * Key 前缀 + */ + private String keyPrefix = "Idempotent"; + + public String getKeyPrefix() { + return keyPrefix; + } + + public void setKeyPrefix(String keyPrefix) { + this.keyPrefix = keyPrefix; + } +} diff --git a/continew-starter-idempotent/src/main/java/top/continew/starter/idempotent/config/IdempotentAutoConfiguration.java b/continew-starter-idempotent/src/main/java/top/continew/starter/idempotent/config/IdempotentAutoConfiguration.java deleted file mode 100644 index d00b1524..00000000 --- a/continew-starter-idempotent/src/main/java/top/continew/starter/idempotent/config/IdempotentAutoConfiguration.java +++ /dev/null @@ -1,73 +0,0 @@ -/* - * Copyright (c) 2022-present Charles7c Authors. All Rights Reserved. - *
- * 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 - *
- * http://www.gnu.org/licenses/lgpl.html - *
- * 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.idempotent.config; - -import org.springframework.beans.factory.annotation.Autowired; -import org.springframework.boot.autoconfigure.condition.ConditionalOnBean; -import org.springframework.boot.autoconfigure.condition.ConditionalOnMissingBean; -import org.springframework.boot.context.properties.EnableConfigurationProperties; -import org.springframework.context.annotation.Bean; -import org.springframework.context.annotation.Configuration; -import org.springframework.data.redis.core.StringRedisTemplate; -import top.continew.starter.idempotent.aspect.IdempotentAspect; -import top.continew.starter.idempotent.service.IdempotentService; -import top.continew.starter.idempotent.service.impl.MemoryIdempotentServiceImpl; -import top.continew.starter.idempotent.service.impl.RedisIdempotentServiceImpl; - -/** - * 引用配置:暂定默认内存实现,扫描到启用redis 使用redis实现 - * - * @version 1.0 - * @Author loach - * @Date 2025-03-07 20:03 - * @Package top.continew.starter.idempotent.config.IdempotentAutoConfiguration - */ -@Configuration -@EnableConfigurationProperties(IdempotentProperties.class) -public class IdempotentAutoConfiguration { - - @Autowired - private IdempotentService idempotentService; - - private final IdempotentProperties properties; - - public IdempotentAutoConfiguration(IdempotentProperties properties) { - this.properties = properties; - } - - @Bean - public IdempotentAspect idempotentAspect(IdempotentService idempotentService) { - return new IdempotentAspect(idempotentService); - } - - @Bean(name = "redisIdempotentService") - @ConditionalOnBean(StringRedisTemplate.class) - public IdempotentService redisIdempotentService(StringRedisTemplate redisTemplate) { - return new RedisIdempotentServiceImpl(redisTemplate, properties.getRedisTimeout()); - } - - @Bean - @ConditionalOnMissingBean(IdempotentService.class) - public IdempotentService memoryIdempotentService() { - return new MemoryIdempotentServiceImpl(properties.getCleanInterval()); - } - - @Bean - public IdempotentProperties idempotentProperties() { - return new IdempotentProperties(); - } -} \ No newline at end of file diff --git a/continew-starter-idempotent/src/main/java/top/continew/starter/idempotent/config/IdempotentProperties.java b/continew-starter-idempotent/src/main/java/top/continew/starter/idempotent/config/IdempotentProperties.java deleted file mode 100644 index d4b7701f..00000000 --- a/continew-starter-idempotent/src/main/java/top/continew/starter/idempotent/config/IdempotentProperties.java +++ /dev/null @@ -1,53 +0,0 @@ -/* - * Copyright (c) 2022-present Charles7c Authors. All Rights Reserved. - *
- * 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 - *
- * http://www.gnu.org/licenses/lgpl.html - *
- * 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.idempotent.config; - -import org.springframework.boot.context.properties.ConfigurationProperties; - -/** - * 属性配置类 - * - * @version 1.0 - * @Author loach - * @Date 2025-03-07 19:27 - * @Package top.continew.starter.idempotent.config.IdempotentProperties - */ -@ConfigurationProperties(prefix = "idempotent") -public class IdempotentProperties { - - // 内存实现清理过期 key 的间隔(毫秒)默认5分钟 - private long cleanInterval = 300000; - - // redis实现过期 key 的间隔(毫秒)默认5分钟 - private long redisTimeout = 300000; - - public long getCleanInterval() { - return cleanInterval; - } - - public void setCleanInterval(long cleanInterval) { - this.cleanInterval = cleanInterval; - } - - public long getRedisTimeout() { - return redisTimeout; - } - - public void setRedisTimeout(long redisTimeout) { - this.redisTimeout = redisTimeout; - } -} diff --git a/continew-starter-idempotent/src/main/java/top/continew/starter/idempotent/config/MemoryIdempotentSchedulingConfig.java b/continew-starter-idempotent/src/main/java/top/continew/starter/idempotent/config/MemoryIdempotentSchedulingConfig.java deleted file mode 100644 index f4970c4a..00000000 --- a/continew-starter-idempotent/src/main/java/top/continew/starter/idempotent/config/MemoryIdempotentSchedulingConfig.java +++ /dev/null @@ -1,49 +0,0 @@ -/* - * Copyright (c) 2022-present Charles7c Authors. All Rights Reserved. - *
- * 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 - *
- * http://www.gnu.org/licenses/lgpl.html - *
- * 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.idempotent.config; - -import org.springframework.beans.factory.annotation.Autowired; -import org.springframework.boot.autoconfigure.condition.ConditionalOnMissingBean; -import org.springframework.context.annotation.Configuration; -import org.springframework.scheduling.annotation.EnableScheduling; -import org.springframework.scheduling.annotation.Scheduled; -import top.continew.starter.idempotent.service.IdempotentService; -import top.continew.starter.idempotent.service.impl.MemoryIdempotentServiceImpl; - -/** - * 内存定时任务配置类 - * - * @version 1.0 - * @Author loach - * @Date 2025-03-07 22:26 - * @Package top.continew.starter.idempotent.config.MemoryIdempotentSchedulingConfig - */ -@Configuration -@ConditionalOnMissingBean(name = "redisIdempotentService") // 当 Redis Bean 不存在时启用 -@EnableScheduling -public class MemoryIdempotentSchedulingConfig { - - @Autowired - private IdempotentService idempotentService; - - @Scheduled(fixedRateString = "${idempotent.clean-interval:60000}") - public void cleanExpiredKeys() { - if (idempotentService instanceof MemoryIdempotentServiceImpl) { - ((MemoryIdempotentServiceImpl)idempotentService).cleanExpiredKeys(); - } - } -} diff --git a/continew-starter-idempotent/src/main/java/top/continew/starter/idempotent/exception/IdempotentException.java b/continew-starter-idempotent/src/main/java/top/continew/starter/idempotent/exception/IdempotentException.java new file mode 100644 index 00000000..5ccbceac --- /dev/null +++ b/continew-starter-idempotent/src/main/java/top/continew/starter/idempotent/exception/IdempotentException.java @@ -0,0 +1,36 @@ +/* + * Copyright (c) 2022-present Charles7c Authors. All Rights Reserved. + *
+ * 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 + *
+ * http://www.gnu.org/licenses/lgpl.html + *
+ * 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.idempotent.exception; + +import top.continew.starter.core.exception.BaseException; + +/** + * 幂等异常 + * + * @author Charles7c + * @since 2.10.0 + */ +public class IdempotentException extends BaseException { + + public IdempotentException(String message) { + super(message); + } + + public IdempotentException(String message, Throwable cause) { + super(message, cause); + } +} diff --git a/continew-starter-idempotent/src/main/java/top/continew/starter/idempotent/service/IdempotentService.java b/continew-starter-idempotent/src/main/java/top/continew/starter/idempotent/generator/IdempotentNameGenerator.java similarity index 57% rename from continew-starter-idempotent/src/main/java/top/continew/starter/idempotent/service/IdempotentService.java rename to continew-starter-idempotent/src/main/java/top/continew/starter/idempotent/generator/IdempotentNameGenerator.java index 2fc6e089..877765dd 100644 --- a/continew-starter-idempotent/src/main/java/top/continew/starter/idempotent/service/IdempotentService.java +++ b/continew-starter-idempotent/src/main/java/top/continew/starter/idempotent/generator/IdempotentNameGenerator.java @@ -14,31 +14,26 @@ * limitations under the License. */ -package top.continew.starter.idempotent.service; +package top.continew.starter.idempotent.generator; + +import java.lang.reflect.Method; /** - * 服务接口 + * 幂等名称生成器 * - * @version 1.0 - * @Author loach - * @Date 2025-03-07 19:48 - * @Package top.continew.starter.idempotent.service.IdempotentService + * @author loach + * @author Charles7c + * @since 2.10.0 */ -public interface IdempotentService { +public interface IdempotentNameGenerator { /** - * 检验是否存在 + * 生成幂等名称 * - * @param key 幂等key - * @param timeout 超时时间 - * @return + * @param target 目标实例 + * @param method 目标方法 + * @param args 方法参数 + * @return 幂等名称 */ - boolean checkAndLock(String key, long timeout); - - /** - * 释放对应key - * - * @param key 幂等key - */ - void unlock(String key); + String generate(Object target, Method method, Object... args); } \ No newline at end of file diff --git a/continew-starter-idempotent/src/main/java/top/continew/starter/idempotent/service/impl/MemoryIdempotentServiceImpl.java b/continew-starter-idempotent/src/main/java/top/continew/starter/idempotent/service/impl/MemoryIdempotentServiceImpl.java deleted file mode 100644 index 2b8108c9..00000000 --- a/continew-starter-idempotent/src/main/java/top/continew/starter/idempotent/service/impl/MemoryIdempotentServiceImpl.java +++ /dev/null @@ -1,74 +0,0 @@ -/* - * Copyright (c) 2022-present Charles7c Authors. All Rights Reserved. - *
- * 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 - *
- * http://www.gnu.org/licenses/lgpl.html - *
- * 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.idempotent.service.impl;
-
-import top.continew.starter.idempotent.service.IdempotentService;
-
-import java.util.concurrent.ConcurrentHashMap;
-import java.util.concurrent.TimeUnit;
-
-/**
- * 内存实现幂等
- *
- * @version 1.0
- * @Author loach
- * @Date 2025-03-07 19:49
- * @Package top.continew.starter.idempotent.service.impl.MemoryIdempotentServiceImpl
- */
-public class MemoryIdempotentServiceImpl implements IdempotentService {
-
- private final ConcurrentHashMap
- * 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
- *
- * http://www.gnu.org/licenses/lgpl.html
- *
- * 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.idempotent.service.impl;
-
-import org.springframework.data.redis.core.StringRedisTemplate;
-import top.continew.starter.idempotent.service.IdempotentService;
-
-import java.util.concurrent.TimeUnit;
-
-/**
- * redis实现幂等
- *
- * @version 1.0
- * @Author loach
- * @Date 2025-03-07 19:49
- * @Package top.continew.starter.idempotent.service.impl.RedisIdempotentServiceImpl
- */
-
-public class RedisIdempotentServiceImpl implements IdempotentService {
-
- private final StringRedisTemplate redisTemplate;
- private final long redisTimeout;
-
- public RedisIdempotentServiceImpl(StringRedisTemplate redisTemplate, long redisTimeout) {
- this.redisTemplate = redisTemplate;
- this.redisTimeout = redisTimeout;
- }
-
- @Override
- public boolean checkAndLock(String key, long timeout) {
- long effectiveTimeout = timeout > 0 ? timeout : redisTimeout;
- Boolean success = redisTemplate.opsForValue().setIfAbsent(key, "1", effectiveTimeout, TimeUnit.SECONDS);
- return success != null && success;
- }
-
- @Override
- public void unlock(String key) {
- redisTemplate.delete(key);
- }
-}
\ No newline at end of file
diff --git a/continew-starter-idempotent/src/main/java/top/continew/starter/idempotent/util/IdempotentKeyGenerator.java b/continew-starter-idempotent/src/main/java/top/continew/starter/idempotent/util/IdempotentKeyGenerator.java
deleted file mode 100644
index 3c303a54..00000000
--- a/continew-starter-idempotent/src/main/java/top/continew/starter/idempotent/util/IdempotentKeyGenerator.java
+++ /dev/null
@@ -1,57 +0,0 @@
-/*
- * Copyright (c) 2022-present Charles7c Authors. All Rights Reserved.
- *
- * 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
- *
- * http://www.gnu.org/licenses/lgpl.html
- *
- * 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.idempotent.util;
-
-import jakarta.servlet.http.HttpServletRequest;
-import org.aspectj.lang.JoinPoint;
-import org.springframework.util.DigestUtils;
-
-import java.util.Arrays;
-
-/**
- * 定义幂等key工具类
- *
- * @version 1.0
- * @Author loach
- * @Date 2025-03-07 20:13
- * @Package top.continew.starter.idempotent.util.IdempotentKeyGenerator
- */
-public class IdempotentKeyGenerator {
-
- /**
- * 创建key
- *
- * @param prefix 幂等key前缀
- * @param joinPoint 切面参数
- * @param request 请求头
- * @return
- */
- public static String generateKey(String prefix, JoinPoint joinPoint, HttpServletRequest request) {
- // 可选使用header中的token
- String token = request.getHeader("Authorization");
- if (token == null || token.isEmpty()) {
- token = request.getParameter("Authorization");
- }
-
- String methodSignature = joinPoint.getSignature().toString();
- String argsStr = Arrays.toString(joinPoint.getArgs());
-
- // 如果没有token,只使用方法签名和参数生成key
- String rawKey = prefix + methodSignature + argsStr + (token != null ? token : "");
- return DigestUtils.md5DigestAsHex(rawKey.getBytes());
- }
-}
\ No newline at end of file
diff --git a/continew-starter-idempotent/src/main/resources/META-INF/spring/org.springframework.boot.autoconfigure.AutoConfiguration.imports b/continew-starter-idempotent/src/main/resources/META-INF/spring/org.springframework.boot.autoconfigure.AutoConfiguration.imports
index b0505757..958e1f69 100644
--- a/continew-starter-idempotent/src/main/resources/META-INF/spring/org.springframework.boot.autoconfigure.AutoConfiguration.imports
+++ b/continew-starter-idempotent/src/main/resources/META-INF/spring/org.springframework.boot.autoconfigure.AutoConfiguration.imports
@@ -1,2 +1 @@
-top.continew.starter.idempotent.config.IdempotentAutoConfiguration
-top.continew.starter.idempotent.config.MemoryIdempotentSchedulingConfig
\ No newline at end of file
+top.continew.starter.idempotent.autoconfigure.IdempotentAutoConfiguration
\ No newline at end of file