com.ideaaedi.commonspring.spi.AbstractAntiDuplicateExecutor Maven / Gradle / Ivy
package com.ideaaedi.commonspring.spi;
import com.ideaaedi.commonspring.aop.ParameterRecorderAdvice;
import com.ideaaedi.commonspring.lite.antidupli.AntiDuplication;
import com.ideaaedi.commonspring.parser.SpelUtil;
import org.aopalliance.intercept.MethodInvocation;
import org.apache.commons.lang3.StringUtils;
import org.springframework.core.annotation.AnnotationUtils;
import org.springframework.lang.NonNull;
import org.springframework.lang.Nullable;
import java.lang.annotation.Annotation;
import java.lang.reflect.Method;
import java.util.Arrays;
import java.util.Map;
import java.util.Objects;
import java.util.concurrent.TimeUnit;
/**
* 防重执行器
*
* @author JustryDeng
* @since 2100.7.3
*/
public abstract class AbstractAntiDuplicateExecutor implements AntiDuplicateExecutor {
@Override
public int adviceOrder() {
return ParameterRecorderAdvice.order + 1;
}
@Override
public String exec(@NonNull MethodInvocation invocation) {
Method method = invocation.getMethod();
Objects.requireNonNull(method, "method should not be null.");
Object[] arguments = invocation.getArguments();
Objects.requireNonNull(arguments, "arguments should not be null.");
Annotation[] annotations = method.getAnnotations();
AntiDuplication antiDuplication = AnnotationUtils.getAnnotation(method, AntiDuplication.class);
Objects.requireNonNull(antiDuplication, "antiDuplication should not be null.");
// 实际注解类型。要么为AntiDuplication注解,要么为AntiDuplication的子注解
Annotation actualAntiDuplication = Arrays.stream(annotations).filter((Annotation annotation) -> {
if (annotation.annotationType() == AntiDuplication.class) {
return true;
}
return annotation.annotationType().isAnnotationPresent(AntiDuplication.class);
}
).findFirst().orElseThrow(() -> new IllegalStateException("Obtain actualAntiDuplication fail."));
Map antiDuplicationAttributes = AnnotationUtils.getAnnotationAttributes(actualAntiDuplication);
if (actualAntiDuplication != antiDuplication) {
Map annotationAttributes = AnnotationUtils.getAnnotationAttributes(antiDuplication);
annotationAttributes.forEach(antiDuplicationAttributes::putIfAbsent);
}
String spel = (String)antiDuplicationAttributes.get("spel");
long during = (long)antiDuplicationAttributes.get("during");
TimeUnit unit = (TimeUnit)antiDuplicationAttributes.get("unit");
String message = (String)antiDuplicationAttributes.get("message");
String spelVal;
if (StringUtils.isNotBlank(spel) && spel.contains("#")) {
Object spelValObj = SpelUtil.parseSpel(method, arguments, Object.class, spel);
spelVal = spelValObj == null ? null : spelValObj.toString();
} else {
spelVal = spel;
}
long duringSeconds = unit.toSeconds(during);
return doExec(spelVal, duringSeconds, message);
}
@Override
public void doFinally(Throwable throwable, String execResult, Object targetPointResult) {
}
/**
* 防重逻辑
*
* @param spelVal 解析后的spel值
* @param duringSeconds 防重注解中的时长(单位秒)
* @param message 防重注解上的message
注:可作为扩展字段进行使用
*
* @return 防重唯一标识
*/
public abstract String doExec(@Nullable String spelVal, long duringSeconds, @NonNull String message);
}