property-placeholder
占位符的用法,详见https://zetcode.com/spring/propertyplaceholder/
解析
解析的实现类是PropertyPlaceholderBeanDefinitionParser,此类的父类继承体系和property-override的PropertyOverrideBeanDefinitionParser完全一样,所以整体的处理套路也是基本一致。为什么会一致呢,查看此配置拥有的属性就会发现,和property-override很多都是一样的,所以这里只对不一样的而进行说明。
PropertyPlaceholderBeanDefinitionParser.doParse:
@Override
protected void doParse(Element element, BeanDefinitionBuilder builder) {
super.doParse(element, builder);
builder.addPropertyValue("ignoreUnresolvablePlaceholders",
Boolean.valueOf(element.getAttribute("ignore-unresolvable")));
String systemPropertiesModeName = element.getAttribute(SYSTEM_PROPERTIES_MODE_ATTRIBUTE);
if (StringUtils.hasLength(systemPropertiesModeName) &&
!systemPropertiesModeName.equals(SYSTEM_PROPERTIES_MODE_DEFAULT)) {
builder.addPropertyValue("systemPropertiesModeName", "SYSTEM_PROPERTIES_MODE_"
+ systemPropertiesModeName);
}
if (element.hasAttribute("value-separator")) {
builder.addPropertyValue("valueSeparator", element.getAttribute("value-separator"));
}
if (element.hasAttribute("trim-values")) {
builder.addPropertyValue("trimValues", element.getAttribute("trim-values"));
}
if (element.hasAttribute("null-value")) {
builder.addPropertyValue("nullValue", element.getAttribute("null-value"));
}
}
system-properties-mode
Spring会将java的System.getProperties也当做属性的来源,此配置用于设置系统的和本地文件的同名属性的覆盖方式(谁覆盖谁),自己看文档去。
value-separator
用于配置默认的值的分隔符:
<bean id="student" class="base.Student">
<property name="name" value="${student.name:skywalker}" />
</bean>
如果属性文件里没有student.name,那么就是skywalker。默认就是:。
null-value
遇到哪些值应该当做空处理,比如可以把空串""设为这个,默认不对任何值进行处理。
trim-values
是否移除开头和结尾的空格,按理说应该是布尔值,但是Spring没有提供可以选择的值,经过测试发现设为true或是false都会把空格干掉,不知道什么鬼。
BeanDefinition
这次是PropertySourcesPlaceholderConfigurer,其类图:
运行
PropertySourcesPlaceholderConfigurer.postProcessBeanFactory:
@Override
public void postProcessBeanFactory(ConfigurableListableBeanFactory beanFactory) throws BeansException {
if (this.propertySources == null) {
this.propertySources = new MutablePropertySources();
if (this.environment != null) {
this.propertySources.addLast(
new PropertySource<Environment>(ENVIRONMENT_PROPERTIES_PROPERTY_SOURCE_NAME,
this.environment) {
@Override
public String getProperty(String key) {
return this.source.getProperty(key);
}
}
);
}
PropertySource<?> localPropertySource =
new PropertiesPropertySource(LOCAL_PROPERTIES_PROPERTY_SOURCE_NAME, mergeProperties());
if (this.localOverride) {
this.propertySources.addFirst(localPropertySource);
}
else {
this.propertySources.addLast(localPropertySource);
}
}
processProperties(beanFactory, new PropertySourcesPropertyResolver(this.propertySources));
this.appliedPropertySources = this.propertySources;
}
从源码中可以看出,如果其内部的propertySources属性不为空(当然默认是空),那么属性文件和系统属性都会被忽略。它的使用场景应该是这样:
不使用property-placeholder标签,以显式的bean定义代替。
处理
处理的过程就是遍历全部BeanDefinition,替换${},不再详细进行详细说明。
|