com.ideaaedi.commonspring.aop.ParameterRecorderConfig Maven / Gradle / Ivy
The newest version!
package com.ideaaedi.commonspring.aop;
import com.ideaaedi.commonspring.lite.params.ParameterHandleModeEnum;
import com.ideaaedi.commonspring.lite.params.ParameterRecorderCustomizer;
import com.ideaaedi.commonspring.lite.params.ParameterSerializer;
import com.ideaaedi.commonspring.lite.params.RequestEntranceJudger;
import com.ideaaedi.commonspring.lite.params.RequestPathProvider;
import lombok.extern.slf4j.Slf4j;
import org.apache.commons.lang3.StringUtils;
import org.springframework.aop.aspectj.AspectJExpressionPointcut;
import org.springframework.beans.factory.annotation.Autowired;
import org.springframework.context.ApplicationContext;
import org.springframework.context.annotation.Bean;
import org.springframework.core.ParameterNameDiscoverer;
import org.springframework.core.annotation.AnnotationAttributes;
import javax.annotation.Nonnull;
import java.util.Arrays;
import java.util.Objects;
import java.util.Set;
import java.util.stream.Collectors;
import static com.ideaaedi.commonspring.lite.params.ParameterRecorder.POINTCUT_FORMAT;
/**
* (non-javadoc)
*
* @author JustryDeng
* @since 1.0.0
*/
@Slf4j
public class ParameterRecorderConfig {
public static final String BEAN_NAME = "parameterRecorderConfig";
private final AnnotationAttributes annotationAttributes;
public ParameterRecorderConfig(AnnotationAttributes annotationAttributes) {
this.annotationAttributes = Objects.requireNonNull(annotationAttributes, "annotationAttributes should not be null.");
}
@Bean(name = ParameterRecorderAdvice.BEAN_NAME)
public PointcutAdvisorWithInitial parameterRecorderAdvice(ApplicationContext applicationContext,
@Autowired(required = false) ParameterRecorderCustomizer parameterRecorderCustomizer) {
// 参数信息
Set includePrefixes = Arrays.stream((String[])annotationAttributes.get("includePrefixes")).collect(Collectors.toSet());
Set excludePrefixes = Arrays.stream((String[])annotationAttributes.get("excludePrefixes")).collect(Collectors.toSet());
Set pointcutAnds = Arrays.stream((String[])annotationAttributes.get("pointcutAnd")).collect(Collectors.toSet());
Set pointcutOrs = Arrays.stream((String[])annotationAttributes.get("pointcutOr")).collect(Collectors.toSet());
ParameterHandleModeEnum parameterHandleMode = (ParameterHandleModeEnum)annotationAttributes.get("parameterHandleMode");
boolean pretty = (boolean)annotationAttributes.get("pretty");
//noinspection rawtypes
Class[] ignoreParamTypes = (Class[])annotationAttributes.get("ignoreParamTypes");
String pointcut = buildPointcut(pointcutAnds, pointcutOrs);
log.info("registry bean '{}' with ConstructorArg includePrefixes -> {}, excludePrefixes -> {}, "
+ "parameterHandleMode -> {}, pretty -> {}, ignoreParamTypes -> {}, pointcut -> {}",
ParameterRecorderAdvice.BEAN_NAME, includePrefixes, excludePrefixes,
parameterHandleMode, pretty, ignoreParamTypes, pointcut);
parameterRecorderCustomizer = createCustomizerIfNecessary(applicationContext, parameterRecorderCustomizer);
// 切面
AspectJExpressionPointcut aspectJExpressionPointcut = new AspectJExpressionPointcut ();
aspectJExpressionPointcut.setExpression(pointcut);
// 切面逻辑
ParameterRecorderAdvice parameterRecorderAdvice = new ParameterRecorderAdvice(
includePrefixes,
excludePrefixes,
parameterHandleMode,
pretty,
ignoreParamTypes,
parameterRecorderCustomizer);
// 增强器
PointcutAdvisorWithInitial defaultPointcutAdvisor = new PointcutAdvisorWithInitial();
defaultPointcutAdvisor.setPointcut(aspectJExpressionPointcut);
defaultPointcutAdvisor.setAdvice(parameterRecorderAdvice);
defaultPointcutAdvisor.setOrder(parameterRecorderAdvice.getOrder());
return defaultPointcutAdvisor;
}
/**
* 才能构建定制化器
*/
@Nonnull
private static ParameterRecorderCustomizer createCustomizerIfNecessary(ApplicationContext applicationContext,
ParameterRecorderCustomizer parameterRecorderCustomizer) {
if (parameterRecorderCustomizer != null) {
return parameterRecorderCustomizer;
}
ParameterSerializer parameterSerializer =
applicationContext.getBeanProvider(ParameterSerializer.class).getIfAvailable();
RequestEntranceJudger requestEntranceJudger =
applicationContext.getBeanProvider(RequestEntranceJudger.class).getIfAvailable();
RequestPathProvider requestPathProvider =
applicationContext.getBeanProvider(RequestPathProvider.class).getIfAvailable();
ParameterNameDiscoverer parameterNameDiscoverer =
applicationContext.getBeanProvider(ParameterNameDiscoverer.class).getIfAvailable();
return new ParameterRecorderCustomizer() {
@Override
public ParameterSerializer customParameterSerializer() {
if (parameterSerializer != null) {
return parameterSerializer;
}
return ParameterRecorderCustomizer.super.customParameterSerializer();
}
@Override
@Nonnull
public RequestEntranceJudger customRequestEntranceJudger() {
return Objects.requireNonNullElseGet(requestEntranceJudger,
ParameterRecorderCustomizer.super::customRequestEntranceJudger);
}
@Override
public RequestPathProvider customRequestPathProvider() {
if (requestPathProvider != null) {
return requestPathProvider;
}
return ParameterRecorderCustomizer.super.customRequestPathProvider();
}
@Override
public ParameterNameDiscoverer customParameterNameDiscoverer() {
if (parameterNameDiscoverer != null) {
return parameterNameDiscoverer;
}
return ParameterRecorderCustomizer.super.customParameterNameDiscoverer();
}
};
}
/**
* 构建切点
*/
protected String buildPointcut(Set pointcutAnds, Set pointcutOrs) {
final String andConnector = " && ";
final String orConnector = " || ";
String and = pointcutAnds.stream().filter(StringUtils::isNotBlank)
.collect(Collectors.joining(andConnector));
String or = pointcutOrs.stream().filter(StringUtils::isNotBlank)
.collect(Collectors.joining(orConnector));
if (StringUtils.isBlank(and)) {
and = "";
} else {
and = andConnector + and;
}
if (StringUtils.isBlank(or)) {
or = "";
} else {
or = orConnector + or;
}
return String.format(POINTCUT_FORMAT, or, and);
}
}