Configuration
Configuration is the settings that change from one place to another while the code stays the same: a server URL, a port, a timeout, a feature switch.
Why
The same build runs on a laptop, in tests and in production. Each place needs its own values, and nothing should be recompiled for that. So the settings live outside the code: in config files, on the command line, in environment variables and in --dart-define values.
The keys, file names and rules are Spring Boot's. Configuration from a Spring project usually works unchanged.
The annotations and the Environment are part of spring_core_dart. Reading the config files at startup and binding @ConfigurationProperties classes is done by SpringApplication (spring_boot_dart and the starters built on it). A plain ApplicationContext.run reads only the environment variables, unless you load the files yourself with ConfigDataEnvironment.
How it fits together
- Config files.
application.properties,application.ymlorapplication.yamlinlib/resources/. The generator embeds them in the generated code, so they work on the Dart VM, in AOT builds, in Flutter and on the web. The two formats mean the same thing and can be mixed. - Profiles. A profile names a situation, such as
devorprod. For each active profile,application-<profile>.*is read as well and wins over the plain file.@Profileregisters beans only for some profiles. See Profiles. - Property sources. The command line,
--dart-definevalues, environment variables and the config files are each a property source. For each key, the highest source wins. See Property sources. - The Environment. One object holds the ordered sources and the active profiles. Code reads a key from it when the key is only known at run time. See Environment.
- Placeholders.
${key}and${key:default}refer to other properties, in config files, in@Valueand in some annotations. See Placeholders. - Reading values in beans.
@Valueinjects one value. A@ConfigurationPropertiesclass binds a whole prefix to typed fields.
Example
# lib/resources/application.yml
shop:
title: NEON Books
url: ${SHOP_URL:http://localhost:8080}
max-basket-size: 20
checkout-timeout: 30s
---
spring:
config:
activate:
on-profile: prod
shop:
url: https://neon.books
import 'package:spring_core_dart/spring_core_dart.dart';
// A whole prefix as a typed bean.
@ConfigurationProperties('shop')
class ShopProperties {
String title = 'Shop';
String url = '';
int maxBasketSize = 10;
Duration checkoutTimeout = const Duration(minutes: 1);
}
@Service()
class Checkout {
Checkout(
this.shop,
// One value; a raw string, so Dart does not read `$`.
@Value(r'${shop.title}') this.title,
);
final ShopProperties shop;
final String title;
}
dart run bin/main.dart --spring.profiles.active=prod --shop.max-basket-size=30
Pages of this section
- @Value: inject one setting or a SpEL result into a bean.
- @ConfigurationProperties: bind a prefix to a typed class, with nested objects, lists, maps and validation.
- Environment: read properties and profiles in code.
- Placeholders:
${key},${key:default}, nesting and escapes. - Profiles: activate profiles, profile files,
@Profile, profile expressions. - Property sources: where values come from, which source wins, adding your own.
In Spring (Java)
This is Spring Boot's Externalized Configuration. Differences that matter:
lib/resources/plays the role of the classpath. Its location prefix isresources:, notclasspath:.- There are no JVM system properties.
--dart-definevalues are a source just below the command line. .propertiesfiles are read as UTF-8, not ISO-8859-1.
The full reference, with every key the framework reads, is configuration.md on GitHub.