PropertyResolver
在Spring
中的作用是负责属性解析,例如在XML
中替换占位符(${}
)属性,@Value
注解等
PropertyResolver
PropertySource & PropertySources
在介绍PropertyResolver
之前,先介绍下PropertySource
和PropertySources
。PropertySource
可以看做是包含了name/value
的对象,而PropertySources
则是由多个PropertySource
组成的对象
PropertySource
1 | public abstract class PropertySource<T> { |
PropertySources
1 | public interface PropertySources extends Iterable<PropertySource<?>> { |
MutablePropertySources
是PropertySources
的默认实现,保存了List<PropertySource<?>>
(虽然是list
但是实际上通过PropertySources.name
保证了每个PropertySources
唯一性),并且还添加了添加/删除等方法,例如addFirst(PropertySource<?> propertySource)
,remove(String name)
等
PropertySourcesPropertyResolver
PropertySourcesPropertyResolver
做的事,就是循环PropertySources
,根据属性名称从PropertySource
中获取属性值,并且对属性值做占位符解析替换
写个例子:
1 | public static void main(String[] args) { |
getProperty()方法实现
1 | // PropertySourcesPropertyResolver.java |
resolveNestedPlaceholders()
调用的是AbstractPropertyResolver.resolveNestedPlaceholders()
:
1 | // AbstractPropertyResolver.java部分代码 |
可以看出,占位符处理工作是在PropertyPlaceholderHelper.replacePlaceholders()
中实现:
1 | // PropertyPlaceholderHelper.java |
1.循环依赖
1
2
3
4 mapProperties.put("def", "${abc}");
mapProperties.put("abc", "${def}");
// 或者如下形式
mapProperties.put("a", "${a}"); // IllegalArgumentException
2.占位符递归
1
2
3
4 mapProperties.put("a", "a");
mapProperties.put("b", "b");
mapProperties.put("ab", "${a}");
mapProperties.put("abc", "${a${b}}"); // getProperty("abc") -> 最终输出`a`
3.分隔符使用
1 mapProperties.put("a", "${abc:123}"); // getProperty("a") -> 如果`abc`存在,输出`abc`的值;否则输出`123`