Загрузка свойств с помощью Spring (через системные свойства) - PullRequest
9 голосов
/ 07 мая 2010

Моя проблема заключается в следующем:

У меня есть server.properties для разных сред. Путь к этим свойствам предоставляется через системное свойство с именем propertyPath. Как я могу поручить своему applicationContext.xml загружать свойства с данным системным свойством propertyPath без какого-либо уродливого MethodInvokingBean, который вызывает System.getProperty('');

Мое приложениеContext.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)

Есть предложения? ;-) Спасибо, Гейб

EDIT:

Теперь я отладил процесс загрузки bean-компонентов, и кажется, что setLocation Метод propertyConfigurer вызывается до создания systemPropertyConfigurer, поэтому propertyResource инициализируется с помощью "sys {propertyPath}". Я играл с depends-on, но не повезло.

Ответы [ 3 ]

6 голосов
/ 11 мая 2010

Хорошо.Я решил это.Проблема в том, что оба моих 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

2 голосов
/ 01 сентября 2014

Решение, данное для расширения PropertyPlaceholderConfigurer, кажется приемлемым, но оно также должно работать на основе стандартной реализации org.springframework.beans.factory.config.PropertiesFactoryBean без написания дополнительного кода.

Просто используйте ссылку на переменную, котораябудет разрешен Spring.

например,

Сконфигурируйте spring следующим образом:

<bean id="configProp"
      class="org.springframework.beans.factory.config.PropertiesFactoryBean">
    <property name="locations">
        <list>
            <value>file:${propertyPath}</value>
        </list>
    </property>
</bean>

Как только вы вызовете Java с переменной env (propertyPath), Spring разрешит ее,загрузить файл свойств и вставить его в контекст приложения

java -DpropertyPath=/path/to/properties

1 голос
/ 07 мая 2010

У вас есть два варианта:

  • используйте sys: в качестве префикса (и, следовательно, sys:propertyPath)

  • установите для свойства placeholderSuffix заполнителя конфигурации значение }, чтобы вы могли получить доступ к свойствам с помощью sys{prop}. Если вы опустите это свойство, вам придется использовать sys{prop

Добро пожаловать на сайт PullRequest, где вы можете задавать вопросы и получать ответы от других членов сообщества.
...