java:Apache Commons Configuration2占位符使用方式
1. 占位符基本使用方式
在 Apache Commons Configuration2 中,占位符(Variable Interpolation)是一種強(qiáng)大的功能,允許在配置值中引用其他配置屬性或外部值。
占位符使用 ${前綴:鍵名} 的格式,其中:
- 前綴:用于標(biāo)識(shí)使用哪個(gè) Lookup 實(shí)現(xiàn)來(lái)解析值
- 鍵名:傳遞給 Lookup 實(shí)現(xiàn)的查找鍵
1.1 基本語(yǔ)法
占位符的基本格式為:
${前綴:鍵名}
例如,在配置文件中:
test.url=${classpath:cell-test.key}
test.runtime=${java:runtime}
1.2 工作原理
當(dāng)配置系統(tǒng)遇到占位符時(shí),會(huì)根據(jù)前綴查找對(duì)應(yīng)的 Lookup 實(shí)現(xiàn),然后調(diào)用其 lookup(String key) 方法獲取實(shí)際值。
這個(gè)過(guò)程在 ConfigurationReader 類中可以看到:
public class ConfigurationReader {
public ConfigurationReader() {
// 創(chuàng)建CombinedConfiguration
this.combinedConfig = new CombinedConfiguration();
// 設(shè)置表達(dá)式引擎為默認(rèn)表達(dá)式引擎
this.combinedConfig.setExpressionEngine(DefaultExpressionEngine.instance());
// 獲取StringLookup對(duì)象用于變量插值
InterpolatorStringLookup interpolator = StringLookupFactory.INSTANCE.interpolatorStringLookup();
// 注冊(cè)自定義的classpath前綴Lookup
interpolator.registerLookup("classpath", ClasspathLookup.INSTANCE);
// 為CombinedConfiguration設(shè)置變量插值器
this.combinedConfig.setInterpolator(interpolator);
// ...
}
}
2. 默認(rèn)提供的占位符
Apache Commons Configuration2 通過(guò) DefaultLookups 和 DefaultStringLookup 提供了多種默認(rèn)的占位符實(shí)現(xiàn)。
2.1 DefaultLookups 提供的占位符
DefaultLookups 是 Apache Commons Configuration2 中定義的枚舉類,提供了各種內(nèi)置的 Lookup 實(shí)現(xiàn):
| 前綴 | 描述 | 使用示例 |
|---|---|---|
| base64Decoder | Base64 解碼 | ${base64Decoder:SGVsbG8gV29ybGQ=} |
| base64Encoder | Base64 編碼 | ${base64Encoder:Hello World} |
| const | 常量引用 | ${const:java.io.File.separator} |
| date | 日期格式化 | ${date:yyyy-MM-dd} |
| env | 環(huán)境變量 | ${env:PATH} |
| file | 文件內(nèi)容 | ${file:/path/to/file.txt} |
| java | Java 系統(tǒng)屬性 | ${java:runtime} |
| localhost | 本地主機(jī)信息 | ${localhost:name} |
| properties | 屬性文件 | ${properties:config.properties:key} |
| resourceBundle | 資源綁定 | ${resourceBundle:messages:greeting} |
| script | 腳本執(zhí)行 | ${script:javascript:1+1} |
| sys | 系統(tǒng)屬性(同java) | ${sys:user.home} |
| url | URL內(nèi)容 | ${url:http://example.com} |
| urlDecoder | URL解碼 | ${urlDecoder:https%3A%2F%2Fexample.com} |
| urlEncoder | URL編碼 | ${urlEncoder:https://example.com} |
| xml | XML內(nèi)容 | ${xml:/path/to/file.xml:/root/child/text()} |
2.2 DefaultStringLookup 提供的占位符
DefaultStringLookup 是 Apache Commons Text 庫(kù)中的枚舉類,為字符串查找提供了各種實(shí)現(xiàn):
| 鍵名 | 對(duì)應(yīng)的查找器 | 描述 |
|---|---|---|
| base64Decoder | Base64DecoderStringLookup | Base64 解碼 |
| base64Encoder | Base64EncoderStringLookup | Base64 編碼 |
| const | ConstantStringLookup | Java 常量引用 |
| date | DateStringLookup | 日期格式化 |
| env | EnvironmentVariableStringLookup | 環(huán)境變量 |
| file | FileStringLookup | 文件內(nèi)容讀取 |
| java | JavaPlatformStringLookup | Java 平臺(tái)信息 |
| localhost | LocalHostStringLookup | 本地主機(jī)信息 |
| properties | PropertiesStringLookup | 屬性文件讀取 |
| resourceBundle | ResourceBundleStringLookup | 資源綁定 |
| script | ScriptStringLookup | 腳本執(zhí)行 |
| sys | SystemPropertyStringLookup | 系統(tǒng)屬性 |
| url | UrlStringLookup | URL內(nèi)容讀取 |
| urlDecoder | UrlDecoderStringLookup | URL解碼 |
| urlEncoder | UrlEncoderStringLookup | URL編碼 |
| xml | XmlStringLookup | XML內(nèi)容讀取 |
3. 自定義占位符實(shí)現(xiàn)
3.1 實(shí)現(xiàn) Lookup 接口
要?jiǎng)?chuàng)建自定義占位符,需要實(shí)現(xiàn) Apache Commons Configuration2 的 Lookup 接口。
以下是 ClasspathLookup 的實(shí)現(xiàn)示例:
public class ClasspathLookup implements Lookup {
public static final ClasspathLookup INSTANCE = new ClasspathLookup();
@Override
public Object lookup(String variable) {
if(Strings.isNullOrEmpty(variable)) {
return null;
}
URL resourceUrl = getClass().getClassLoader().getResource(variable);
return (resourceUrl != null) ? resourceUrl : null;
}
}
3.2 注冊(cè)自定義 Lookup
實(shí)現(xiàn) Lookup 接口后,需要將其注冊(cè)到配置系統(tǒng)中。在 ConfigurationReader 類中,可以看到如何注冊(cè)自定義 Lookup:
// 獲取StringLookup對(duì)象用于變量插值
InterpolatorStringLookup interpolator = StringLookupFactory.INSTANCE.interpolatorStringLookup();
// 注冊(cè)自定義的classpath前綴Lookup
interpolator.registerLookup("classpath", ClasspathLookup.INSTANCE);
// 為CombinedConfiguration設(shè)置變量插值器
this.combinedConfig.setInterpolator(interpolator);
3.3 使用自定義占位符
注冊(cè)后,可以在配置文件中使用自定義占位符。根據(jù) ClasspathLookupTest 的示例:
# 在cell-config.properties中定義
test.url=${classpath:cell-test.key}
test.url2=${classpath:nofound.key}
test.runtime=${java:runtime}
3.4 測(cè)試示例
以下是測(cè)試自定義占位符的示例代碼:
@Test
public void test1ClasspathLookup() {
// 讀取通過(guò)classpath前綴定義的資源路徑(URL)
String value = config.getString("test.url");
log("value:{}", value);
assertNotNull(value);
assertNotEquals("${classpath:cell-test.key}", value); // 驗(yàn)證占位符已被解析
// 讀取為URL類型
URL urlValue = config.get(URL.class, "test.url");
log("value:{}", urlValue);
assertNotNull(urlValue);
// 測(cè)試不存在的資源(應(yīng)保留原始占位符)
String notFound = config.getString("test.url2");
log("value:{}", notFound);
assertEquals("${classpath:nofound.key}", notFound); // 資源不存在時(shí)保持原樣
}
4. 實(shí)現(xiàn)細(xì)節(jié)與注意事項(xiàng)
4.1 占位符解析行為
- 當(dāng) Lookup 返回
null時(shí),原始占位符字符串會(huì)被保留 - 占位符可以嵌套使用
- 默認(rèn)情況下,占位符使用
${}格式,可以自定義表達(dá)式引擎更改格式
4.2 ClasspathLookup 實(shí)現(xiàn)特點(diǎn)
- 使用單例模式(INSTANCE 常量)
- 對(duì)空輸入進(jìn)行處理,返回 null
- 當(dāng)資源未找到時(shí)返回 null,而不是拋出異常
- 返回 URL 對(duì)象,而不是路徑字符串
4.3 性能考慮
- 頻繁使用的 Lookup 實(shí)現(xiàn)應(yīng)考慮使用緩存
- 對(duì)于資源密集型操作,應(yīng)確保 Lookup 實(shí)現(xiàn)高效
5. 總結(jié)
Apache Commons Configuration2 的占位符機(jī)制提供了靈活強(qiáng)大的配置管理能力:
- 通過(guò)
${前綴:鍵名}格式在配置中引用外部值 - 內(nèi)置多種 Lookup 實(shí)現(xiàn)滿足常見(jiàn)需求
- 可以通過(guò)實(shí)現(xiàn) Lookup 接口輕松擴(kuò)展自定義占位符
ClasspathLookup展示了如何創(chuàng)建從類路徑加載資源的自定義占位符
通過(guò)合理使用占位符,可以構(gòu)建更加靈活、可維護(hù)的配置系統(tǒng),特別是在需要引用外部資源或環(huán)境變量的場(chǎng)景中。
以上為個(gè)人經(jīng)驗(yàn),希望能給大家一個(gè)參考,也希望大家多多支持腳本之家。
參考資料:
Apache Commons Configuration2 官方文檔
Apache Commons Text 官方文檔
相關(guān)文章
舉例說(shuō)明JAVA調(diào)用第三方接口的GET/POST/PUT請(qǐng)求方式
在日常工作和學(xué)習(xí)中,有很多地方都需要發(fā)送請(qǐng)求,這篇文章主要給大家介紹了關(guān)于JAVA調(diào)用第三方接口的GET/POST/PUT請(qǐng)求方式的相關(guān)資料,文中通過(guò)代碼介紹的非常詳細(xì),需要的朋友可以參考下2024-01-01
一篇文章帶你搞定SpringBoot中的熱部署devtools方法
這篇文章主要介紹了一篇文章帶你搞定SpringBoot中的熱部署devtools方法,文中通過(guò)示例代碼介紹的非常詳細(xì),對(duì)大家的學(xué)習(xí)或者工作具有一定的參考學(xué)習(xí)價(jià)值,需要的朋友們下面隨著小編來(lái)一起學(xué)習(xí)學(xué)習(xí)吧2020-09-09
SpringAop中AspectJ框架的切入點(diǎn)表達(dá)式
這篇文章主要介紹了SpringAop中AspectJ框架的切入點(diǎn)表達(dá)式,AspectJ是一個(gè)基于Java語(yǔ)言的AOP框架,Spring2.0以后新增了對(duì)AspectJ切點(diǎn)表達(dá)式支持,@AspectJ 是AspectJ1.5新增功能,通過(guò)JDK5注解技術(shù),允許直接在Bean類中定義切面,需要的朋友可以參考下2023-08-08
SpringWebMVC的常用注解及應(yīng)用分層架構(gòu)詳解
這篇文章主要介紹了SpringWebMVC的常用注解及應(yīng)用分層架構(gòu),SpringWebMVC是基于ServletAPI構(gòu)建的原始Web框架,從?開始就包含在Spring框架中,感興趣的朋友可以參考下2024-05-05
idea下的工具欄中services不見(jiàn)了,如何調(diào)用出來(lái)
這篇文章主要介紹了idea下的工具欄中services不見(jiàn)了,如何調(diào)用出來(lái)的解決方案,具有很好的參考價(jià)值,希望對(duì)大家有所幫助,如有錯(cuò)誤或未考慮完全的地方,望不吝賜教2025-05-05
Java實(shí)現(xiàn)調(diào)用第三方相關(guān)接口
最近在做一個(gè)項(xiàng)目,需要調(diào)用第三方接口,本文主要介紹了Java實(shí)現(xiàn)調(diào)用第三方相關(guān)接口,具有一定的參考價(jià)值,感興趣的可以了解一下2023-09-09
MyBatis-plus實(shí)現(xiàn)逆向生成器
本文主要介紹了MyBatis-plus實(shí)現(xiàn)逆向生成器,文中通過(guò)示例代碼介紹的非常詳細(xì),對(duì)大家的學(xué)習(xí)或者工作具有一定的參考學(xué)習(xí)價(jià)值,需要的朋友們下面隨著小編來(lái)一起學(xué)習(xí)學(xué)習(xí)吧2022-08-08

