spring笔记-PropertyPlaceholderHelper
Spring源码解析之PropertyPlaceholderHelper(占位符解析器)
spring配置属性值中可以使用占位符,类似于MessageFormat中的占位符,例如 foo=我是${name},foo的最终值,是由key为name的value的值替换后的最终结果 ;
如果name 的值为 张三 ,那么 foo 就是"我是张三";如果name值是李四,那么foo就是 "我是李四";
Binder 中 的占位符解析器PropertySourcesPlaceholdersResolver
,其内部是PropertyPlaceholderHelper
;
其构造函数中,指定了占位符的标识信息 开始和结束 分别是 ${
和 }
;所以spring中的占位符用他们,当然这是个工具类,我们可以在单独在类似场景中使用;
new PropertyPlaceholderHelper(SystemPropertyUtils.PLACEHOLDER_PREFIX,// "${"
SystemPropertyUtils.PLACEHOLDER_SUFFIX,// "}"
SystemPropertyUtils.VALUE_SEPARATOR,// ":"
true);
1.替换单个key
private final PropertyPlaceholderHelper helper = new PropertyPlaceholderHelper("${", "}");
@Test
public void testWithProperties() {
String text = "foo=${foo}";
Properties props = new Properties();
props.setProperty("foo", "bar");
assertEquals("foo=bar", this.helper.replacePlaceholders(text, props));
}
2.替换多个key
@Test
public void testWithMultipleProperties() {
String text = "foo=${foo},bar=${bar}";
Properties props = new Properties();
props.setProperty("foo", "bar");
props.setProperty("bar", "baz");
assertEquals("foo=bar,bar=baz", this.helper.replacePlaceholders(text, props));
}
3.替换递归属性
@Test
public void testRecurseInProperty() {
String text = "foo=${bar}";
Properties props = new Properties();
props.setProperty("bar", "${baz}");
props.setProperty("baz", "bar");
assertEquals("foo=bar", this.helper.replacePlaceholders(text, props));
}
springboot的demo
@Autowired
private ConfigurableEnvironment configurableEnvironment;
/**
* 配置文件中的内容
* name=I'm [ ${name1} ]
* name1=name1 say my name is [ ${name2} ]
* name2=name2 say my name is [ ${name3} ]
* name3=name3 say i have no name yet;
*/
@Test
void contextLoads() {
Binder binder = Binder.get(configurableEnvironment);
BindResult<String> name = binder.bind("name", String.class);
System.out.println(name.get());
//I'm [ name1 say my name is [ name2 say my name is [ name3 say i have no name yet; ] ] ]
//可嵌套
}
spring内部的处理逻辑,把占位符中间的内容取出,作为key,在propertySouce中,取出value值,如果不是null,就替换,如果还有占位符,继续查找替换。
@Override
public Object resolvePlaceholders(Object value) {
if (value != null && value instanceof String) {
return this.helper.replacePlaceholders((String) value,
this::resolvePlaceholder);
}
return value;
}
protected String resolvePlaceholder(String placeholder) {
if (this.sources != null) {
for (PropertySource<?> source : this.sources) {
Object value = source.getProperty(placeholder);
if (value != null) {
return String.valueOf(value);
}
}
}
return null;
}
4.自定义占位符替换接口,
比如以下在replace时则不通过Properties数据源,而是通过自定义的数据源来处理
@Test
public void testWithResolver() {
String text = "foo=${foo}";
assertEquals("foo=bar",
this.helper.replacePlaceholders(text, new PropertyPlaceholderHelper.PlaceholderResolver() {
@Override
public String resolvePlaceholder(String placeholderName) {
if ("foo".equals(placeholderName)) {
return "bar";
}
else {
return null;
}
}
}));
网友评论