properties 文件是什么?
properties 文件是一种用于存储配置信息的简单文本文件,它通常以 .properties 为后缀。
格式为 键=值,注释以 或 开头。

示例 config.properties 文件:
# Database Configuration db.url=jdbc:mysql://localhost:3306/mydb db.username=admin db.password=secret123 db.pool.size=10 # Application Settings app.name=My Cool Application app.version=1.2.0
使用 java.util.Properties 和 ClassLoader (最核心、最常用)
这是最传统、最基础的方法,适用于任何 Java 环境(包括标准 Java SE),它的核心思想是利用 类加载器 (ClassLoader) 来从 classpath(类路径)中加载资源文件。
核心步骤:
- 创建
Properties对象。 - 通过
ClassLoader获取输入流InputStream。getClass().getClassLoader().getResourceAsStream("文件名")- 关键点:文件路径必须是相对于 classpath 的根目录,如果你的
src/main/resources目录在 Maven/Gradle 项目中,它会被默认打包到 classpath 的根目录下。
- 使用
properties.load(InputStream)加载流。 - 通过
properties.getProperty("键")获取值。
完整代码示例:
import java.io.IOException;
import java.io.InputStream;
import java.util.Properties;
public class PropertiesExample {
public static void main(String[] args) {
// 1. 创建 Properties 对象
Properties prop = new Properties();
// 使用 try-with-resources 语句确保 InputStream 被自动关闭
try (InputStream input = PropertiesExample.class.getClassLoader().getResourceAsStream("config.properties")) {
// 2. 检查文件是否存在
if (input == null) {
System.out.println("Sorry, unable to find config.properties");
return;
}
// 3. 加载 properties 文件
prop.load(input);
// 4. 获取属性值并打印
String dbUrl = prop.getProperty("db.url");
String dbUsername = prop.getProperty("db.username");
String dbPassword = prop.getProperty("db.password");
String appName = prop.getProperty("app.name");
// 为可选的属性提供默认值,避免 NullPointerException
String appVersion = prop.getProperty("app.version", "1.0.0"); // app.version 不存在,则返回 "1.0.0"
System.out.println("Database URL: " + dbUrl);
System.out.println("Database Username: " + dbUsername);
System.out.println("Application Name: " + appName);
System.out.println("Application Version: " + appVersion);
} catch (IOException ex) {
ex.printStackTrace();
}
}
}
关键点说明:
getResourceAsStream("config.properties"):这里的"config.properties"是相对于 classpath 根的路径,如果你的文件在resources/config/db/目录下,路径就应该是"config/db/config.properties"。getClassLoader():通过当前类的类加载器来加载资源,这是推荐的方式,因为它能找到位于 classpath 中的任何资源。try-with-resources:这是一种好习惯,可以确保InputStream在使用完毕后自动关闭,防止资源泄漏。prop.getProperty("key", "defaultValue"):这是一个非常实用的方法,当指定的键不存在时,会返回你提供的默认值,避免了NullPointerException。
使用 java.util.ResourceBundle (国际化友好)
ResourceBundle 专门用于本地化,但它也是加载非本地化 properties 文件的绝佳选择,它不直接处理 InputStream,而是由底层实现(通常是 PropertyResourceBundle)来读取文件。
核心步骤:
- 使用
ResourceBundle.getBundle("基础文件名")加载资源。- 同样,文件路径基于 classpath。
- 不需要
.properties后缀。
- 通过
resourceBundle.getString("键")获取值。
完整代码示例:
import java.util.ResourceBundle;
public class ResourceBundleExample {
public static void main(String[] args) {
// 1. 加载 properties 文件
// 文件名是 "config",不需要 .properties 后缀
// ResourceBundle 会自动寻找 classpath 下的 config.properties
ResourceBundle rb = ResourceBundle.getBundle("config");
// 2. 获取属性值
// 注意:ResourceBundle.getString() 在键不存在时会抛出 MissingResourceException
// 所以最好先检查是否存在
if (rb.containsKey("db.url")) {
String dbUrl = rb.getString("db.url");
System.out.println("Database URL: " + dbUrl);
}
String appName = rb.getString("app.name");
System.out.println("Application Name: " + appName);
// 如果键不存在,会抛出 java.util.MissingResourceException
// String nonExistentKey = rb.getString("this.key.does.not.exist");
}
}
与 Properties 类的对比:
- 优点:
- 更简洁,无需手动处理
InputStream。 - 是 Java 国际化框架的一部分,可以轻松加载不同语言的资源文件(如
config_zh_CN.properties)。
- 更简洁,无需手动处理
- 缺点:
- 获取值时,如果键不存在会直接抛出
MissingResourceException,不像Properties.getProperty()那样灵活地支持默认值。 - 主要设计初衷是用于本地化,虽然可以用于普通配置,但略显“杀鸡用牛刀”。
- 获取值时,如果键不存在会直接抛出
使用 Spring Framework 的 @Value 注解 (Spring/Spring Boot 项目)
如果你在使用 Spring 或 Spring Boot 框架,这是最优雅、最推荐的方式,它允许你直接将 properties 文件中的值注入到字段中。

核心步骤:
- Spring Boot: 确保你的
application.properties或application.yml文件位于src/main/resources目录下,Spring Boot 会自动加载它们。 - Spring: 在你的 XML 配置文件中(
applicationContext.xml)添加<context:property-placeholder location="classpath:config.properties"/>。 - 在 Java 类的字段上使用
@Value("${键名}")注解。
完整代码示例 (Spring Boot):
src/main/resources/application.properties
app.name=My Spring Boot App message=Hello from properties file!
Java Bean
import org.springframework.beans.factory.annotation.Value;
import org.springframework.stereotype.Component;
@Component
public class AppConfig {
@Value("${app.name}")
private String appName;
@Value("${message}")
private String message;
// 可以为属性设置默认值,如果配置文件中没有找到该键
@Value("${feature.enabled:false}") // feature.enabled 不存在,则默认为 false
private boolean featureEnabled;
public void printConfig() {
System.out.println("App Name: " + appName);
System.out.println("Message: " + message);
System.out.println("Feature Enabled: " + featureEnabled);
}
}
主程序或测试类中调用
import org.springframework.boot.SpringApplication;
import org.springframework.boot.autoconfigure.SpringBootApplication;
import org.springframework.context.ConfigurableApplicationContext;
@SpringBootApplication
public class DemoApplication {
public static void main(String[] args) {
ConfigurableApplicationContext context = SpringApplication.run(DemoApplication.class, args);
AppConfig appConfig = context.getBean(AppConfig.class);
appConfig.printConfig();
}
}
优点:
- 解耦:配置与代码完全分离。
- 类型安全:可以直接注入到
String,int,boolean等类型的字段中。 - 默认值支持:
@Value("${key:default_value}")语法非常方便。 - 自动刷新(配合
@RefreshScope):在动态配置中心(如 Spring Cloud Config)中,可以不重启应用就更新配置。
总结与最佳实践
| 方法 | 适用场景 | 优点 | 缺点 |
|---|---|---|---|
java.util.Properties |
任何 Java 项目,特别是标准 Java SE 或非 Spring 项目。 | 最核心、最灵活,可处理任意资源路径,支持默认值。 | 需要手动管理 InputStream,代码稍显冗长。 |
java.util.ResourceBundle |
需要国际化的项目,或需要简洁加载方式的普通项目。 | 自动管理资源,支持本地化,代码简洁。 | 获取值时无默认值,会抛异常。 |
@Value (Spring) |
Spring / Spring Boot 项目。 | **最优雅、 |

