Configuration and environments
The blog title, the page size or the database address should not be written straight into code: they differ on your computer and on the server. Such values live in the settings file src/main/resources/application.properties, and the code reads them. An environment is a named set of settings, for example dev for development and prod for the server.
Your own settings
Add lines to the file the generator created:
# src/main/resources/application.properties
micronaut.application.name=blog
blog.title=My blog
blog.author=AnnaThe framework reads the micronaut.* keys itself; the blog.* keys are ours. The YAML format (application.yml) is supported too if you pick the yaml feature when creating the project.
A group of settings in a record
Several related values are best collected into one record with @ConfigurationProperties:
// src/main/java/com/example/BlogConfig.java
package com.example;
import io.micronaut.context.annotation.ConfigurationProperties;
import io.micronaut.core.bind.annotation.Bindable;
@ConfigurationProperties("blog")
public record BlogConfig(String title, @Bindable(defaultValue = "10") int pageSize) {
}The blog prefix plus the component name give the key: title is read from blog.title, and pageSize from blog.page-size (files conventionally use hyphens). If a key is missing, the defaultValue applies. The record becomes a bean, and you inject it like a service.
A single value with @Value
For a single value there is @Value with a ${key} expression:
// src/main/java/com/example/AboutController.java
package com.example;
import io.micronaut.context.annotation.Value;
import io.micronaut.context.env.Environment;
import io.micronaut.http.annotation.Controller;
import io.micronaut.http.annotation.Get;
@Controller("/about")
public class AboutController {
private final BlogConfig config;
private final Environment environment;
private final String author;
public AboutController(BlogConfig config, Environment environment,
@Value("${blog.author}") String author) {
this.config = config;
this.environment = environment;
this.author = author;
}
@Get
public AboutInfo about() {
return new AboutInfo(config.title(), config.pageSize(), author, environment.getActiveNames());
}
}AboutInfo is a @Serdeable record with the fields title, pageSize, author and environments (of type Set<String>). The request curl http://localhost:8080/about returns:
{"title":"My blog","pageSize":10,"author":"Anna"}The list of environments is empty, so it is left out of the JSON.
Environments
Create a file next to it for the dev environment:
# src/main/resources/application-dev.properties
blog.title=My blog (dev)
blog.page-size=3An environment is switched on with the MICRONAUT_ENVIRONMENTS variable or the -Dmicronaut.environments=dev property:
MICRONAUT_ENVIRONMENTS=dev ./mvnw mn:runThe log shows Established active environments: [dev], and /about answers {"title":"My blog (dev)","pageSize":3,"author":"Anna","environments":["dev"]}. Values from application-dev.properties override the common file.
OS environment variables
Any key can be overridden with an OS variable: dots and hyphens become underscores and letters become uppercase. blog.title turns into BLOG_TITLE:
BLOG_TITLE="Oleg's blog" ./mvnw mn:runThis is how passwords and addresses are set on a server without changing project files.
Common mistake
If no source has the key used in @Value, the first request to the controller returns 500, and the log says:
Message: Error resolving property value [${blog.author}]. Property doesn't exist
Path Taken:
new c.e.AboutController(BlogConfig config, Environment environment, @Value String author)Add the key to application.properties or put a default value right in the expression: @Value("${blog.author:Anna}").