Environment
Access profiles, property sources, and resolved configuration from runtime code.
The environment is the runtime view of configuration and profiles. It is prepared before components are created, so constructors, binders, conditions, and runtime extensions can all read the same values.
The public contract is focused on profiles, property sources, and property resolution:
type Environment interface {
// ActiveProfiles returns profiles explicitly enabled for this run.
// These profiles are used by config loading, conditions, and runtime decisions.
ActiveProfiles() []string
// DefaultProfiles returns fallback profiles used when no active profile is set.
DefaultProfiles() []string
// IsProfileActive reports whether a profile is currently enabled.
IsProfileActive(profile string) bool
// SetActiveProfiles replaces the active profile list.
// Use it during early startup when the runtime should choose a specific environment.
SetActiveProfiles(profiles ...string) error
// AddActiveProfiles appends profiles without replacing the existing list.
AddActiveProfiles(profiles ...string) error
// SetDefaultProfiles replaces the fallback profile list.
SetDefaultProfiles(profiles ...string) error
// PropertySources returns the ordered list of configuration sources.
// Earlier sources win over later sources during property lookup.
PropertySources() *config.PropertySources
// PropertyResolver reads values from PropertySources and expands placeholders.
PropertyResolver() config.PropertyResolver
}This is why environment setup happens early: active profiles and property source order affect which values later components receive.
ActiveProfiles, DefaultProfiles, and IsProfileActive describe the profile
state the application is running with. Conditions and configuration loaders use
this state to decide what should be active.
SetActiveProfiles, AddActiveProfiles, and SetDefaultProfiles are mutation
methods for early runtime setup. Use them from environment customizers or tests,
before components are created.
PropertySources() returns the ordered source list. This is where command-line
arguments, environment variables, configuration files, and custom sources are
combined.
PropertyResolver() reads from that ordered list and expands placeholders. Use
it when runtime code needs a single value; use binding when components need a
typed configuration object.
func (r *InspectRunner) Run(ctx runtime.Context, args *runtime.Args) error {
env := ctx.Environment()
profiles := env.ActiveProfiles()
port := env.PropertyResolver().LookupOrDefault("server.port", 8080)
slog.Info("runtime environment",
"profiles", profiles,
"port", port,
)
return nil
}Profiles
The environment exposes active and default profiles. Active profiles are the runtime choice. Default profiles are used only when no active profile is set.
if env.IsProfileActive("prod") {
// configure production-only behavior
}You can set profiles programmatically from early runtime code:
if err := env.SetActiveProfiles("prod"); err != nil {
return err
}
if err := env.SetDefaultProfiles("local"); err != nil {
return err
}Property sources
Runtime code can inspect or extend property sources. This is useful for framework packages that load configuration from an additional place, test setup that needs overrides, or platform integrations that inject deployment metadata.
env.PropertySources().PushFront(config.NewMapPropertySource("test", map[string]any{
"server.port": 3000,
}))Use PushFront for overrides and PushBack for defaults. Resolution uses the
first source that contains a value.
Property sources are ordered. Command-line arguments and explicit overrides should usually be pushed toward the front. Defaults should be pushed toward the back so they do not hide deployment-specific values.
Property resolver
The resolver reads values from the ordered source list and supports placeholder expansion:
address, err := env.PropertyResolver().ExpandStrict("${server.host}:${server.port}")
if err != nil {
return err
}
server.Listen(address)Use the resolver for small dynamic decisions. Use typed configuration binding for normal component configuration so the component receives regular Go values.
