java如何實(shí)時(shí)動(dòng)態(tài)獲取properties文件的內(nèi)容
實(shí)時(shí)動(dòng)態(tài)獲取properties文件的內(nèi)容
用“ClassLoader.getResourceAsStream”讀取properties文件時(shí)會(huì)發(fā)現(xiàn)修改了.properties后,即使重新執(zhí)行,讀入的仍為修改前的參數(shù)。
此問(wèn)題的原因在于ClassLoader.getResourceAsStream讀入后,會(huì)將.properties保存在緩存中,重新執(zhí)行時(shí)會(huì)從緩存中讀取,而不是再次讀取.properties文件。
動(dòng)態(tài)讀取的代碼
import java.util.Properties;
/**
* 實(shí)時(shí)動(dòng)態(tài)獲取properties文件的值
* @author Administrator
*
*/
public class demo01 {
/**
* 根據(jù)配置變量實(shí)時(shí)獲取配置文件中的值
* @param key 配置名
* @param filePath 配置文件路徑名,例如:test.properties
* @return 配置值
*/
public static String getCurrentPropertiesValue(String key,String filePath){
String value="";
Properties p = new Properties();
try {
//非實(shí)時(shí)動(dòng)態(tài)獲取
//p.load(new InputStreamReader(this.class.getClassLoader().getResourceAsStream(filePath), "UTF-8"));
//下面為動(dòng)態(tài)獲取
String path = Thread.currentThread().getContextClassLoader().getResource("").getPath();
InputStream is = new FileInputStream(path +File.separator+ filePath);
p.load(is);
value=p.getProperty(key);
} catch (UnsupportedEncodingException e) {
e.printStackTrace();
} catch (IOException e) {
e.printStackTrace();
}
return value;
}
}
讀取配置文件 Properties VS ResourceBundle
在java開(kāi)發(fā)中, 對(duì)于一些常用的配置性的信息, 通常會(huì)采用存放在屬性文件中, 因?yàn)樾薷呐渲梦募o(wú)須重新編譯jar包. 對(duì)于屬性文件,通??梢允褂肞roperties和ResourceBundle 兩個(gè)類來(lái)解析. 需要注意的是, 默認(rèn)情況下java工程中的*.properties文件編碼格式是ISO-8859-1, Properties和ResourceBundle也是按照ISO-8859-1格式來(lái)解析屬性文件中字符串的. 所以對(duì)于解析包含中文的熟悉文件時(shí),需要額外注意.
- ResourceBundle: 通常用于解析國(guó)際化資源屬性文件, 會(huì)根據(jù)本地環(huán)境自動(dòng)選擇對(duì)應(yīng)的國(guó)際化資源.
- Properties: 用來(lái)解析普通屬性文件
1. 常用API
1.1 Properties 常用API
Properties 繼承Hashtable<Object,Object>類.
| 方法簽名 | 方法描述 |
|---|---|
| public String getProperty(String key | 獲取屬性文件中的Key, 如果key不存在返回Null |
| public String getProperty(String key, String defaultValue) | 獲取屬性文件中key對(duì)象的value, 如果key不存在則返回默認(rèn)值defaultValue |
| public Object get(String key) | 父類HashTable中的方法, 返回值類型為Object |
1.2 ResourceBundle 常用API
ResourceBundle 是一個(gè)接口, 默認(rèn)使用PropertyResourceBundle來(lái)解析屬性文件.
| 方法簽名 | 方法描述 |
|---|---|
| public Locale getLocale() | 獲取本地國(guó)際化環(huán)境 |
| public Enumeration getKeys() | 獲取屬性文件中所有key |
| public final String getString(String key) | 獲取屬性文件中key對(duì)應(yīng)的value, 返回值為String, 如果不存在, 則拋出異常 |
| public final Object getObject(String key) | 獲取屬性文件中key對(duì)應(yīng)的value, 返回值為Object, 如果不存在, 則拋出異常 |
2. Properties 解析屬性文件
默認(rèn)使用ISO-8859-1 解析配置文件中的字符串, 所以會(huì)導(dǎo)致中文亂碼.
2.1 解析純英文配置文件
// 默認(rèn)編碼(ISO-8859-1)讀取屬性文件, 中文亂碼
@Test
public void test_properties_en() throws IOException{
// 屬性文件位置, 相對(duì)路徑為src/main/resources 或 src/test/resources, 不能添加classpath:/前綴
String propertyFileName = "jdbc.properties";
// 獲取字節(jié)流
InputStream is = getClass().getClassLoader().getResourceAsStream(propertyFileName);
// 創(chuàng)建屬性文件, 并加載文件內(nèi)容
Properties properties = new Properties();
properties.load(is);
String username = properties.getProperty("jdbc.username");
String password = properties.getProperty("jdbc.password");
System.out.println("username:" + username + ", password:" + password);
}
2.2 解析含中文配置文件
默認(rèn)使用ISO-8859-1, 采用InputStreamReader轉(zhuǎn)換為UTF8字符流.
// 指定讀取文件編碼方式,支持讀取中文
@Test
public void test_properties_zh() throws IOException{
// 屬性文件位置, 相對(duì)路徑為src/main/resources 或 src/test/resources, 不能添加classpath:/前綴
String propertyFileName = "jdbc.properties";
// 獲取字節(jié)流
InputStream is = getClass().getClassLoader().getResourceAsStream(propertyFileName);
// 轉(zhuǎn)換為UTF-8格式字符流
InputStreamReader isr = new InputStreamReader(is, "UTF-8");
// 創(chuàng)建屬性文件, 并加載文件內(nèi)容
Properties properties = new Properties();
properties.load(isr);
String username = properties.getProperty("jdbc.username");
String password = properties.getProperty("jdbc.password");
System.out.println("username:" + username + ", password:" + password);
}
3. ResourceBundle 解析屬性文件
3.1 解析純英文配置文件
@Test
public void testRb_en() {
// 資源配置文件,無(wú)須寫文件后綴名, 默認(rèn)尋找properties文件
String bundleName = "jdbc";
// 設(shè)置本地默認(rèn)環(huán)境為英文環(huán)境
Locale.setDefault(Locale.ENGLISH);
// 指定加載
ResourceBundle rb = ResourceBundle.getBundle(bundleName);
String username = rb.getString("jdbc.username");
String password = rb.getString("jdbc.password");
System.out.println("username:" + username + ", password:" + password);
}
3.2 解析含中文配置文件
// 處理中文
@Test
public void testRb_zh() {
// 資源配置文件,無(wú)須寫文件后綴名, 默認(rèn)尋找properties文件
String bundleName = "jdbc";
// 根據(jù)本地默認(rèn)環(huán)境加載資源配置文件
ResourceBundle rb = ResourceBundle.getBundle(bundleName);
String username = iso2Utf8(rb.getString("jdbc.username"));
String password = iso2Utf8(rb.getString("jdbc.password"));
System.out.println("username:" + username + ", password:" + password);
}
/**
* @Description iso編碼格式字符串轉(zhuǎn)換為UTF8格式
* @param str iso 編碼字符串
* @return
* @author zongf
* @date 2019年1月8日-下午3:55:29
*/
private String iso2Utf8(String str) {
if(null == str) return null;
try {
return new String(str.getBytes("ISO-8859-1"), "UTF-8");
} catch (UnsupportedEncodingException e) {
e.printStackTrace();
}
return null;
}
4. 屬性文件
筆者創(chuàng)建的是maven 工程, 使用的是junit 單元測(cè)試, 所以筆者的配置文件存放在 src/test/resources 目錄下.
jdbc.properties
jdbc.username=張三 jdbc.password=123456
jdbc_zh.properties
jdbc.username=張三 jdbc.password=123456
jdbc_en.properties
jdbc.username=zhangsan jdbc.password=123456
5. 實(shí)戰(zhàn)推薦
筆者認(rèn)為, 一個(gè)設(shè)計(jì)良好的屬性配置類應(yīng)該是一個(gè)常量類, 至少需要符合兩個(gè)設(shè)計(jì)原則:
屬性一旦設(shè)置不可動(dòng)態(tài)修改, 即使在編譯環(huán)境也不能調(diào)用修改方法.
能夠直接通過(guò)類屬性進(jìn)行訪問(wèn), 無(wú)須通過(guò)類對(duì)象訪問(wèn)
自動(dòng)裝配屬性, 而無(wú)須手動(dòng)解析熟悉文件(spring中可借助自帶注解或自定義注解實(shí)現(xiàn))
public class JdbcProperty {
/** 用戶名 */
public static final String username;
/** 用戶密碼 */
public static final String password;
// 在Spring應(yīng)用中,可借助注解或自定義注解進(jìn)行自動(dòng)裝配,筆者此處只針對(duì)一般java應(yīng)用
static {
// 加載屬性文件
ResourceBundle resourceBundle = ResourceBundle.getBundle("jdbc");
// 初始化屬性
username = resourceBundle.getString("jdbc.username");
password = resourceBundle.getString("jdbc.password");
}
}
以上為個(gè)人經(jīng)驗(yàn),希望能給大家一個(gè)參考,也希望大家多多支持腳本之家。
相關(guān)文章
Java獲取指定父節(jié)點(diǎn)、子節(jié)點(diǎn)的方法實(shí)現(xiàn)
在Java中,要獲取指定節(jié)點(diǎn)的父節(jié)點(diǎn)和子節(jié)點(diǎn),通常需要使用 DOM,文中通過(guò)示例代碼介紹的非常詳細(xì),需要的朋友們下面隨著小編來(lái)一起學(xué)習(xí)學(xué)習(xí)吧2024-02-02
POI讀取excel簡(jiǎn)介_(kāi)動(dòng)力節(jié)點(diǎn)Java學(xué)院整理
這篇文章主要介紹了POI讀取excel簡(jiǎn)介,詳細(xì)的介紹了什么是Apache POI和組件,有興趣的可以了解了解一下2017-08-08
Java自定義過(guò)濾器和攔截器實(shí)現(xiàn)ThreadLocal線程封閉
本文主要介紹了Java自定義過(guò)濾器和攔截器實(shí)現(xiàn)ThreadLocal線程封閉,文中通過(guò)示例代碼介紹的非常詳細(xì),對(duì)大家的學(xué)習(xí)或者工作具有一定的參考學(xué)習(xí)價(jià)值,需要的朋友們下面隨著小編來(lái)一起學(xué)習(xí)學(xué)習(xí)吧2022-08-08
SpringMVC之RequestContextHolder詳細(xì)解析
這篇文章主要介紹了SpringMVC之RequestContextHolder詳細(xì)解析,正常來(lái)說(shuō)在service層是沒(méi)有request的,然而直接從controlller傳過(guò)來(lái)的話解決方法太粗暴,后來(lái)發(fā)現(xiàn)了SpringMVC提供的RequestContextHolder,需要的朋友可以參考下2023-11-11
Java實(shí)現(xiàn)一個(gè)簡(jiǎn)易聊天室流程
這篇文章主要介紹了我的java課程設(shè)計(jì)一個(gè)多人聊天室(socket+多線程)本文給大家介紹的非常詳細(xì),對(duì)大家的學(xué)習(xí)或工作具有一定的參考借鑒價(jià)值,需要的朋友可以參考下2022-11-11
如何解決SpringBoot2.6及之后版本取消了循環(huán)依賴的支持問(wèn)題
循環(huán)依賴指的是兩個(gè)或者多個(gè)bean之間相互依賴,形成一個(gè)閉環(huán),SpringBoot從2.6.0開(kāi)始默認(rèn)不允許出現(xiàn)Bean循環(huán)引用,解決方案包括在全局配置文件設(shè)置允許循環(huán)引用存在、在SpringApplicationBuilder添加設(shè)置允許循環(huán)引用、構(gòu)造器注入2024-10-10
Spring Boot實(shí)現(xiàn)STOMP協(xié)議的WebSocket的方法步驟
這篇文章主要介紹了Spring Boot實(shí)現(xiàn)STOMP協(xié)議的WebSocket的方法步驟,小編覺(jué)得挺不錯(cuò)的,現(xiàn)在分享給大家,也給大家做個(gè)參考。一起跟隨小編過(guò)來(lái)看看吧2019-05-05
SpringBoot實(shí)現(xiàn)圖片識(shí)別文字的四種方式小結(jié)
本文主要介紹了SpringBoot實(shí)現(xiàn)圖片識(shí)別文字的四種方式,包括Tess4J,百度智能云,阿里云,騰訊云這四種,具有一定的參考價(jià)值,感興趣的可以了解一下2024-02-02

