升级完善异常实现

This commit is contained in:
白茶清欢 2025-06-03 21:19:05 +08:00
parent e23e7969e1
commit 8d81df1ad6
6 changed files with 86 additions and 31 deletions

View File

@ -2,6 +2,8 @@ package cn.zhangdeman;
import lombok.Getter;
import lombok.Setter;
import java.util.Objects;
// 自定义异常
@Getter
@ -9,23 +11,37 @@ import lombok.Setter;
public class CustomException extends RuntimeException {
private final String code; // 错误码
private final String message; // 异常信息
private final String category; // 错误分类
private final Object data; // 异常数据
public CustomException(String message) {
super(message);
this.code = "-1";
this.category = "-1";
this.data = null;
this.message = message;
}
// 根据code与
public CustomException(String code, Object data) {
this.code = code;
this.message = HashMapCache.getInstance().getCodeMessage(code); // 根据code初始化Message
public CustomException(ICustomExceptionConfig iCustomExceptionConfig, Object data) {
this.code = iCustomExceptionConfig.getCode();
this.message = iCustomExceptionConfig.getMessage();
this.category = iCustomExceptionConfig.getCategory();
this.data = data;
}
public CustomException(String code, String message, Object data) {
public CustomException(String category, String code, Object data) {
this.category = category;
this.code = code;
this.message = message;
this.message = HashMapCache.getInstance().getCodeMessage(category, code);
this.data = data;
}
// 是否制定分类的错误
public Boolean isCategory(String category) {
return this.category.equals(category);
}
// 是否指定分类下的指定错误
public Boolean isErrorCode(String category, String code) {
return this.category.equals(category) && this.code.equals(code);
}
}

View File

@ -0,0 +1,27 @@
package cn.zhangdeman;
// 获取一个异常定义
public class CustomExceptionConfig implements ICustomExceptionConfig{
private final String category;
private final String code;
private final String message;
CustomExceptionConfig(String category, String code, String message) {
this.category = category;
this.code = code;
this.message = message;
}
@Override
public String getCode() {
return code;
}
@Override
public String getMessage() {
return message;
}
@Override
public String getCategory() {
return category;
}
}

View File

@ -6,6 +6,7 @@ import jakarta.servlet.ServletContextListener;
import org.springframework.beans.factory.annotation.Autowired;
import org.springframework.context.ApplicationContext;
import org.springframework.core.annotation.AnnotationUtils;
import org.springframework.stereotype.Component;
import org.springframework.util.ClassUtils;
import java.io.File;
@ -17,10 +18,11 @@ import java.util.*;
// 基于hashmap实现的内存缓存
// 因为就是服务启动时初始化一次, 无需考虑多线程并发安全问题
@Component
public class HashMapCache implements ServletContextListener {
// 单例: 饿汉模式
private static final HashMapCache hashMapCache = new HashMapCache();
private final Map<Object, String> cache = new HashMap<>();
private final Map<String, ICustomExceptionConfig> cache = new HashMap<>();
@Autowired
private ApplicationContext applicationContext;
//将构造器设置为private禁止通过new进行实例化
@ -39,33 +41,30 @@ public class HashMapCache implements ServletContextListener {
List<String> classList = getAllClassList(scanPackageList, exceptionClassList);
for (String className: classList) {
Class<?> classInstance = Class.forName(className);
// 判断是否实现接口
if(!ICustomExceptionAnnotation.class.isAssignableFrom(classInstance)) {
// 判断是否实现接口: 要求实现 ICustomExceptionAnnotation IExceptionConfig
if(!ICustomExceptionAnnotation.class.isAssignableFrom(classInstance) || !ICustomExceptionConfig.class.isAssignableFrom(classInstance)) {
// 未实现接口
continue;
}
// 实现了接口
Map<String, String> codeTable = new HashMap<>();
// 反射获取类实例
if (!classInstance.isEnum()) {
// 不是枚举类
Constructor<?> constructor = classInstance.getDeclaredConstructor();
constructor.setAccessible(true);
ICustomExceptionAnnotation iCustomExceptionAnnotation = (ICustomExceptionAnnotation) (constructor.newInstance());
codeTable = iCustomExceptionAnnotation.getCodeTable();
List<ICustomExceptionConfig> list = iCustomExceptionAnnotation.list();
for (ICustomExceptionConfig iCustomExceptionConfig: list) {
cache.put(iCustomExceptionConfig.getCategory()+"_"+iCustomExceptionConfig.getCode(), iCustomExceptionConfig);
}
} else {
// 是枚举类
Method method = classInstance.getMethod("values");
Object[] objectList = (Object[]) method.invoke(null);
for (Object itemEnumObject: objectList) {
codeTable.put(((IExceptionConfig)itemEnumObject).getCode(), ((IExceptionConfig)itemEnumObject).getMessage());
ICustomExceptionConfig iCustomExceptionConfig = (ICustomExceptionConfig)itemEnumObject;
cache.put(iCustomExceptionConfig.getCategory()+"_"+iCustomExceptionConfig.getCode(), iCustomExceptionConfig);
}
}
// TODO : 获取分类注解
for (Map.Entry<String, String> entry: codeTable.entrySet()) {
getInstance().put(entry.getKey(), entry.getValue());
}
}
}
}
@ -74,18 +73,28 @@ public class HashMapCache implements ServletContextListener {
return hashMapCache;
}
// 读取
public String getCodeMessage(Object code) {
if (!cache.containsKey(code)) {
public String getCodeMessage(String category, String code) {
String key = category + "_" + code;
if (!cache.containsKey(key)) {
// 不包含指定code
return code.toString();
return key;
}
return cache.get(code);
return cache.get(key).getMessage();
}
// 添加
public void put(Object code, String message) {
cache.put(code, message);
public void put(String category, String code, String message) {
String key = category + "_" + code;
cache.put(key, new CustomExceptionConfig(category, code, message));
}
// 直接添加异常实例
public void putByConfig(ICustomExceptionConfig iCustomExceptionConfig) {
String key = iCustomExceptionConfig.getCategory() + "_" + iCustomExceptionConfig.getCode();
cache.put(key, iCustomExceptionConfig);
}
// 获取一个包下的所有类列表
private List<String> getPackageClassList(String packageName) {
List<String> classList = new ArrayList<>();
@ -162,3 +171,4 @@ public class HashMapCache implements ServletContextListener {
public void contextDestroyed(ServletContextEvent sce) {
}
}

View File

@ -1,9 +1,9 @@
package cn.zhangdeman;
import java.util.Map;
import java.util.List;
// 为了支持注解扫描, 自定义exception必须实现此注解
public interface ICustomExceptionAnnotation {
// 获取错误码列表: code => message
Map<String, String> getCodeTable();
List<ICustomExceptionConfig> list();
}

View File

@ -0,0 +1,8 @@
package cn.zhangdeman;
// 异常的配置: 所属服务 + 错误分类 + 错误码全局唯一, 所属服务未配置, 将会随机生成
public interface ICustomExceptionConfig {
String getCode(); // 错误码
String getMessage(); // 错误信息
String getCategory(); // 错误分类
}

View File

@ -1,6 +0,0 @@
package cn.zhangdeman;
public interface IExceptionConfig {
String getCode();
String getMessage();
}