From c75a491bf5c53c644e90f2340cf687732457e39a Mon Sep 17 00:00:00 2001 From: =?UTF-8?q?=E5=86=B7=E5=86=B7?= <2270033969@qq.com> Date: Tue, 16 Jul 2024 18:11:04 +0800 Subject: [PATCH] =?UTF-8?q?refactor(common-idempotent):=20=E5=B9=82?= =?UTF-8?q?=E7=AD=89=E6=8F=92=E4=BB=B6=E9=87=8D=E6=9E=84@Idempotent?= =?UTF-8?q?=E9=BB=98=E8=AE=A4=E5=80=BC?= MIME-Version: 1.0 Content-Type: text/plain; charset=UTF-8 Content-Transfer-Encoding: 8bit 默认执行完后删除key 修改默认错误信息格式 --- .../IdempotentAutoConfiguration.java | 40 +++-- .../idempotent/annotation/Idempotent.java | 2 +- .../idempotent/aspect/IdempotentAspect.java | 165 ++++++++---------- 3 files changed, 100 insertions(+), 107 deletions(-) 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 index 451c9f499..b8ab16d3e 100644 --- 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 @@ -3,6 +3,7 @@ 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.redisson.Redisson; import org.springframework.boot.autoconfigure.AutoConfigureAfter; import org.springframework.boot.autoconfigure.condition.ConditionalOnMissingBean; import org.springframework.boot.autoconfigure.data.redis.RedisAutoConfiguration; @@ -19,23 +20,28 @@ import org.springframework.context.annotation.Configuration; @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(); - } + /** + * KEY解析器 + * + * @return {@link KeyResolver } + */ + @Bean + @ConditionalOnMissingBean(KeyResolver.class) + public KeyResolver keyResolver() { + return new ExpressionResolver(); + } + + /** + * 幂等方面 + * + * @param redisson redisson 客户端 + * @param keyResolver KEY解析器 + * @return {@link IdempotentAspect } + */ + @Bean + public IdempotentAspect idempotentAspect(Redisson redisson, KeyResolver keyResolver) { + return new IdempotentAspect(redisson, keyResolver); + } } 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 index b82cdf7fc..1b5f8bf38 100644 --- 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 @@ -39,6 +39,6 @@ public @interface Idempotent { * 是否在业务完成后删除key true:删除 false:不删除 * @return boolean */ - boolean delKey() default false; + boolean delKey() default true; } 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 index 2b4eb3637..8827be73d 100644 --- 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 @@ -1,10 +1,9 @@ package com.pig4cloud.pigx.common.idempotent.aspect; -import cn.hutool.core.util.StrUtil; -import com.pig4cloud.pigx.common.core.util.KeyStrResolver; import com.pig4cloud.pigx.common.idempotent.annotation.Idempotent; import com.pig4cloud.pigx.common.idempotent.exception.IdempotentException; import com.pig4cloud.pigx.common.idempotent.expression.KeyResolver; +import lombok.RequiredArgsConstructor; import org.aspectj.lang.JoinPoint; import org.aspectj.lang.annotation.After; import org.aspectj.lang.annotation.Aspect; @@ -15,7 +14,6 @@ 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; @@ -27,7 +25,6 @@ import java.time.LocalDateTime; import java.util.Arrays; import java.util.HashMap; import java.util.Map; -import java.util.Optional; import java.util.concurrent.TimeUnit; /** @@ -36,110 +33,100 @@ import java.util.concurrent.TimeUnit; * @author ITyunqing */ @Aspect +@RequiredArgsConstructor public class IdempotentAspect { - private static final Logger LOGGER = LoggerFactory.getLogger(IdempotentAspect.class); + private static final Logger LOGGER = LoggerFactory.getLogger(IdempotentAspect.class); - private static final ThreadLocal> THREAD_CACHE = ThreadLocal.withInitial(HashMap::new); + private static final ThreadLocal> THREAD_CACHE = ThreadLocal.withInitial(HashMap::new); - private static final String RMAPCACHE_KEY = "idempotent"; + private static final String RMAPCACHE_KEY = "idempotent"; - private static final String KEY = "key"; + private static final String KEY = "key"; - private static final String DELKEY = "delKey"; + private static final String DELKEY = "delKey"; - @Autowired - private Redisson redisson; + private final Redisson redisson; - @Autowired - private KeyResolver keyResolver; + private final KeyResolver keyResolver; - @Autowired - private Optional keyStrResolverOptional; + @Pointcut("@annotation(com.pig4cloud.pigx.common.idempotent.annotation.Idempotent)") + public void pointCut() { + } - @Pointcut("@annotation(com.pig4cloud.pigx.common.idempotent.annotation.Idempotent)") - public void pointCut() { - } + @Before("pointCut()") + public void beforePointCut(JoinPoint joinPoint) { + ServletRequestAttributes requestAttributes = (ServletRequestAttributes) RequestContextHolder + .getRequestAttributes(); + HttpServletRequest request = requestAttributes.getRequest(); - @Before("pointCut()") - public void beforePointCut(JoinPoint joinPoint) { - ServletRequestAttributes requestAttributes = (ServletRequestAttributes) RequestContextHolder - .getRequestAttributes(); - HttpServletRequest request = requestAttributes.getRequest(); + MethodSignature signature = (MethodSignature) joinPoint.getSignature(); + Method method = signature.getMethod(); + if (!method.isAnnotationPresent(Idempotent.class)) { + return; + } + Idempotent idempotent = method.getAnnotation(Idempotent.class); - MethodSignature signature = (MethodSignature) joinPoint.getSignature(); - Method method = signature.getMethod(); - if (!method.isAnnotationPresent(Idempotent.class)) { - return; - } - Idempotent idempotent = method.getAnnotation(Idempotent.class); + String key; - String key; + // 若没有配置 幂等 标识编号,则使用 url + 参数列表作为区分 + if (!StringUtils.hasLength(idempotent.key())) { + String url = request.getRequestURL().toString(); + String argString = Arrays.asList(joinPoint.getArgs()).toString(); + key = url + argString; + } else { + // 使用jstl 规则区分 + key = keyResolver.resolver(idempotent, joinPoint); + } - // 若没有配置 幂等 标识编号,则使用 url + 参数列表作为区分 - if (!StringUtils.hasLength(idempotent.key())) { - String url = request.getRequestURL().toString(); - String argString = Arrays.asList(joinPoint.getArgs()).toString(); - key = url + argString; - } - else { - // 使用jstl 规则区分 - key = keyResolver.resolver(idempotent, joinPoint); - } + long expireTime = idempotent.expireTime(); + String info = idempotent.info(); + TimeUnit timeUnit = idempotent.timeUnit(); + boolean delKey = idempotent.delKey(); - if (keyStrResolverOptional.isPresent()) { - key = keyStrResolverOptional.get().extract(key, StrUtil.COLON); - } + // do not need check null + RMapCache rMapCache = redisson.getMapCache(RMAPCACHE_KEY); + String value = LocalDateTime.now().toString().replace("T", " "); + Object v1; + if (null != rMapCache.get(key)) { + // had stored + throw new IdempotentException(info); + } + synchronized (this) { + v1 = rMapCache.putIfAbsent(key, value, expireTime, timeUnit); + if (null != v1) { + throw new IdempotentException(info); + } else { + LOGGER.info("[idempotent]:has stored key={},value={},expireTime={}{},now={}", key, value, expireTime, + timeUnit, LocalDateTime.now().toString()); + } + } - long expireTime = idempotent.expireTime(); - String info = idempotent.info(); - TimeUnit timeUnit = idempotent.timeUnit(); - boolean delKey = idempotent.delKey(); + Map map = THREAD_CACHE.get(); + map.put(KEY, key); + map.put(DELKEY, delKey); + } - // do not need check null - RMapCache rMapCache = redisson.getMapCache(RMAPCACHE_KEY); - String value = LocalDateTime.now().toString().replace("T", " "); - Object v1; - if (null != rMapCache.get(key)) { - // had stored - throw new IdempotentException("[idempotent]:" + info); - } - synchronized (this) { - v1 = rMapCache.putIfAbsent(key, value, expireTime, timeUnit); - if (null != v1) { - throw new IdempotentException("[idempotent]:" + info); - } - else { - LOGGER.info("[idempotent]:has stored key={},value={},expireTime={}{},now={}", key, value, expireTime, - timeUnit, LocalDateTime.now().toString()); - } - } + @After("pointCut()") + public void afterPointCut(JoinPoint joinPoint) { + Map map = THREAD_CACHE.get(); + if (CollectionUtils.isEmpty(map)) { + return; + } - Map map = THREAD_CACHE.get(); - map.put(KEY, key); - map.put(DELKEY, delKey); - } + RMapCache mapCache = redisson.getMapCache(RMAPCACHE_KEY); + if (mapCache.isEmpty()) { + return; + } - @After("pointCut()") - public void afterPointCut(JoinPoint joinPoint) { - Map map = THREAD_CACHE.get(); - if (CollectionUtils.isEmpty(map)) { - return; - } + String key = map.get(KEY).toString(); + boolean delKey = (boolean) map.get(DELKEY); - RMapCache mapCache = redisson.getMapCache(RMAPCACHE_KEY); - if (mapCache.size() == 0) { - return; - } - - String key = map.get(KEY).toString(); - boolean delKey = (boolean) map.get(DELKEY); - - if (delKey) { - mapCache.fastRemove(key); - LOGGER.info("[idempotent]:has removed key={}", key); - } - THREAD_CACHE.remove(); - } + if (delKey) { + mapCache.fastRemove(key); + LOGGER.info("[idempotent]:has removed key={}", key); + } + THREAD_CACHE.remove(); + } }