我可以为Spring FileSystemResource使用基于环境变量的位置吗?

12

我有一个要求,需要将我们所有的属性文件存储在一个目录中。该目录的位置应存储在系统环境变量中。在我的应用程序上下文中,我需要访问此环境变量以创建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。


我想我可以使用System.getEnv(String envName)来返回值。但是我不确定在应用程序上下文中是否可以调用该方法? - user130532
2
Spring 4中的@PropertySources提供了一种基于Java配置的方法来实现此功能:@Configuration @PropertySources({ @PropertySource("default.properties"), @PropertySource(value = "file:${CONF_DIR}/optional-override.properties", ignoreResourceNotFound = true) } public class ApplicationConfig { } - chrisjleu
5个回答

15

更新

我们后来升级到Spring 3.0.X,并且我们能够利用spring表达式语言。我们的方法从三个bean简化为以下片段:

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

这使我们可以在开发时(第一个默认值)使用静态已知位置,或通过环境变量配置部署位置。配置器按顺序处理它们(即部署位置优先于默认值)。

旧版

最终我选择了非编程方法。我使用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>

${AN_ENV_CONFIGURED_DIR} 是什么? - fresh_dev
Spring EL。只是一个属性或环境变量(假设您的propertiesplaceholderconfigurer设置为搜索环境变量)。 - user130532
我尝试了你的解决方案,但它并没有起作用。我创建了一个新的环境变量,其中包含特定属性文件的路径。我的两个问题是:1. 你能否提供环境变量的值以及如何在环境变量中定义它?2. 环境变量的值是在运行时还是编译时被替换的?如何知道该值已正确替换? - fresh_dev
设置环境变量是特定于操作系统的。我建议通过谷歌搜索了解如何设置环境变量。在顶部的示例中,我展示了如何配置PropertyPlaceHolderConfigurer。最重要的是<property name="searchSystemEnvironment" value="true" />。如果您想获取更具体的详细信息,请参考Spring文档:http://static.springsource.org/spring/docs/3.0.x/spring-framework-reference/htmlsingle/spring-framework-reference.html#new-feature-el - user130532
您在列表中指定了三个值。运行时,如果Spring在values标签中找到了所有三个属性文件,它会选择哪一个?优先顺序是什么? - rudrasiva86

3

虽然我注意到这个问题需要2.5.x版本,但值得指出的是,自2009年11月以来可用的Spring 3的EL支持可以轻松处理这类事情

@Value("#{ systemProperties['user.home'] }") 
private String userHome ;

或者
<property name = "userHome" value ="#{ systemProperties['user.home'] }"/>

是的,我们最终升级到了Spring 3.0.X。我用我们采用的方法更新了我的最终解决方案。 - user130532

1

您可以始终扩展FileSystemResource(即PropertiesFileResource),它将通过将属性文件位置系统属性预置到文件路径中来初始化自己。


我曾考虑过这样做,但我有三个不同的项目需要用相同的方法来完成。我认为使用一小段XML代码比重复实现同一个类三次更好。 - user130532

1
在Spring.Net中,我们拥有IVariableSource接口和PropertyPlaceholderConfigurer,可以从环境变量中检索值。也许在Java的Spring框架中有类似的东西? 编辑:认为我在Java文档中找到了相应的Java Bean,它也被命名为PropertyPlaceholderConfigurer (参见此处)

0

示例:

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

网页内容由stack overflow 提供, 点击上面的
可以查看英文原文,
原文链接