写在前面
本文少量涉及源码分析,对源码感兴趣的朋友可以参考这里。
1:替换单个key
1.1:测试代码
@Test
public void testReplaceSinglePlaceholder() {
PropertyPlaceholderHelper helper = new PropertyPlaceholderHelper("${", "}");
String text = "foo=${foo}";
System.out.println("替换前的值是:" + text);
Properties props = new Properties();
props.setProperty("foo", "bar");
String replacedResult = helper.replacePlaceholders(text, props);
System.out.println("替换后的值是:" + replacedResult);
}
1.2:运行
替换前的值是:foo=${foo}
替换后的值是:foo=bar
2:替换多个key
2.1:测试代码
@Test
public void testReplaceMultiPlaceholder() {
PropertyPlaceholderHelper helper = new PropertyPlaceholderHelper("${", "}");
String text = "foo=${foo},bar=${bar}";
System.out.println("替换前的值是:" + text);
Properties props = new Properties();
props.setProperty("foo", "bar");
props.setProperty("bar", "baz");
String replacedResult = helper.replacePlaceholders(text, props);
System.out.println("替换后的值是:" + replacedResult);
}
2.2:运行
替换前的值是:foo=${foo},bar=${bar}
替换后的值是:foo=bar,bar=baz
3:替换递归属性
3.1:测试代码
@Test
public void testRecurseInProperty() {
PropertyPlaceholderHelper helper = new PropertyPlaceholderHelper("${", "}");
String text = "foo=${bar}";
System.out.println("替换前的值是:" + text);
Properties props = new Properties();
props.setProperty("bar", "${baz}");
props.setProperty("baz", "bar");
String replacedResult = helper.replacePlaceholders(text, props);
System.out.println("替换后的值是:" + replacedResult);
}
3.2:运行
替换前的值是:foo=${bar}
替换后的值是:foo=bar
4:自定义替换占位符数据源
正常是提供一个java.util.Properties
来作为数据源,我们也可以通过org.springframework.util.PropertyPlaceholderHelper.PlaceholderResolver
接口来自定义数据源。
4.1:测试代码
@Test
public void replaceWithSelfDefineSource() {
PropertyPlaceholderHelper helper = new PropertyPlaceholderHelper("${", "}");
String text = "foo=${foo},bar=${bar}";
System.out.println("替换前的值是:" + text);
Properties props = new Properties();
props.setProperty("foo", "bar");
props.setProperty("bar", "baz");
// public String replacePlaceholders(String value, PlaceholderResolver placeholderResolver)
String replacedResult = helper.replacePlaceholders(text, (placeholderName) -> queryWithWithMySource(placeholderName));
System.out.println("替换后的值是:" + replacedResult);
}
private String queryWithWithMySource(String placeholderName) {
String result = "";
if ("foo".equals(placeholderName)) {
result = "bar_selfsource";
} else if ("bar".equals(placeholderName)) {
result = "baz_selfsource";
}
return result;
}
4.2:运行
替换前的值是:foo=${foo},bar=${bar}
替换后的值是:foo=bar_selfsource,bar=baz_selfsource
5:StringValueResolver
org.springframework.util.StringValueResolver
是一个函数接口,源码如下:
@FunctionalInterface
public interface StringValueResolver {
// 解析字符串值,子类,实现该方法,使用自己的策略来解析,如占位符的替换
@Nullable
String resolveStringValue(String strVal);
}
用来定义字符串的解析策略,其实就是将一个字符串转换为另外一个字符串,常见的如占位符的替换,如spring中其子类org.springframework.beans.factory.config.PropertyPlaceholderConfigurer.PlaceholderResolvingStringValueResolver
,我们看下该子类源码:
org.springframework.beans.factory.config.PropertyPlaceholderConfigurer.PlaceholderResolvingStringValueResolver
private class PlaceholderResolvingStringValueResolver implements StringValueResolver {
// 执行替换真正使用的类
privatefinal PropertyPlaceholderHelper helper;
// 提供数据源的类
private final PlaceholderResolver resolver;
public PlaceholderResolvingStringValueResolver(Properties props) {
this.helper = new PropertyPlaceholderHelper(
placeholderPrefix, placeholderSuffix, valueSeparator, ignoreUnresolvablePlaceholders);
this.resolver = new PropertyPlaceholderConfigurerResolver(props);
}
@Override
@Nullable
public String resolveStringValue(String strVal) throws BeansException {
// 调用PropertyReplaceholderHelper替换字符串中的占位符,获取结果
String resolved = this.helper.replacePlaceholders(strVal, this.resolver);
if (trimValues) {
resolved = resolved.trim();
}
return (resolved.equals(nullValue) ? null : resolved);
}
}