Table of content:
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 will read all the properties files declared by PropertyPlaceholderConfigurerbean to resolve the placeholders at application’s start up time.
Declare a PropertyPlaceholderConfigurer bean in Spring’s application context file as follows:
<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:
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:
<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.
<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).
<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/classes directory (or in the source directory (src) in Eclipse IDE).
<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.
Spring allows us to specify multiple properties files for the PropertyPlaceholderConfigurer bean declaration as follows:
<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.properties files in the application’s classpath.
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 called systemPropertiesModeName of the PropertyPlaceholderConfigurerbean:
<property name="systemPropertiesModeName" value="SYSTEM_PROPERTIES_MODE_FALLBACK" />
Spring provides three modes as follows:
A complete declaration of the PropertyPlaceholderConfigurerbean would look like this:
<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>
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 the PropertyPlaceholderConfigurer bean:
<property name="ignoreResourceNotFound" value="true" />
For example:
<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 PropertyPlaceholderConfigurerbean:
<property name="ignoreUnresolvablePlaceholders" value="true" />
For example:
<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.