在 Java 開發中,正確載入類路徑下的配置文件(如 .properties、.xml)是基礎卻常令人困惑的環節。本文通過實例深入剖析 Class.getResourceAsStream() 的路徑解析規則,並提供靈活、健壯的最佳實踐方案。
假設專案結構如下:
src/
└── zy/
└── pro/
└── sc/
└── db/
├── ParseProperties.java
└── database.properties
InputStream is = this.getClass().getResourceAsStream("database.properties");
// 或
InputStream is = ParseProperties.class.getResourceAsStream("database.properties");
解析: 不以 / 開頭的路徑為相對路徑,相對於當前類的包路徑(即 zy/pro/sc/db/)。
若結構變為:
src/
├── database.properties
└── zy/pro/sc/db/ParseProperties.java
則需使用絕對路徑(以 / 開頭):
InputStream is = this.getClass().getResourceAsStream("/database.properties");
解析: / 代表類路徑根目錄(即 src/ 或編譯後的 classes/),不受當前類包結構影響。
NullPointerException: 相對路徑在類被不同 ClassLoader 載入時易失效。package zy.pro.sc.db;
import java.io.IOException;
import java.io.InputStream;
import java.util.Properties;
public class ParseProperties {
private final Properties properties = new Properties();
public ParseProperties() {
try {
parseProp();
} catch (IOException e) {
throw new RuntimeException("配置文件載入失敗", e);
}
}
private void parseProp() throws IOException {
// 使用絕對路徑,確保穩定性
try (InputStream is = this.getClass().getResourceAsStream("/database.properties")) {
if (is == null) {
throw new IOException("找不到配置文件: /database.properties");
}
properties.load(is);
}
}
public String getProperty(String key) {
return properties.getProperty(key);
}
public static void main(String[] args) {
ParseProperties pp = new ParseProperties();
System.out.println("JDBC Driver: " + pp.getProperty("jdbc.driver"));
}
}
對於 DocumentBuilder.parse(InputStream) 或 Spring 的 ClassPathResource,同樣適用「絕對路徑優先」原則:
// DOM4J / JAXP
InputStream is = getClass().getResourceAsStream("/config/mybatis-config.xml");
// Spring Resource
Resource resource = new ClassPathResource("/config/app-context.xml");
/ 開頭的絕對類路徑載入資源。src/main/resources(Maven/Gradle 標準目錄),編譯後自動複製至 classes/ 根目錄。C:/config/xxx.properties),破壞可移植性。src/test/resources,同樣以 / 開頭訪問。掌握類路徑資源載入機制,能讓配置管理更優雅、部署更無憂。