Могу ли я использовать местоположение на основе переменных среды для Spring FileSystemResource?
У меня есть требование хранить все наши файлы свойств в каталоге. Местоположение этого каталога должно храниться в переменной системной среды. В моем контексте приложения мне нужно будет получить доступ к этой переменной среды для создания FileSystemResource bean. Вот пример того, что я обычно имел бы:
<bean id="properties" class="org.springframework.beans.factory.config.PropertyPlaceholderConfigurer">
<property name="locations">
<bean class="org.springframework.core.io.FileSystemResource">
<constructor-arg>
<value>myprops.properties</value>
</constructor-arg>
</bean>
</property>
</bean>
Вместо этого мне нужно будет иметь что-то вроде
<value>${prop_file_location}/myprops.properties</value>
Где расположение файла prop является переменной окружения. Кто-нибудь знает простой способ сделать это?
Я использую spring 2.5.6 и java 1.6
Ответы
Ответ 1
UPDATE
Позднее мы обновили до Spring 3.0.X, и нам удалось воспользоваться языком выражения Spring. Наш подход упрощен от трех beans к следующему фрагменту:
<bean id="propertyConfigurer" class="org.springframework.beans.factory.config.PropertyPlaceholderConfigurer">
<property name="locations">
<list>
<value>classpath:defaults.properties</value>
<value>file:/a/defined/location/project.properties</value>
<value>file:${AN_ENV_CONFIGURED_DIR}/project.properties</value>
</list>
</property>
<property name="ignoreResourceNotFound" value="true" />
<property name="searchSystemEnvironment" value="true" />
<property name="systemPropertiesModeName" value="SYSTEM_PROPERTIES_MODE_OVERRIDE" />
</bean>
Это позволило нам иметь либо старое известное местоположение разработки (первое значение по умолчанию), либо развернутое местоположение, настроенное с помощью переменных env. Конфигуратор обрабатывает их по порядку (т.е. Развертывание имеет приоритет над значениями по умолчанию).
OLD
Я закончил работу с не-программным подходом. Я использовал MethodInvoker для извлечения значения среды. Я смог передать это в FileSystemResource.
<bean id="configPath" class="org.springframework.beans.factory.config.MethodInvokingFactoryBean" >
<property name="targetClass" value="java.lang.String" />
<property name="staticMethod" value="java.lang.System.getenv" />
<property name="arguments">
<list>
<value>NAME_OF_VARIABLE</value>
</list>
</property>
</bean>
Ответ 2
в то время как я отмечаю, что вопрос, требуемый 2.5.x, стоит отметить, что поддержка Spring 3 EL (доступная с ноября 2009 года) сделала бы короткую работу такого рода
@Value("#{ systemProperties['user.home'] }")
private String userHome ;
или
<property name = "userHome" value ="#{ systemProperties['user.home'] }"/>
Ответ 3
Вы всегда можете расширить FileSystemResource (то есть PropertiesFileResource), который инициализировал бы себя, предварительно добавив свойство системы местоположения файла свойств в путь к файлу.
Ответ 4
В Spring.Net у нас есть интерфейс IVariableSource и PropertyPlaceholderConfigurer, которые могут извлекать значения из переменных среды. Возможно, что-то похожее в Spring Framework для Java?
Изменить: Я думаю, что нашел соответствующий java bean, который также называется PropertyPlaceholderConfigurer, а в java docs.
Ответ 5
Пример:
Начните приложение с -DDA_HOME = c:\temp
c:\temp должен содержать каталог с именем "config"
В c:\temp\config у вас есть файл app.properties(например)
Разверните загрузчик Spring:
public class Loader extends org.springframework.beans.factory.config.PropertyPlaceholderConfigurer{
private String appHome;
public void setAppHome(String appHome) {
this.appHome = appHome;
}
@Override
public void setLocation(Resource location) {
if(appHome==null){
throw new RuntimeException("You must specify VM property DA_HOME, this directory must contain " +
"another directory, called config, inside the config directory app.properties " +
"file must be found with the configuration properties");
}
String configurationDirectory = appHome + System.getProperty("file.separator") + "config";
String fileName = location.getFilename();
Resource file = new FileSystemResource( configurationDirectory + System.getProperty("file.separator")+ fileName);
super.setLocation(file);
}
}
Укажите новый загрузчик и его конфигурационную базу:
<bean id="placeholderConfig" class="your.Loader">
<property name="appHome" value="#{systemProperties['DA_HOME']}"/>
<property name="location" value="app.properties" />
</bean>