How to load properties file in Spring / Various ways to load Properties file in Spring / Supply bean values from Properties file

Scenario

It is always advisable not to use configuration values inside your application code directly. Rather, supply them through configuration files which are external to the code. For Example, almost all applications involve database interaction wherein they connect to a database. Obviously there are database connection parameters such as database server url, database port etc. If they are hard-coded inside the code, then for every change in those parameters (suppose for a change in database server URL), the code will have to be touched. If they are supplied through an external properties file, then changing them would only require a restart of application or not even that in some cases.

]

There are many ways to load a properties file in Spring. Each of them will be discussed here. First let’s define the properties file which is to be loaded in Spring context. Name of the file is application.properties.

db.url = localhost
db.port = 3306
db.name = codippa

Now let’s come to the methods of loading properties file into Spring context and then populate the above bean values :

Method 1 : Using PropertyPlaceHolderConfigurer

Following steps should be performed in this method :

  1. Declare a bean with value of class attribute as org.springframework.beans.factory.config.PropertyPlaceholderConfigurer in your Spring configuration file.
  2. Add a child <property>node with a nameattribute and value as “locations“.
  3. Add a <value>node as child node of the above <property> node. This child node will have the path of your properties file. Confusing !!! Don’t worry, the below illustration will make everything clear.

The above steps will result into a bean of the following form :

<bean id=”propertyConfigurer”
class=”org.springframework.beans.factory.config.PropertyPlaceholderConfigurer”>
<property name=”ignoreUnresolvablePlaceholders” value=”true” />
<property name=”locations”>
<value>classpath:application.properties</value>
</property>
</bean>

Let’s tweak in :

  1. The idattribute is not mandatory.
  2. The property ignoreUnresolvablePlaceholdersset to true ignores any properties which are not present in the properties file. Default value of this property is false. If this property is set to false and a property is not found in properties file, an exception will be thrown.
  3. Prefix classpath:before the name of properties file instructs Spring to search for the file in all classpath locations else it will search the file at the path provided.
  4. It is also possible to load multiple files using the above bean declaration. The syntax is :

    <property name=”locations”>
    <list>
    <value>classpath:application.properties</value>
    <value>classpath:configuration.properties</value>
    // add any number of files
    </list>
    </property>

Method 2 : Using PropertySourcesPlaceHolderConfigurer

Steps to use this method are exactly the same as the above method. You only need to change the value of classattribute of the bean declaration tag. Property loader bean in this case would look like :

<bean id=”propertyConfigurer”
class=”org.springframework.context.support.PropertySourcesPlaceholderConfigurer”>
<property name=”ignoreUnresolvablePlaceholders” value=”true” />
<property name=”locations”>
<value>classpath:application.properties</value>
</property>
</bean>

Let’s tweak in :

  1. All the above tweaks apply to this method as well.
  2. This method can only be used if you are using Spring v3.1 and above since the class PropertySourcesPlaceholderConfigurer was added in Spring v3.1.

Method 3 : Using context element declaration

A properties file in Spring can also be registered using <context: property-placeholder> element. Just declare an element in your Spring XML configuration file as:

<beans xmlns=”http://www.springframework.org/schema/beans”
xmlns:context=”http://www.springframework.org/schema/context”
xmlns:xsi=”http://www.w3.org/2001/XMLSchema-instance” xmlns:p=”http://www.springframework.org/schema/p”
xmlns:mvc=”http://www.springframework.org/schema/mvc”
xsi:schemaLocation=”http://www.springframework.org/schema/beans
http://www.springframework.org/schema/beans/spring-beans-4.2.xsd
http://www.springframework.org/schema/context
http://www.springframework.org/schema/context/spring-context-4.2.xsd”>

  <context:property-placeholder location=”classpath:application.properties”/>
</beans>

Let’s tweak in :

  1. Prior to Spring 3.1 the above <context:property-placeholder>element registered an instance of org.springframework.beans.factory.config.PropertyPlaceholderConfigurerbean in Spring context. That is, it serves the same purpose as Method 1 above.
  2. Starting Spring v3.1, <context:property-placeholder>element registers an instance of org.springframework.context.support.PropertySourcesPlaceholderConfigurer bean in Spring context. That is, it serves the purpose of Method 2 described above.
  3. It is mandatory to define context namespace to use <context:property-placeholder>element.
  4. Removing http://www.springframework.org/schema/context
    http://www.springframework.org/schema/context/spring-context-4.2.xsd
    from the root tag of Spring XML configuration will give an error like no declaration can be found for element 'context:component-scan'.

Method 4 : Using @PropertySource annotation

This method uses org.springframework.context.annotation.PropertySourceannotation. This annotation takes the location of properties file to be loaded as its argument as given below :

@Configuration
@PropertySource(“classpath:application.properties”)
public class Main {

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

@PropertySourceannotation should be used on classes annotated with @Configuration. Also, this annotation explicitly requires registering a bean with a staticmethod which returns an instance of org.springframework.context.support.PropertySourcesPlaceholderConfigurer. It should be noted that this happens automatically when a property file is loaded using <context: property-placeholder> element (Method 3 described above) but not with @PropertySourceannotation.

Let’s tweak in :
  1. @PropertySourceannotation should  be used with @Configurationannotation. In absence of @Configuration, the property file will not be read. There will be no error but the properties will not be resolved.
  2. When using @PropertySourceto load a properties file, the bean in which properties are utilized should also be created using annotations, that is by using @Component,@Service,etc. annotations and by scanning their package using <context:component-scan>element. A bean declared using XML configuration will not be able to resolve the properties loaded using @PropertySourceannotation. Learn Various ways of bean creation in Spring.

Utilizing loaded properties

Loading a property file into Spring context is what we achieved above. But now the question arises How to use these properties? The properties defined in the properties file need to be injected into bean fields. There are again many ways to do that also. A simple method is discussed below.

Now let’s see the sample java class (or the bean) whose fields will be populated with values from the properties file shown above.

package com.codippa;
   
public class DBParams {
    private String host;
    private String port;
    private String dbName;
  }

This class must be declared as a bean in Spring container either in XML declaration or using annotation. See Various ways to create a bean in Spring to learn more. For this post, we declare this bean in XML configuration file as :
<bean class=”com.codippa.DBParams”>
      <property name=”host” value=”localhost”>
      <property name=”port” value=”3306″>
      <property name=”dbName” value=”codippa”>
</bean>
]

To inject its properties with values defined in properties file, the above bean should be declared as :

<bean class=”com.codippa.DBParams”>
      <property name=”host” value=”${db.url}”>
      <property name=”port” value=”${db.port}”>
      <property name=”dbName” value=”${db.name}”>
</bean>

Here, ${...}is a placeholder which instructs Spring container to resolve the string given between these against properties at runtime. This syntax resembles Ant / JSP EL / log4j syntax.

Find More methods of injecting bean properties in detail.

Reached at the end…Great !!! Would be happy to hear about the quality of this post. Provide your feedback.

4 Comments

Leave a Reply