Java案例如何解析Properties文件?一文掌握核心方法与最佳实践
📚 目录导读
- 什么是Properties文件?
- 核心解析方法详解
- 1 传统Properties类加载
- 2 基于ResourceBundle的国际化方案
- 3 第三方库:Apache Commons Configuration
- 实战案例:从配置文件到业务逻辑
- 常见问题与解答(FAQ)
- 性能优化与安全建议
什么是Properties文件?
Properties文件是Java生态中最基础的配置格式,采用键=值的纯文本结构。

# 数据库配置 db.url=jdbc:mysql://localhost:3306/mydb db.username=root db.password=secret
它在Spring Boot、MyBatis等框架中广泛应用,但许多开发者仅停留在“会用”层面,本文将带你从原生API到工业级方案,彻底掌握解析技巧。
核心解析方法详解
1 传统Properties类加载(原生方案)
核心步骤:
Properties props = new Properties();
try (InputStream input = new FileInputStream("config.properties")) {
props.load(input);
String url = props.getProperty("db.url");
System.out.println("URL: " + url);
} catch (IOException e) {
e.printStackTrace();
}
注意事项:
- 使用
try-with-resources自动关闭流(Java 7+) - 路径问题:建议用
getClass().getResourceAsStream("/config.properties")访问classpath资源 - 中文乱码:
load()默认使用ISO 8859-1,中文需手动转码:props.load(new InputStreamReader(input, StandardCharsets.UTF_8));
Q1: 为什么不能直接用Properties.load()读取中文?
A: Properties类诞生于Java 1.0,当时只支持ISO 8859-1,现代项目必须显式指定UTF-8编码。
2 基于ResourceBundle的国际化方案
适用场景:多语言配置或需要根据Locale切换配置。
ResourceBundle bundle = ResourceBundle.getBundle("config", Locale.US);
String url = bundle.getString("db.url");
局限性:
- 只能读properties文件,不支持XML、YAML
- 文件必须放在classpath根目录,且命名需遵循
baseName_language_country约定
Q2: ResourceBundle和Properties类有何本质区别?
A: Properties是通用键值存储,ResourceBundle专为国际化设计,自动根据Locale匹配对应配置文件。
3 第三方库:Apache Commons Configuration(进阶方案)
引入依赖(Maven):
<dependency>
<groupId>org.apache.commons</groupId>
<artifactId>commons-configuration2</artifactId>
<version>2.8.0</version>
</dependency>
优势代码:
Parameters params = new Parameters();
FileBasedConfigurationBuilder<PropertiesConfiguration> builder =
new FileBasedConfigurationBuilder<>(PropertiesConfiguration.class)
.configure(params.fileBased()
.setFile(new File("config.properties"))
.setEncoding("UTF-8")
.setListDelimiterHandler(new DefaultListDelimiterHandler(',')));
PropertiesConfiguration config = builder.getConfiguration();
// 支持列表、层级、变量插值
String[] ips = config.getStringArray("server.ips");
String dbUrl = config.getString("db.url");
Q3: 为什么推荐用Commons Configuration而非原生API?
A: 它提供自动重载(AutoSave)、变量插值(${sys:user.home})、多格式支持(XML、YAML)等功能,适合中大型项目。
实战案例:从配置文件到业务逻辑
场景:解析一个业务规则配置文件,实现动态开关功能。
config.properties:
feature.new-login.enabled=true feature.payment.timeout=3000 feature.blacklist=192.168.1.1,10.0.0.1
解析代码:
public class FeatureConfig {
private static final Properties props = new Properties();
static {
try (InputStream is = FeatureConfig.class.getResourceAsStream("/features.properties")) {
props.load(new InputStreamReader(is, StandardCharsets.UTF_8));
} catch (IOException e) {
throw new RuntimeException("Failed to load features config", e);
}
}
public static boolean isNewLoginEnabled() {
return Boolean.parseBoolean(props.getProperty("feature.new-login.enabled", "false"));
}
public static List<String> getBlacklist() {
String raw = props.getProperty("feature.blacklist", "");
return Arrays.asList(raw.split(","));
}
}
调用:
if (FeatureConfig.isNewLoginEnabled()) {
// 处理新登录逻辑
}
Q4: 如何避免每次读取都解析文件?
A: 使用静态初始化(如上述代码),或借助Guava Cache实现定时刷新。
常见问题与解答(FAQ)
Q5: Properties文件中的注释支持哪些格式?
A: 仅支持行首的或,不支持行尾注释。
# 这是正确注释 key=value # 这是错误用法(会被解析为值的一部分)
Q6: 如何安全存储数据库密码等敏感信息?
A: 不要明文存储!方案:
- 使用Jasypt加密库进行可逆加密
- 结合Spring Cloud Config的加密功能
- 环境变量+系统属性覆盖(
System.getProperty())
Q7: 解析时出现java.lang.IllegalArgumentException: Key contains blank怎么办?
A: 检查值中是否混入空格,如key = value(等号前后空格会被忽略,但键内部不能有空格)。
性能优化与安全建议
性能优化
- 缓存策略:对于低频变更的配置,使用静态缓存(如ConcurrentHashMap)
- 懒加载:只有在首次访问配置时才加载文件
- 避免频繁IO:使用
watchService监听文件变化,而非每次请求都重新读取
安全最佳实践
- 文件权限:配置文件设置
600(仅所有者读写) - 避免硬编码:所有配置路径应外部化,通过环境变量传递
- 敏感信息加密:密码使用AES加密后存储,运行时注入解密密钥
从原生Properties类到Commons Configuration,再到企业级加密与缓存,解析Properties文件远不止load()一个方法,掌握这些技巧,你不仅能高效处理配置,还能写出更健壮、可维护的Java应用。
拓展阅读:如果你正在使用Spring Boot,请优先考虑
@ConfigurationProperties注解,它能自动绑定配置文件到Java对象,实现类型安全配置。