Categories: spring

Spring @PropertySource & @Value annotations example

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:

  • Spring 4.0.6.RELEASE
  • Maven 3
  • JDK 1.6
  • Eclipse JUNO Service Release 2

Project directory structure

Following will be the final project directory structure for this example:

Let’s add the content mentioned in above directory structure.

Step 1: Provide Spring dependencies in Maven pom.xml

<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>

Step 2: Create Spring Configuration Class

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>

Step 3: Create Sample properties file

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.

Step 4: Create 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.

Step 5: Create Main to run as Java Application

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.

Download Source Code


References

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

  • 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?

      • 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.

Share
Published by

Recent Posts

Spring Boot + AngularJS + Spring Data + JPA CRUD App Example

In this post we will be developing a full-blown CRUD application using Spring Boot, AngularJS, Spring Data, JPA/Hibernate and MySQL,…

8 years ago

Spring Boot Rest API Example

Spring Boot complements Spring REST support by providing default dependencies/converters out of the box. Writing RESTful services in Spring Boot…

8 years ago

Spring Boot WAR deployment example

Being able to start the application as standalone jar is great, but sometimes it might not be possible to run…

8 years ago

Spring Boot Introduction + hello world example

Spring framework has taken the software development industry by storm. Dependency Injection, rock solid MVC framework, Transaction management, messaging support,…

8 years ago

Secure Spring REST API using OAuth2

Let's secure our Spring REST API using OAuth2 this time, a simple guide showing what is required to secure a…

8 years ago

AngularJS+Spring Security using Basic Authentication

This post shows how an AngularJS application can consume a REST API which is secured with Basic authentication using Spring…

8 years ago