Spring Boot
Configuration
Annotations
Property Management
Java

ConfigurationProperties vs PropertySource vs Value

Master System Design with Codemia

Enhance your system design skills with over 120 practice problems, detailed solutions, and hands-on exercises.

Introduction

@Value, @PropertySource, and @ConfigurationProperties are related to configuration in Spring, but they operate at different layers. One injects individual values, one adds a source of properties, and one binds a structured group of properties into a typed object.

@Value Injects Individual Properties

Use @Value when you need one or two standalone values inside a bean.

java
1import org.springframework.beans.factory.annotation.Value;
2import org.springframework.stereotype.Component;
3
4@Component
5public class MailClient {
6
7    @Value("${mail.host}")
8    private String host;
9
10    @Value("${mail.port:25}")
11    private int port;
12}

This is concise, but it becomes messy when many related settings are scattered across several fields or classes.

@PropertySource Adds Another Property Source

@PropertySource does not inject values by itself. Its job is to load an extra properties file into the Spring environment.

java
1import org.springframework.context.annotation.Configuration;
2import org.springframework.context.annotation.PropertySource;
3
4@Configuration
5@PropertySource("classpath:mail.properties")
6public class MailConfig {
7}

After this, other mechanisms such as @Value or @ConfigurationProperties can read from that source.

That is the core distinction: @PropertySource changes where properties come from, not how they are bound into objects.

For structured configuration, @ConfigurationProperties is usually the cleaner option.

java
1import org.springframework.boot.context.properties.ConfigurationProperties;
2
3@ConfigurationProperties(prefix = "mail")
4public class MailProperties {
5    private String host;
6    private int port;
7    private boolean sslEnabled;
8
9    public String getHost() { return host; }
10    public void setHost(String host) { this.host = host; }
11
12    public int getPort() { return port; }
13    public void setPort(int port) { this.port = port; }
14
15    public boolean isSslEnabled() { return sslEnabled; }
16    public void setSslEnabled(boolean sslEnabled) { this.sslEnabled = sslEnabled; }
17}

Then register it as a bean:

java
1import org.springframework.boot.context.properties.EnableConfigurationProperties;
2import org.springframework.context.annotation.Configuration;
3
4@Configuration
5@EnableConfigurationProperties(MailProperties.class)
6public class MailConfiguration {
7}

This approach scales better because the configuration is typed, grouped, and easier to validate.

When to Choose Each One

A practical rule is:

  • use @Value for a very small number of simple values
  • use @PropertySource when you need to add another property file
  • use @ConfigurationProperties for grouped application settings

These annotations are not real substitutes for one another. They solve different parts of the configuration story.

Why @ConfigurationProperties Usually Wins for Real Applications

Large applications often have grouped settings such as mail.*, storage.*, or feature.*. Injecting each field separately with @Value spreads string keys throughout the codebase and makes testing harder.

A properties class keeps that configuration cohesive. It also makes it easier to add validation, constructor injection, and clearer documentation of what the application expects.

In other words, @ConfigurationProperties treats configuration as structured data instead of as scattered string lookups.

A major reason teams prefer @ConfigurationProperties is validation. Once configuration is grouped into a typed class, you can validate it as one coherent unit instead of discovering missing or malformed values later through scattered failures.

Configuration precedence also becomes easier to understand when property sources and binding are treated separately. Once those responsibilities are mixed mentally, it becomes much harder to explain why a particular value won or where it actually came from.

Common Pitfalls

Treating @PropertySource as though it binds values directly is a conceptual mistake.

Overusing @Value for large groups of settings leads to scattered configuration and duplicated property keys.

Defining a @ConfigurationProperties class without registering or scanning it leaves you with a type that never actually binds.

Summary

  • '@Value injects individual property values.'
  • '@PropertySource adds an additional property source to the environment.'
  • '@ConfigurationProperties binds a related group of settings into a typed object.'
  • For larger, structured configuration, @ConfigurationProperties is usually the best long-term choice.

Course illustration
Course illustration

All Rights Reserved.