Моя проблема следующие:
Я имею 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 alsways жалуется на
java.io.FileNotFoundException: sys{propertyPath} (The system cannot find the file specified)
Какие-либо предложения?;-) Спасибо gabe
Править:
Теперь я отладил процесс загрузки бобов, и это кажется setLocation
Метод propertyConfigurer
назван перед systemPropertyConfigurer
создается так, propertyResource инициализируется с "sys {propertyPath}". Я играл вокруг с depends-on
но никакая удача.
Хорошо. Я решил это. Проблема в том, что оба моих PropertyPlaceholder - это 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
У вас есть два варианта:
использовать sys:
в качестве префикса (и, следовательно, sys: propertyPath
)
установите для свойства placeholderSuffix
конфигуратора заполнителя значение }
, чтобы вы могли получить доступ к свойствам с помощью sys {prop}
. Если вы опустите это свойство, вам придется использовать sys {prop