1
0
Files
spring-boot-demo/configuration-properties/docs/01-two-mechanisms.md
Ankur Mhatre 86246dc860 Three new article modules: configuration binding, profiles and config data, Spring AOP
configuration-properties/  @ConfigurationProperties vs @Value on Spring Boot 4.1.1.
  The relaxed-binding matrix is generated by binding each spelling rather than
  transcribed, and re-checked against real processes -- the in-process probe was
  wrong twice before it was right. Records the three findings that came out of it:
  @Value does get relaxed resolution inside Spring Boot (Boot attaches
  ConfigurationPropertySources), the configuration processor silently stops
  generating metadata on JDK 23+ when declared as a plain dependency, and @Valid is
  not what makes nested constraints run.

profiles-and-config/       Precedence, profiles, spring.config.import and config trees.
  /precedence reports every source holding a property in rank order with file and
  line, which turns "my profile file had no effect" into a two-line answer. Also
  pins the counterintuitive one: an imported file outranks the file that imported it.

spring-aop/                Designators, proxy types, and aspects that do not fire.
  One advice per supported designator so the reference table is generated from real
  matches; all fourteen unsupported designators fed to the parser. Two corrections to
  the reference documentation: unsupported designators throw
  UnsupportedPointcutPrimitiveException (extends RuntimeException, not
  IllegalArgumentException), and spring-boot-starter-aop was renamed to
  spring-boot-starter-aspectj in Boot 4.

19 contract tests across the three modules, 15 captured transcripts, all regenerated
by scripts/run-all.sh. Verified on Spring Boot 4.1.1, Spring Framework 7.0.9,
JDK 25.0.4.1.

Co-Authored-By: Claude Opus 5 <noreply@anthropic.com>
Claude-Session: https://claude.ai/code/session_01Gip4srpzMwjgoba6uEfbr5
2026-09-08 16:47:48 +00:00

2.3 KiB

Index · Relaxed binding →

1. Two mechanisms, not two styles

@Value and @ConfigurationProperties are often presented as a matter of taste. They are not. They are two different mechanisms that happen to read from the same Environment, and almost every difference in behaviour follows from that.

@Value is placeholder resolution

@Value("${demo.mail.host}") is a string. Spring's PropertySourcesPlaceholderConfigurer resolves it against the environment during bean post-processing, converts the result to the field's type, and assigns it. There is no model of what a property is — only a name, a lookup and a conversion.

Consequences:

  • The property name lives in a string literal. Renaming a property is a text search.
  • One field, one lookup. There is no way to express "these six properties belong together".
  • Defaulting is : inside the placeholder, and nothing else.
  • There is no validation step, because there is no object to validate.
  • SpEL is available: #{...} can compute rather than look up.

@ConfigurationProperties is binding

Binder walks a target type, works out which properties it needs, asks the ConfigurationPropertySources for each one, converts, and constructs the object. The target type is the model.

Consequences:

  • The property names are derived from the type. Renaming a component renames the property.
  • Nested types, lists and maps bind, because the binder knows the shape it is filling.
  • Defaults are @DefaultValue, applied per component during construction.
  • The bound object can be validated as an object, once, at startup.
  • No SpEL. The binder maps values; it does not compute them.

The one that surprises people

Because both read from the same environment, the relaxed rules ought to differ — and in the Spring Framework alone they do. Inside Spring Boot they largely do not, because Boot attaches an extra property source that gives placeholder resolution the binder's name matching. Chapter 2 has the measured matrix.

Which to use

Use @ConfigurationProperties for anything that is a group of settings — which is most things. Reach for @Value when you need a single value in a place where a type would be ceremony, or when you need SpEL. Chapter 6 is the honest list.