提交 4cbc1462 编写于 作者: 无难事者若执's avatar 无难事者若执

doc : 【幂等】: 防重token令牌方案实现

- 使用默认内存token存储【后续实现redis】
- 使用请求依赖Const.REQUEST_TOKEN_VALUE_HOLDER 二维数组模拟请求参数传参数。【后续需要在web环境中,获取 请求Header中的token和服务中UserId】
上级 55dc95e4
...@@ -49,6 +49,11 @@ ...@@ -49,6 +49,11 @@
<groupId>org.springframework.boot</groupId> <groupId>org.springframework.boot</groupId>
<artifactId>spring-boot-starter-aop</artifactId> <artifactId>spring-boot-starter-aop</artifactId>
</dependency> </dependency>
<dependency>
<groupId>org.springframework.data</groupId>
<artifactId>spring-data-redis</artifactId>
<scope>provided</scope>
</dependency>
</dependencies> </dependencies>
......
package com.kx.config;
import org.springframework.boot.autoconfigure.condition.ConditionalOnClass;
import org.springframework.context.annotation.Configuration;
import org.springframework.data.redis.core.RedisOperations;
/**
* redis引入,工具类使用redis相关的配置
*
* @author kongxiang
*/
@Configuration(proxyBeanMethods = false)
@ConditionalOnClass(RedisOperations.class)
public class RedisAutoConfiguration {
}
...@@ -54,8 +54,10 @@ public class IdAlgorithmRegister { ...@@ -54,8 +54,10 @@ public class IdAlgorithmRegister {
}else { }else {
Integer[] arr = nameOrderMap.get(algorithm); Integer[] arr = nameOrderMap.get(algorithm);
if (arr[0] < orderValue){ if (arr[0] < orderValue){
arr[0] = orderValue;// 取较大的order // 取较大的order
arr[1] = i; // 更新下表 arr[0] = orderValue;
// 更新下表
arr[1] = i;
// nameOrderMap.put(algorithm,arr) ; // nameOrderMap.put(algorithm,arr) ;
}else if (arr[0 ] == orderValue){ }else if (arr[0 ] == orderValue){
// 如果order一致,比较类名的字符串字典大小,取大值 // 如果order一致,比较类名的字符串字典大小,取大值
......
...@@ -5,7 +5,6 @@ import com.kx.utils.idempotent.annotation.Idempotent; ...@@ -5,7 +5,6 @@ import com.kx.utils.idempotent.annotation.Idempotent;
import com.kx.utils.idempotent.bean.IdempotentProperties; import com.kx.utils.idempotent.bean.IdempotentProperties;
import com.kx.utils.idempotent.impl.AntiDuplicateTokenHandler; import com.kx.utils.idempotent.impl.AntiDuplicateTokenHandler;
import lombok.extern.slf4j.Slf4j; import lombok.extern.slf4j.Slf4j;
import org.aspectj.lang.JoinPoint;
import org.aspectj.lang.ProceedingJoinPoint; import org.aspectj.lang.ProceedingJoinPoint;
import org.aspectj.lang.annotation.Around; import org.aspectj.lang.annotation.Around;
import org.aspectj.lang.annotation.Aspect; import org.aspectj.lang.annotation.Aspect;
...@@ -17,8 +16,12 @@ import org.springframework.stereotype.Component; ...@@ -17,8 +16,12 @@ import org.springframework.stereotype.Component;
import org.springframework.util.StringUtils; import org.springframework.util.StringUtils;
import java.lang.reflect.Method; import java.lang.reflect.Method;
import java.util.function.DoubleToIntFunction;
/**
* 幂等注解切面
*
* @author kongxiang
*/
@Component @Component
@Aspect @Aspect
@Slf4j @Slf4j
...@@ -29,6 +32,7 @@ public class IdempotentAnnotationAspect { ...@@ -29,6 +32,7 @@ public class IdempotentAnnotationAspect {
@Autowired @Autowired
private TokenValueRequestHolder tokenValueRequestHolder; private TokenValueRequestHolder tokenValueRequestHolder;
/** /**
* aop 切面 * aop 切面
* \@annotation 所有注解的方法 * \@annotation 所有注解的方法
...@@ -40,7 +44,7 @@ public class IdempotentAnnotationAspect { ...@@ -40,7 +44,7 @@ public class IdempotentAnnotationAspect {
@Around(value = "condition()") @Around(value = "condition()")
public Object round(ProceedingJoinPoint joinPoint ) throws Throwable { public Object round(ProceedingJoinPoint joinPoint) throws Throwable {
// 获取执行的方法 // 获取执行的方法
MethodSignature methodSignature = (MethodSignature) joinPoint.getSignature(); MethodSignature methodSignature = (MethodSignature) joinPoint.getSignature();
Method method = methodSignature.getMethod(); Method method = methodSignature.getMethod();
...@@ -59,16 +63,16 @@ public class IdempotentAnnotationAspect { ...@@ -59,16 +63,16 @@ public class IdempotentAnnotationAspect {
log.debug("方法上注解存在 : " + (methodAnnotation != null)); log.debug("方法上注解存在 : " + (methodAnnotation != null));
log.debug("类上注解存在 : " + (classAnnotation != null)); log.debug("类上注解存在 : " + (classAnnotation != null));
IdempotentProperties idempotentProperties = getIdempotentPropertiesFromAnnotation(classAnnotation,methodAnnotation); IdempotentProperties idempotentProperties = getIdempotentPropertiesFromAnnotation(classAnnotation, methodAnnotation);
log.info("幂等配置: cacheKey : {}", idempotentProperties.getCacheKey()); log.info("幂等配置: cacheKey : {}", idempotentProperties.getCacheKey());
String token = tokenValueRequestHolder.getToken(); String token = tokenValueRequestHolder.getToken();
String value = tokenValueRequestHolder.getValidValue(); String value = tokenValueRequestHolder.getValidValue();
boolean validStatus = antiDuplicateTokenHandler.validToken(idempotentProperties,token, value); boolean validStatus = antiDuplicateTokenHandler.validToken(idempotentProperties, token, value);
if (validStatus){ if (validStatus) {
Object object = joinPoint.proceed(); Object object = joinPoint.proceed();
return object; return object;
}else { } else {
throw new RuntimeException("操作已经处理,请稍后再试"); throw new RuntimeException("操作已经处理,请稍后再试");
} }
} }
...@@ -80,34 +84,34 @@ public class IdempotentAnnotationAspect { ...@@ -80,34 +84,34 @@ public class IdempotentAnnotationAspect {
* @param classAnnotation 类上的Idempotent注解 * @param classAnnotation 类上的Idempotent注解
* @param methodAnnotation 方法 上的Idempotent注解 * @param methodAnnotation 方法 上的Idempotent注解
* @return 获取的幂等配置对象 * @return 获取的幂等配置对象
*
*/ */
private IdempotentProperties getIdempotentPropertiesFromAnnotation(Idempotent classAnnotation, Idempotent methodAnnotation) { private IdempotentProperties getIdempotentPropertiesFromAnnotation(Idempotent classAnnotation, Idempotent methodAnnotation) {
IdempotentProperties idempotentProperties = new IdempotentProperties(); IdempotentProperties idempotentProperties = new IdempotentProperties();
// 先加载类注解信息 // 先加载类注解信息
if (classAnnotation != null ){ if (classAnnotation != null) {
idempotentProperties = getIdempotentPropertiesFromAnnotation(idempotentProperties,classAnnotation); idempotentProperties = getIdempotentPropertiesFromAnnotation(idempotentProperties, classAnnotation);
} }
// 后加载方法上注解信息,如果有存在的配置,替换类上的 // 后加载方法上注解信息,如果有存在的配置,替换类上的
if (methodAnnotation != null){ if (methodAnnotation != null) {
idempotentProperties = getIdempotentPropertiesFromAnnotation(idempotentProperties,methodAnnotation); idempotentProperties = getIdempotentPropertiesFromAnnotation(idempotentProperties, methodAnnotation);
} }
return idempotentProperties; return idempotentProperties;
} }
/** /**
* 获取配置 * 获取配置
*
* @param annotation 注解 * @param annotation 注解
* @return 配置 * @return 配置
*/ */
private IdempotentProperties getIdempotentPropertiesFromAnnotation(IdempotentProperties idempotentProperties,Idempotent annotation ) { private IdempotentProperties getIdempotentPropertiesFromAnnotation(IdempotentProperties idempotentProperties, Idempotent annotation) {
if (annotation == null){ if (annotation == null) {
return new IdempotentProperties(); return new IdempotentProperties();
} }
if (idempotentProperties == null){ if (idempotentProperties == null) {
idempotentProperties = new IdempotentProperties(); idempotentProperties = new IdempotentProperties();
} }
if (!StringUtils.isEmpty(annotation.value())){ if (!StringUtils.isEmpty(annotation.value())) {
idempotentProperties.setCacheKey(annotation.value()); idempotentProperties.setCacheKey(annotation.value());
} }
return idempotentProperties; return idempotentProperties;
......
...@@ -3,4 +3,5 @@ ...@@ -3,4 +3,5 @@
org.springframework.boot.autoconfigure.EnableAutoConfiguration=\ org.springframework.boot.autoconfigure.EnableAutoConfiguration=\
com.kx.config.ConfigPropertiesAutoConfiguration,\ com.kx.config.ConfigPropertiesAutoConfiguration,\
com.kx.config.IdAutoConfiguration,\ com.kx.config.IdAutoConfiguration,\
com.kx.config.IdempotentAutoConfiguration com.kx.config.IdempotentAutoConfiguration,\
\ No newline at end of file com.kx.config.RedisAutoConfiguration
\ No newline at end of file
Markdown is supported
0% .
You are about to add 0 people to the discussion. Proceed with caution.
先完成此消息的编辑!
想要评论请 注册