diff --git a/pigx-common/pigx-common-idempotent/pom.xml b/pigx-common/pigx-common-idempotent/pom.xml
new file mode 100644
index 000000000..138424fe7
--- /dev/null
+++ b/pigx-common/pigx-common-idempotent/pom.xml
@@ -0,0 +1,41 @@
+
+
+ 4.0.0
+
+ com.pig4cloud
+ pigx-common
+ 4.2.0
+
+
+ pigx-common-idempotent
+ jar
+
+ pigx 幂等插件
+
+
+ 3.16.7
+
+
+
+
+
+ org.springframework.boot
+ spring-boot-starter-aop
+ provided
+
+
+
+
+ org.redisson
+ redisson-spring-boot-starter
+ ${redisson.version}
+
+
+
+
+ jakarta.servlet
+ jakarta.servlet-api
+
+
+
diff --git a/pigx-common/pigx-common-idempotent/src/main/java/com/pig4cloud/pigx/common/idempotent/IdempotentAutoConfiguration.java b/pigx-common/pigx-common-idempotent/src/main/java/com/pig4cloud/pigx/common/idempotent/IdempotentAutoConfiguration.java
new file mode 100644
index 000000000..451c9f499
--- /dev/null
+++ b/pigx-common/pigx-common-idempotent/src/main/java/com/pig4cloud/pigx/common/idempotent/IdempotentAutoConfiguration.java
@@ -0,0 +1,41 @@
+package com.pig4cloud.pigx.common.idempotent;
+
+import com.pig4cloud.pigx.common.idempotent.aspect.IdempotentAspect;
+import com.pig4cloud.pigx.common.idempotent.expression.ExpressionResolver;
+import com.pig4cloud.pigx.common.idempotent.expression.KeyResolver;
+import org.springframework.boot.autoconfigure.AutoConfigureAfter;
+import org.springframework.boot.autoconfigure.condition.ConditionalOnMissingBean;
+import org.springframework.boot.autoconfigure.data.redis.RedisAutoConfiguration;
+import org.springframework.context.annotation.Bean;
+import org.springframework.context.annotation.Configuration;
+
+/**
+ * @author lengleng
+ * @date 2020/9/25
+ *
+ * 幂等插件初始化
+ */
+@Configuration(proxyBeanMethods = false)
+@AutoConfigureAfter(RedisAutoConfiguration.class)
+public class IdempotentAutoConfiguration {
+
+ /**
+ * 切面 拦截处理所有 @Idempotent
+ * @return Aspect
+ */
+ @Bean
+ public IdempotentAspect idempotentAspect() {
+ return new IdempotentAspect();
+ }
+
+ /**
+ * key 解析器
+ * @return KeyResolver
+ */
+ @Bean
+ @ConditionalOnMissingBean(KeyResolver.class)
+ public KeyResolver keyResolver() {
+ return new ExpressionResolver();
+ }
+
+}
diff --git a/pigx-common/pigx-common-idempotent/src/main/java/com/pig4cloud/pigx/common/idempotent/annotation/Idempotent.java b/pigx-common/pigx-common-idempotent/src/main/java/com/pig4cloud/pigx/common/idempotent/annotation/Idempotent.java
new file mode 100644
index 000000000..b82cdf7fc
--- /dev/null
+++ b/pigx-common/pigx-common-idempotent/src/main/java/com/pig4cloud/pigx/common/idempotent/annotation/Idempotent.java
@@ -0,0 +1,44 @@
+package com.pig4cloud.pigx.common.idempotent.annotation;
+
+import java.lang.annotation.*;
+import java.util.concurrent.TimeUnit;
+
+/**
+ * @author ITyunqing
+ */
+@Inherited
+@Target(ElementType.METHOD)
+@Retention(value = RetentionPolicy.RUNTIME)
+public @interface Idempotent {
+
+ /**
+ * 幂等操作的唯一标识,使用spring el表达式 用#来引用方法参数
+ * @return Spring-EL expression
+ */
+ String key() default "";
+
+ /**
+ * 有效期 默认:1 有效期要大于程序执行时间,否则请求还是可能会进来
+ * @return expireTime
+ */
+ int expireTime() default 1;
+
+ /**
+ * 时间单位 默认:s
+ * @return TimeUnit
+ */
+ TimeUnit timeUnit() default TimeUnit.SECONDS;
+
+ /**
+ * 提示信息,可自定义
+ * @return String
+ */
+ String info() default "重复请求,请稍后重试";
+
+ /**
+ * 是否在业务完成后删除key true:删除 false:不删除
+ * @return boolean
+ */
+ boolean delKey() default false;
+
+}
diff --git a/pigx-common/pigx-common-idempotent/src/main/java/com/pig4cloud/pigx/common/idempotent/aspect/IdempotentAspect.java b/pigx-common/pigx-common-idempotent/src/main/java/com/pig4cloud/pigx/common/idempotent/aspect/IdempotentAspect.java
new file mode 100644
index 000000000..ab1b4b423
--- /dev/null
+++ b/pigx-common/pigx-common-idempotent/src/main/java/com/pig4cloud/pigx/common/idempotent/aspect/IdempotentAspect.java
@@ -0,0 +1,135 @@
+package com.pig4cloud.pigx.common.idempotent.aspect;
+
+import com.pig4cloud.pigx.common.idempotent.annotation.Idempotent;
+import com.pig4cloud.pigx.common.idempotent.expression.KeyResolver;
+import com.pig4cloud.pigx.common.idempotent.exception.IdempotentException;
+import org.aspectj.lang.JoinPoint;
+import org.aspectj.lang.annotation.After;
+import org.aspectj.lang.annotation.Aspect;
+import org.aspectj.lang.annotation.Before;
+import org.aspectj.lang.annotation.Pointcut;
+import org.aspectj.lang.reflect.MethodSignature;
+import org.redisson.Redisson;
+import org.redisson.api.RMapCache;
+import org.slf4j.Logger;
+import org.slf4j.LoggerFactory;
+import org.springframework.beans.factory.annotation.Autowired;
+import org.springframework.util.CollectionUtils;
+import org.springframework.util.StringUtils;
+import org.springframework.web.context.request.RequestContextHolder;
+import org.springframework.web.context.request.ServletRequestAttributes;
+
+import javax.servlet.http.HttpServletRequest;
+import java.lang.reflect.Method;
+import java.time.LocalDateTime;
+import java.util.Arrays;
+import java.util.HashMap;
+import java.util.Map;
+import java.util.concurrent.TimeUnit;
+
+/**
+ * The Idempotent Aspect
+ *
+ * @author ITyunqing
+ */
+@Aspect
+public class IdempotentAspect {
+
+ private static final Logger LOGGER = LoggerFactory.getLogger(IdempotentAspect.class);
+
+ private static final ThreadLocal