In this post we will see how to read values from properties files using Spring @PropertySource
& @Value
annotations. We will also discuss about Spring Environment
interface. We will see corresponding XML configuration as well for side-by-side comparison.
Spring @PropertySource annotations is mainly used to read from properties file using Spring’s Environment interface. This annotation is in practice, placed on @Configuration
classes. Spring @Value annotation can be used to specify expression on field or methods. Common use case is to specify the property from a .properties file along with default value. Let’s see complete example below.
Following technologies being used:
Following will be the final project directory structure for this example:
Let’s add the content mentioned in above directory structure.
<project xmlns="http://maven.apache.org/POM/4.0.0" xmlns:xsi="http://www.w3.org/2001/XMLSchema-instance" xsi:schemaLocation="http://maven.apache.org/POM/4.0.0 http://maven.apache.org/xsd/maven-4.0.0.xsd"> <modelVersion>4.0.0</modelVersion> <groupId>com.websystique.spring</groupId> <artifactId>Spring4PropertySourceExample</artifactId> <version>1.0.0</version> <packaging>jar</packaging> <name>Spring4PropertySourceExample</name> <properties> <springframework.version>4.0.6.RELEASE</springframework.version> </properties> <dependencies> <dependency> <groupId>org.springframework</groupId> <artifactId>spring-core</artifactId> <version>${springframework.version}</version> </dependency> <dependency> <groupId>org.springframework</groupId> <artifactId>spring-context</artifactId> <version>${springframework.version}</version> </dependency> </dependencies> <build> <pluginManagement> <plugins> <plugin> <groupId>org.apache.maven.plugins</groupId> <artifactId>maven-compiler-plugin</artifactId> <version>3.2</version> <configuration> <source>1.6</source> <target>1.6</target> </configuration> </plugin> </plugins> </pluginManagement> </build> </project>
Spring configuration class are the ones annotated with @Configuration
. These classes contains methods annotated with @Bean
. These @Bean annotated methods generates beans managed by Spring container.
package com.websystique.spring.configuration; import org.springframework.context.annotation.Bean; import org.springframework.context.annotation.ComponentScan; import org.springframework.context.annotation.Configuration; import org.springframework.context.annotation.PropertySource; import org.springframework.context.support.PropertySourcesPlaceholderConfigurer; @Configuration @ComponentScan(basePackages = "com.websystique.spring") @PropertySource(value = { "classpath:application.properties" }) public class AppConfig { /* * PropertySourcesPlaceHolderConfigurer Bean only required for @Value("{}") annotations. * Remove this bean if you are not using @Value annotations for injecting properties. */ @Bean public static PropertySourcesPlaceholderConfigurer propertySourcesPlaceholderConfigurer() { return new PropertySourcesPlaceholderConfigurer(); } }
@PropertySource(value = { “classpath:application.properties” }) annotation makes the properties available from named property file[s] (referred by value attribute) to Spring Envirronment
. Environment interface provides getter methods to read the individual property in application.
Notice the PropertySourcesPlaceholderConfigurer
bean method. This bean is required only for resolving ${…} placeholders in @Value annotations. In case you don’t use ${…} placeholders, you can remove this bean altogether.
Above Configuration can be expressed in XML based approach as follows (let’s name it app-config.xml):
<?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: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-4.0.xsd"> <context:component-scan base-package="com.websystique.spring"/> <bean class="org.springframework.context.support.PropertySourcesPlaceholderConfigurer"> <property name="ignoreUnresolvablePlaceholders" value="true"/> <property name="locations"> <list> <value>classpath:application.properties</value> </list> </property> </bean> </beans>
jdbc.driverClassName = com.mysql.jdbc.Driver jdbc.url = jdbc:mysql://localhost:3306/websystique jdbc.username = myuser jdbc.password = mypassword hibernate.dialect = org.hibernate.dialect.MySQLDialect hibernate.show_sql = false hibernate.format_sql = false sourceLocation = /dev/input
We will read the properties from this file using above mentioned configuration in our sample service class.
package com.websystique.spring.service; public interface FileService { void readValues(); }
package com.websystique.spring.service; import org.springframework.beans.factory.annotation.Autowired; import org.springframework.beans.factory.annotation.Value; import org.springframework.core.env.Environment; import org.springframework.stereotype.Service; @Service("fileService") public class FileServiceImpl implements FileService { @Value("${sourceLocation:c:/temp/input}") private String source; @Value("${destinationLocation:c:/temp/output}") private String destination; @Autowired private Environment environment; public void readValues() { System.out.println("Getting property via Spring Environment :" + environment.getProperty("jdbc.driverClassName")); System.out.println("Source Location : " + source); System.out.println("Destination Location : " + destination); } }
First point to notice is Environment got auto-wired by Spring. Thanks to @PropertySoruce annotation , this Environment will get access to all the properties declared in specified .properties file. You can get the value of specif property using getProperty method. Several methods are defined in Environment interface.
Other interesting point here is @Value
annotation. Format of value annotation is
@value("${key:default") private String var;
Above declaration instruct Spring to find a property with key named ‘key’ (from .properties file e.g.) and assign it’s value to variable var.In case property ‘key’ not found, assign value ‘default’ to variable var.
Note that above ${…} placeholder will only be resolved when we have registered PropertySourcesPlaceholderConfigurer
bean (which we have already done above) else the @Value annotation will always assign default values to variable var.
package com.websystique.spring; import org.springframework.context.annotation.AnnotationConfigApplicationContext; import org.springframework.context.support.AbstractApplicationContext; import com.websystique.spring.configuration.AppConfig; import com.websystique.spring.service.FileService; public class AppMain { public static void main(String args[]){ AbstractApplicationContext context = new AnnotationConfigApplicationContext(AppConfig.class); FileService service = (FileService) context.getBean("fileService"); service.readValues(); context.close(); } }
Run above program , you will see following output:
Getting property via Spring Environment :com.mysql.jdbc.Driver Source Location : /dev/input Destination Location : c:/temp/output
Since destinationLocation property was not found in application.properties, it’s got the default value.
That’s it.
For XML based configuration , replace
AbstractApplicationContext context = new AnnotationConfigApplicationContext(AppConfig.class);
with
AbstractApplicationContext context = new ClassPathXmlApplicationContext("app-config.xml");
in above main, no other changes. Run the program and you will see same output.
References
If you like tutorials on this site, why not take a step further and connect me on Facebook , Google Plus & Twitter as well? I would love to hear your thoughts on these articles, it will help improve further our learning process.
In this post we will be developing a full-blown CRUD application using Spring Boot, AngularJS, Spring Data, JPA/Hibernate and MySQL,…
Spring Boot complements Spring REST support by providing default dependencies/converters out of the box. Writing RESTful services in Spring Boot…
Being able to start the application as standalone jar is great, but sometimes it might not be possible to run…
Spring framework has taken the software development industry by storm. Dependency Injection, rock solid MVC framework, Transaction management, messaging support,…
Let's secure our Spring REST API using OAuth2 this time, a simple guide showing what is required to secure a…
This post shows how an AngularJS application can consume a REST API which is secured with Basic authentication using Spring…
View Comments
very nice tutorial ,Iearning a lot .
I compared this tutorial with mkyong.com , you have missed to handle FileNotFoundexception
@PropertySource(value="classpath:missing.properties", ignoreResourceNotFound=true)
Hi,
I am getting the following error while running the above application main class.
Exception in thread "main" org.springframework.beans.factory.NoSuchBeanDefinitionException: No bean named 'fileService' is defined
Hi Tapan, Please make sure that your service implementation class [FileServiceImpl] is annotated appropriately [@Service("fileService")].
Thanks..issue resolved
Why i have this?
Getting property via Spring Environment :com.mysql.jdbc.Driver
Source Location : ${sourceLocation:c:/temp/input}
Destination Location : ${destinationLocation:c:/temp/output}
Hi Igor, With property configuraton, it will first look for the value of sourceLocation into properties, if it found, that value will be used, else default value [mentioned after :] will be used. If you are facing issue with them, it means your resolver is not configured correctly. Are you using Spring Boot?
Thanks for the post. It's clear and i could follow pretty well but after trying it is not working to me.
I created a post in Stack overflow http://stackoverflow.com/questions/33166013/reading-values-from-property-files-in-spring-mvc-using-java-based-anotations where i reference to this one.
Any ideas what could be wrong in my project.
Hi,
Could you please mention the exact version of spring you are using?
Sure.
3.2.6.RELEASE
org.springframework
spring-web
${spring.version}
org.springframework
spring-webmvc
${spring.version}
org.springframework
spring-context
${spring.version}
Hi Jesus,
I tested this example with 3.2.6.RELEASE without any issue. Anyway, Is there a way you could share your minimal runnable code you are trying to run (through github for example)? That would help me to pinpoint particular issue you are getting. You can also use 'contact us' page of this site to send the details if you prefer.
Yes, you are right. I found there is something else.
I can execute this in @Controller classes and in @Services classes, but i also have a @Service class that implements UserDetailsService class.
Using this solution provided by spring, i'm overriding the method:
@Override
public UserDetails loadUserByUsername(String username)
throws UsernameNotFoundException {
and here is where I can not use property source values. I still need to investigate this further to see if there is something wrong in my side.
Thanks for all your assistance.