top of page

Application.yml made easy: How to load and access properties in Spring Boot Application

  • pranaypourkar
  • Apr 27, 2023
  • 3 min read

Updated: May 10, 2023


In Spring Boot, there are different ways to load properties from the application.yml file and use them in the code. We will see 4 different ways in this blog.



1. Using @ConfigurationProperties Annotation

This approach allows us to map all the properties under a specific prefix to a Java class. We need to create a Java class and annotate it with the @ConfigurationProperties annotation, and specify the prefix of the properties that we want to map. Spring Boot will automatically map the properties to the fields of the class.

@Component
@ConfigurationProperties(prefix = "my.properties")
public class MyProperties {
    private String propertyKey1;
    private String propertyKey2;
    private String propertyKey3;
    // getters and setters
}

Pros

  • Provides a type-safe way of mapping multiple properties to a single Java class

  • Supports nested properties and binding to lists or maps

  • Allows validation of the properties using annotations such as @NotNull or @Min

Cons

  • Cannot be used to inject properties into arbitrary beans outside of the Spring context


2. Using @Value Annotation

In this case, we need to annotate a field in our class with the @Value annotation and pass the property key as a string to the annotation. Spring Boot will automatically inject the value of the property into the field.

@Value("${my.property.key}")
private String myPropertyValue;

Pros

  • Supports Spring Expression Language (SpEL) for complex property values.

  • Can be used to inject properties into any Spring-managed bean

Cons

  • Does not provide type safety checks for the injected properties.

  • Limited to injecting properties into individual fields



3. Using Environment object

We can also access properties using the Environment object. We need to inject the Environment object into your class and use the getProperty method to retrieve the value of the property.

@Autowired
private Environment environment;

String myPropertyValue = environment.getProperty("my.property.key");

Pros

  • Provides a programmatic way of accessing properties

  • Can be used to access properties from any Spring-managed bean or outside the Spring context

Cons

  • Does not provide type safety checks for the retrieved properties

  • Does not support nested properties or lists/maps


4. Using @PropertySource Annotation

We can access custom properties file (other than application.yml) using @PropertySource Annotation. We need to pass the path of the property file as a string to the annotation. Then, we can use the @Value annotation or the Environment object to access the properties.

@Configuration
@PropertySource("classpath:my.properties")
public class MyConfig {
    @Value("${my.property.key}")
    private String myProperty;
}

Pros

  • Allows loading properties from multiple property files with different formats and locations

  • Can be used to customize the name and location of the application.yml file

  • Supports using profiles to load properties based on the active profile

Cons

  • Requires more setup compared to the other methods

  • Does not provide type safety checks for the retrieved properties



Let's see an example in action which covers the above 4 approach

Project Setup
ree

application.yml
server:
  port: 4040
property:
  store:
    project: sample-project 
    username: sample-user
    password: sample-password
    url: http://sample/com.test.gateway
    required: true
custom.properties
application.name = sample-integration-service


pom.xml
<project xmlns:xsi="http://www.w3.org/2001/XMLSchema-instance"
	xmlns="http://maven.apache.org/POM/4.0.0"
	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>
	<parent>
		<groupId>org.springframework.boot</groupId>
		<artifactId>spring-boot-starter-parent</artifactId>
		<version>2.7.4</version>
		<relativePath />
	</parent>
	
	<groupId>com.company.project</groupId>
	<artifactId>sample-integration-service</artifactId>
	<version>0.0.1-SNAPSHOT-1</version>
	<name>Company :: sample-integration-service</name>
	
	<properties>
		<java.version>17</java.version>
	</properties>
	
	<dependencies>
		<dependency>
			<groupId>org.springframework.boot</groupId>
			<artifactId>spring-boot-starter-web</artifactId>
		</dependency>
		<dependency>
			<groupId>org.springframework.boot</groupId>
			<artifactId>spring-boot-devtools</artifactId>
			<scope>runtime</scope>
			<optional>true</optional>
		</dependency>
		<dependency>
			<groupId>org.projectlombok</groupId>
			<artifactId>lombok</artifactId>
			<optional>true</optional>
		</dependency>
	</dependencies>
</project>

ConfigProperties.java
package com.company.project.config;

import lombok.Getter;
import lombok.Setter;
import org.springframework.boot.context.properties.ConfigurationProperties;
import org.springframework.context.annotation.Configuration;

@Configuration
@ConfigurationProperties(prefix = "property.store")
@Getter
@Setter
public class ConfigProperties {
    private String username;
    private String password;
}

CustomProperties.java
package com.company.project.config;

import lombok.Getter;
import org.springframework.beans.factory.annotation.Value;
import org.springframework.context.annotation.Configuration;
import org.springframework.context.annotation.PropertySource;

@Configuration
@PropertySource("classpath:custom.properties")
@Getter
public class CustomProperties {

    @Value("${application.name}")
    private String applicationName;
}

SampleController.java
package com.company.project.controller;

import com.company.project.config.ConfigProperties;
import com.company.project.config.CustomProperties;
import lombok.RequiredArgsConstructor;
import lombok.extern.slf4j.Slf4j;
import org.springframework.beans.factory.annotation.Value;
import org.springframework.core.env.Environment;
import org.springframework.web.bind.annotation.GetMapping;
import org.springframework.web.bind.annotation.RequestMapping;
import org.springframework.web.bind.annotation.RestController;

@Slf4j
@RequiredArgsConstructor
@RestController
@RequestMapping("/api")
public class SampleController {
	
    @Value("${property.store.project}")
    private final String projectName;
	
    private final ConfigProperties configProperties;
    private final Environment environment;
    private final CustomProperties customProperties;

    @GetMapping("/hello")
    public String sayHello() {
	   String url = environment.getProperty("property.store.url");	
		
	   log.info("Project: {}", projectName);
	   log.info("Username: {}", configProperties.getUsername());
	   log.info("Password: {}", configProperties.getPassword());
	   log.info("Url: {}", url);
	   log.info("Application Name: {}", customProperties.getApplicationName());
		
        return "Hello, world!";
    }
}

Hit the controller endpoint and verify the log statements

ree



Thank you for taking the time to read this post. I hope that you found it informative and useful in your own development work.

Comments


bottom of page