Can I use an Environment variable based location for Spring FileSystemResource?

前端 未结 5 589
清歌不尽
清歌不尽 2020-12-01 05:45

I have a requirement to have all our properties files be stored in a directory. The location of this directory should be stored in a system environment variable. In my appli

相关标签:
5条回答
  • 2020-12-01 06:21

    In Spring.Net we have got the IVariableSource interface and PropertyPlaceholderConfigurer which are able to retrieve values from environment variables. Maybe there is something similar in the Spring Framework for Java?

    Edit: I think I found the corresponding java bean which is named PropertyPlaceholderConfigurer as well in the java docs.

    0 讨论(0)
  • 2020-12-01 06:25

    UPDATE

    We later upgraded to Spring 3.0.X and we were able to take advantage of the spring expression language. Our approach simplified from three beans to the following snippet:

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

    This allowed us to have either a development (the first defaults) statically well known location, or a deployed location configured via env variables. The configurer processes these in order (i.e. the deployed takes precedence over the defaults).

    OLD

    I ended up going with a non programmatic approach. I used a MethodInvoker to retrieve the environment value. I was able to then pass that into the 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>
    
    0 讨论(0)
  • 2020-12-01 06:27

    while I note that the question required 2.5.x, it's worth pointing out that Spring 3's EL support (available since Nov 2009) would've made short work of this sort of thing

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

    or

    <property name = "userHome" value ="#{ systemProperties['user.home'] }"/>
    
    0 讨论(0)
  • 2020-12-01 06:34

    Example:

    Start you app with -DDA_HOME=c:\temp

    c:\temp must contain directory called "config"

    In c:\temp\config you have file app.properties (for example)

    Extend the Spring loader:

    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);
        }
    }
    

    Specify the new loader and its configuration base:

        <bean id="placeholderConfig"    class="your.Loader">
            <property name="appHome" value="#{systemProperties['DA_HOME']}"/>
            <property name="location" value="app.properties" />
        </bean>
    
    0 讨论(0)
  • 2020-12-01 06:43

    You could always extend the FileSystemResource (i.e. PropertiesFileResource) that would initialize itself by taking prepending the property file location system property to the file path.

    0 讨论(0)
提交回复
热议问题