@PropertySource Spring 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.

YouTube Video - @PropertySource Spring Boot Example

Spring @PropertySource Annotation with Simple Example

In this example, we are reading database configuration from file config.properties file and setting 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 the file config.properties file and setting 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 the 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>3.0.4</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>17</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

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

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);
    }
}
Let's run Application.java class and observe the console output.

Output


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

Comments