Card 04/ 06

ComparisonDifficulty: Intermediate1 min

@Value vs @ConfigurationProperties

One property into one field, or a whole group of related properties into one typed class.

@Value and @ConfigurationProperties both copy configuration properties into your own code, from the same sources and in the same order of priority. @Value("${pricing.base-fare}") fills one field with one property; @ConfigurationProperties fills a whole class from every property that starts with a given prefix. The card compares them and ends with when to use each.

What they share: both are filled once at startup, both read every source in the same order, and both stop the application from starting if a value cannot be converted, such as abc where a number is expected.

Three pricing properties that belong together, bound into one record (a compact Java class that only holds data):

java
@ConfigurationProperties(prefix = "pricing")
record PricingProperties(double baseFare, double perKmRate, String currency) {}
application.propertiestext
pricing.base-fare=2.50
pricing.per-km-rate=1.20
pricing.currency=USD
text
PricingProperties[baseFare=2.5, perKmRate=1.2, currency=USD]
run in a container: kebab-case in the file, camelCase in the record, bound automatically
Choosing between @Value and @ConfigurationProperties
NeedReach for
One or two unrelated properties@Value("${property.name}")
A group of properties that belong together@ConfigurationProperties, bound into one typed class
A value computed with an expression (SpEL)@Value, which supports expressions; @ConfigurationProperties does not
Checking the properties at startup@ConfigurationProperties, which works with Bean Validation annotations (constraints such as @NotNull on fields) on the class

Twelve related properties as twelve @Value fields scattered across a class is legal, and it is exactly the case @ConfigurationProperties exists to replace: one prefix, one typed class, and every property that belongs together arrives together.

One thing @ConfigurationProperties needs that @Value does not: the class has to be registered, with @ConfigurationPropertiesScan on the application class or @EnableConfigurationProperties naming it. Without that, the record is never created and nothing is bound.