当前位置: 首页 > news >正文

Java 属性配置文件读取方法详解

Java 属性配置文件读取方法详解

一、配置文件基础概念

1. 配置文件类型对比

类型格式优点缺点适用场景
Propertieskey=value简单易读,Java原生支持不支持层级结构简单配置,JDBC参数
XML标签层级结构结构化强,支持复杂数据类型冗余,解析复杂复杂配置,Spring旧版本
YAML缩进层级结构简洁易读,支持复杂结构依赖缩进,易出错Spring Boot,云原生应用
JSON键值对结构通用性强,语言无关无注释支持前后端共享配置

2. 配置文件位置策略

graph TDA[配置文件位置] --> B[类路径 resources/]A --> C[文件系统绝对路径]A --> D[相对项目路径]A --> E[网络位置 URL]A --> F[JVM启动参数指定]

二、Properties 文件读取方法

1. 原生 Java 读取方式

import java.io.InputStream;
import java.util.Properties;public class PropertiesLoader {public static void main(String[] args) {Properties prop = new Properties();try (InputStream input = PropertiesLoader.class.getClassLoader().getResourceAsStream("config.properties")) {if (input == null) {throw new RuntimeException("配置文件未找到");}// 加载配置文件prop.load(input);// 获取属性值String dbUrl = prop.getProperty("database.url");int maxConnections = Integer.parseInt(prop.getProperty("pool.max_connections", "10") // 默认值);System.out.println("DB URL: " + dbUrl);System.out.println("Max Connections: " + maxConnections);} catch (Exception e) {e.printStackTrace();}}
}

2. 增强型读取工具类

import java.util.Properties;public class ConfigUtils {private static final Properties properties = new Properties();private static boolean loaded = false;static {loadProperties("application.properties");}private static void loadProperties(String fileName) {try (InputStream is = Thread.currentThread().getContextClassLoader().getResourceAsStream(fileName)) {if (is == null) {throw new FileNotFoundException(fileName + " not found");}properties.load(is);loaded = true;} catch (IOException e) {throw new RuntimeException("加载配置文件失败", e);}}// 获取字符串值public static String getString(String key) {checkLoaded();return properties.getProperty(key);}// 获取整数值(带默认值)public static int getInt(String key, int defaultValue) {try {return Integer.parseInt(getString(key));} catch (NumberFormatException e) {return defaultValue;}}// 获取布尔值public static boolean getBoolean(String key) {return Boolean.parseBoolean(getString(key));}private static void checkLoaded() {if (!loaded) {throw new IllegalStateException("配置文件未加载");}}// 热重载配置文件public static void reload() {properties.clear();loaded = false;loadProperties("application.properties");}
}

三、YAML 文件读取方法

1. SnakeYAML 库读取

<!-- Maven 依赖 -->
<dependency><groupId>org.yaml</groupId><artifactId>snakeyaml</artifactId><version>1.33</version>
</dependency>
import org.yaml.snakeyaml.Yaml;
import java.util.Map;public class YamlLoader {public static void main(String[] args) {Yaml yaml = new Yaml();try (InputStream in = YamlLoader.class.getClassLoader().getResourceAsStream("application.yml")) {// 加载为MapMap<String, Object> config = yaml.load(in);// 获取嵌套值Map<String, Object> dbConfig = (Map<String, Object>) config.get("database");String url = (String) dbConfig.get("url");// 获取列表值List<String> servers = (List<String>) config.get("servers");System.out.println("DB URL: " + url);System.out.println("Servers: " + servers);} catch (Exception e) {e.printStackTrace();}}
}

2. 绑定到 Java 对象

public class AppConfig {private Database database;private List<String> servers;private Security security;// getters and setterspublic static class Database {private String url;private String username;private String password;private int maxConnections;// getters and setters}public static class Security {private boolean enabled;private String token;// getters and setters}
}// 读取并绑定
public class YamlToObject {public static void main(String[] args) {Yaml yaml = new Yaml(new Constructor(AppConfig.class));try (InputStream in = YamlToObject.class.getClassLoader().getResourceAsStream("application.yml")) {AppConfig config = yaml.load(in);System.out.println("DB User: " + config.getDatabase().getUsername());} catch (Exception e) {e.printStackTrace();}}
}

四、Spring Boot 配置读取最佳实践

1. 基础配置绑定

import org.springframework.beans.factory.annotation.Value;
import org.springframework.stereotype.Component;@Component
public class DatabaseConfig {@Value("${database.url}")private String url;@Value("${database.username}")private String username;@Value("${database.password}")private String password;@Value("${pool.max_connections:20}") // 带默认值private int maxConnections;// 使用配置public void initDataSource() {System.out.println("Connecting to: " + url);}
}

2. 类型安全配置绑定

import org.springframework.boot.context.properties.ConfigurationProperties;
import org.springframework.stereotype.Component;@Component
@ConfigurationProperties(prefix = "app")
public class AppProperties {private Database database;private List<String> servers;private Security security;// 嵌套静态类public static class Database {private String url;private String username;private String password;private int maxConnections;// getters and setters}public static class Security {private boolean enabled;private String token;// getters and setters}// getters and setters
}// application.yml
app:database:url: jdbc:mysql://localhost/dbusername: rootpassword: secretmax_connections: 50servers:- server1.example.com- server2.example.comsecurity:enabled: truetoken: abc123xyz

3. 多环境配置管理

src/main/resources/
├── application.yml          # 公共配置
├── application-dev.yml      # 开发环境
├── application-test.yml     # 测试环境
└── application-prod.yml     # 生产环境

启动参数指定环境

java -jar myapp.jar --spring.profiles.active=prod

五、高级配置技巧

1. 动态刷新配置

import org.springframework.cloud.context.config.annotation.RefreshScope;@RefreshScope
@Component
public class DynamicConfig {@Value("${dynamic.property}")private String dynamicValue;public String getConfig() {return dynamicValue;}
}

通过 /actuator/refresh 端点刷新配置(需要 Spring Cloud)

2. 加密敏感配置

import org.jasypt.encryption.StringEncryptor;
import org.springframework.beans.factory.annotation.Autowired;public class SecureConfig {@Autowiredprivate StringEncryptor encryptor;@Value("${encrypted.property}")private String encryptedProperty;public String getDecryptedValue() {return encryptor.decrypt(encryptedProperty);}
}

3. 自定义配置源

import org.springframework.context.annotation.Configuration;
import org.springframework.core.env.PropertySource;@Configuration
public class CustomPropertySourceConfig {@Beanpublic PropertySource<?> customPropertySource() {Map<String, Object> properties = new HashMap<>();properties.put("custom.property", "value-from-db");return new MapPropertySource("customSource", properties);}
}

六、配置读取安全最佳实践

1. 敏感信息处理

风险解决方案实现方式
密码明文存储使用加密配置Jasypt, Spring Cloud Config 加密
配置文件泄露配置文件与代码分离外部化配置(K8s ConfigMap, Vault)
生产配置误用环境隔离Spring Profiles, 独立配置文件

2. 配置审计策略

import org.springframework.boot.context.event.ApplicationReadyEvent;
import org.springframework.context.event.EventListener;@Component
public class ConfigAuditor {private final Environment env;public ConfigAuditor(Environment env) {this.env = env;}@EventListener(ApplicationReadyEvent.class)public void auditConfiguration() {System.out.println("=== 配置审计报告 ===");System.out.println("Active Profiles: " + Arrays.toString(env.getActiveProfiles()));System.out.println("DB URL: " + env.getProperty("spring.datasource.url"));System.out.println("Security Enabled: " + env.getProperty("app.security.enabled"));// 记录到审计日志...}
}

七、性能优化方案

1. 配置读取优化策略

场景优化方案效果
高频访问配置缓存配置值减少重复解析
大型配置文件按需加载减少启动内存占用
分布式配置客户端缓存+版本校验减少网络请求
敏感配置延迟解密启动时不暴露敏感信息

2. 高效配置缓存实现

public class ConfigCache {private static final Map<String, Object> cache = new ConcurrentHashMap<>();private static final Properties properties = new Properties();static {// 初始化加载配置try (InputStream is = ConfigCache.class.getResourceAsStream("/application.properties")) {properties.load(is);} catch (IOException e) {throw new RuntimeException("配置加载失败", e);}}// 获取缓存配置public static Object getProperty(String key) {return cache.computeIfAbsent(key, k -> {Object value = properties.get(k);if (value instanceof String) {// 处理加密值等}return value;});}// 刷新缓存public static void refresh() {cache.clear();}
}

八、配置读取完整流程示例

应用程序配置管理器文件系统环境变量请求配置值(key)返回缓存值读取配置文件返回文件内容解析配置检查环境变量覆盖返回环境变量值应用默认值(如有)缓存结果返回最终值alt[内存缓存存在][需要加载]应用程序配置管理器文件系统环境变量

九、总结:配置读取最佳实践

1. 技术选型指南

场景推荐方案
简单Java应用Properties + 工具类
Spring Boot应用@ConfigurationProperties
复杂配置结构YAML + 配置类
微服务/云原生Spring Cloud Config
高安全要求HashiCorp Vault

2. 配置管理黄金法则

  1. 环境隔离:严格区分dev/test/prod环境配置
  2. 安全第一:绝不将敏感信息提交到代码仓库
  3. 外部化配置:配置文件与应用程序分离
  4. 版本控制:所有配置文件纳入版本管理
  5. 配置监控:实时监控配置变更和生效状态
  6. 默认安全:设置安全相关的默认值
  7. 文档化:维护配置项说明文档

3. 配置读取检查清单

  • 配置文件位置正确(类路径/resources)
  • 配置文件名符合规范(application-{profile}.yml)
  • 敏感信息已加密处理
  • 提供了合理的默认值
  • 支持环境变量覆盖
  • 配置变更有监控和告警
  • 配置项有完整的文档说明

架构师建议:在现代应用架构中,配置管理已从简单的文件读取发展为独立的基础设施。对于关键业务系统,建议采用专业的配置中心(如Spring Cloud Config、Apollo、Nacos),实现配置的集中管理、版本控制、实时推送和审计跟踪,将配置读取提升到新的专业水平。

http://www.dtcms.com/a/275859.html

相关文章:

  • 《Java HashMap底层原理全解析(源码+性能+面试)》
  • LangChain 的链(Chain)
  • Java 接口与抽象类:深入解析两者的区别及应用场景
  • 【深度学习】常见评估指标Params、FLOPs、MACs
  • 牛客:HJ19 简单错误记录[华为机考][字符串]
  • 多表查询-4-外连接
  • EMC接地
  • 试用了10款翻译软件后,我只推荐这一款!完全免费还超好用
  • 6.isaac sim4.2 教程-Core API-多机器人,多任务
  • 单细胞入门(1)——介绍
  • C语言中整数编码方式(原码、反码、补码)
  • C++ 模板工厂、支持任意参数代理、模板元编程
  • 如何使用postman做接口测试?
  • dify 用postman调试参数注意
  • MOSFET驱动电路设计时,为什么“慢”开,“快”关?
  • 《Java Web程序设计》实验报告二 学习使用HTML标签、表格、表单
  • 零基础搭建监控系统:Grafana+InfluxDB 保姆级教程,5分钟可视化服务器性能!​
  • elementuiPlus+vue3手脚架后台管理系统,上生产环境之后,如何隐藏vite.config.ts的target地址
  • 游戏开发日记7.12
  • 现代C++打造音乐推荐系统:看看如何从0到1实现
  • 80. 删除有序数组中的重复项 II
  • Web学习笔记3
  • 网络检测:Linux下实时获取WiFi与热点状态
  • 游戏开发团队并非蚂蚁协作(随记):在各种“外部攻击”下保护自己的工具
  • C++中的容斥原理
  • css 判断是ios设备 是Safari浏览器
  • 敏捷开发方法全景解析
  • vue2和vue3的响应式原理
  • 【Datawhale AI 夏令营】 用AI做带货视频评论分析(二)
  • npgsql/dapper/postgresql的时区问题