Thursday, May 14, 2015

PropertyPlaceholderConfigurer bean

Spring allows us to externalize String literals in its context configuration files into external properties files in order to separate application-specific settings from framework-specific configuration. For example, SMTP settings for sending e-mails can be placed in a separate properties file. Then in Spring’s context configuration file we can use placeholders in style of${variable_name} to map the keys declared in the properties files. The following picture explains the concepts:
 Spring externalization to properties diagram
Spring will read all the properties files declared by PropertyPlaceholderConfigurer bean to resolve the placeholders at application’s start up time.

1. A simple example

Declare a PropertyPlaceholderConfigurer bean in Spring’s application context file as follows:
1
2
3
4
5
6
<bean id="mailProperties"
    class="org.springframework.beans.factory.config.PropertyPlaceholderConfigurer">
    <property name="location" value="classpath:mail.properties" />
</bean>
That tells Spring to load the properties file named “mail.properties” in the classpath to resolve any placeholders ${…} found. An exception will be thrown if Spring could not find the specified properties file. The properties file has the following entries:
1
2
3
4
smtp.host=smtp.gmail.com
smtp.port=587
smtp.user=tom@gmail.com
smtp.pass=secret
And the following bean declaration uses some placeholders which will be resolved by Spring:
1
2
3
4
5
6
<bean id="mailSender" class="org.springframework.mail.javamail.JavaMailSenderImpl">
    <property name="host" value="${smtp.host}" />
    <property name="port" value="${smtp.port}" />
    <property name="username" value="${smtp.user}" />
    <property name="password" value="${smtp.pass}" />
</bean>
Spring will replace these placeholders by actual values of the corresponding entries in the properties file. An exception will be thrown if a placeholder could not be resolved, e.g there is no entry with the specified key.


2. Location of the properties files

  • By default, Spring looks for the properties files in the application’s directory. So if we specify:
<property name="location" value="WEB-INF/mail.properties" />
Then it will find the mail.properties file under WEB-INF directory of the application (in case of a Spring MVC application).
We can use the prefix classpath: to tell Spring loads a properties file in the application’s classpath. For example:
<property name="location" value="classpath:mail.properties" />
In case of a Spring MVC application, the mail.properties file should be present in the WEB-INF/classesdirectory (or in the source directory (src) in Eclipse IDE).

  • Use the prefix file:/// or file: to load a properties file from an absolute path. For example:
<property name="location" value="file:///D:/Config/mail.properties" />

NOTE: There is no white space between the prefixes classpath: and file: with the path of properties file.



3. Loading multiple properties files

Spring allows us to specify multiple properties files for the PropertyPlaceholderConfigurer bean declaration as follows:
1
2
3
4
5
6
7
8
9
<bean id="appProperties"
    class="org.springframework.beans.factory.config.PropertyPlaceholderConfigurer">
    <property name="locations">
        <list>
            <value>classpath:mail.properties</value>
            <value>classpath:database.properties</value>
        </list>
    </property>
</bean>
That tells Spring to resolve the placeholders with entries loaded from both mail.properties and database.propertiesfiles in the application’s classpath.


4. Fallback or override with system properties

By default, if a placeholder could not be resolved by the specified properties files, Spring will try to resolve it with a system property. For example, if Spring could not resolve the placeholder ${user.dir}, it will try with the corresponding system property user.dir. This is call system properties mode fallback. We can change this behavior by specifying a property calledsystemPropertiesModeName of the PropertyPlaceholderConfigurer bean:
<property name="systemPropertiesModeName" value="SYSTEM_PROPERTIES_MODE_FALLBACK" />
Spring provides three modes as follows:
    • SYSTEM_PROPERTIES_MODE_FALLBACK: This is the default mode as mentioned above.
    • SYSTEM_PROPERTIES_MODE_OVERRIDE: In this mode, Spring will resolve the placeholders to system properties first. If a system property does exist, its value will override the value in the properties file.
    • SYSTEM_PROPERTIES_MODE_NEVER: Spring will not take system properties into consideration when resolving the placeholders.
A complete declaration of the PropertyPlaceholderConfigurer bean would look like this:
1
2
3
4
5
6
7
8
<bean id="mailProperties"
    class="org.springframework.beans.factory.config.PropertyPlaceholderConfigurer">
    <property name="location" value="classpath:mail.properties" />
    <property name="systemPropertiesModeName" value="SYSTEM_PROPERTIES_MODE_NEVER" />
</bean>



5. Ignoring exceptions

By default, Spring will throw an exception if it could not find a properties file or could not resolve a placeholder. That cause the application fails to start.
To ignore the exception which will be thrown in case a properties file could not be found, specify the following property of thePropertyPlaceholderConfigurer bean:
<property name="ignoreResourceNotFound" value="true" />
For example:
1
2
3
4
5
6
7
8
<bean id="mailProperties"
    class="org.springframework.beans.factory.config.PropertyPlaceholderConfigurer">
    <property name="location" value="classpath:mail.properties" />
    <property name="ignoreResourceNotFound" value="true" />
</bean>
And to ignore the exception which will be thrown in case a placeholder could not be resolved, specify the following property of the PropertyPlaceholderConfigurer bean:
<property name="ignoreUnresolvablePlaceholders" value="true" />
For example:
1
2
3
4
5
6
7
8
<bean id="mailProperties"
    class="org.springframework.beans.factory.config.PropertyPlaceholderConfigurer">
    <property name="location" value="classpath:mail.properties" />
    <property name="ignoreUnresolvablePlaceholders" value="true" />
</bean>
When the property ignoreUnresolvablePlaceholders is set to true and a placeholder could not be resolved, Spring will inject name of the placeholder as it is.





 Source: http://www.codejava.net/frameworks/spring/reading-properties-files-in-spring-with-propertyplaceholderconfigurer-bean

No comments :

Post a Comment