1
0
Files
spring-boot-demo/configuration-properties
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
..

@ConfigurationProperties vs @Value

Companion project for @ConfigurationProperties vs @Value in Spring Boot 4 on ankurm.com.

Every table and transcript quoted in that article was produced by running something here. Three of them were produced twice, because the first answer was wrong — see chapter 2.

Versions

Spring Boot 4.1.1
Spring Framework 7.0.9
JDK Eclipse Temurin 25.0.4.1 (LTS)
Validation Hibernate Validator via spring-boot-starter-validation

Quickstart

export JAVA_HOME=/path/to/jdk-25
mvn -DskipTests package
./scripts/run-all.sh          # regenerate every transcript in docs/output/
mvn test                      # 7 contract tests

Profiles

Profile What it does
(none) binds demo.* from application.yaml
probe runs the relaxed-binding matrix and exits
envprobe reports one property as seen by the binder and by @Value
badvalidation values that violate every constraint, so startup fails
csvlist the recipients list as a comma-separated string

Endpoints

Endpoint Purpose
GET /diag/bound the bound objects, and the same values via @Value
GET /diag/origin?name= every source holding a property, in precedence order, with file and line

Both are diagnostics. Delete them before shipping.

Documentation

  1. Two mechanisms, not two styles
  2. Relaxed binding, measured
  3. Getting the bean registered
  4. Records, constructor binding and defaults
  5. Validation
  6. When @Value is still the right answer
  7. IDE metadata, and the JDK 23 change that silently breaks it
  8. Diagnosing a value

Captured output

File Produced by
00-versions.txt scripts/demo-versions.sh
01-relaxed-matrix.txt scripts/demo-relaxed-matrix.sh
02-env-var-binding.txt scripts/demo-env-binding.sh
03-value-vs-binding.txt scripts/demo-value-vs-binding.sh
04-validation-failure.txt scripts/demo-validation.sh
05-metadata-generation.txt scripts/demo-metadata-generation.sh

Three findings worth the trip

  • @Value gets relaxed binding inside Spring Boot. The universal claim that it does not is a statement about the Spring Framework; Boot attaches a property source that changes it.
  • The configuration processor silently stops on JDK 23+ when declared as a plain dependency, so IDE auto-completion quietly dies while the build stays green.
  • @Valid is not what makes nested constraints run. Boot's ValidationBindHandler validates every object it binds.