ConfigDataEnvironment class

Reads the application's config files (application.properties, application.yml and their profile variants, imports, config trees) into an environment and sets the active profiles they name.

This is what makes lib/resources/application.yml and --spring.profiles.active=prod work. SpringApplication runs it on every start, so applications with spring_boot_dart only write the files. Run it yourself when you start an ApplicationContext without SpringApplication, or in a tool or test that needs the configuration without a context. Run it once, after the command line and other sources are in the environment and before any bean reads a property.

What it reads, with Spring Boot's rules:

  • Files <name>.<ext> and <name>-<profile>.<ext> in each location. Locations come in groups: in spring.config.location and spring.config.additional-location, , separates groups and ; joins locations into one group. The defaults are two groups, optional:resources:/;optional:resources:/config/ and optional:file:./;optional:file:./config/;optional:file:./config/*/ (*/ searches every subdirectory, in alphabetical order). Within a group, later locations override earlier ones and profile files override plain ones; a later group overrides an earlier one entirely, so ./application.properties beats a packaged application-prod.properties. With several active profiles the last one wins. In one location .properties beats .yml and .yaml. A file named at several places is read once, at the place Boot keeps: the later item of a list (x,y,x puts x above y), the command line's spring.config.import before additional-location before location, the first of two identical entries of a ; group; the encoding hint written there applies (the file is not read at the other places).
  • .properties (PropertiesPropertySourceLoader) and YAML (YamlPropertySourceLoader: nested keys become a.b, list items a.hosts[0]) are built in; other formats need a PropertySourceLoader.
  • spring.profiles.active, spring.profiles.include and spring.profiles.group.<name> in config files activate profiles (a group's <name> matched exactly, as Boot's map keys are). A higher source (command line, environment variables) wins over a file's spring.profiles.active; profiles set in code (setActiveProfiles) are kept and the file's are added after them; include always adds; additionalProfiles come first. spring.profiles.default (from the environment, the command line or a non-profile document) picks the profile files while no profile is active, groups expanded. Profile names are checked like Boot's (letters, digits, -_.+@, starting and ending with a letter or digit); spring.profiles.validate=false turns the check off. The profiles are decided before the profile files are read: a -{profile} file may not set the active, default or included profiles, and an on-profile document read before them may set none of the four keys (InvalidConfigDataPropertyException), under any relaxed spelling (spring.profiles.Active); in the files read later (imported by a profile file or an on-profile document) they are ignored, like a profile file's groups.
  • A file can hold several documents, separated by #--- or !--- (--- in YAML; PropertiesPropertySourceLoader says what counts as a separator). Each can be limited with spring.config.activate.on-profile (an empty guard is no guard) and spring.config.activate.on-cloud-platform (the CloudPlatform detected from the environment or set by spring.main.cloud-platform; none matches when there is none). The legacy spring.profiles key is rejected.
  • spring.config.import imports more files (relative to the importing file) or directories (file:./config/: application* files, like a search location). Imported files override the file that imports them and get their -{profile} variants too, which win over the profile files of the importing file (Boot's order: with application.yml importing x.yml, x-dev.yml beats application-dev.yml). On the command line or as SPRING_CONFIG_IMPORT it imports above every location, the variants of all its files above all its plain files.
  • spring.config.name, spring.config.location and spring.config.additional-location change what is searched; they are read from the sources present before the files.
  • optional: locations never fail when missing, and none does with spring.config.on-not-found=ignore. Otherwise a missing file fails, and so does a location that finds nothing (a missing directory, a wildcard without a match), wherever it is written. As in Boot, that is decided once the profile files are read: a location whose -{profile} variant is found counts as found, and a resources: directory counts only when a file is found in it. The variants are the only files that may always be missing. A ; group of locations (in spring.config.import too, in a file or not) is one location: optional when its first entry is, found when any entry finds something; a location that is not found is reported as written (the whole group, a relative import as it is, an extension hint kept). A location without a known extension needs a trailing / (a directory) or an extension hint (file:./conf[.yml]). Extensions and hints are matched without case, and the loader's spelling names the file (x.YAML reads x.yaml), as in Boot. A file location also takes Boot 4.1's encoding hint, x.properties[encoding=iso-8859-1] (fileHints; PropertySourceLoader.encodingFor decides whether a format uses it: .properties does, YAML does not). XML properties files (Boot's application.xml) are not read.
  • configtree: locations read a directory tree, one file per property (configTreePrefix).

The config sources go below the sources already present (command line, environment variables) and above a defaultProperties source (SpringApplication's default properties). Last, relaxed names are switched on (ConfigurationPropertySources.attach), so app.read-timeout also finds app.readTimeout, app.read_timeout or APP_READTIMEOUT.

Errors fail with ConfigDataResourceNotFoundException, ConfigDataLocationNotFoundException, InvalidConfigDataPropertyException or ConfigDataLoadException.

// An application on spring_core_dart alone, without SpringApplication.
Future<void> main(List<String> args) async {
  final environment = StandardEnvironment()
    ..propertySources.addFirst(SimpleCommandLinePropertySource(args));
  // Reads application.yml / application.properties from lib/resources/,
  // then ./application.properties, ./config/application-dev.yml...
  await ConfigDataEnvironment(environment).processAndApply();
  final context = ApplicationContext.run(
    [appBeans],
    environment: environment,
  );
}
# application.yml
spring:
  profiles:
    active: dev
  config:
    import: optional:file:./secrets.yml
---
spring.config.activate.on-profile: dev
app:
  debug: true

Spring (Java):

// Spring Boot runs config data processing inside SpringApplication.run,
// via ConfigDataEnvironmentPostProcessor:
public static void main(String[] args) {
  SpringApplication.run(App.class, args);
}

Differences from Spring Boot: without SpringApplication, run it yourself before creating the context. The classpath is lib/resources/ (custom resource loaders, such as Flutter assets, work too). Boot 4.1.2 reads spring.profiles.active, .default and .group.* from on-profile documents and documents of another cloud platform, which its documentation forbids; here such a document fails when it applies and is ignored when it does not. Of the profile keys ignored in files read after the profiles are decided, spring.profiles.active is hidden from the environment when no profile is active, and spring.profiles.default when the default profile is default: StandardEnvironment would read them then (Boot's environment never does). In a ; group, spaces around an entry are trimmed and empty entries skipped; Boot keeps the spaces in the location and reads an empty entry as the importing file's directory. Each entry of a group is read by its own prefix, so x.yml;configtree:/run/secrets/ reads the tree; Boot picks the resolver of the whole group from its first entry (reading that tree entry as a plain directory, and failing on configtree:/run/secrets/;x.yml as a config tree location not ending in /). A relative import in a file found through a wildcard location is relative to that file; Boot resolves it against the wildcard pattern (reading it from every subdirectory, and failing on a path with a directory). A directory location ends with /, also on Windows (Boot also takes \ there).

Constructors

ConfigDataEnvironment(ConfigurableEnvironment environment, {ResourceLoader? resourceLoader, List<PropertySourceLoader> loaders = const [PropertiesPropertySourceLoader(), YamlPropertySourceLoader()], List<String> defaultLocations = defaultSearchLocations, List<String> additionalProfiles = const []})
Creates a loader that will fill environment; nothing is read until processAndApply or processAndApplySync.

Properties

additionalProfiles → List<String>
Profiles activated on top of the configured ones, as Spring Boot's SpringApplication.setAdditionalProfiles does. They come first, so their files lose to those of the other profiles.
final
defaultLocations → List<String>
The location groups searched when spring.config.location is not set; each entry is a group of ;-separated locations.
final
environment → ConfigurableEnvironment
The environment the config files are read into and whose profiles are set.
final
hashCode → int
The hash code for this object.
no setterinherited
loaders → List<PropertySourceLoader>
The file format readers; for each extension the first that handles it is used.
final
resourceLoader → ResourceLoader
Finds the resource behind each location.
final
runtimeType → Type
A representation of the runtime type of the object.
no setterinherited

Methods

noSuchMethod(Invocation invocation) → dynamic
Invoked when a nonexistent method or property is accessed.
inherited
processAndApply() → Future<void>
Reads the config files into environment and sets its active and default profiles. Call it once, before the application context is created.
processAndApplySync() → void
Does what processAndApply does, without waiting, for a synchronous start (SpringApplication.run uses it). Every resource must be readable synchronously: files and the generated classpath are.
toString() → String
A string representation of this object.
inherited

Operators

operator ==(Object other) → bool
The equality operator.
inherited

Static Methods

fileHints(String location) → ({Encoding? encoding, String? extension, String path})
A file location as Spring Boot 4.1's file hints read it: location without its bracketed parts (path, wherever they are: conf[x]/app.yml is conf/app.yml), the extension an extension hint names, without its dot (x.conf[.yml]: yml), and the encoding an encoding hint names ([encoding=iso-8859-1]: latin1); several hints in any order, the last of a kind winning. A bracketed part of another form names nothing.

Constants

additionalLocationProperty → const String
The property with locations searched after the default ones, and so winning over them: spring.config.additional-location.
configNameProperty → const String
The property with the base names of the config files, comma-separated: spring.config.name (application when unset; a later name wins).
configTreePrefix → const String
The prefix of a config tree location, configtree:, for secrets and settings mounted as files (Kubernetes volumes, Docker secrets).
defaultPropertiesSourceName → const String
The name of the property source that holds SpringApplication's default properties: defaultProperties. Config files are added just above it, so they override the defaults, as in Spring Boot's DefaultPropertiesPropertySource.
defaultSearchLocations → const List<String>
Where config files are looked for unless configured otherwise, as in Spring Boot: two groups of ;-separated locations, the packaged one first and the working directory second (which wins). resources: is lib/resources/ (see ClasspathResources); config/*/ searches each subdirectory of ./config/.
importProperty → const String
The property that imports more files from a config document, relative to that document: spring.config.import.
includeProfilesProperty → const String
The property with profiles always added to the active ones, comma-separated: spring.profiles.include.
legacyProfilesProperty → const String
The pre-2.4 document guard spring.profiles, rejected as Spring Boot rejects it; write onProfileProperty instead.
locationProperty → const String
The property whose locations replace defaultSearchLocations: spring.config.location (, separates groups, ; joins locations into one group).
onCloudPlatformProperty → const String
The property that limits a document to a CloudPlatform: spring.config.activate.on-cloud-platform.
onNotFoundProperty → const String
The property that decides what a missing required location does: spring.config.on-not-found, fail (default) or ignore. Any other value fails with ConfigDataLoadException.
onProfileProperty → const String
The property that limits a document to profiles: spring.config.activate.on-profile, a profile expression or a comma list meaning "any of".
optionalPrefix → const String
The prefix that makes a location optional: optional:.
profileGroupPrefix → const String
The prefix of profile group properties: spring.profiles.group.prod=db,mq activates db and mq whenever prod is active.
validateProfilesProperty → const String
The property that turns the check of profile names off when false: spring.profiles.validate (default true).