Spring Boot从配置读取异常类名动态加载到HashMap的实现方法
实现方案
你可以通过类反射加载配置中的异常类,同时做类型合法性校验,避免加载非异常类型的类导致类型转换错误,完整实现代码如下:
import org.springframework.beans.factory.annotation.Value; import org.springframework.stereotype.Component; import javax.annotation.PostConstruct; import java.util.HashMap; import java.util.Map; @Component public class RetryExceptionConfig { @Value("${myapp.exception.class}") private String myclassesList; private Map<Class<? extends Throwable>, Boolean> exceptionRetryMap; @PostConstruct public void initExceptionMap() throws ClassNotFoundException { exceptionRetryMap = new HashMap<>(); // 分割逗号分隔的类名,同时去除每个类名前后的空白字符 String[] classNames = myclassesList.split(","); for (String className : classNames) { className = className.trim(); // 加载类 Class<?> clazz = Class.forName(className); // 校验类是否是Throwable的子类,避免非法配置 if (Throwable.class.isAssignableFrom(clazz)) { exceptionRetryMap.put((Class<? extends Throwable>) clazz, Boolean.TRUE); } else { // 可根据业务需求选择抛出异常或者打warn日志跳过非法配置 throw new IllegalArgumentException("配置的类" + className + "不是异常类型,无法配置为重试触发异常"); } } } // 对外提供获取异常Map的方法 public Map<Class<? extends Throwable>, Boolean> getExceptionRetryMap() { return exceptionRetryMap; } }
注意事项
- 配置文件中填写的异常类需要写全限定名(比如
java.util.concurrent.TimeoutException,不能只写类名),否则类加载器找不到对应类 - 如果你项目里有自定义异常,确保自定义异常的包路径正确,类能被当前应用的类加载器加载到
- 可以根据业务需求调整非法配置的处理逻辑,比如不想因为配置错误启动失败,可以把抛出异常换成打warn日志跳过非法类即可
- 可选优化:如果想兼容Spring环境下的多类加载器场景,可以替换
Class.forName(className)为org.springframework.util.ClassUtils.forName(className, Thread.currentThread().getContextClassLoader()),类加载兼容性更好 - 后续把这个生成的
exceptionRetryMap注入到你的RetryTemplate配置类里,替换原来硬编码的Map即可生效
内容的提问来源于stack exchange,提问作者James
相关产品推荐
相关产品推荐

