Micronaut provides a lightweight and highly efficient event publishing mechanism. Events allow decoupled communication within your application, which is especially useful when different components need to respond to certain actions, such as user creation or order processing.
In this guide, you’ll learn how to:
- Define custom events
- Publish events
- Handle events using listeners
- Use Maven for your project setup
- Keep your app decoupled and clean

📦 Project Setup (Maven)
Ensure your pom.xml
includes:
1 2 3 4 5 6 7 8 9 |
<dependencies> <dependency> <groupId>io.micronaut</groupId> <artifactId>micronaut-inject</artifactId> </dependency> </dependencies> |
Set Micronaut and Java versions in properties:
1 2 3 4 5 6 7 |
<properties> <micronaut.version>4.2.0</micronaut.version> <java.version>17</java.version> </properties> |
Use Micronaut CLI or Maven archetype to generate the project.
🔔 Step 1: Define a Custom Event
Create a POJO to hold event data.
1 2 3 4 5 6 7 8 9 10 11 12 13 14 15 16 |
package com.kscodes.micronaut.advanced; public class UserCreatedEvent { private final String username; public UserCreatedEvent(String username) { this.username = username; } public String getUsername() { return username; } } |
📢 Step 2: Publish an Event
Inject the ApplicationEventPublisher
and publish the event.
1 2 3 4 5 6 7 8 9 10 11 12 13 14 15 16 17 18 19 20 21 22 23 24 25 |
package com.kscodes.micronaut.advanced; import io.micronaut.context.event.ApplicationEventPublisher; import jakarta.inject.Singleton; @Singleton public class UserService { private final ApplicationEventPublisher<UserCreatedEvent> publisher; public UserService(ApplicationEventPublisher<UserCreatedEvent> publisher) { this.publisher = publisher; } public void registerUser(String username) { // Logic to persist user System.out.println("User registered: " + username); // Publish the event publisher.publishEvent(new UserCreatedEvent(username)); } } |
🎧 Step 3: Handle the Event with Listener
Create a listener using @EventListener
.
1 2 3 4 5 6 7 8 9 10 11 12 13 14 15 16 17 |
package com.kscodes.micronaut.advanced; import io.micronaut.runtime.event.annotation.EventListener; import jakarta.inject.Singleton; @Singleton public class UserEventListener { @EventListener public void onUserCreated(UserCreatedEvent event) { System.out.println("User creation event handled: " + event.getUsername()); // e.g., send welcome email } } |
✅ Benefits of Using Events in Micronaut
- Loose coupling: Your services don’t need to know about each other.
- Testability: You can test listeners and services independently.
- Clean architecture: Keeps business logic separate from side effects.
🧪 Bonus: Testing the Event Flow
1 2 3 4 5 6 7 8 9 10 11 12 13 14 15 |
package com.kscodes.micronaut.advanced; import io.micronaut.context.ApplicationContext; public class EventDemoApp { public static void main(String[] args) { try (ApplicationContext context = ApplicationContext.run()) { UserService userService = context.getBean(UserService.class); userService.registerUser("kscodes"); } } } |
🔗 External References
🏁 Conclusion
Micronaut’s event system is clean, efficient, and perfect for decoupling components in modern microservices and monoliths alike. Whether you’re sending notifications, updating logs, or integrating third-party systems — events provide the perfect solution.
🔥 Tip: Use
@Async
on your listeners to make them non-blocking and improve performance.