我的问题如下:
我有server.properties
针对不同的环境。通过名为propertyPath
的系统属性提供了这些属性的路径。如何指示我的applicationContext.xml
使用给定的propertyPath
系统属性加载属性,而没有调用MethodInvokingBean
System.getProperty('');
我的applicationContext.xml
<bean id="systemPropertyConfigurer" class="org.springframework.beans.factory.config.PropertyPlaceholderConfigurer">
<property name="systemPropertiesModeName" value="SYSTEM_PROPERTIES_MODE_OVERRIDE"/>
<property name="placeholderPrefix" value="sys{"/>
<property name="properties">
<props>
<prop key="propertyPath">/default/path/to/server.properties</prop>
</props>
</property>
</bean>
<bean id="propertyResource" class="org.springframework.core.io.FileSystemResource" dependency-check="all" depends-on="systemPropertyConfigurer">
<constructor-arg value="sys{propertyPath}"/>
</bean>
<bean id="serviceProperties" class="org.springframework.beans.factory.config.PropertiesFactoryBean">
<property name="location" ref="propertyResource"/>
</bean>
<bean id="propertyConfigurer" class="org.springframework.beans.factory.config.PropertyPlaceholderConfigurer">
<property name="location" ref="propertyResource"/>
<property name="placeholderPrefix" value="prop{"/>
<property name="ignoreUnresolvablePlaceholders" value="true"/>
<property name="ignoreResourceNotFound" value="false"/>
</bean>
<bean id="dataSource" class="org.springframework.jndi.JndiObjectFactoryBean">
<property name="jndiName" value="prop{datasource.name}"/>
</bean>
使用此配置,propertyResource也会抱怨
java.io.FileNotFoundException: sys{propertyPath} (The system cannot find the file specified)
有什么建议吗? ;-) 谢谢gabe
编辑:
现在我调试了bean的加载过程,似乎在创建setLocation
之前调用了propertyConfigurer
的{{1}}方法,因此使用“sys {propertyPath”初始化了propertyResource }”。
我玩systemPropertyConfigurer
但没有运气。
答案 0 :(得分:6)
确定。我解决了问题是我的PropertyPlaceholders都是BeanFactoryPostProcessor,它们在加载上下文后被处理,但属性是在之后设置的。所以不可能用另一个填充一个PropertyPlaceholder。
package property.util;
import org.apache.commons.lang.StringUtils;
import org.springframework.beans.factory.config.PropertyPlaceholderConfigurer;
import org.springframework.core.io.FileSystemResource;
import org.springframework.core.io.Resource;
import java.io.IOException;
import java.util.Properties;
/**
* ConfigurablePropertyPlaceholder takes instructions which SystemProperty
* contains the path to the propertyfile to load.
*
* @author Gabe Kaelin
*
*/
public class ConfigurablePropertyPlaceholder extends PropertyPlaceholderConfigurer {
private String propertyLocationSystemProperty;
private String defaultPropertyFileName;
public String getPropertyLocationSystemProperty() {
return propertyLocationSystemProperty;
}
public void setPropertyLocationSystemProperty(String propertyLocationSystemProperty) {
this.propertyLocationSystemProperty = propertyLocationSystemProperty;
}
public String getDefaultPropertyFileName() {
return defaultPropertyFileName;
}
public void setDefaultPropertyFileName(String defaultPropertyFileName) {
this.defaultPropertyFileName = defaultPropertyFileName;
}
/**
* Overridden to fill the location with the path from the {@link #propertyLocationSystemProperty}
*
* @param props propeties instance to fill
* @throws IOException
*/
@Override
protected void loadProperties(Properties props) throws IOException {
Resource location = null;
if(StringUtils.isNotEmpty(propertyLocationSystemProperty)){
String propertyFilePath = System.getProperties().getProperty(propertyLocationSystemProperty);
StringBuilder pathBuilder = new StringBuilder(propertyFilePath);
if(StringUtils.isNotEmpty(defaultPropertyFileName) && !propertyFilePath.endsWith(defaultPropertyFileName)){
pathBuilder.append("/").append(defaultPropertyFileName);
}
location = new FileSystemResource(pathBuilder.toString());
}
setLocation(location);
super.loadProperties(props);
}
}
相应的applicationContext.xml条目
<bean id="propertyConfigurer" class="property.util.ConfigurablePropertyPlaceholder">
<property name="propertyLocationSystemProperty" value="propertyPath" />
<property name="defaultPropertyFileName" value="server.properties" />
<property name="ignoreResourceNotFound" value="false"/>
</bean>
可以使用
启动java进程java -DpropertyPath=/path/to/properties
并加载属性,它们在applicationContext.xml
中可用答案 1 :(得分:2)
扩展PropertyPlaceholderConfigurer的解决方案似乎没问题,但它也应该依赖于标准的org.springframework.beans.factory.config.PropertiesFactoryBean实现,而无需编写任何其他代码。
只需使用Spring将解析的变量引用。
e.g。
按如下方式配置弹簧:
<bean id="configProp"
class="org.springframework.beans.factory.config.PropertiesFactoryBean">
<property name="locations">
<list>
<value>file:${propertyPath}</value>
</list>
</property>
</bean>
一旦使用env变量(propertyPath)调用Java,Spring将解析它,加载属性文件并将其注入应用程序上下文
java -DpropertyPath=/path/to/properties
答案 2 :(得分:1)
您有两种选择:
使用sys:
作为前缀(因此sys:propertyPath
)
将占位符配置程序的placeholderSuffix
属性设置为}
,以便您可以使用sys{prop}
访问属性。如果省略此属性,则必须使用sys{prop