Micronaut @ConfigurationProperties Example
Micronaut is a modern, JVM-based, full-stack microservices framework designed for building modular, easily testable microservice and serverless applications. One of the powerful features Micronaut provides is the ability to bind configuration properties from configuration files (like application.yml
) directly to Java objects using the @ConfigurationProperties
annotation. Let us delve into understanding a practical Micronaut @ConfigurationProperties example that demonstrates how to bind external configuration into structured Java classes using the Micronaut framework.
1. What is Micronaut?
Micronaut is a modern, JVM-based, full-stack framework specifically designed for building modular, high-performance microservices, serverless applications, and cloud-native systems. It offers first-class support for Java, Kotlin, and Groovy, making it a flexible choice for JVM developers.
Unlike traditional Java frameworks that rely heavily on runtime reflection and proxies (such as Spring), Micronaut uses compile-time annotation processing for dependency injection, AOP (Aspect-Oriented Programming), and configuration. This unique approach drastically reduces memory usage and startup time, making it ideal for microservices and serverless environments like AWS Lambda or Google Cloud Functions.
Micronaut also integrates seamlessly with GraalVM to enable ahead-of-time (AOT) compilation into native executables, further improving performance and resource efficiency.
Key features of Micronaut include:
- Compile-time dependency injection: No reflection or runtime proxies, leading to better performance and smaller memory footprint.
- Fast startup time and low memory usage: Ideal for microservices and containerized environments.
- Seamless integration with GraalVM: Supports building native images for ultra-fast execution and minimal memory use.
- Reactive and non-blocking: Includes built-in support for reactive programming using RxJava, Project Reactor, etc.
- Built-in HTTP server/client: Lightweight Netty-based web server and declarative HTTP clients with easy configuration.
- Cloud-native readiness: Support for service discovery, distributed tracing, configuration management, and more.
- Modular architecture: Encourages separation of concerns and better maintainability.
1.1 What is @ConfigurationProperties annotation?
The @ConfigurationProperties
annotation in Micronaut is used to map configuration properties from your application.yml
or application.properties
file into a POJO. This allows you to cleanly separate configuration data from your business logic and access strongly typed configuration values throughout your application.
It works similarly to the configuration property binding mechanism in Spring Boot. However, a key advantage of Micronaut is that it performs this binding at compile time rather than runtime. This design choice contributes to faster startup times, reduced memory consumption, and overall better performance — especially important for microservices and serverless environments where cold-start times and resource efficiency are critical.
By leveraging @ConfigurationProperties
, developers can group related configurations into logically structured Java classes, reducing the chance of errors caused by typo-prone property lookups. Since the values are strongly typed, you benefit from compile-time checks and IDE auto-completion, which enhances productivity and maintainability.
Micronaut also supports nested configuration objects, validation via Jakarta Bean Validation annotations (like @NotBlank
or @Email
), and environment-specific overrides. These features allow you to build robust, configurable applications that are easy to scale and adapt to different deployment targets.
Overall, @ConfigurationProperties
is a foundational feature in Micronaut’s configuration system, and using it properly leads to cleaner code, centralized config management, and a more modular and testable application design.
2. Code Example
In this section, we’ll walk through a complete example of using @ConfigurationProperties
in a Micronaut application. This includes setting up dependencies, writing configuration, creating the POJO, and injecting it into a controller. This hands-on approach will solidify your understanding of how configuration binding works in Micronaut.
2.1 Add Micronaut dependencies (build.gradle)
First, we set up the required dependencies and plugins in our build.gradle
file. Micronaut requires annotation processing during compilation to enable features like dependency injection and configuration binding.
plugins { id "io.micronaut.application" version "4.1.2" } micronaut { runtime("netty") // Micronaut's default HTTP server testRuntime("junit5") // Testing framework processing { incremental(true) annotations("example.*") // Specifies which packages to process } } dependencies { implementation("io.micronaut:micronaut-runtime") // Core Micronaut runtime annotationProcessor("io.micronaut:micronaut-inject-java") // Required for compile-time DI and config processing }
2.2 Define Configuration in application.yml
This file contains our externalized configuration. We’ll define application-specific properties that will later be mapped to a Java class using @ConfigurationProperties
.
app: name: My Micronaut App version: 1.0 developer: name: Yatin email: yatin@example.com
Here, the app
block is our configuration namespace. It contains basic metadata about the application and a nested developer
block with personal information.
2.3 Create a ConfigurationProperties Class
We now create a strongly typed POJO that maps to the YAML structure defined above. Micronaut will automatically populate this class with the appropriate values at startup.
package example.config; import io.micronaut.context.annotation.ConfigurationProperties; @ConfigurationProperties("app") // Binds to the 'app' root in application.yml public class AppConfiguration { private String name; private String version; private Developer developer; public String getName() { return name; } public void setName(String name) { this.name = name; } public String getVersion() { return version; } public void setVersion(String version) { this.version = version; } public Developer getDeveloper() { return developer; } public void setDeveloper(Developer developer) { this.developer = developer; } @ConfigurationProperties("developer") // Binds to 'app.developer' public static class Developer { private String name; private String email; public String getName() { return name; } public void setName(String name) { this.name = name; } public String getEmail() { return email; } public void setEmail(String email) { this.email = email; } } }
The outer class maps to app
, while the nested static class maps to app.developer
. This structure keeps related configurations logically grouped.
2.4 Inject Configuration in a Controller or Bean
Once the configuration class is created, we can inject it into any Micronaut bean (like a controller) using constructor injection. Here’s how you might use it to return configuration details via an HTTP endpoint.
package example; import example.config.AppConfiguration; import io.micronaut.http.annotation.Controller; import io.micronaut.http.annotation.Get; @Controller("/config") // Exposes an HTTP endpoint public class ConfigController { private final AppConfiguration appConfiguration; public ConfigController(AppConfiguration appConfiguration) { this.appConfiguration = appConfiguration; } @Get("/") // HTTP GET request public String getConfigInfo() { return "App Name: " + appConfiguration.getName() + "<br>" + "Version: " + appConfiguration.getVersion() + "<br>" + "Developer: " + appConfiguration.getDeveloper().getName() + " (" + appConfiguration.getDeveloper().getEmail() + ")"; } }
The configuration is automatically injected by Micronaut. When a user accesses /config
, the application returns values loaded from application.yml
.
2.5 Run the Application
Once everything is in place, run the application using:
./gradlew run
Navigate to http://localhost:8080/config
in your browser and you should see:
App Name: My Micronaut App Version: 1.0 Developer: Yatin (yatin@example.com)
3. Conclusion
The @ConfigurationProperties
annotation in Micronaut is a clean and powerful way to access strongly typed configuration values from your configuration files. It enables better separation of concerns, enhances testability, and leverages Micronaut’s compile-time capabilities to ensure optimal performance. Whether you’re building microservices or monolithic applications, using @ConfigurationProperties
improves the maintainability and readability of your application configuration.