Hey dev community!
When working on Spring Boot projects, we all need to read values from our application.properties or application.yml files.
Most of us start by using the @Value annotation to inject each property one by one.
The Problem (The "Old Way")
As your application grows, your service or configuration class starts to look like this:
@Service
public class MyOldService {
@Value("${app.api.url}")
private String apiUrl;
@Value("${app.api.key}")
private String apiKey;
@Value("${app.feature.toggle.new-feature}")
private boolean featureToggle;
@Value("${app.thread-pool-size}")
private int poolSize;
// ... and it goes on and on
}
This is verbose, hard to maintain, and not type-safe (just Strings and primitives). If you mistype a prefix, everything breaks at runtime.
The Solution: @ConfigurationProperties
Spring Boot offers a much cleaner, safer, and more organized way to manage your configuration: the @ConfigurationProperties annotation.
The idea is simple: map an entire block of your configuration file to a single Java object (a POJO or a Record).
Let's see how.
Step 1: Your application.yml file
Structure your properties logically. It's much more readable!
app:
name: "My Awesome Service"
feature-toggle:
new-feature: true
beta-access: false
api:
url: "https://api.example.com"
key: "your-secret-api-key"
Step 2: Create the Configuration Class
We'll create a class (or even better, a Java 17+ record) that represents this structure.
Note: For this to work with records (constructor binding), you need a recent version of Spring Boot (3+). Otherwise, use a classic class with getters and setters.
import org.springframework.boot.context.properties.ConfigurationProperties;
// The "app" prefix matches the root of our config
@ConfigurationProperties(prefix = "app")
public record AppProperties(
String name,
ApiConfig api,
FeatureToggle featureToggle
) {
// We can even have nested objects!
public record ApiConfig(String url, String key) {}
public record FeatureToggle(boolean newFeature, boolean betaAccess) {}
}
Step 3: Enable the Configuration
We need to tell Spring to scan and activate this class. The easiest way is on your main application class:
import org.springframework.boot.context.properties.EnableConfigurationProperties;
import org.springframework.boot.SpringApplication;
import org.springframework.boot.autoconfigure.SpringBootApplication;
@SpringBootApplication
@EnableConfigurationProperties(AppProperties.class) // <-- The key step!
public class MyApplication {
public static void main(String[] args) {
SpringApplication.run(MyApplication.class, args);
}
}
Step 4: Use Your Configuration (The Clean Way!)
Now, instead of injecting 10 @Value fields, you just inject one single bean, perfectly typed:
@Service
public class MyNewService {
private final AppProperties appProperties;
// Constructor injection (always a good practice!)
public MyNewService(AppProperties appProperties) {
this.appProperties = appProperties;
}
public void doSomething() {
String url = appProperties.api().url(); // Clean!
String key = appProperties.api().key(); // Type-safe!
if (appProperties.featureToggle().newFeature()) {
// ... new feature logic
}
System.out.println("App name: " + appProperties.name());
}
}
Why This is 100x Better
Type-Safe: No more 'String' vs. 'int' errors. You're handling a real Java object.
Centralized: All 'app'-related configuration is in one single class.
Validation: You can add validation annotations (@Validated, @min, @NotEmpty) directly to the fields of your AppProperties class!
Auto-completion (The Pro-Tip):
If you add this dependency to your pom.xml (or Gradle), your IDE will give you auto-completion right in your .yml or .properties file!
<dependency>
<groupId>org.springframework.boot</groupId>
<artifactId>spring-boot-configuration-processor</artifactId>
<optional>true</optional>
</dependency>
Conclusion
Stop fighting with @Value. For any configuration that's more than two or three keys, switch to @ConfigurationProperties. It's cleaner, more robust, and much more maintainable.
What's your favorite Spring Boot tip? Let me know in the comments! 👇
Happy coding!
Top comments (0)