|
|
|
@ -5,14 +5,15 @@ import org.springframework.context.ApplicationContext;
|
|
|
|
|
import org.springframework.core.annotation.AnnotationUtils;
|
|
|
|
|
import org.springframework.util.ClassUtils;
|
|
|
|
|
|
|
|
|
|
import java.util.Arrays;
|
|
|
|
|
import java.util.HashMap;
|
|
|
|
|
import java.util.Map;
|
|
|
|
|
import java.io.File;
|
|
|
|
|
import java.lang.reflect.InvocationTargetException;
|
|
|
|
|
import java.util.*;
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
// 基于hashmap实现的内存缓存
|
|
|
|
|
// 因为就是服务启动时初始化一次, 无需考虑多线程并发安全问题
|
|
|
|
|
public class HashMapCache {
|
|
|
|
|
// 单例: 懒汉模式
|
|
|
|
|
// 单例: 饿汉模式
|
|
|
|
|
private static final HashMapCache hashMapCache = new HashMapCache();
|
|
|
|
|
private final Map<Object, String> cache = new HashMap<>();
|
|
|
|
|
//将构造器设置为private禁止通过new进行实例化
|
|
|
|
@ -20,19 +21,35 @@ public class HashMapCache {
|
|
|
|
|
|
|
|
|
|
}
|
|
|
|
|
// 此处实现的是自定义注解的解析逻辑, 将错误码全部加载到内存中
|
|
|
|
|
public void loadCustomException(ApplicationContext applicationContext) {
|
|
|
|
|
Map<String, Object> customExceptionAnnotationMap = applicationContext.getBeansWithAnnotation(CustomExceptionScanAnnotation.class);
|
|
|
|
|
for(Object bean : customExceptionAnnotationMap.values()){
|
|
|
|
|
public void loadCustomException(ApplicationContext applicationContext) throws ClassNotFoundException, InvocationTargetException, IllegalAccessException, NoSuchMethodException, InstantiationException {
|
|
|
|
|
Map<String, Object> customExceptionScanAnnotationMap = applicationContext.getBeansWithAnnotation(CustomExceptionScanAnnotation.class);
|
|
|
|
|
for(Object bean : customExceptionScanAnnotationMap.values()){
|
|
|
|
|
Class<?> extensionClz = ClassUtils.getUserClass(bean);
|
|
|
|
|
CustomExceptionScanAnnotation customExceptionAnnotation = AnnotationUtils.findAnnotation(extensionClz, CustomExceptionScanAnnotation.class);
|
|
|
|
|
assert customExceptionAnnotation != null;
|
|
|
|
|
String[] scanPackageList = customExceptionAnnotation.exceptionPackageList();
|
|
|
|
|
String[] scanExceptionClassList = customExceptionAnnotation.exceptionClassList();
|
|
|
|
|
System.out.println(Arrays.toString(scanExceptionClassList));
|
|
|
|
|
System.out.println(Arrays.toString(scanPackageList));
|
|
|
|
|
String[] exceptionClassList = customExceptionAnnotation.exceptionClassList();
|
|
|
|
|
List<String> classList = getAllClassList(scanPackageList, exceptionClassList);
|
|
|
|
|
for (String className: classList) {
|
|
|
|
|
Class<?> classInstance = Class.forName(className);
|
|
|
|
|
// 判断是否实现接口
|
|
|
|
|
if(!ICustomExceptionAnnotation.class.isAssignableFrom(classInstance)) {
|
|
|
|
|
// 未实现接口
|
|
|
|
|
continue;
|
|
|
|
|
}
|
|
|
|
|
// 实现了接口
|
|
|
|
|
// 反射获取类实例
|
|
|
|
|
ICustomExceptionAnnotation iCustomExceptionAnnotation = (ICustomExceptionAnnotation) (classInstance.getDeclaredConstructor().newInstance());
|
|
|
|
|
Map<String, String> codeTable = iCustomExceptionAnnotation.getCodeTable();
|
|
|
|
|
// TODO : 获取分类注解
|
|
|
|
|
for (Map.Entry<String, String> entry: codeTable.entrySet()) {
|
|
|
|
|
getInstance().put(entry.getKey(), entry.getValue());
|
|
|
|
|
}
|
|
|
|
|
}
|
|
|
|
|
}
|
|
|
|
|
}
|
|
|
|
|
public static HashMapCache getHashMapCache() {
|
|
|
|
|
// 获取实例
|
|
|
|
|
public static HashMapCache getInstance() {
|
|
|
|
|
return hashMapCache;
|
|
|
|
|
}
|
|
|
|
|
// 读取
|
|
|
|
@ -48,4 +65,55 @@ public class HashMapCache {
|
|
|
|
|
public void put(Object code, String message) {
|
|
|
|
|
cache.put(code, message);
|
|
|
|
|
}
|
|
|
|
|
// 获取一个包下的所有类列表
|
|
|
|
|
private List<String> getPackageClassList(String packageName) {
|
|
|
|
|
List<String> classList = new ArrayList<>();
|
|
|
|
|
String path = packageName.replace(".", "/");
|
|
|
|
|
ClassLoader classLoader = Thread.currentThread().getContextClassLoader();
|
|
|
|
|
File directory = new File(Objects.requireNonNull(classLoader.getResource(path)).getFile());
|
|
|
|
|
if (!directory.exists()) {
|
|
|
|
|
return classList;
|
|
|
|
|
}
|
|
|
|
|
File[] fileList = directory.listFiles();
|
|
|
|
|
for (File file : fileList) {
|
|
|
|
|
String fileName = file.getName();
|
|
|
|
|
if (!fileName.endsWith(".class")) {
|
|
|
|
|
// 不是类文件
|
|
|
|
|
continue;
|
|
|
|
|
}
|
|
|
|
|
// 移除.class后缀
|
|
|
|
|
String className = packageName + "." + fileName.substring(0, fileName.length() - 6);
|
|
|
|
|
classList.add(className); // 添加到列表
|
|
|
|
|
}
|
|
|
|
|
return classList;
|
|
|
|
|
}
|
|
|
|
|
|
|
|
|
|
// 同时获取多个包下的class列表, 并支持重复的数据去重
|
|
|
|
|
private List<String> getClassListByPackageList(String[] packageList) {
|
|
|
|
|
List<String> classList = new ArrayList<>();
|
|
|
|
|
for (String packageName: packageList) {
|
|
|
|
|
List<String> packageClassList = getPackageClassList(packageName);
|
|
|
|
|
for (String className: packageClassList) {
|
|
|
|
|
if (classList.contains(className)) {
|
|
|
|
|
// 已存在, 无需重复添加
|
|
|
|
|
continue;
|
|
|
|
|
}
|
|
|
|
|
classList.add(className);
|
|
|
|
|
}
|
|
|
|
|
}
|
|
|
|
|
return classList;
|
|
|
|
|
}
|
|
|
|
|
|
|
|
|
|
// 获取输入的全部class列表
|
|
|
|
|
private List<String> getAllClassList(String[] packageList, String... configClassNameList) {
|
|
|
|
|
List<String> classList =getClassListByPackageList(packageList);
|
|
|
|
|
for (String className: configClassNameList) {
|
|
|
|
|
if (classList.contains(className)) {
|
|
|
|
|
// 已存在, 无需重复添加
|
|
|
|
|
continue;
|
|
|
|
|
}
|
|
|
|
|
classList.add(className);
|
|
|
|
|
}
|
|
|
|
|
return classList;
|
|
|
|
|
}
|
|
|
|
|
}
|
|
|
|
|