4.2 Externalized Configuration with PropertySources
Additional PropertySource instances can be added to the environment prior to initializing the ApplicationContext.
Initializing the Environment
ApplicationContext applicationContext = ApplicationContext.run(
PropertySource.of(
"test",
CollectionUtils.mapOf(
"micronaut.server.host", "foo",
"micronaut.server.port", 8080
)
),
"test", "android");
Environment environment = applicationContext.getEnvironment();
assertEquals(
"foo",
environment.getProperty("micronaut.server.host", String.class).orElse("localhost")
);
Initializing the Environment
when:
ApplicationContext applicationContext = ApplicationContext.run(
PropertySource.of(
"test",
[
"micronaut.server.host": "foo",
"micronaut.server.port": 8080
]
),
"test", "android")
Environment environment = applicationContext.getEnvironment()
then:
"foo" == environment.getProperty("micronaut.server.host", String.class).orElse("localhost")
Initializing the Environment
val applicationContext = ApplicationContext.run(
PropertySource.of(
"test",
mapOf(
"micronaut.server.host" to "foo",
"micronaut.server.port" to 8080
)
),
"test", "android")
val environment = applicationContext.getEnvironment()
assertEquals(
"foo",
environment.getProperty("micronaut.server.host", String::class.java).orElse("localhost")
)
The PropertySource.of method can be used to create a ProperySource
from a map of values.
Alternatively one can register a PropertySourceLoader by creating a META-INF/services/io.micronaut.context.env.PropertySourceLoader
containing a reference to the class name of the PropertySourceLoader
.
Included PropertySource Loaders
Micronaut by default contains PropertySourceLoader
implementations that load properties from the given locations and priority:
Command line arguments
Properties from
SPRING_APPLICATION_JSON
(for Spring compatibility)Properties from
MICRONAUT_APPLICATION_JSON
Java System Properties
OS environment variables
Configuration files loaded in order from the system property ‘micronaut.config.files’ or the environment variable
MICRONAUT_CONFIG_FILES
. The value can be a comma separated list of paths with the last file having precedence. The files can be referenced from the file system as a path or the classpath with aclasspath:
prefix.Environment-specific properties from
application-{environment}.{extension}
Application-specific properties from
application.{extension}
.properties , .json , .yml are supported out of the box. For Groovy users .groovy is supported as well. |
Supplying Configuration via Command Line
Configuration can be supplied at the command line using Gradle or our Maven plugin. For example:
Gradle
$ ./gradlew run --args="-endpoints.health.enabled=true -config.property=test"
Maven
$ ./mvnw mn:run -Dmn.appArgs="-endpoints.health.enabled=true -config.property=test"
In order for the configuration to be apart of the context, the args from the main method must be passed to the context builder. For example:
import io.micronaut.runtime.Micronaut;
public class Application {
public static void main(String[] args) {
Micronaut.run(Application.class, args); // passing args
}
}
Property Value Placeholders
Micronaut includes a property placeholder syntax which can be used to reference configuration properties both within configuration values and with any Micronaut annotation (see @Value and the section on Configuration Injection).
Programmatic usage is also possible via the PropertyPlaceholderResolver interface. |
The basic syntax is to wrap a reference to a property in ${…}
. For example in application.yml
:
Defining Property Placeholders
myapp:
endpoint: http://${micronaut.server.host}:${micronaut.server.port}/foo
The above example embeds references to the micronaut.server.host
and micronaut.server.port
properties.
You can specify default values by defining a value after the :
character. For example:
Using Default Values
myapp:
endpoint: http://${micronaut.server.host:localhost}:${micronaut.server.port:8080}/foo
The above example will default to localhost
and port 8080
if no value is found (rather than throwing an exception). Note that if default value itself contains a :
character, you should escape it using back ticks:
Using Backticks
myapp:
endpoint: ${server.address:`http://localhost:8080`}/foo
The above example tries to read a server.address
property otherwise fallbacks back to [http://localhost:8080](http://localhost:8080)
, since the address has a :
character we have to escape it with back ticks.
Property Value Binding
Note that these property references should always be in kebab case (lowercase and hyphen-separated) when placing references in code or in placeholder values. For example, you should use micronaut.server.default-charset
and not micronaut.server.defaultCharset
.
Micronaut still allows specifying the latter in configuration, but normalizes the properties into kebab case form to optimize memory consumption and reduce complexity when resolving properties. The following table summarizes how properties are normalized from different sources:
Configuration Value | Resulting Properties | Property Source |
---|---|---|
|
| Properties, YAML etc. |
|
| Properties, YAML etc. |
|
| Properties, YAML etc. |
|
| Environment Variable |
|
| Environment Variable |
Environment variables are given special treatment to allow the definition of environment variables to be more flexible. Note that there is no way to reference an environment variable with camel-case.
Because the number of properties generated is exponential based on the number of _ characters in the environment variable, it is recommended to refine which, if any, environment variables are included in configuration if the number of environment variables with a large number of underscores is high. |
To control how environment properties participate in configuration, call the respective methods on the Micronaut
builder.
Application class
import io.micronaut.runtime.Micronaut;
public class Application {
public static void main(String[] args) {
Micronaut.build(args)
.mainClass(Application.class)
.environmentPropertySource(false)
//or
.environmentVariableIncludes("THIS_ENV_ONLY")
//or
.environmentVariableExcludes("EXCLUDED_ENV")
.start();
}
}
Application class
import io.micronaut.runtime.Micronaut
class Application {
static void main(String[] args) {
Micronaut.build()
.mainClass(Application)
.environmentPropertySource(false)
//or
.environmentVariableIncludes("THIS_ENV_ONLY")
//or
.environmentVariableExcludes("EXCLUDED_ENV")
.start()
}
}
Application class
import io.micronaut.runtime.Micronaut
object Application {
@JvmStatic
fun main(args: Array<String>) {
Micronaut.build(null)
.mainClass(Application::class.java)
.environmentPropertySource(false)
//or
.environmentVariableIncludes("THIS_ENV_ONLY")
//or
.environmentVariableExcludes("EXCLUDED_ENV")
.start()
}
}
The configuration above does not have any impact on property placeholders. It is still possible to reference an environment variable in a placeholder regardless of whether environment configuration is disabled, or even if the specific property is explicitly excluded. |
Using Random Properties
You can use random
values by using the following properties. These can be used in configuration files as variables like the following.
micronaut:
application:
name: myapplication
instance:
id: ${random.shortuuid}
Property | Value |
---|---|
random.port | An available random port number |
random.int | Random int |
random.integer | Random int |
random.long | Random long |
random.float | Random float |
random.shortuuid | Random UUID of only 10 chars in length (Note: As this isn’t full UUID, collision COULD occur) |
random.uuid | Random UUID with dashes |
random.uuid2 | Random UUID without dashes |
Fail Fast Property Injection
For beans that inject required properties, the injection and potential failure will not occur until the bean is requested. To verify at startup that the properties exist and can be injected, the bean can be annotated with @Context. Context scoped beans will be injected at startup time and thus will fail at startup time if any required properties are missing or could not be converted to the required type.
To maintain a fast startup time, it is recommended to use this feature as sparingly as possible. |
Controlling Log Levels with Properties
Log levels can be configured via properties defined in application.yml
(and environment variables) with the log.level
prefix:
logger:
levels:
foo.bar: ERROR
Note that the ability to control log levels via config is controlled via the LoggingSystem interface. Currently Micronaut ships with a single implementation that allows setting log levels for the Logback library. If another library is chosen you should provide a bean that implements this interface.