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

IT小君   2021-10-27T02:37:39

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

点击广告,支持我们为你提供更好的服务
评论(5)
IT小君

更新

我们后来升级到 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>

这使我们可以拥有静态众所周知的开发位置(第一个默认值),或者通过 env 变量配置的部署位置。配置器按顺序处理这些(即部署的优先于默认值)。

老的

我最终采用了非程序化的方法。我使用 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>
2021-10-27T02:37:40   回复
IT小君

虽然我注意到这个问题需要 2.5.x,但值得指出的是 Spring 3 的 EL 支持(自 2009 年 11 月以来可用)会在这类事情上做一些简短的工作

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

或者

<property name = "userHome" value ="#{ systemProperties['user.home'] }"/>
2021-10-27T02:37:41   回复
IT小君

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

2021-10-27T02:37:41   回复
IT小君

在 Spring.Net 中,我们有IVariableSource接口和PropertyPlaceholderConfigurer,它们能够从环境变量中检索值。也许 Spring Framework for Java 中有类似的东西?

编辑:在 java docs 中也找到了名为 PropertyPlaceholderConfigurer 的相应 java bean

2021-10-27T02:37:41   回复
IT小君

例子:

使用 -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>
2021-10-27T02:37:42   回复