Micronaut provides a powerful way to manage configuration using @ConfigurationProperties. This annotation allows us to bind external configuration properties (such as values from application.yml or application.properties) directly to Java objects.
Table of contents
- 1. Setting Up the Micronaut Project
- 2. Defining Configuration in application.yml
- 3. Setting Up the Configuration
- 4. Injecting the Configuration into a Service
- 5. Running the Application
- 6. Unit Tests
- 7. Conclusion
- 8. Download Source Code
- 9. References
Technologies used:
- Java 21
- Micronaut 4.7.6
- Maven 3.x
1. Setting Up the Micronaut Project
We can create a Micronaut project using the Micronaut CLI. Open the terminal and run the following command:
mn create-app com.mkyong.configuration --build=maven --lang=java --features=yaml
2. Defining Configuration in application.yml
We configure the properties in src/main/resources/application.yml
micronaut:
application:
name: configuration
app:
name: "MicronautApp"
version: 1
supportedLanguages:
- "English"
- "Spanish"
- "French"
metadata:
author: "mkyong"
license: "MIT"
3. Setting Up the Configuration
We define a configuration class using @ConfigurationProperties, specifying a prefix that matches the property keys in application.yml.
package com.mkyong.config;
import io.micronaut.context.annotation.ConfigurationProperties;
import java.util.List;
import java.util.Map;
@ConfigurationProperties("app")
public class AppConfig {
private String name;
private int version;
private List<String> supportedLanguages;
private Map<String, String> metadata;
public String getName() {
return name;
}
public void setName(String name) {
this.name = name;
}
public int getVersion() {
return version;
}
public void setVersion(int version) {
this.version = version;
}
public List<String> getSupportedLanguages() {
return supportedLanguages;
}
public void setSupportedLanguages(List<String> supportedLanguages) {
this.supportedLanguages = supportedLanguages;
}
public Map<String, String> getMetadata() {
return metadata;
}
public void setMetadata(Map<String, String> metadata) {
this.metadata = metadata;
}
}
4. Injecting the Configuration into a Service
Now, we inject AppConfig into a service or controller:
package com.mkyong.config;
import jakarta.inject.Singleton;
@Singleton
public class AppService {
private final AppConfig appConfig;
public AppService(AppConfig appConfig) {
this.appConfig = appConfig;
}
public void printConfig() {
System.out.println("App Name: " + appConfig.getName());
System.out.println("App Version: " + appConfig.getVersion());
System.out.println("Supported Languages: " + String.join(", ", appConfig.getSupportedLanguages()));
System.out.println("Metadata: " + appConfig.getMetadata());
}
}
5. Running the Application
When we run the application, AppService prints the values from application.yml.
package com.mkyong;
import com.mkyong.config.AppService;
import io.micronaut.runtime.Micronaut;
import jakarta.inject.Singleton;
@Singleton
public class Application {
private final AppService appService;
public Application(AppService appService) {
this.appService = appService;
}
public static void main(String[] args) {
Micronaut.run(Application.class, args) // start app
.getBean(Application.class).init(); // run startup code
}
public void init() {
appService.printConfig();
}
}
Output
__ __ _ _
| \/ (_) ___ _ __ ___ _ __ __ _ _ _| |_
| |\/| | |/ __| '__/ _ \| '_ \ / _` | | | | __|
| | | | | (__| | | (_) | | | | (_| | |_| | |_
|_| |_|_|\___|_| \___/|_| |_|\__,_|\__,_|\__|
18:58:48.937 [main] INFO io.micronaut.runtime.Micronaut - Startup completed in 467ms. Server Running: http://localhost:8080
App Name: MicronautApp
App Version: 1
Supported Languages: English, Spanish, French
Metadata: {author=mkyong, license=MIT}
6. Unit Tests
We create a unit test to verify all fields in AppConfig, including lists, map keys, and values:
package com.mkyong;
import com.mkyong.config.AppConfig;
import com.mkyong.config.AppService;
import io.micronaut.test.extensions.junit5.annotation.MicronautTest;
import jakarta.inject.Inject;
import org.junit.jupiter.api.Test;
import java.util.List;
import java.util.Map;
import static org.junit.jupiter.api.Assertions.*;
@MicronautTest
class AppServiceTest {
@Inject
AppService appService;
@Inject
AppConfig appConfig;
@Test
void testAppConfigProperties() {
assertEquals("MicronautApp", appConfig.getName());
assertEquals(1, appConfig.getVersion());
List<String> supportedLanguages = appConfig.getSupportedLanguages();
assertNotNull(supportedLanguages);
assertEquals(3, supportedLanguages.size());
assertTrue(supportedLanguages.contains("English"));
assertTrue(supportedLanguages.contains("Spanish"));
assertTrue(supportedLanguages.contains("French"));
Map<String, String> metadata = appConfig.getMetadata();
assertNotNull(metadata);
assertEquals(2, metadata.size());
assertEquals("mkyong", metadata.get("author"));
assertEquals("MIT", metadata.get("license"));
}
}
7. Conclusion
Using @ConfigurationProperties, we can easily manage external configurations in a clean and structured way. This approach makes our Micronaut applications more flexible and maintainable.
After reading a lot of documentation, I could finally find a very easy example of how @ConfigurationProperties works. Thank you, sir.
Thanks.