Java中YAML配置文件的高效读取方法
简介
在非Spring框架项目中处理YAML配置时,需要手动实现类似Spring Boot的配置加载功能。本文提供一个可主动指定环境的配置解析工具,解决静态代码块阶段无法获取配置的问题。
配置路径
支持解析变量占位符

Maven依赖
<dependency>
<groupId>org.yaml</groupId>
<artifactId>snakeyaml</artifactId>
<version>1.26</version>
</dependency>
配置加载器
/**
* 提供YAML文件解析及变量替换功能
* @author config_tool
* @version 1.0
*/
public class YamlConfigLoader {
// 变量占位符正则
private static final java.util.regex.Pattern VAR_PATTERN = java.util.regex.Pattern.compile("\\$\\{.*?\\}");
private YamlConfigLoader() {
throw new UnsupportedOperationException("工具类禁止实例化");
}
// 存储加载的配置文件
private static final java.util.Map<String, java.util.Map<String, Object>> configMaps = new java.util.HashMap<>();
// 当前线程配置文件标识
private static final java.lang.ThreadLocal<String> currentConfigFile = new java.lang.InheritableThreadLocal<>();
// 环境标识存储
private static final java.lang.ThreadLocal<String> activeProfile = new java.lang.InheritableThreadLocal<>();
/**
* 设置当前环境标识
* @param env 环境名称
*/
public static void setEnvironment(String env) {
activeProfile.set(env);
}
/**
* 加载指定配置文件
* @param fileName 配置文件路径
*/
private static void loadConfig(String fileName) {
currentConfigFile.set(fileName);
if (!configMaps.containsKey(fileName)) {
configMaps.put(fileName, new org.yaml.snakeyaml.Yaml().loadAs(
YamlConfigLoader.class.getResourceAsStream("/" + fileName),
java.util.Map.class
));
}
}
/**
* 获取配置值并处理嵌套变量
* @param key 配置键
* @return 对象值
*/
private static Object getVal(String key) {
String[] parts = key.split("\\.");
java.util.Map<String, Object> config = new java.util.HashMap<>(configMaps.get(currentConfigFile.get()));
for (int i = 0; i < parts.length; i++) {
Object val = config.get(parts[i]);
if (i < parts.length - 1) {
config = (java.util.Map<String, Object>) val;
} else if (val == null) {
throw new java.lang.IllegalArgumentException("配置项不存在: " + key);
} else {
String value = val.toString();
java.util.regex.Matcher matcher = VAR_PATTERN.matcher(value);
while (matcher.find()) {
String placeholder = matcher.group();
String varKey = placeholder.substring(2, placeholder.length() - 1);
String replacement = getVal(varKey).toString();
value = value.replace(placeholder, replacement);
}
return value;
}
}
return null;
}
/**
* 通过文件名和键获取配置值
* @param fileName 配置文件名
* @param key 配置键
* @return 对象值
*/
public static Object getVal(String fileName, String key) {
loadConfig(fileName);
return getVal(key);
}
/**
* 获取环境标识
* @return 环境名称
*/
public static String getEnv() {
if (activeProfile.get() == null) {
String env = (String) getVal("application.yml", "spring.profiles.active");
setEnvironment(env);
}
return activeProfile.get();
}
/**
* 获取字符串类型配置值
* @param fileName 配置文件名
* @param key 配置键
* @return 字符串值
*/
public static String getString(String fileName, String key) {
return (String) getVal(fileName, key);
}
/**
* 获取默认配置文件的字符串值
* @param key 配置键
* @return 字符串值
*/
public static String getDefaultString(String key) {
return (String) getVal("application.yml", key);
}
/**
* 获取环境特定配置文件的字符串值
* @param key 配置键
* @return 字符串值
*/
public static String getEnvString(String key) {
String fileName = "application-" + getEnv() + ".yml";
return (String) getVal(fileName, key);
}
/**
* 测试方法
*/
public static void main(String[] args) {
System.out.println(getEnv());
System.out.println(getString("pulsar.topic", "application.yml"));
System.out.println(getString("your-yaml-file-name.yml", "key1.key2"));
System.out.println(getEnvString("Ignite-addr"));
setEnvironment("test");
System.out.println(getEnvString("Ignite-addr"));
}
}