Standard precedence (lowest to highest)

  1. Compile-time defaults
  2. YAML config file (base)
  3. YAML config file (env-specific: dev/staging/prod)
  4. Environment variables
  5. Runtime overrides (feature flags)
Advertisement

Merge implementation

ConfigLoader loader = ConfigLoader.builder()
    .withDefaults(DefaultConfig.class)
    .withFile("application.yaml")
    .withFile("application-" + env + ".yaml")
    .withEnv()
    .withFlags(flagsClient)
    .build();
AppConfig cfg = loader.load(AppConfig.class);
Advertisement

Deep vs shallow merge

Nested objects: deep merge (only override specified keys). Lists: usually replace, not concat.