使用Spring加载属性(通过系统属性) [英] Loading Properties with Spring (via System Properties)

查看:86
本文介绍了使用Spring加载属性(通过系统属性)的处理方法,对大家解决问题具有一定的参考价值,需要的朋友们下面随着小编来一起学习吧!

问题描述

我的问题如下:

我有server.properties用于不同的环境.这些属性的路径是通过称为propertyPath的系统属性提供的.我如何指示我的applicationContext.xml使用给定的propertyPath系统属性加载属性,而又没有难看的MethodInvokingBean调用System.getProperty('');

I have server.properties for different environments. The path to those properties is provided trough a system property called propertyPath. How can I instruct my applicationContext.xml to load the properties with the given propertyPath system property without some ugly MethodInvokingBean which calls System.getProperty('');

我的applicationContext.xml

My 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总是抱怨

with this configuration the propertyResource alsways complains about

java.io.FileNotFoundException: sys{propertyPath} (The system cannot find the file specified)

有什么建议吗? ;-) 谢谢gabe

Any suggestions? ;-) Thanks gabe

现在,我调试了bean的加载过程,并且似乎在创建systemPropertyConfigurer之前调用了propertyConfigurersetLocation方法,因此,用"sys {propertyPath}"初始化了propertyResource. 我和depends-on一起玩,但是没有运气.

Now I debugged the loading process of the beans and it seems the setLocation Method of the propertyConfigurer is called before the systemPropertyConfigurer is created so the propertyResource is initialized with "sys{propertyPath}". I played around with depends-on but no luck.

推荐答案

好.我解决了问题是我的两个PropertyPlaceholders都是BeanFactoryPostProcessor,它们是在加载上下文之后但在设置属性之后才进行处理的.因此不可能用另一个填充一个PropertyPlaceholder.

Ok. I solved it. The problem is both of my PropertyPlaceholders are BeanFactoryPostProcessor those get processed after the context is loaded but the properties are set after. So it is impossible to populate one PropertyPlaceholder with another.

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条目

The according applicationContext.xml entry

<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中使用

and it loads the properties and they are available in the applicationContext.xml

这篇关于使用Spring加载属性(通过系统属性)的文章就介绍到这了,希望我们推荐的答案对大家有所帮助,也希望大家多多支持IT屋!

查看全文
登录 关闭
扫码关注1秒登录
发送“验证码”获取 | 15天全站免登陆