This post shows how to read properties file in Spring framework using XML configuration or by using @PropertySource
Annotation.
There are scenarios when you have to provide few configuration properties in order to configure the resource like in case of Database you need to provide driver class, DB location, user name and password or in case of sending mail through your application you need to provide properties like SMTP host, user name, password.
Many a times developers put all these details in the Spring XML configuration file itself which is not a good practice. It’s better to put them in a properties file that way you can have specific properties files like db.properties, mail.properties, app.properties etc. and read the property value from that properties file rather than hard coding them. Another advantage is that any change in any setting will require you to change the specific properties file only.
In Spring reading properties file and setting property values can be done using-
- XML configuration
- Using @PropertySource Annotation
Reading properties file in Spring using XML configuration
Suppose you have your Database properties in a properties file called db.properties residing under config folder under resources folder.
db.properties (for connecting to MYSQL DB)
db.driverClassName=com.mysql.jdbc.Driver db.url=jdbc:mysql://localhost:3306/netjs db.username=root db.password=password pool.initialSize=5
Then you can use ${property key} placeholders in <bean> definitions. In order to resolve these placeholders
you must register a PropertySourcesPlaceholderConfigurer
. This happens automatically when using
<context:property-placeholder>
in XML.
Full XML configuration
<?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:aop="http://www.springframework.org/schema/aop" xmlns:context="http://www.springframework.org/schema/context" xsi:schemaLocation="http://www.springframework.org/schema/beans http://www.springframework.org/schema/beans/spring-beans-4.0.xsd http://www.springframework.org/schema/context http://www.springframework.org/schema/context/spring-context.xsd"> <!-- For reading properties files --> <context:property-placeholder location="classpath:config/db.properties" /> <bean id="jdbcTemplate" class="org.springframework.jdbc.core.JdbcTemplate"> <property name="dataSource" ref="dataSource"></property> </bean> <bean id="employeeDAO" class="org.netjs.daoimpl.EmployeeDAOImpl"> <property name="jdbcTemplate" ref="jdbcTemplate"></property> </bean> <bean id="dataSource" class="org.apache.commons.dbcp2.BasicDataSource"> <property name="driverClassName" value = "${db.driverClassName}" /> <property name="url" value = "${db.url}" /> <property name="username" value = "${db.username}" /> <property name="password" value = "${db.password}" /> <property name="initialSize" value = "${pool.initialSize}" /> </bean> </beans>
Reading properties file in Spring using @PropertySource Annotation
Spring also has @PropertySource
annotation (added in Spring 3.1) for reading properties file. It can be used with @Value
annotation to read the value of the given property.
Example Program
Given a file db.properties (as used above) containing the key/value pairs, the following Configuration class uses @PropertySource along with @Value annotation to read properties.
import org.apache.commons.dbcp2.BasicDataSource; import org.springframework.beans.factory.annotation.Value; import org.springframework.context.annotation.Bean; import org.springframework.context.annotation.Configuration; import org.springframework.context.annotation.PropertySource; import org.springframework.context.support.PropertySourcesPlaceholderConfigurer; @Configuration @PropertySource("classpath:config/db.properties") public class DBConfig { @Value("${db.driverClassName}") private String dbDriverClass; @Value("${db.url}") private String dbUrl; @Value("${db.username}") private String dbUser; @Value("${db.password}") private String dbPwd; @Bean public BasicDataSource dataSource() { BasicDataSource ds = new BasicDataSource(); ds.setDriverClassName(dbDriverClass); ds.setUrl(dbUrl); ds.setUsername(dbUser); ds.setPassword(dbPwd); return ds; } //register PropertySourcesPlaceholderConfigurer //in order to resolve ${...} placeholders @Bean public static PropertySourcesPlaceholderConfigurer propertyConfigInDev() { return new PropertySourcesPlaceholderConfigurer(); } }
Here you can see how fields are annotated with @Value(property key name) annotation in order to map them with the specific property in the .properties file.
In order to resolve ${...} placeholders in <bean> definitions or @Value annotations using properties from a PropertySource, one must register a PropertySourcesPlaceholderConfigurer. This happens automatically when using <context:property-placeholder> in XML (in above example), but must be explicitly registered using a static @Bean method when using @Configuration classes. That’s what is done in DBConfig class.
If you want to run this you can use the following class-
import org.apache.commons.dbcp2.BasicDataSource; import org.springframework.context.annotation.AnnotationConfigApplicationContext; import org.springframework.context.support.AbstractApplicationContext; public class App { public static void main(String[] args) { AbstractApplicationContext context = new AnnotationConfigApplicationContext (DBConfig.class); BasicDataSource ds = (BasicDataSource)context.getBean("dataSource"); System.out.println("URL - " + ds.getUrl()); } }
Using @PropertySource Annotation with Spring’s Environment
Rather than using @Value annotation, Environment should be used to read properties file in Spring. Actually @PropertySource annotation adds a PropertySource to Spring's Environment so that can be used to make your code simpler.
Reading properties file example with Environment
import org.apache.commons.dbcp2.BasicDataSource; import org.springframework.beans.factory.annotation.Autowired; import org.springframework.context.annotation.Bean; import org.springframework.context.annotation.Configuration; import org.springframework.context.annotation.PropertySource; import org.springframework.core.env.Environment; @Configuration @PropertySource("classpath:config/db.properties") public class DBConfig { @Autowired private Environment env; @Bean public BasicDataSource dataSource() { BasicDataSource ds = new BasicDataSource(); System.out.println("User " + env.getProperty("db.username")); ds.setDriverClassName(env.getProperty("db.driverClassName")); ds.setUrl(env.getProperty("db.url")); ds.setUsername(env.getProperty("db.username")); ds.setPassword(env.getProperty("db.password")); return ds; } }
In that case you just need to Autowire (or Inject) Environment into your Config class and use Environment object to get property value.
Property overriding with @PropertySource
In cases where a given property key exists in more than one .properties file, the last @PropertySource annotation processed will 'win' and override. For example, given two properties files a.properties and b.properties, consider the following two configuration classes that reference them with @PropertySource annotations:
@Configuration @PropertySource("classpath:/com/myco/a.properties") public class ConfigA { } @Configuration @PropertySource("classpath:/com/myco/b.properties") public class ConfigB { }
The override ordering depends on the order these classes are registered with the application context.
Using ignoreResourceNotFound attribute with @PropertySource
In case your properties file is optional and you don't want exception to be thrown if it doesn't exist you can use ignoreResourceNotFound attribute and set it as true. Default is false.
As example
If you want to load test.properties file and want to ignore the resource if not found then you can do it as-
@Configuration @PropertySource(value="classpath:config/test.properties", ignoreResourceNotFound=true) public class DBConfig { @Autowired private Environment env; .......... ..........
That's all for this topic How to Read Properties File in Spring Framework. If you have any doubt or any suggestions to make please drop a comment. Thanks!
>>>Return to Spring Tutorial Page
Related Topics
You may also like-
is there any way by which i can validate value of each key with in the xml file while loading of after loading the same bean?
ReplyDelete