Properties with Spring

Table of Contents

1. Overview

This tutorial will show how to set up and use Properties in Spring – via XML and <property-placeholder> or Java configuration and @PropertySource.

Before Spring 3.1, adding new properties files into Spring and using property values wasn’t as flexible and as robust as it could be. Starting with Spring 3.1, the new Environment and PropertySource abstractions have simplified then entire process.

Learn to work with Properties in Spring

2. Register a Properties File in XML

In XML, new properties files can be made accessible to Spring via the <context:property-placeholder … >namespace element:

<?xml version="1.0" encoding="UTF-8"?>
<beans xmlns="http://www.springframework.org/schema/beans" 
   xmlns:xsi="http://www.w3.org/2001/XMLSchema-instance" 
   xmlns:context="http://www.springframework.org/schema/context"
   xsi:schemaLocation="
      http://www.springframework.org/schema/beans 
      http://www.springframework.org/schema/beans/spring-beans-3.2.xsd
      http://www.springframework.org/schema/context 
      http://www.springframework.org/schema/context/spring-context-3.2.xsd">

      <context:property-placeholder location="classpath:foo.properties" />

</beans>

The foo.properties file should be placed under /src/main/resources so that it will be available on the classpath at runtime.

2.1. Multiple <property-placeholder>

In case multiple <property-placeholder> elements are present in the Spring context, there are a few best practices that should be followed:

  • the order attribute needs to be specified to fix the order in which these are processed by Spring
  • all property placeholders minus the last one (highest order) should have ignore-unresolvable=”true” to allow the resolution mechanism to pass to others in the context without throwing an exception

3. Register a Properties File via Java Annotations

Spring 3.1 also introduces the new @PropertySource annotation, as a convenient mechanism of adding property sources to the environment. This annotation is to be used in conjunction with Java based configuration and the @Configuration annotation:

@Configuration
@PropertySource("classpath:foo.properties")
public class PropertiesWithJavaConfig {

   @Bean
   public static PropertySourcesPlaceholderConfigurer propertySourcesPlaceholderConfigurer() {
      return new PropertySourcesPlaceholderConfigurer();
   }
}

As opposed to using XML namespace element, the Java @PropertySource annotation does not automatically register a PropertySourcesPlaceholderConfigurer with Spring. Instead, the bean must be explicitly defined in the configuration to get the property resolution mechanism working. The reasoning behind this unexpected behavior is by design and documented on this issue.

4. Using / Injecting Properties

Injecting a property with the @Value annotation is straightforward:

@Value( "${jdbc.url}" )
private String jdbcUrl;

A default value for the property can also be specified:

@Value( "${jdbc.url:aDefaultUrl}" )
private String jdbcUrl;

Using properties in Spring XML configuration:

<bean id="dataSource">
  <property name="url" value="${jdbc.url}" />
</bean>

Both the older PropertyPlaceholderConfigurer and the new PropertySourcesPlaceholderConfigurer added in Spring 3.1 resolve ${…} placeholders within bean definition property values and @Value annotations.

Finally – to obtain the value of a property with the new Environment API:

@Autowired
private Environment env;
...
dataSource.setUrl(env.getProperty("jdbc.url"));

An very important caveat here is that using <property-placeholder> will not expose the properties to the Spring Environment – this means that retrieving the value like this will not work – it will return null:

env.getProperty("key.something")

4.1 Properties Search Precedence

By default, in Spring 4, local properties are search last, after all environment property sources, including properties files. This behavior can be overridden via the localOverride property of the PropertySourcesPlaceholderConfigurer, which can be set to true to allow local properties to override file properties.

In Spring 3.0 and before, the old PropertyPlaceholderConfigurer also attempted to look for properties both in the manually defined sources as well as in the System properties. The lookup precedence was also customizable via the systemPropertiesMode property of the configurer:

  • never – Never check system properties
  • fallback (default) – Check system properties if not resolvable in the specified properties files
  • override – Check system properties first, before trying the specified properties files. This allows system properties to override any other property source.

Finally, note that in case a property is defined in two or more files defined via @PropertySource - the last definition will win and override the previous ones. This makes the exact property value hard to predict, so if overriding is important, the PropertySource API can be used instead.

5. Behind the Scenes – the Spring Configuration

5.1. Before Spring 3.1

Spring 3.1 introduced the convenient option of defining properties sources using annotations – but before that, XML Configuration was necessary for these.

The <context:property-placeholder> XML element automatically registers a new PropertyPlaceholderConfigurer bean in the Spring Context. For backwards compatibility, this is also the case in Spring 3.1 and above if the XSD schemas are not yet upgraded to point to the new 3.1 XSD versions.

5.2. After Spring 3.1

From Spring 3.1 onward, the XML <context:property-placeholder> will no longer register the old PropertyPlaceholderConfigurer but the newly introduced PropertySourcesPlaceholderConfigurer. This replacement class was created to be more flexible and to better interact with the newly introduced Environment and PropertySource mechanism.

For applications using Spring 3.1 or above, this should be considered the standard.

6. Configuration using Raw Beans in Spring 3.0 – the PropertyPlaceholderConfigurer

Besides the convenient methods of getting properties into Spring – annotations and the XML namespace – the property configuration bean can also be defined and registered manually. Working with the PropertyPlaceholderConfigurer gives us full control over the configuration, with the downside of being more verbose and most of the time, unnecessary.

6.1. Java configuration

@Bean
public static PropertyPlaceholderConfigurer properties(){
  PropertyPlaceholderConfigurer ppc = new PropertyPlaceholderConfigurer();
  Resource[] resources = new ClassPathResource[ ]
    { new ClassPathResource( "foo.properties" ) };
  ppc.setLocations( resources );
  ppc.setIgnoreUnresolvablePlaceholders( true );
  return ppc;
}

6.2. XML configuration

<bean class="org.springframework.beans.factory.config.PropertyPlaceholderConfigurer">
  <property name="locations">
    <list>
      <value>classpath:foo.properties</value>
    </list>
  </property>
  <property name="ignoreUnresolvablePlaceholders" value="true"/>
</bean>

7. Configuration using Raw Beans in Spring 3.1 – the PropertySourcesPlaceholderConfigurer

Similarly, in Spring 3.1, the new PropertySourcesPlaceholderConfigurer can also be configured manually:

7.1. Java configuration

@Bean
public static PropertySourcesPlaceholderConfigurer properties(){
  PropertySourcesPlaceholderConfigurer pspc =
    new PropertySourcesPlaceholderConfigurer();
  Resource[] resources = new ClassPathResource[ ]
    { new ClassPathResource( "foo.properties" ) };
  pspc.setLocations( resources );
  pspc.setIgnoreUnresolvablePlaceholders( true );
  return pspc;
}

7.2. XML configuration

<bean class="org.springframework.context.support.PropertySourcesPlaceholderConfigurer">
  <property name="locations">
    <list>
      <value>classpath:foo.properties</value>
    </list>
  </property>
  <property name="ignoreUnresolvablePlaceholders" value="true"/>
</bean>

8. Properties in Parent-Child Contexts

This question keeps coming up again and again – what happens when you web application has a parent and a child context? The parent context may have some common core functionality and beans, and then one (or multiple) child contexts, maybe containing servlet specific beans. In that case, what’s the best way to define properties files and include them into these contexts? What’s more – how to best retrieve these properties form Spring? Here is the simple breakdown.

8.1. If the properties file is defined in XML with <property-placeholder>

If the file is defined in the Parent context:

  • @Value works in Child context: NO
  • @Value works in Parent context: YES

If the file is defined in the Child context:

  • @Value works in Child context: YES
  • @Value works in Parent context: NO

Finally, as we discussed before, <property-placeholder> does not expose the properties to the environment, so:

  • environment.getProperty works in either context: NO

8.2. If the properties file is defined in Java with @PropertySource

If the file is defined in the Parent context:

  • @Value works in Child context: YES
  • @Value works in Parent context: YES
  • environment.getProperty in Child context: YES
  • environment.getProperty in Parent context: YES

If the file is defined in the Child context:

  • @Value works in Child context: YES
  • @Value works in Parent context: YES
  • environment.getProperty in Child context: NO
  • environment.getProperty in Parent context: NO

9. Conclusion

This article showed several examples of working with properties and properties files in Spring, and discussed the older Spring 3.0 options as well as the new support for properties introduced in Spring 3.1. The implementation of this Spring Properties Tutorial can be downloaded as a working sample project.

This is an Eclipse based project, so it should be easy to import and run as it is.

I usually post about Spring stuff on Google+ - you can follow me there:

 

GET THE 3 EBOOKS >>
Download the 3 eBooks - Build Your App "The Right Way"
×
Build Your Web App with Spring (and quickly prototype it to 90%)

,

  • Jennifer Wiss

    Please keep on posting such quality articles as this is a rare thing to find these days. I am always searching online for articles that can help me. Looking forward to another great blog. Good luck to the author! all the best! Plagiarism detection tools

  • Patrick Radtke

    You can also define a default value to use if the property doesn’t exist. “${jdbc.url:myDefaultUrl}”

  • Chris Beams

    Thanks for the write-up, Eugen. See here for more detail on using the Environment API directly within @Configuration classes (over the use of @Value): https://jira.springsource.org/browse/SPR-8539?focusedCommentId=75569&page=com.atlassian.jira.plugin.system.issuetabpanels:comment-tabpanel#comment-75569

  • schochet

    Nice overview. Thanks.

  • sathis

    Hi eugen,

    Can i repost this in my blog?

  • Pay Liu

    hi, the XML configuation miss a small ‘s’. Because the sample use , thanks your this article :)

    wrong:
    correct:

  • Pay Liu

    hi, the XML Configuration miss a small ‘s’. Because this sample use to accept many property files.

    thank you for this article.

    wrong:

    correct:

  • endless

    Any idea how to force PropertySourcesPlaceholderConfigurer use system property override? Currently it seems to ignore that and take the value from the property file.

  • Vlad Tanasescu

    Great article! shouldn’t “” be “” (with an s). For those reading this, remember it won’t work if you use ‘new’ on your component.

    • baeldung

      Thanks for pointing it out – I updated the example.

  • pl47ypus

    great post(!), however, the suggested solution seams to work only when you define the PropertySourcesPlaceholderConfigurer in the same context of the injected bean. i’ll explain:

    in my application i have one application context file: app.xml and two mvc context files: x-servlet.xml and y-servlet.xml. my PropertySourcesPlaceholderConfigurer is configured in the app.xml (which is the parent context of both servlet contexts). the servlet contexts manage @Controller instance that use @Value injection.

    the problem is that spring doesn’t inject embedded values from parent contexts (bean-factories).

    i don’t want to declare the PropertySourcesPlaceholderConfigurer in each *-servlet.xml separately.
    any ideas?

    • baeldung

      That’s an interesting use-case – can you please open an issue on github and I’ll take a look.
      Cheers,
      Eugen.

    • Sravan

      My immeadiate answer to this problem is to have a dummy bean which stores all the properties across the application in the root context. As we know the beans from root context are available to child, It may solve the problem. But I am not sure how good this design is….

    • http://www.baeldung.com/ Eugen Paraschiv

      I updated the article with a clear breakdown of what works and what doesn’t for parent-child contexts. Let me know if this answers your question. Cheers.

  • Manuel Ortiz

    What happens with properties defined at runtime with the -D prefix (eg: -DapiVersion=1.0)? Do they override those defined on files? Are they recognized by the @Value annotation?

    • http://www.baeldung.com/ Eugen Paraschiv

      Hey Manuel – sorry for the late response – yes, a runtime property will override a local one and will be correctly resolved by @Value. Of course, this is only the default – this behavior can be overridden both in XML and in the Java config.
      Cheers,
      Eugen.

  • Lucas Saldanha

    Hi! Do you know if there are any way in Spring to load a list of properties like in Apache Common, repeating the property key, e.g. prop=a, prop=b and prop=c would result in a list like {‘a’, ‘b’, ‘c’}. Or something like prop.1=a, prop.2=b, prop.3=c.

    I tried to find something but all that have come to my mind envolves subclassing the property placeholder. :(

    Thanks!

    • http://www.baeldung.com/ Eugen Paraschiv

      No way to do that as far as I know; having a single property such as: prop.something=a,b,c would be one thing, but loading multiple properties at once, based on a prefix – that’s really an edge case. You could try to roll your own placeholder – or maybe you can step back and see if, since you need that kind of query operation over your data – maybe properties is not the right way to store that data.
      Cheers,
      Eugen.

      • Lucas Saldanha

        Thanks for your reply! :-)

        Do you really think that this is unusual?

        I have a RPC like system where each node can reply to 1 to N operation types. My ideia is that each node reads the operations it handles from a property file. The requests are stored in a message queue system. So the node polls for requests based in the operations it has been assigned.

        With that approach I could choose to tackle the overall load of the system. If an operation A is requested twice than an operation B, I can start a node dedicated to the first one and so on.

        Do you have any sugestion about how to do that node configuration?

        See ya! Thanks again for your help.

        • http://www.baeldung.com/ Eugen Paraschiv

          I am assuming the nodes don’t have any sort of persistence to keep this data (rather then in properties). For light node configuration, you can take a look at Zookeeper – that’s what it’s meant to do.
          Properties are meant to have a single operation – get one by name – and it looks like you basically need more intelligent query operations over them. This is why I said that this is a corner case – not in the sense that it’s extremely rare, but that queries over properties are – in my view – a code smell – a signal that that may not be the right way to store my data (in your case, the operations to be handled), and that I may need real persistence, not just properties files.
          Hope that helps – let me know how it goes,
          Eugen.

  • Rodislav Moldovan

    thanks for detailed explanations, that helped me to understand better this mechanism. I, for example, was using .properties files – loaded and parsed at application start-up, this is working all the time, but I should write all the parsing stuff, which is not a tragedy, but it works every time, even if it’s not very pretty :)

    • http://www.baeldung.com/ Eugen Paraschiv

      Glad it helps – the Spring support is also a lot more flexible than parsing property files manually.

      • Rodislav Moldovan

        yes, I know and I agree, but I had situations when @Value was not instantiated at applications start, etc. now :) everything looks cleaner to me

  • Binh Thanh Nguyen

    Thanks, nice post. It’s helpful to me a lot.

  • Anup

    What a post ..so very informative ..!!.However I wish to add a use case which probably your post does not adher to .

    Use case :- I have a use case where in I wish to read property files dynamically from my java code .

    I also wish to have my value stored in .property file to have dynamic data using place holders.

    In short there is no mention about ResourceBundleMessageSource class of Spring which enables us to use place holder to include dynamic data in the value against the key in .property file.

    • http://www.baeldung.com/ Eugen Paraschiv

      Hey Anup, thanks for the interesting usecase – I’ll take a look and get back to you.
      Cheers,
      Eugen.

    • http://www.baeldung.com/ Eugen Paraschiv

      Hey Anup – so let me see if I understand your usecase correctly. Are you’re trying to set values of these properties at runtime? Or are you just trying to read the properties from the file?
      If you’re trying to set values of properties at runtime – what is the reason for that?
      If you are just reading the properties – why do you need another mechanism (other than env.getProperty()?)
      Cheers,

      Eugen.

      • Anup

        Hey Eugen,

        I wish to read the properties from file .However as mentioned in the previous post ,I cant use env.getProperty() because I wish to put dynamic data in the message that I read from the properties using placeholders. To adher to this use case I had to use org.springframework.context.support.ResourceBundleMessageSource which internally uses ResourceBundle which in turn allows us to insert Dynamic data in the messages against a particular key in properties file.

        For example in my property file i have this entry
        xyzKey= Welcome {0} to the site.

        So while reading it in my code I use the below code :-

        messageSource.getMessage(‘xyzKey’,new String{‘Anup’}, new Locale(“en”,”US”) );

        which would read the value against ‘xyzKey’ and relpace {0} with ‘Anup’ on the fly.

        Cheers,
        Anup

        • http://www.baeldung.com/ Eugen Paraschiv

          I see – well, in that case, you can have a property with that value, but you will of course have no resolution of {0} = you’ll need to handle that yourself. If you also need resulution for the placeholder, then properties are not your best bet, as they are not meant to solve this kind of problem.
          Properties are simple – they have clear purpose and do it well, but they do have their constraints and cannot be used for everything.
          Hope this helps.
          Cheers,
          Eugen.

  • Boxing Cat

    In 7.2 not

    • http://www.baeldung.com/ Eugen Paraschiv

      Nice catch – fixed. Thanks,
      Eugen.

  • Tonio Caputo

    Nice article, all in one, thanks for it !!!!

    One thing its worth to mention, a use case I faced sometime ago not present in this article, how to use a ‘placeholder’ in an import statement, useful when the property value is not known at start time (if not you can just add it as a java property).

    Since spring 3.1 (as you probably already know) you can implement ApplicationContextInitializer and add properties (placeholders) you can use in your imports at runtime, may be its also useful in other use cases I can’t figure out right now.

    Hope this info is useful, and again thanks for your article.

  • Duane

    I can’t seem to download the Spring Properties Tutorial sample project. When I click on the link, it tells me I need to subscribe, but when I enter my email, it redirects me to a page that says I’m already subscribed, with no way I can see to download the sample project.

    • http://www.baeldung.com/ Eugen Paraschiv

      Hey Duane – if you’re already subscribed, that’s the way it should behave, yes. However, you should also receive the email with the download link, regardless of the fact that you’re subscribed. Hope that makes sense – and do let me know if that’s not the case. Cheers,
      Eugen.

  • Jayakumar Jayaraman

    Very useful. Mainly ignore-unresolvable=”true” helped me when I had multiple files and struggled to fix a error due to this.