首頁
編程語言
C語言|JAVA編程
Python編程
網頁編程
ASP編程|PHP編程
JSP編程
數據庫
MYSQL數據庫|SqlServer數據庫
Oracle數據庫|DB2數據庫
您现在的位置: 程式碼之家 >> 編程語言 >  >> Java 程式設計 >> Java 相關知識

Java 讀取 Properties 配置文件的 6 種標準姿勢 + Servlet 場景補充

     編輯:Java 相關知識

java.util.Properties 是 Java 處理鍵值配置的基石。本文梳理 JDK 標準 API 的 6 種加載方式,對比適用場景,並補充 Web 容器場景下的最佳實踐。

一、 核心 API 基礎

Properties props = new Properties();
props.load(inputStream); // 核心加載方法
String value = props.getProperty("key", "defaultValue"); // 安全取值

二、 6 種加載路徑對比

#方式代碼示例路徑解析規則適用場景
1文件系統絕對/相對路徑
InputStream in = new BufferedInputStream(
    new FileInputStream("config/app.properties"));
相對於 user.dir(啟動工作目錄)獨立應用、外部化配置、Docker 掛載配置文件
2ResourceBundle 機制
ResourceBundle rb = ResourceBundle.getBundle("config/app", Locale.getDefault());
類路徑下 config/app.properties(無後綴),支持 i18n 變體國際化配置、模塊化項目、偏好「約定優於配置」
3PropertyResourceBundle 直接構造
InputStream in = new BufferedInputStream(
    new FileInputStream("config/app.properties"));
ResourceBundle rb = new PropertyResourceBundle(in);
同方式 1,但返回 ResourceBundle 只讀視圖需只讀、國際化特性時
4Class.getResourceAsStream()
InputStream in = MyClass.class.getResourceAsStream("/config/app.properties");
以 / 開頭:類路徑根;不以 / 開頭:當前類包目錄類內部加載同包/項目內配置,最常用
5ClassLoader.getResourceAsStream()
InputStream in = MyClass.class.getClassLoader()
    .getResourceAsStream("config/app.properties");
永遠從類路徑根查找,不可帶 /工具類、框架代碼、跨模塊加載共享配置
6ClassLoader.getSystemResourceAsStream()
InputStream in = ClassLoader.getSystemResourceAsStream("config/app.properties");
系統類加載器路徑(-cp 指定路徑)啟動參數指定配置、Agent、命令行工具

三、 關鍵區別:Class vs ClassLoader 路徑規則

// 假設類結構:com.demo.util.ConfigUtil
// 資源位置:src/main/resources/config/app.properties (編譯到 classes 根目錄)

ConfigUtil.class.getResourceAsStream("/config/app.properties")     // ✅ 根路徑
ConfigUtil.class.getResourceAsStream("config/app.properties")      // ❌ 找 com/demo/util/config/app.properties
ConfigUtil.class.getClassLoader().getResourceAsStream("config/app.properties") // ✅ 根路徑
ConfigUtil.class.getClassLoader().getResourceAsStream("/config/app.properties") // ❌ ClassLoader 不認 /

口訣:Class 帶 / 找根,不帶找包;ClassLoader 只認相對根路徑,禁帶 /。

四、 Servlet/Web 容器專屬最佳實踐

@WebListener
public class ConfigLoader implements ServletContextListener {
    private static final String CONFIG_PATH = "/WEB-INF/classes/config/app.properties";
    public static Properties PROPS = new Properties();

    @Override
    public void contextInitialized(ServletContextEvent sce) {
        try (InputStream in = sce.getServletContext().getResourceAsStream(CONFIG_PATH)) {
            if (in == null) throw new IllegalStateException("Config not found: " + CONFIG_PATH);
            PROPS.load(in);
        } catch (IOException e) {
            throw new ExceptionInInitializerError(e);
        }
    }
}

// 業務代碼直接用
String url = ConfigLoader.PROPS.getProperty("db.url");

優勢:
① 容器管理生命周期,啟動失敗快速暴露
② 支持 WAR 內部路徑、解壓目錄、JAR 內資源統一訪問
③ 避免類加載器層級差異導致的找不到資源

五、 生產級增強建議

  1. 統一入口:封裝 ConfigService,內部按優先級嘗試:系統屬性 -Dconfig.file → 環境變量 → ServletContext → 類路徑默認值。
  2. 熱加載:WatchService 監聽文件變更 + ReentrantReadWriteLock 保護 Properties 實例,或接入 Apollo/Nacos/Spring Cloud Config。
  3. 類型安全:getInt()、getBoolean()、getDuration() 封裝轉換與默認值。
  4. 敏感信息:密碼、Key 必須加密存儲,啟動時解密注入,絕不明文入 Properties 文件。

六、 總結選型表

場景推薦方式關鍵點
Spring/Spring Boot 項目@Value / @ConfigurationProperties / Environment框架已封裝,勿手工 load
獨立 Java 應用 / 命令行工具方式 5 (ClassLoader) + 外部文件優先-Dconfig.file=/opt/app/config.properties
Web 應用 (非 Spring)ServletContextListener + getResourceAsStream生命周期綁定,路徑穩定
庫/框架代碼 / 多模塊共享配置方式 5 (ClassLoader)不依賴具體類,跨模塊通用
國際化配置方式 2 (ResourceBundle)自動解析 _zh_CN 變體

掌握這 6 種標準姿勢與路徑規則,配置加載不再是「玄學」,而是可控、可測、可遷移的基礎設施能力。

  1. 上一篇文章:
  2. 下一篇文章:
Copyright © 程式碼之家 All Rights Reserved