148 lines
5.4 KiB
Java
148 lines
5.4 KiB
Java
package com.hua.valid;
|
||
|
||
import cn.hutool.core.util.ArrayUtil;
|
||
import com.hua.annotation.Handles;
|
||
import com.hua.valid.annotation.PackageScanConfig;
|
||
import org.reflections.Reflections;
|
||
import org.reflections.scanners.SubTypesScanner;
|
||
import org.reflections.scanners.TypeAnnotationsScanner;
|
||
import org.reflections.util.ClasspathHelper;
|
||
import org.reflections.util.ConfigurationBuilder;
|
||
|
||
import java.lang.annotation.Annotation;
|
||
import java.util.HashMap;
|
||
import java.util.Map;
|
||
import java.util.ServiceLoader;
|
||
import java.util.Set;
|
||
import java.util.function.Consumer;
|
||
|
||
/**
|
||
* @author Hua
|
||
* @since 2024/7/18 下午2:43
|
||
*/
|
||
public class AnnotationHandleFactory {
|
||
|
||
// 缓存已加载的注解处理器
|
||
private static final Map<Class<? extends Annotation>, AnnotationHandler> cache = new HashMap<>();
|
||
private static boolean useSPI = true; // 是否使用SPI加载处理器
|
||
private static boolean useReflection = false; // 是否使用反射加载处理器
|
||
private static String[] packagesToScan = {"com.hua.valid"}; // 反射扫描的包路径
|
||
|
||
// 静态初始化块,在类加载时进行处理器初始化
|
||
static {
|
||
resolvePackageConfig();
|
||
initializeHandlers();
|
||
}
|
||
|
||
/**
|
||
* 配置处理器加载方式和扫描路径。
|
||
*
|
||
* @param useSpi 是否使用SPI加载处理器。
|
||
* @param useRef 是否使用反射加载处理器。
|
||
* @param packages 反射扫描的包路径。
|
||
*/
|
||
public static void configure(boolean useSpi, boolean useRef, String[] packages) {
|
||
useSPI = useSpi;
|
||
useReflection = useRef;
|
||
packagesToScan = packages;
|
||
cache.clear(); // 清除缓存
|
||
initializeHandlers(); // 重新初始化处理器
|
||
}
|
||
|
||
private static void resolvePackageConfig() {
|
||
Reflections reflections = new Reflections(new ConfigurationBuilder()
|
||
.setUrls(ClasspathHelper.forJavaClassPath())
|
||
.setScanners(new TypeAnnotationsScanner(), new SubTypesScanner()));
|
||
|
||
// 查找所有应用了PackageScanConfig注解的类
|
||
Set<Class<?>> configClasses = reflections.getTypesAnnotatedWith(PackageScanConfig.class);
|
||
if (configClasses.isEmpty()) {
|
||
return;
|
||
}
|
||
PackageScanConfig config = configClasses.stream().findFirst().get().getAnnotation(PackageScanConfig.class);
|
||
useSPI = config.useSPI();
|
||
useReflection = config.useReflection();
|
||
packagesToScan = config.packages();
|
||
}
|
||
|
||
// 初始化处理器,根据配置决定使用SPI或反射加载
|
||
private static void initializeHandlers() {
|
||
if (useSPI) {
|
||
loadHandlersViaSPI();
|
||
}
|
||
if (useReflection) {
|
||
loadHandlersViaReflection();
|
||
}
|
||
}
|
||
|
||
// 通过SPI加载注解处理器
|
||
private static void loadHandlersViaSPI() {
|
||
ServiceLoader<AnnotationHandler> loadedHandlers = ServiceLoader.load(AnnotationHandler.class);
|
||
loadedHandlers.forEach(handler -> {
|
||
Handles handles = handler.getClass().getAnnotation(Handles.class);
|
||
if (handles != null) {
|
||
cache.put(handles.value(), handler);
|
||
}
|
||
});
|
||
}
|
||
|
||
// 通过反射加载注解处理器
|
||
private static void loadHandlersViaReflection() {
|
||
// 单独的方法用于加载处理器
|
||
Consumer<Reflections> loadHandlers = (reflections) -> {
|
||
reflections.getTypesAnnotatedWith(Handles.class).forEach(cls -> {
|
||
try {
|
||
AnnotationHandler handler = (AnnotationHandler) cls.getDeclaredConstructor().newInstance();
|
||
Handles handlesAnnotation = cls.getAnnotation(Handles.class);
|
||
cache.put(handlesAnnotation.value(), handler);
|
||
} catch (ReflectiveOperationException e) {
|
||
// 推荐使用日志记录异常,而非仅仅打印堆栈信息
|
||
e.printStackTrace();
|
||
}
|
||
});
|
||
};
|
||
|
||
if (ArrayUtil.isEmpty(packagesToScan)) {
|
||
Reflections reflections = new Reflections(new ConfigurationBuilder()
|
||
.setUrls(ClasspathHelper.forJavaClassPath())
|
||
.setScanners(new TypeAnnotationsScanner(), new SubTypesScanner()));
|
||
loadHandlers.accept(reflections);
|
||
} else {
|
||
for (String pkg : packagesToScan) {
|
||
Reflections reflections = new Reflections(new ConfigurationBuilder()
|
||
.forPackages(pkg)
|
||
.setScanners(new SubTypesScanner(), new TypeAnnotationsScanner()));
|
||
loadHandlers.accept(reflections);
|
||
}
|
||
}
|
||
}
|
||
|
||
|
||
/**
|
||
* 根据注解类型获取对应的处理器。
|
||
*
|
||
* @param annotation 注解实例。
|
||
* @return 对应的注解处理器,如果未找到返回null。
|
||
*/
|
||
public static AnnotationHandler getHandler(Annotation annotation) {
|
||
return cache.get(annotation.annotationType());
|
||
}
|
||
|
||
/**
|
||
* 处理给定的注解数据对象。
|
||
*
|
||
* @param handleDTO 包含注解信息的数据传输对象。
|
||
* @return 处理结果,成功或失败。
|
||
*/
|
||
public static boolean handle(HandleDTO handleDTO) {
|
||
for (Annotation annotation : handleDTO.getAnnotations()) {
|
||
AnnotationHandler handler = getHandler(annotation);
|
||
if (handler != null) {
|
||
handleDTO.setCurrentAnnotation(annotation);
|
||
return handler.handle(handleDTO);
|
||
}
|
||
}
|
||
return true;
|
||
}
|
||
}
|