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

Java 讀取 Properties 配置文件的 6 種方式與 1 個 Servlet 擴展

     編輯:Java 相關知識

Properties 文件是 Java 專案最常見的配置載體。但根據配置文件位置(類路徑、檔案系統、JAR 內部、War 內部)、訪問上下文(普通類、Servlet、Spring 容器),最佳讀取方式不同。本文系統梳理 6 種核心 API 用法與 1 個 Servlet 擴展,附帶適用場景對照表。

六大核心讀取方式對照

#API適用場景關鍵特點
1Properties.load(InputStream)檔案系統絕對/相對路徑最基礎,需自行管理流關閉
2ResourceBundle.getBundle(baseName)類路徑下 .properties 文件(無副檔名)支援 Locale 變體、緩存機制、不可熱重載
3new PropertyResourceBundle(InputStream)需手動控制流來源的 ResourceBundle可讀取任意 InputStream 來源
4Class.getResourceAsStream(path)相對於當前類的類路徑資源路徑不以 / 開頭 = 相對路徑
5Class.getClassLoader().getResourceAsStream(path)類路徑根目錄下的資源路徑不以 / 開頭 = 絕對路徑(從 classpath root)
6ClassLoader.getSystemResourceAsStream(path)系統類加載器可見資源(啟動類路徑)不受自定義類加載器影響

代碼範例:統一工具類

public final class PropsUtil {
    private PropsUtil() {}

    /** 從類路徑讀取(最常用) */
    public static Properties loadFromClasspath(String path) {
        try (InputStream in = PropsUtil.class.getClassLoader().getResourceAsStream(path)) {
            if (in == null) throw new IllegalArgumentException("Resource not found: " + path);
            Properties props = new Properties();
            props.load(in);
            return props;
        } catch (IOException e) {
            throw new UncheckedIOException(e);
        }
    }

    /** 從檔案系統讀取 */
    public static Properties loadFromFile(String filePath) {
        try (InputStream in = new BufferedInputStream(new FileInputStream(filePath))) {
            Properties props = new Properties();
            props.load(in);
            return props;
        } catch (IOException e) {
            throw new UncheckedIOException(e);
        }
    }

    /** 從 ServletContext 讀取(Web 環境) */
    public static Properties loadFromServletContext(ServletContext ctx, String path) {
        try (InputStream in = ctx.getResourceAsStream(path)) {
            if (in == null) throw new IllegalArgumentException("Resource not found: " + path);
            Properties props = new Properties();
            props.load(in);
            return props;
        } catch (IOException e) {
            throw new UncheckedIOException(e);
        }
    }
}

關鍵差異深度解析

Class.getResourceAsStream vs ClassLoader.getResourceAsStream

// 假設類結構:com.example.MyClass,resources/config.properties
MyClass.class.getResourceAsStream("config.properties")        // → com/example/config.properties (相對)
MyClass.class.getResourceAsStream("/config.properties")       // → config.properties (絕對,從 classpath root)
MyClass.class.getClassLoader().getResourceAsStream("config.properties") // → config.properties (絕對,從 classpath root)

規則:Class 方法支援相對路徑;ClassLoader 方法永遠視為絕對路徑(相對 classpath root),不可以 / 開頭。

ResourceBundle 的緩存陷阱

ResourceBundle.getBundle() 預設緩存永久,修改 .properties 文件不生效。解決方案:

  • 使用 ResourceBundle.Control 自定義緩存策略(JDK 9+ 推薦)
  • 或改用 Properties.load() 配合文件監聽實現熱重載

Spring 環境下的最佳實踐

若專案使用 Spring,請勿手寫上述代碼,直接使用:

  • @PropertySource("classpath:config.properties") + Environment
  • @Value("${key}") / @ConfigurationProperties 綁定
  • PropertySourcesPlaceholderConfigurer 解析 ${...} 佔位符
  • Spring Boot 更簡單:application.properties/yml 自動載入,@ConfigurationProperties 類型安全綁定

總結建議

  • 獨立 Java 應用:優先 ClassLoader.getResourceAsStream() 讀取 classpath 資源
  • Web 應用 (非 Spring):ServletContext.getResourceAsStream() 讀取 /WEB-INF/classes/ 或 /WEB-INF/ 下配置
  • 需國際化/ Locale 變體:使用 ResourceBundle 機制
  • 需熱重載:Properties + 文件監聽 / Apache Commons Configuration / Spring Cloud Config
  1. 上一篇文章:
  2. 下一篇文章:
Copyright © 程式碼之家 All Rights Reserved