1
0

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
This commit is contained in:
2026-09-08 16:36:17 +00:00
parent 958b401f0f
commit 86246dc860
107 changed files with 5075 additions and 0 deletions

View File

@@ -0,0 +1,70 @@
[&larr; Precedence list](01-the-precedence-list.md) &middot; [Index](../README.md) &middot; [Seeing precedence &rarr;](03-seeing-precedence.md)
# 2. Profiles: files, documents and groups
## Profile-specific files
`application-<profile>.yaml`, loaded from the same locations as `application.yaml`, and always
overriding it. With several profiles active, last one wins:
`--spring.profiles.active=prod,live` means `application-live.yaml` beats
`application-prod.yaml`.
## Multi-document files
The same effect without multiplying files. Documents are separated by `---` and activated by
condition:
```yaml
demo:
greeting: from-multidoc-default-document
---
spring:
config:
activate:
on-profile: staging
demo:
greeting: from-multidoc-staging-document
```
Later documents win over earlier ones, so an unconditional first document acts as the default
and each conditional document overrides it. Measured in
[`04-import-and-multidoc.txt`](output/04-import-and-multidoc.txt).
`spring.config.activate.on-cloud-platform` and `spring.config.activate.on-profile` can be
combined; both must match.
## Profile groups
One profile that activates several:
```yaml
spring:
profiles:
group:
prod: prod-db,prod-metrics
```
`--spring.profiles.active=prod` reports all three as active, and all three
`application-<name>.yaml` files are loaded. Groups are resolved before config data is
processed, which is why declaring a group in `application.yaml` can still affect which files
get loaded.
## The activation Spring Boot refuses
`spring.profiles.active` cannot be set from a document that is itself profile-specific:
```
InvalidConfigDataPropertyException: Property 'spring.profiles.active' imported from location
'class path resource [application-badactivation.yaml]' is invalid in a profile specific
resource [origin: ... - 12:13]
```
A profile that activates itself would change which files are loaded after the set of files had
already been decided. Boot refuses rather than half-applying it. `spring.profiles.include` has
the same restriction; `spring.config.activate.on-profile` is how you express the condition.
## `@Profile` is a different mechanism
`@Profile("prod")` on a bean is evaluated when the context is built, long after config data is
resolved. It decides which *beans* exist, not which *properties* are set. The two use the same
profile names and nothing else.