Spring @PropertySource Annotation with Example

In Spring, you can use @PropertySource annotation to externalize your configuration to a properties file. In this article, we will discuss how to use @PropertySource to read a properties file and display the values with @Value and Environment.
The @PropertySource annotation provides a convenient and declarative mechanism for adding a PropertySource to Spring’s Environment. To be used in conjunction with @Configuration classes.

Spring @PropertySource Annotation with Simple Example

In this example, we are reading database configuration from file config.properties file and set these property values to DataSourceConfig class using Environment.
import org.springframework.beans.factory.InitializingBean;
import org.springframework.beans.factory.annotation.Autowired;
import org.springframework.context.annotation.Configuration;
import org.springframework.context.annotation.PropertySource;
import org.springframework.core.env.Environment;

@Configuration
@PropertySource("classpath:config.properties")
public class ProperySourceDemo implements InitializingBean {

 @Autowired
 Environment env;

 @Override
 public void afterPropertiesSet() throws Exception {
  setDatabaseConfig();
 }

 private void setDatabaseConfig() {
  DataSourceConfig config = new DataSourceConfig();
  config.setDriver(env.getProperty("jdbc.driver"));
  config.setUrl(env.getProperty("jdbc.url"));
  config.setUsername(env.getProperty("jdbc.username"));
  config.setPassword(env.getProperty("jdbc.password"));
  System.out.println(config.toString());
 }
}

Spring @PropertySource Annotation Placeholders Example

Any ${…} placeholders present in a @PropertySource resource location will be resolved against the set of property sources already registered against the environment. 
For example:
import org.springframework.beans.factory.InitializingBean;
import org.springframework.beans.factory.annotation.Autowired;
import org.springframework.context.annotation.Configuration;
import org.springframework.context.annotation.PropertySource;
import org.springframework.core.env.Environment;

@Configuration
@PropertySource("classpath:/com/${my.placeholder:default/path}/config.properties")
public class ProperySourceDemo implements InitializingBean {

 @Autowired
 Environment env;

 @Override
 public void afterPropertiesSet() throws Exception {
  setDatabaseConfig();
 }

 private void setDatabaseConfig() {
  DataSourceConfig config = new DataSourceConfig();
  config.setDriver(env.getProperty("jdbc.driver"));
  config.setUrl(env.getProperty("jdbc.url"));
  config.setUsername(env.getProperty("jdbc.username"));
  config.setPassword(env.getProperty("jdbc.password"));
  System.out.println(config.toString());
 }
}
Assuming that "my.placeholder" is present in one of the property sources already registered, e.g. system properties or environment variables, the placeholder will be resolved to the corresponding value. If not, then "default/path" will be used as a default. If no default is specified and a property cannot be resolved, an IllegalArgumentException will be thrown

@PropertySources Annotation - Include multiple properties files

Introduces new @PropertySources to support Java 8 and a better way to include multiple properties files.
 @Configuration
 @PropertySources({
  @PropertySource("classpath:config.properties"),
  @PropertySource("classpath:db.properties")
 })
 public class AppConfig {
  //...
 }
Allow @PropertySource to ignore the not found properties file.
 @Configuration
 @PropertySource("classpath:missing.properties")
 public class AppConfig {
  //...
 }
If missing.properties is not found, the system is unable to start and throws FileNotFoundException
 Caused by: java.io.FileNotFoundException: 
  classpath resource [missiong.properties] cannot be opened because it does not exist
In Spring 4, you can use ignoreResourceNotFound to ignore the not found properties file
 @Configuration
 @PropertySource(value="classpath:missing.properties", ignoreResourceNotFound=true)
 public class AppConfig {
  //...
 }

        @PropertySources({
  @PropertySource(value = "classpath:missing.properties", ignoreResourceNotFound=true),
  @PropertySource("classpath:config.properties")
        })

Spring @PropertySource Annotation Complete Example

Let's create a simple Spring boot maven project to bootstrap quickly.
In this example, we are reading database configuration from file config.properties file and set these property values to DataSourceConfig class.
Create a maven project using Spring Initializr at http://start.spring.io/, which is an online Spring Boot application generator.
Create a packing structure as per above diagram.

The pom.xml File

<?xml version="1.0" encoding="UTF-8"?>
<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>net.guides.springboot2</groupId>
 <artifactId>spring-propertysource-example</artifactId>
 <version>0.0.1-SNAPSHOT</version>
 <packaging>jar</packaging>

 <name>spring-propertysource-example</name>
 <description>Demo project for Spring Boot</description>

 <parent>
  <groupId>org.springframework.boot</groupId>
  <artifactId>spring-boot-starter-parent</artifactId>
  <version>2.0.5.RELEASE</version>
  <relativePath/> <!-- lookup parent from repository -->
 </parent>

 <properties>
  <project.build.sourceEncoding>UTF-8</project.build.sourceEncoding>
  <project.reporting.outputEncoding>UTF-8</project.reporting.outputEncoding>
  <java.version>1.8</java.version>
 </properties>

 <dependencies>
  <dependency>
   <groupId>org.springframework.boot</groupId>
   <artifactId>spring-boot-starter</artifactId>
  </dependency>

  <dependency>
   <groupId>org.springframework.boot</groupId>
   <artifactId>spring-boot-starter-test</artifactId>
   <scope>test</scope>
  </dependency>
 </dependencies>

 <build>
  <plugins>
   <plugin>
    <groupId>org.springframework.boot</groupId>
    <artifactId>spring-boot-maven-plugin</artifactId>
   </plugin>
  </plugins>
 </build>
</project>

Create a config.properties File

Let's create a config.properties file in classpath and we will use @PropertySource annotation to read a properties file and display the values with @Value and Environment.
jdbc.driver=com.mysql.jdbc.Driver
jdbc.url=jdbc:mysql://localhost:3306/dev_db
jdbc.username=root
jdbc.password=root

Create DataSourceConfig.java File

package net.guides.springboot2.springpropertysourceexample;

public class DataSourceConfig {
 private String driver;
 private String url;
 private String username;
 private String password;
 
 @Override
 public String toString()
 {
  return "DataSourceConfig [driver=" + driver + ", url=" + url + ", username=" + username + "]";
 }
 public String getDriver()
 {
  return driver;
 }
 public void setDriver(String driver)
 {
  this.driver = driver;
 }
 public String getUrl()
 {
  return url;
 }
 public void setUrl(String url)
 {
  this.url = url;
 }
 public String getUsername()
 {
  return username;
 }
 public void setUsername(String username)
 {
  this.username = username;
 }
 public String getPassword()
 {
  return password;
 }
 public void setPassword(String password)
 {
  this.password = password;
 }
}

Create ProperySourceDemo.java File

package net.guides.springboot2.springpropertysourceexample;

import org.slf4j.Logger;
import org.slf4j.LoggerFactory;
import org.springframework.beans.factory.InitializingBean;
import org.springframework.beans.factory.annotation.Autowired;
import org.springframework.beans.factory.annotation.Value;
import org.springframework.context.annotation.Configuration;
import org.springframework.context.annotation.PropertySource;
import org.springframework.core.env.Environment;

@Configuration
@PropertySource("classpath:config.properties")
public class ProperySourceDemo implements InitializingBean {

 private static final Logger LOGGER = LoggerFactory.getLogger(ProperySourceDemo.class);

 @Value("${jdbc.driver}")
 private String driver;

 @Value("${jdbc.url}")
 private String url;

 @Value("${jdbc.username}")
 private String username;

 @Value("${jdbc.password}")
 private String password;

 @Autowired
 Environment env;

 @Override
 public void afterPropertiesSet() throws Exception {
  LOGGER.info(driver);
  LOGGER.info(url);
  LOGGER.info(password);
  LOGGER.info(username);
  setDatabaseConfig();
 }

 private void setDatabaseConfig() {
  DataSourceConfig config = new DataSourceConfig();
  config.setDriver(env.getProperty("jdbc.driver"));
  config.setUrl(env.getProperty("jdbc.url"));
  config.setUsername(env.getProperty("jdbc.username"));
  config.setPassword(env.getProperty("jdbc.password"));
  System.out.println(config.toString());
 }
}

The Application.java File

This spring boot application has an entry point Java class called Application.java with the public static void main(String[] args) method, which you can run to start the application.
package net.guides.springboot2.springpropertysourceexample;

import org.springframework.boot.SpringApplication;
import org.springframework.boot.autoconfigure.SpringBootApplication;

@SpringBootApplication
public class Application {

 public static void main(String[] args) {
  SpringApplication.run(Application.class, args);
 }
}
@SpringBootApplication is a convenience annotation that adds all of the following:
@Configuration tags the class as a source of bean definitions for the application context.
@EnableAutoConfiguration tells Spring Boot to start adding beans based on classpath settings, other beans, and various property settings.
Normally you would add @EnableWebMvc for a Spring MVC app, but Spring Boot adds it automatically when it sees spring-webmvc on the classpath. This flags the application as a web application and activates key behaviors such as setting up a DispatcherServlet.
@ComponentScan tells Spring to look for other components, configurations, and services in the hello package, allowing it to find the controllers.
Let's run Application.java class and oberve the console output.

Output


Note that the database configurations are printed at the console using Environment class.




Comments