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

Java 讀取 Properties 配置文件兩大核心方法:ClassLoader 與 ResourceBundle 實戰對比

     編輯:Java 綜合教學

場景:外部化配置管理

數據庫連接參數、第三方服務密鑰、功能開關等不應硬編碼,通過 .properties 文件外部化,運行時動態加載。

項目結構示例

src/
└── main/
    ├── java/
    │   └── com/example/config/
    │       └── ConfigLoader.java
    └── resources/
        └── application.properties

application.properties 內容

jdbc.url=jdbc:mysql://localhost:3306/mydb?useSSL=false&serverTimezone=UTC
jdbc.driver=com.mysql.cj.jdbc.Driver
jdbc.username=root
jdbc.password=secret123
app.feature.cache.enabled=true
app.max.connections=20

方法一:ClassLoader + Properties.load()(推薦通用)

package com.example.config;

import java.io.IOException;
import java.io.InputStream;
import java.util.Properties;

public class ConfigLoader {
    private static final Properties PROPS = new Properties();

    static {
        // 1. 通過類加載器獲取資源流(classpath 根目錄)
        try (InputStream in = ConfigLoader.class.getClassLoader()
                .getResourceAsStream("application.properties")) {
            if (in == null) {
                throw new IllegalStateException("找不到 application.properties");
            }
            PROPS.load(in);
        } catch (IOException e) {
            throw new ExceptionInInitializerError(e);
        }
    }

    public static String get(String key) {
        return PROPS.getProperty(key);
    }

    public static String get(String key, String defaultValue) {
        return PROPS.getProperty(key, defaultValue);
    }

    public static int getInt(String key, int defaultValue) {
        String val = PROPS.getProperty(key);
        return val != null ? Integer.parseInt(val.trim()) : defaultValue;
    }
    
    // 測試
    public static void main(String[] args) {
        System.out.println("URL: " + get("jdbc.url"));
        System.out.println("Driver: " + get("jdbc.driver"));
        System.out.println("Cache: " + get("app.feature.cache.enabled"));
    }
}

關鍵點

  • getClassLoader().getResourceAsStream():從 classpath 根路徑加載,不加前導斜槓
  • ClassName.class.getResourceAsStream("/path"):從 classpath 根路徑加載,需加前導斜槓
  • 靜態代碼塊初始化,全程只讀取一次,線程安全
  • 提供類型轉換輔助方法(int/boolean/long)

方法二:ResourceBundle(專為 i18n 設計,也可用於配置)

package com.example.config;

import java.util.ResourceBundle;

public class ConfigLoaderRB {
    private static final ResourceBundle BUNDLE = 
        ResourceBundle.getBundle("application"); // 不加 .properties,不加路徑

    public static String get(String key) {
        return BUNDLE.getString(key); // 找不到拋 MissingResourceException
    }

    public static String getOrDefault(String key, String defaultValue) {
        try { return BUNDLE.getString(key); }
        catch (Exception e) { return defaultValue; }
    }

    public static void main(String[] args) {
        System.out.println("URL: " + get("jdbc.url"));
        System.out.println("Driver: " + get("jdbc.driver"));
    }
}

ResourceBundle 特性與限制

特性說明
基於鍵值查找getString(key),無 getProperty 類似方法
缓存機制JVM 緩存 Bundle 實例,修改文件需重啟或手動清理緩存
國際化支持自動查找 application_zh_CN.properties 等本地化文件
編碼要求ISO-8859-1,中文需用 native2ascii 轉義或 JDK 9+ 用 UTF-8
異常行為鍵不存在拋 MissingResourceException(Properties 返回 null)

兩種方法對比選型指南

維度Properties + ClassLoaderResourceBundle
適用場景通用配置、數據庫連接、功能開關國際化文本、多語言資源
編碼靈活性UTF-8 直接支持歷史包袱,需注意編碼
鍵缺失處理返回 null,可提供默認值拋異常,需 try-catch
熱加載支持易結合 WatchService 實現緩存機制較難熱加載
推薦度⭐⭐⭐⭐⭐⭐⭐ (非 i18n 場景)

進階:Spring @Value / @ConfigurationProperties 註解注入

實際項目中極少手寫加載代碼,直接用 Spring 注解:

@Configuration
@ConfigurationProperties(prefix = "jdbc")
public class JdbcConfig {
    private String url;
    private String driver;
    private String username;
    private String password;
    // getter/setter
}

// 或單值注入
@Service
public class MyService {
    @Value("${app.max.connections:10}")
    private int maxConnections;
}

總結

  • 通用配置讀取:Properties + ClassLoader 最靈活、編碼友好
  • 國際化文本:ResourceBundle 原生支持 Locale
  • Spring 項目:直接用 @ConfigurationProperties / @Value,零樣板代碼
  • 文件放在 src/main/resources,打包進 JAR 根目錄,ClassLoader 即可訪問
  1. 上一篇文章:
  2. 下一篇文章:
Copyright © 程式碼之家 All Rights Reserved