1
0
Files
spring-boot-demo/profiles-and-config/docs/output/04-import-and-multidoc.txt
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

61 lines
3.6 KiB
Plaintext

== spring.config.import: which document wins? ==
application-import.yaml imports imported.yaml. Both set demo.greeting.
$ java -jar target/profiles-and-config-1.0.0.jar --spring.profiles.active=import
active profiles : import
effective value : from-imported-yaml
1. from-imported-yaml <- 'file imported.yaml' via location 'optional:classpath:/imported.yaml''}
2. from-application-import-yaml <- 'file application-import.yaml' via location 'optional:classpath:/''}
3. from-application-yaml <- 'file application.yaml' via location 'optional:classpath:/''}
holders that lost: 2
demo.imported-only = yes-this-file-was-read
The imported file WON. spring.config.import does not behave like #include, and it
does not behave like a default either: the imported document is processed AFTER the
document that declared the import, so it outranks the file that pulled it in.
If you import a shared baseline expecting your own file to override it, every key
the baseline sets will quietly beat yours.
== one file, several documents, activated by condition ==
--- spring.profiles.active=<none> (with the multidoc profile) ---
active profiles : multidoc
effective value : from-multidoc-default-document
1. from-multidoc-default-document <- 'file application-multidoc.yaml' via location 'optional:classpath:/' (document ...
2. from-application-yaml <- 'file application.yaml' via location 'optional:classpath:/''}
holders that lost: 1
--- spring.profiles.active=staging (with the multidoc profile) ---
active profiles : multidoc, staging
effective value : from-multidoc-staging-document
1. from-multidoc-staging-document <- 'file application-multidoc.yaml' via location 'optional:classpath:/' (document ...
2. from-multidoc-default-document <- 'file application-multidoc.yaml' via location 'optional:classpath:/' (document ...
3. from-application-yaml <- 'file application.yaml' via location 'optional:classpath:/''}
holders that lost: 2
--- spring.profiles.active=prod (with the multidoc profile) ---
active profiles : multidoc, prod, prod-db, prod-metrics
effective value : from-application-prod-yaml
1. from-application-prod-yaml <- 'file application-prod.yaml' via location 'optional:classpath:/''}
2. from-multidoc-prod-document <- 'file application-multidoc.yaml' via location 'optional:classpath:/' (document ...
3. from-multidoc-default-document <- 'file application-multidoc.yaml' via location 'optional:classpath:/' (document ...
4. from-application-yaml <- 'file application.yaml' via location 'optional:classpath:/''}
holders that lost: 3
Later documents in the same file win over earlier ones, so the unconditional first
document acts as the default and each conditional document overrides it.
== the activation Spring Boot refuses ==
application-badactivation.yaml tries to set spring.profiles.active from a document
that is itself conditional on a profile.
$ java -jar target/profiles-and-config-1.0.0.jar --spring.profiles.active=badactivation,staging
org.springframework.boot.context.config.InvalidConfigDataPropertyException: Property
'spring.profiles.active' imported from location 'class path resource
[application-badactivation.yaml]' is invalid in a profile specific resource [origin: class path
resource [application-badactivation.yaml] from profiles-and-config-1.0.0.jar - 12:13]
at
org.springframework.boot.context.config.InvalidConfigDataPropertyException.lambda$throwIfPropert
yFound$1(InvalidConfigDataPropertyException.java:123)