添加枚举字段注解扫描注入
This commit is contained in:
@@ -18,7 +18,11 @@ public class ReflectionsConfig {
|
||||
@Bean("reflections")
|
||||
Reflections reflections() {
|
||||
return new Reflections(new ConfigurationBuilder()
|
||||
.addScanners(Scanners.MethodsAnnotated, Scanners.SubTypes, Scanners.TypesAnnotated)
|
||||
.addScanners(
|
||||
Scanners.MethodsAnnotated,
|
||||
Scanners.SubTypes,
|
||||
Scanners.FieldsAnnotated,
|
||||
Scanners.TypesAnnotated)
|
||||
.forPackages("quant.rich.emoney"));
|
||||
}
|
||||
|
||||
|
||||
@@ -0,0 +1,75 @@
|
||||
package quant.rich.emoney.entity.config;
|
||||
|
||||
import java.net.Proxy;
|
||||
import java.time.LocalDateTime;
|
||||
import java.util.Objects;
|
||||
|
||||
import org.apache.commons.lang3.ObjectUtils;
|
||||
import org.apache.commons.lang3.StringUtils;
|
||||
import org.apache.commons.lang3.Validate;
|
||||
import org.springframework.beans.factory.annotation.Autowired;
|
||||
|
||||
import com.fasterxml.jackson.annotation.JsonIgnore;
|
||||
import com.fasterxml.jackson.databind.ObjectMapper;
|
||||
import com.fasterxml.jackson.databind.annotation.JsonDeserialize;
|
||||
import com.fasterxml.jackson.databind.annotation.JsonSerialize;
|
||||
import com.fasterxml.jackson.databind.node.ObjectNode;
|
||||
|
||||
import com.fasterxml.jackson.datatype.jsr310.ser.LocalDateTimeSerializer;
|
||||
import com.fasterxml.jackson.datatype.jsr310.deser.LocalDateTimeDeserializer;
|
||||
import lombok.AccessLevel;
|
||||
import lombok.Data;
|
||||
import lombok.Getter;
|
||||
import lombok.Setter;
|
||||
import lombok.experimental.Accessors;
|
||||
import lombok.extern.slf4j.Slf4j;
|
||||
import quant.rich.emoney.entity.config.DeviceInfoConfig.DeviceInfo;
|
||||
import quant.rich.emoney.interceptor.EnumOptionsInterceptor.EnumOptions;
|
||||
import quant.rich.emoney.interfaces.ConfigInfo;
|
||||
import quant.rich.emoney.interfaces.IConfig;
|
||||
import quant.rich.emoney.interfaces.ValidEmoneyRequestConfig;
|
||||
import quant.rich.emoney.patch.okhttp.PatchOkHttp;
|
||||
import quant.rich.emoney.util.EncryptUtils;
|
||||
import quant.rich.emoney.util.SpringContextHolder;
|
||||
import quant.rich.emoney.util.TextUtils;
|
||||
|
||||
/**
|
||||
* 独立出来一个代理设置的原因是后续可能需要做一个代理池,这样的话独立配置比较适合后续扩展
|
||||
*/
|
||||
@Data
|
||||
@Accessors(chain = true)
|
||||
@Slf4j
|
||||
@ValidEmoneyRequestConfig
|
||||
@ConfigInfo(field = "proxy", name = "代理设置", initDefault = true)
|
||||
public class ProxyConfig implements IConfig<ProxyConfig> {
|
||||
|
||||
/**
|
||||
* 代理类型
|
||||
*/
|
||||
@EnumOptions("ProxyTypeEnum")
|
||||
private Proxy.Type proxyType = Proxy.Type.DIRECT;
|
||||
|
||||
/**
|
||||
* 代理主机
|
||||
*/
|
||||
private String proxyHost = "";
|
||||
|
||||
/**
|
||||
* 代理端口
|
||||
*/
|
||||
private Integer proxyPort = 0;
|
||||
|
||||
/**
|
||||
* 是否忽略 HTTPS 证书校验
|
||||
*/
|
||||
private Boolean ignoreHttpsVerification = false;
|
||||
|
||||
public void afterBeanInit() {
|
||||
|
||||
}
|
||||
|
||||
|
||||
public ProxyConfig() {}
|
||||
|
||||
|
||||
}
|
||||
@@ -0,0 +1,113 @@
|
||||
package quant.rich.emoney.interceptor;
|
||||
|
||||
|
||||
import org.reflections.Reflections;
|
||||
import org.springframework.beans.factory.annotation.Autowired;
|
||||
import org.springframework.core.annotation.AliasFor;
|
||||
import org.springframework.lang.Nullable;
|
||||
import org.springframework.stereotype.Component;
|
||||
import org.springframework.web.bind.annotation.ResponseBody;
|
||||
import org.springframework.web.bind.annotation.RestController;
|
||||
import org.springframework.web.method.HandlerMethod;
|
||||
import org.springframework.web.servlet.*;
|
||||
|
||||
import jakarta.servlet.http.*;
|
||||
import lombok.extern.slf4j.Slf4j;
|
||||
|
||||
import java.lang.reflect.*;
|
||||
import java.util.*;
|
||||
import java.util.Map.Entry;
|
||||
import java.lang.annotation.*;
|
||||
|
||||
@Component
|
||||
@Slf4j
|
||||
public class EnumOptionsInterceptor implements HandlerInterceptor {
|
||||
|
||||
@Autowired
|
||||
Reflections reflections;
|
||||
|
||||
private Map<String, Map<String, Enum<?>>> options = null;
|
||||
|
||||
private Map<String, String> optionNameMap = new HashMap<>();
|
||||
|
||||
@Override
|
||||
public boolean preHandle(HttpServletRequest request,
|
||||
HttpServletResponse response,
|
||||
Object handler) throws Exception {
|
||||
|
||||
// 只在 Controller(HandlerMethod)里才做注入
|
||||
if (!(handler instanceof HandlerMethod)) {
|
||||
// 静态资源、图片、css、js 都会被 ResourceHttpRequestHandler 处理,
|
||||
// 这里一律跳过
|
||||
return true;
|
||||
}
|
||||
|
||||
// 排除 @ResponseBody/json 接口
|
||||
HandlerMethod hm = (HandlerMethod) handler;
|
||||
if (hm.hasMethodAnnotation(ResponseBody.class)
|
||||
|| hm.getBeanType().isAnnotationPresent(RestController.class)) {
|
||||
return true;
|
||||
}
|
||||
|
||||
if (options == null) {
|
||||
options = new HashMap<>();
|
||||
Set<Field> enumOptionFields = reflections.getFieldsAnnotatedWith(EnumOptions.class);
|
||||
for (Field f : enumOptionFields) {
|
||||
if (!f.isAnnotationPresent(EnumOptions.class)) continue;
|
||||
if (!Enum.class.isAssignableFrom(f.getType())) continue;
|
||||
|
||||
// 拿到注解和名前缀
|
||||
EnumOptions anno = f.getAnnotation(EnumOptions.class);
|
||||
String prefix = anno.value().isBlank() ?
|
||||
f.getName() + "Enum" :
|
||||
anno.value();
|
||||
|
||||
prefix = prefix.toUpperCase().charAt(0) + prefix.substring(1);
|
||||
|
||||
if (optionNameMap.containsKey(prefix)) {
|
||||
log.warn("EnumOption name {}:{} has already been taken by {}, please check",
|
||||
prefix, f.getType().getName(), optionNameMap.get(prefix));
|
||||
continue;
|
||||
}
|
||||
|
||||
optionNameMap.put(prefix, f.getType().getName());
|
||||
|
||||
// enum 值列表
|
||||
@SuppressWarnings("unchecked")
|
||||
Class<? extends Enum<?>> enumType = (Class<? extends Enum<?>>) f.getType();
|
||||
Enum<?>[] constants = enumType.getEnumConstants();
|
||||
|
||||
// 构造 Map<name, constant>
|
||||
Map<String, Enum<?>> optionsMap = new LinkedHashMap<>();
|
||||
for (Enum<?> c : constants) {
|
||||
optionsMap.put(c.name(), c);
|
||||
}
|
||||
|
||||
// 放到 Model 里
|
||||
options.put(prefix, optionsMap);
|
||||
}
|
||||
|
||||
}
|
||||
for (Entry<String, Map<String, Enum<?>>> entry : options.entrySet()) {
|
||||
request.setAttribute(entry.getKey(), entry.getValue());
|
||||
log.debug("Inject enums {}: {} to request {}",
|
||||
entry.getKey(), optionNameMap.get(entry.getKey()),
|
||||
request.getRequestURI());
|
||||
}
|
||||
return true;
|
||||
}
|
||||
|
||||
|
||||
@Target(ElementType.FIELD)
|
||||
@Retention(RetentionPolicy.RUNTIME)
|
||||
@Documented
|
||||
public static @interface EnumOptions {
|
||||
/**
|
||||
* 注入到 Model 时用的属性名前缀,
|
||||
* 默认:字段名 + "Options"
|
||||
*/
|
||||
String value() default "";
|
||||
}
|
||||
|
||||
|
||||
}
|
||||
Reference in New Issue
Block a user