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 :
- Declare a bean with value of
class
attribute asorg.springframework.beans.factory.config.PropertyPlaceholderConfigurer
in your Spring configuration file. - Add a child
<property>
node with aname
attribute and value as “locations“. - 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 :
- The
id
attribute is not mandatory. - The property
ignoreUnresolvablePlaceholders
set 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. - 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. - 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 class
attribute 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 :
- All the above tweaks apply to this method as well.
- 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 :
- Prior to Spring 3.1 the above
<context:property-placeholder>
element registered an instance oforg.springframework.beans.factory.config.PropertyPlaceholderConfigurer
bean in Spring context. That is, it serves the same purpose as Method 1 above. - Starting Spring v3.1,
<context:property-placeholder>
element registers an instance oforg.springframework.context.support.PropertySourcesPlaceholderConfigurer
bean in Spring context. That is, it serves the purpose of Method 2 described above. - It is mandatory to define context namespace to use
<context:property-placeholder>
element. - Removing
http://www.springframework.org/schema/context
from the root tag of Spring XML configuration will give an error like
http://www.springframework.org/schema/context/spring-context-4.2.xsdno declaration can be found for element 'context:component-scan'
.
Method 4 : Using @PropertySource annotation
This method uses org.springframework.context.annotation.PropertySource
annotation. 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();
}
}
@PropertySource
annotation should be used on classes annotated with @Configuration
. Also, this annotation explicitly requires registering a bean with a static
method 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 @PropertySource
annotation.
@PropertySource
annotation should be used with@Configuration
annotation. In absence of@Configuration
, the property file will not be read. There will be no error but the properties will not be resolved.- When using
@PropertySource
to 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@PropertySource
annotation. 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;
}
To inject its properties with values defined in properties file, the above bean should be declared as :
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.
Very useful to see all methods at one place.
Thanks Vinay..Keep visiting codippa.com
Very useful.
Thank you. Keep visiting !!!