java:Apache Commons Configuration2占位符使用方式

 更新时间:2025年12月28日 10:15:07   作者:10km  
Apache Commons Configuration2中的占位符功能允许在配置值中引用其他配置属性或外部值,通过`${前缀:键名}`格式实现,它提供了多种默认的Lookup实现,如base64编码/解码、日期格式化、环境变量、文件读取等,此外,还支持自定义占位符实现,以满足特定需求

1. 占位符基本使用方式

在 Apache Commons Configuration2 中,占位符(Variable Interpolation)是一种强大的功能,允许在配置值中引用其他配置属性或外部值。

占位符使用 ${前缀:键名} 的格式,其中:

  • 前缀:用于标识使用哪个 Lookup 实现来解析值
  • 键名:传递给 Lookup 实现的查找键

1.1 基本语法

占位符的基本格式为:

${前缀:键名}

例如,在配置文件中:

test.url=${classpath:cell-test.key}
test.runtime=${java:runtime}

1.2 工作原理

当配置系统遇到占位符时,会根据前缀查找对应的 Lookup 实现,然后调用其 lookup(String key) 方法获取实际值。

这个过程在 ConfigurationReader 类中可以看到:

public class ConfigurationReader {
    public ConfigurationReader() {
        // 创建CombinedConfiguration
        this.combinedConfig = new CombinedConfiguration();
        // 设置表达式引擎为默认表达式引擎
        this.combinedConfig.setExpressionEngine(DefaultExpressionEngine.instance());
        // 获取StringLookup对象用于变量插值
        InterpolatorStringLookup interpolator = StringLookupFactory.INSTANCE.interpolatorStringLookup();
        // 注册自定义的classpath前缀Lookup
        interpolator.registerLookup("classpath", ClasspathLookup.INSTANCE);
        // 为CombinedConfiguration设置变量插值器
        this.combinedConfig.setInterpolator(interpolator);
        // ...
    }
}

2. 默认提供的占位符

Apache Commons Configuration2 通过 DefaultLookupsDefaultStringLookup 提供了多种默认的占位符实现。

2.1 DefaultLookups 提供的占位符

DefaultLookups 是 Apache Commons Configuration2 中定义的枚举类,提供了各种内置的 Lookup 实现:

前缀描述使用示例
base64DecoderBase64 解码${base64Decoder:SGVsbG8gV29ybGQ=}
base64EncoderBase64 编码${base64Encoder:Hello World}
const常量引用${const:java.io.File.separator}
date日期格式化${date:yyyy-MM-dd}
env环境变量${env:PATH}
file文件内容${file:/path/to/file.txt}
javaJava 系统属性${java:runtime}
localhost本地主机信息${localhost:name}
properties属性文件${properties:config.properties:key}
resourceBundle资源绑定${resourceBundle:messages:greeting}
script脚本执行${script:javascript:1+1}
sys系统属性(同java)${sys:user.home}
urlURL内容${url:http://example.com}
urlDecoderURL解码${urlDecoder:https%3A%2F%2Fexample.com}
urlEncoderURL编码${urlEncoder:https://example.com}
xmlXML内容${xml:/path/to/file.xml:/root/child/text()}

2.2 DefaultStringLookup 提供的占位符

DefaultStringLookup 是 Apache Commons Text 库中的枚举类,为字符串查找提供了各种实现:

键名对应的查找器描述
base64DecoderBase64DecoderStringLookupBase64 解码
base64EncoderBase64EncoderStringLookupBase64 编码
constConstantStringLookupJava 常量引用
dateDateStringLookup日期格式化
envEnvironmentVariableStringLookup环境变量
fileFileStringLookup文件内容读取
javaJavaPlatformStringLookupJava 平台信息
localhostLocalHostStringLookup本地主机信息
propertiesPropertiesStringLookup属性文件读取
resourceBundleResourceBundleStringLookup资源绑定
scriptScriptStringLookup脚本执行
sysSystemPropertyStringLookup系统属性
urlUrlStringLookupURL内容读取
urlDecoderUrlDecoderStringLookupURL解码
urlEncoderUrlEncoderStringLookupURL编码
xmlXmlStringLookupXML内容读取

3. 自定义占位符实现

3.1 实现 Lookup 接口

要创建自定义占位符,需要实现 Apache Commons Configuration2 的 Lookup 接口。

以下是 ClasspathLookup 的实现示例:

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 注册自定义 Lookup

实现 Lookup 接口后,需要将其注册到配置系统中。在 ConfigurationReader 类中,可以看到如何注册自定义 Lookup:

// 获取StringLookup对象用于变量插值
InterpolatorStringLookup interpolator = StringLookupFactory.INSTANCE.interpolatorStringLookup();
// 注册自定义的classpath前缀Lookup
interpolator.registerLookup("classpath", ClasspathLookup.INSTANCE);
// 为CombinedConfiguration设置变量插值器
this.combinedConfig.setInterpolator(interpolator);

3.3 使用自定义占位符

注册后,可以在配置文件中使用自定义占位符。根据 ClasspathLookupTest 的示例:

# 在cell-config.properties中定义
test.url=${classpath:cell-test.key}
test.url2=${classpath:nofound.key}
test.runtime=${java:runtime}

3.4 测试示例

以下是测试自定义占位符的示例代码:

@Test
public void test1ClasspathLookup() {
    // 读取通过classpath前缀定义的资源路径(URL)
    String value = config.getString("test.url");
    log("value:{}", value);
    assertNotNull(value);
    assertNotEquals("${classpath:cell-test.key}", value); // 验证占位符已被解析
    
    // 读取为URL类型
    URL urlValue = config.get(URL.class, "test.url");
    log("value:{}", urlValue);
    assertNotNull(urlValue);
    
    // 测试不存在的资源(应保留原始占位符)
    String notFound = config.getString("test.url2");
    log("value:{}", notFound);
    assertEquals("${classpath:nofound.key}", notFound); // 资源不存在时保持原样
}

4. 实现细节与注意事项

4.1 占位符解析行为

  • 当 Lookup 返回 null 时,原始占位符字符串会被保留
  • 占位符可以嵌套使用
  • 默认情况下,占位符使用 ${} 格式,可以自定义表达式引擎更改格式

4.2 ClasspathLookup 实现特点

  • 使用单例模式(INSTANCE 常量)
  • 对空输入进行处理,返回 null
  • 当资源未找到时返回 null,而不是抛出异常
  • 返回 URL 对象,而不是路径字符串

4.3 性能考虑

  • 频繁使用的 Lookup 实现应考虑使用缓存
  • 对于资源密集型操作,应确保 Lookup 实现高效

5. 总结

Apache Commons Configuration2 的占位符机制提供了灵活强大的配置管理能力:

  1. 通过 ${前缀:键名} 格式在配置中引用外部值
  2. 内置多种 Lookup 实现满足常见需求
  3. 可以通过实现 Lookup 接口轻松扩展自定义占位符
  4. ClasspathLookup 展示了如何创建从类路径加载资源的自定义占位符

通过合理使用占位符,可以构建更加灵活、可维护的配置系统,特别是在需要引用外部资源或环境变量的场景中。

以上为个人经验,希望能给大家一个参考,也希望大家多多支持脚本之家。

参考资料:

Apache Commons Configuration2 官方文档

Apache Commons Text 官方文档

相关文章

  • 举例说明JAVA调用第三方接口的GET/POST/PUT请求方式

    举例说明JAVA调用第三方接口的GET/POST/PUT请求方式

    在日常工作和学习中,有很多地方都需要发送请求,这篇文章主要给大家介绍了关于JAVA调用第三方接口的GET/POST/PUT请求方式的相关资料,文中通过代码介绍的非常详细,需要的朋友可以参考下
    2024-01-01
  • 详解java如何正确使用volatile

    详解java如何正确使用volatile

    这篇文章给大家分享了java如何正确使用volatile的相关知识点内容,有兴趣的朋友可以参考学习下。
    2018-07-07
  • 一篇文章带你搞定SpringBoot中的热部署devtools方法

    一篇文章带你搞定SpringBoot中的热部署devtools方法

    这篇文章主要介绍了一篇文章带你搞定SpringBoot中的热部署devtools方法,文中通过示例代码介绍的非常详细,对大家的学习或者工作具有一定的参考学习价值,需要的朋友们下面随着小编来一起学习学习吧
    2020-09-09
  • SpringAop中AspectJ框架的切入点表达式

    SpringAop中AspectJ框架的切入点表达式

    这篇文章主要介绍了SpringAop中AspectJ框架的切入点表达式,AspectJ是一个基于Java语言的AOP框架,Spring2.0以后新增了对AspectJ切点表达式支持,@AspectJ 是AspectJ1.5新增功能,通过JDK5注解技术,允许直接在Bean类中定义切面,需要的朋友可以参考下
    2023-08-08
  • SpringWebMVC的常用注解及应用分层架构详解

    SpringWebMVC的常用注解及应用分层架构详解

    这篇文章主要介绍了SpringWebMVC的常用注解及应用分层架构,SpringWebMVC是基于ServletAPI构建的原始Web框架,从⼀开始就包含在Spring框架中,感兴趣的朋友可以参考下
    2024-05-05
  • idea下的工具栏中services不见了,如何调用出来

    idea下的工具栏中services不见了,如何调用出来

    这篇文章主要介绍了idea下的工具栏中services不见了,如何调用出来的解决方案,具有很好的参考价值,希望对大家有所帮助,如有错误或未考虑完全的地方,望不吝赐教
    2025-05-05
  • Java BeanUtils工具类常用方法讲解

    Java BeanUtils工具类常用方法讲解

    这篇文章主要介绍了Java BeanUtils工具类常用方法讲解,本篇文章通过简要的案例,讲解了该项技术的了解与使用,以下就是详细内容,需要的朋友可以参考下
    2021-08-08
  • SpringCloud的Hystrix简单介绍

    SpringCloud的Hystrix简单介绍

    这篇文章主要介绍了SpringCloud的Hystrix简单介绍,SpringCloud Hystrix是Netflix开源的一款容错框架,具备服务降级,服务熔断,依赖隔离,监控(Hystrix Dashboard)等功能,同样具有自我保护能力,需要的朋友可以参考下
    2023-07-07
  • Java实现调用第三方相关接口

    Java实现调用第三方相关接口

    最近在做一个项目,需要调用第三方接口,本文主要介绍了Java实现调用第三方相关接口,具有一定的参考价值,感兴趣的可以了解一下
    2023-09-09
  • MyBatis-plus实现逆向生成器

    MyBatis-plus实现逆向生成器

    本文主要介绍了MyBatis-plus实现逆向生成器,文中通过示例代码介绍的非常详细,对大家的学习或者工作具有一定的参考学习价值,需要的朋友们下面随着小编来一起学习学习吧
    2022-08-08

最新评论