Sandeep
Sandeep

Reputation: 586

loading properties file in spring

One of our team has implemented loading properties this way (see pseudo code below) and advises this approach is right as the client application using this is free to keep the properties in any file. Contrary to the widely used propertyplaceholderconfigurer.

application-context.xml

<bean class="com.mypackage.Myclass">
<property name="xml" value="classpath:"{com.myapp.myproperty1}"> </property> 
</bean>

config.properties

com.myapp.myproperty1=data.xml

edit: I should have added it is data.properties and not data.xml. We want to load a property file (this property file is given in the config.properties as a "property". com.myapp.myproperty1=data.properties

java class

import org.springframework.core.io.Resource;
public class Myclass {

private Resource xmlField;

// setter & getter methods..

}

Is it right to use spring core.io.Resource?

Another reason is the client application wants to load a environment specific configuration. I suggested use the propertyconfigurer and use maven profiles to generate the environment specific build

Can you please advise which one suits which case? and if it differs in different scenarios, please help me point out them?

thanks

Upvotes: 4

Views: 18253

Answers (3)

jtoberon
jtoberon

Reputation: 9036

You can put the properties in any file and still use PropertyPlaceholderConfigurer. Here's an example that satisfies both your coworker's concerns and your desire for environment specific stuff:

<bean id="propertyPlaceholderConfigurer" class="org.springframework.beans.factory.config.PropertyPlaceholderConfigurer">
    <property name="locations">
        <list>
            <!-- default settings -->
            <value>classpath:MyCompany.properties</value>
            <!-- environment-specific settings -->
            <value>classpath:MyCompany.${mycompany.env:dev}.properties</value>
            <!-- keep your coworker happy -->
            <value>classpath:${mycoworker}</value>
            <!-- allows emergency reconfiguration via the local file system -->
            <value>file:///${user.home}/MyCompany.properties</value>
        </list>
    </property>
    <property name="systemPropertiesModeName" value="SYSTEM_PROPERTIES_MODE_OVERRIDE"/>
    <property name="ignoreResourceNotFound" value="true" />
    <!-- should be validated separately, in case users of the library load additional properties -->
    <property name="ignoreUnresolvablePlaceholders" value="false"/> 
</bean>

If you pass in no -D arguments, then you'll pick up the following properties files, where properties in the later files overwrite previously determined values.

  1. MyCompany.properties off the classpath
  2. MyCompany.dev.properties off the classpath
  3. $HOME/MyCompany.properties if it exists

To swap in a production config for #2, just pass -Dmycompany.env=prod to java. Similarly your coworker can pass -Dmycoworker=/some/path/config.properties if he/she wants.

Upvotes: 10

skusunam
skusunam

Reputation: 411

+1 for Dave's suggestion. You should be using PropertyPlaceholderConfigurer for loading\reading properties. Here is the example i just pulled out from my previous project if you wonder how to use this. This example is for loading multiple properties files but the concept is same. Good luck.

<bean id="projectProperties" class="org.springframework.beans.factory.config.PropertiesFactoryBean">
    <property name="locations">
        <list>
            <value>classpath:config.properties</value>
        </list>
    </property>
</bean>

<bean class="org.springframework.beans.factory.config.PropertyPlaceholderConfigurer">
        <property name="properties" ref="projectProperties" />
</bean>

<bean id="uniqueAssetIdRetriever" class="com.mypackage.Myclass">
    <property name="xml" value="${com.myapp.myproperty1}" />
</bean>

Upvotes: 3

Dave Newton
Dave Newton

Reputation: 160291

I'm not sure why a PropertyPlaceholderConfigurator wouldn't have been the correct choice.

I've almost always handled environment-specific configs via a customized PPC that can either (a) get a -D parameter on startup, and/or (b) use the machine name, to decide which property file to load.

For me, this is more convenient than bundling the information in via Maven, since I can more easily test arbitrary configurations from whatever machine I'm on (using a -D property).

Upvotes: 5

Related Questions