org.springframework.beans.factory.config.PropertyPlaceholderConfigurer。由这个类别,您可以将一些组态设定,移出至.properties档案中,如此的安排可以让XML定义档负责系统相关设定,而.properties档可 以作为客户根据需求,自定义一些相关的参数。实际上,PropertyPlaceholderConfigurer起的作用就是将占位符指向的数据库配置 信息放在bean中定义的工具。
(1)使用以下方式读取单个本地文件到xml中:
<bean id="propertyConfigurer" class="org.springframework.beans.factory.config.PropertyPlaceholderConfigurer"> <property name="location"> <value>file:/opt/config/config1.properties</value> </property> </bean>
(2)使用以下方式读取多个本地文件到xml中:
<!-- 使用spring提供的PropertyPlaceholderConfigurer读取properties -->
<bean class="org.springframework.beans.factory.config.PropertyPlaceholderConfigurer"> <!-- 属性名是 locations,使用子标签<list></list>可以指定多个数据库的配置文件,这里指定了一个-->
<property name="locations"> <list> <value>file:/opt/config/config1.properties</value>
<value>file:/opt/config/config2.properties</value> </list> </property> <property name="ignoreUnresolvablePlaceholders" value="true"/> </bean> <dubbo:application name="lease-risk-consumer"/> <!-- 读取本地配置文件 --> <dubbo:registry address="${dubbo.registry.address}"/>
注意读取单个配置文件,使用location,多个使用locations
上面是介绍org.springframework.beans.factory.config.PropertyPlaceholderConfigurer工具类的具体使用,下面浅析Spring框架下PropertyPlaceholderConfigurer类
package org.springframework.beans.factory.config; import java.util.Properties; import java.util.Set; import org.springframework.beans.BeansException; import org.springframework.core.Constants; import org.springframework.util.PropertyPlaceholderHelper; import org.springframework.util.PropertyPlaceholderHelper.PlaceholderResolver; import org.springframework.util.StringValueResolver; public class PropertyPlaceholderConfigurer extends PlaceholderConfigurerSupport { /** 是否覆盖proprties文件 */ public static final int SYSTEM_PROPERTIES_MODE_NEVER = 0; /** * 默认值,不存在时覆盖 */ public static final int SYSTEM_PROPERTIES_MODE_FALLBACK = 1; /**覆盖proprties文件*/ public static final int SYSTEM_PROPERTIES_MODE_OVERRIDE = 2; private static final Constants constants = new Constants(PropertyPlaceholderConfigurer.class); private int systemPropertiesMode = SYSTEM_PROPERTIES_MODE_FALLBACK; private boolean searchSystemEnvironment = true; public void setSystemPropertiesModeName(String constantName) throws IllegalArgumentException { this.systemPropertiesMode = constants.asNumber(constantName).intValue(); } public void setSystemPropertiesMode(int systemPropertiesMode) { this.systemPropertiesMode = systemPropertiesMode; } public void setSearchSystemEnvironment(boolean searchSystemEnvironment) { this.searchSystemEnvironment = searchSystemEnvironment; } protected String resolvePlaceholder(String placeholder, Properties props, int systemPropertiesMode) { String propVal = null; if (systemPropertiesMode == SYSTEM_PROPERTIES_MODE_OVERRIDE) { propVal = resolveSystemProperty(placeholder); } if (propVal == null) { propVal = resolvePlaceholder(placeholder, props); } if (propVal == null && systemPropertiesMode == SYSTEM_PROPERTIES_MODE_FALLBACK) { propVal = resolveSystemProperty(placeholder); } return propVal; } protected String resolvePlaceholder(String placeholder, Properties props) { return props.getProperty(placeholder); } protected String resolveSystemProperty(String key) { try { String value = System.getProperty(key); if (value == null && this.searchSystemEnvironment) { value = System.getenv(key); } return value; } catch (Throwable ex) { if (logger.isDebugEnabled()) { logger.debug("Could not access system property '" + key + "': " + ex); } return null; } } @Override protected void processProperties(ConfigurableListableBeanFactory beanFactoryToProcess, Properties props) throws BeansException { StringValueResolver valueResolver = new PlaceholderResolvingStringValueResolver(props); this.doProcessProperties(beanFactoryToProcess, valueResolver); } @Deprecated protected String parseStringValue(String strVal, Properties props, Set<?> visitedPlaceholders) { PropertyPlaceholderHelper helper = new PropertyPlaceholderHelper( placeholderPrefix, placeholderSuffix, valueSeparator, ignoreUnresolvablePlaceholders); PlaceholderResolver resolver = new PropertyPlaceholderConfigurerResolver(props); return helper.replacePlaceholders(strVal, resolver); } private class PlaceholderResolvingStringValueResolver implements StringValueResolver { private final PropertyPlaceholderHelper helper; private final PlaceholderResolver resolver; public PlaceholderResolvingStringValueResolver(Properties props) { this.helper = new PropertyPlaceholderHelper( placeholderPrefix, placeholderSuffix, valueSeparator, ignoreUnresolvablePlaceholders); this.resolver = new PropertyPlaceholderConfigurerResolver(props); } public String resolveStringValue(String strVal) throws BeansException { String value = this.helper.replacePlaceholders(strVal, this.resolver); return (value.equals(nullValue) ? null : value); } } private class PropertyPlaceholderConfigurerResolver implements PlaceholderResolver { private final Properties props; private PropertyPlaceholderConfigurerResolver(Properties props) { this.props = props; } public String resolvePlaceholder(String placeholderName) { return PropertyPlaceholderConfigurer.this.resolvePlaceholder(placeholderName, props, systemPropertiesMode); } } }
首先看下PropertyPlaceholderConfigurer类的结构
1、注入会初始化property的location属性
public void setLocation(Resource location) { this.locations = new Resource[] {location}; } public void setLocations(Resource[] locations) { this.locations = locations; }
2、SystemPropertiesModeName:SystemPropertiesModeName属性用来指定系统变量(System.getProperty)是否覆盖proprties文件。默认是在配置文件里找不到时使用。三个选项分别是:
SYSTEM_PROPERTIES_MODE_NEVER(不覆盖)
SYSTEM_PROPERTIES_MODE_FALLBACK(默认值,不存在时覆盖)
SYSTEM_PROPERTIES_MODE_OVERRIDE(覆盖)
从源码中可以看出searchSystemEnvironment属性的默认值为true,即允许环境变量覆盖properties中的值。