
Spring Boot Event Driven Patterns
Implement Spring Boot domain events, Kafka messaging, transactional listeners, and outbox-style reliable publishing when splitting a monolith or connecting microservices.
Overview
Spring Boot Event-Driven Patterns is an agent skill most often used in Build integrations (also Ship testing, Operate monitoring) that implements EDA with domain events, Kafka, transactional listeners, and the outbox pat
Install
npx skills add https://github.com/giuseppe-trisciuoglio/developer-kit --skill spring-boot-event-driven-patternsWhat is this skill?
- Domain events with eventId, occurredAt, and correlationId on a DomainEvent base
- ApplicationEventPublisher and @TransactionalEventListener for post-commit publishing
- Spring Kafka producer and consumer setup with Spring Cloud Stream references
- Transactional outbox pattern for reliable distributed messaging
- Quick-reference table mapping EDA concepts to Spring Boot 3.x APIs
- Quick-reference table mapping Domain Events, Event Publishing, Kafka, and Outbox concepts to Spring APIs
Adoption & trust: 1.2k installs on skills.sh; 271 GitHub stars; 3/3 security scanners passed (skills.sh audits).
What problem does it solve?
You need async communication between Spring services but synchronous calls or fire-and-forget publishes risk lost events and tangled domains.
Who is it for?
Solo builders shipping event-driven microservices or modular monoliths on Spring Boot who want agent-guided Kafka and listener setup.
Skip if: Simple CRUD apps with no messaging, non-JVM stacks, or teams that only need in-memory Spring events with no broker.
When should I use this skill?
Implementing event-driven systems in Spring Boot, setting up async messaging with Kafka, publishing domain events from DDD aggregates, or needing reliable event publishing with the outbox pattern.
What do I get? / Deliverables
You can publish domain events after DB commits, wire Kafka producers and consumers, and adopt outbox-style reliability instead of brittle dual writes.
- Domain event types and publishers
- Kafka listener and producer configuration
- Transactional outbox implementation outline
Recommended Skills
Journey fit
Spans multiple journey phases - primary shelf plus alternate fits below.
Event-driven wiring is authored during Build integrations, then validated in Ship and monitored in Operate once messages flow in production. Integrations is the primary shelf because Kafka producers, consumers, and cross-service events are boundary concerns between services.
Where it fits
Stand up a Kafka producer and consumer pair when extracting billing events from a modular monolith.
Emit domain events from aggregate roots after save using ApplicationEventPublisher.
Verify @TransactionalEventListener handlers only run after commit using integration tests.
Triage stuck outbox rows or consumer lag after a partial broker outage.
How it compares
Spring-specific EDA playbook, not a generic message-queue tutorial or an MCP bridge to Kafka.
Common Questions / FAQ
Who is spring-boot-event-driven-patterns for?
Indie and solo developers on Spring Boot 3.x who are adding Kafka, domain events, or outbox reliability between services.
When should I use spring-boot-event-driven-patterns?
During Build when integrating Kafka and domain events; in Ship when testing listeners and failure paths; in Operate when you iterate on consumer lag and outbox delivery.
Is spring-boot-event-driven-patterns safe to install?
It allows Bash and file writes—review the Security Audits panel on this Prism page, restrict credentials, and audit generated config before deploying brokers.
SKILL.md
READMESKILL.md - Spring Boot Event Driven Patterns
# Spring Boot Event-Driven Patterns ## Overview Implement Event-Driven Architecture (EDA) patterns in Spring Boot 3.x using domain events, ApplicationEventPublisher, `@TransactionalEventListener`, and distributed messaging with Kafka and Spring Cloud Stream. ## When to Use - Implementing event-driven microservices with Kafka messaging - Publishing domain events from aggregate roots in DDD architectures - Setting up transactional event listeners that fire after database commits - Adding async messaging with producers and consumers via Spring Kafka - Ensuring reliable event delivery using the transactional outbox pattern - Replacing synchronous calls with event-based communication between services ## Quick Reference | Concept | Description | |---------|-------------| | **Domain Events** | Immutable events extending `DomainEvent` base class with eventId, occurredAt, correlationId | | **Event Publishing** | `ApplicationEventPublisher.publishEvent()` for local, `KafkaTemplate` for distributed | | **Event Listening** | `@TransactionalEventListener(phase = AFTER_COMMIT)` for reliable handling | | **Kafka** | `@KafkaListener(topics = "...")` for distributed event consumption | | **Spring Cloud Stream** | Functional programming model with `Consumer` beans | | **Outbox Pattern** | Atomic event storage with business data, scheduled publisher | ## Examples ### Monolithic to Event-Driven Refactoring **Before (Anti-Pattern):** ```java @Transactional public Order processOrder(OrderRequest request) { Order order = orderRepository.save(request); inventoryService.reserve(order.getItems()); // Blocking paymentService.charge(order.getPayment()); // Blocking emailService.sendConfirmation(order); // Blocking return order; } ``` **After (Event-Driven):** ```java @Transactional public Order processOrder(OrderRequest request) { Order order = Order.create(request); orderRepository.save(order); // Publish event after transaction commits eventPublisher.publishEvent(new OrderCreatedEvent(order.getId(), order.getItems())); return order; } @Component public class OrderEventHandler { @TransactionalEventListener(phase = TransactionPhase.AFTER_COMMIT) public void handleOrderCreated(OrderCreatedEvent event) { // Execute asynchronously after the order is saved inventoryService.reserve(event.getItems()); paymentService.charge(event.getPayment()); } } ``` See [examples.md](references/examples.md) for complete working examples. ## Instructions ### 1. Design Domain Events Create immutable event classes extending a base `DomainEvent` class: ```java public abstract class DomainEvent { private final UUID eventId; private final LocalDateTime occurredAt; private final UUID correlationId; } public class ProductCreatedEvent extends DomainEvent { private final ProductId productId; private final String name; private final BigDecimal price; } ``` See [domain-events-design.md](references/domain-events-design.md) for patterns. ### 2. Publish Events from Aggregates Add domain events to aggregate roots, publish via `ApplicationEventPublisher`: ```java @Service @Transactional public class ProductService { public Product createProduct(CreateProductRequest request) { Product product = Product.create(request.getName(), request.getPrice(), request.getStock()); repository.sa