spring-boot-event-driven-patterns
This skill provides event-driven architecture patterns for Spring Boot 3.x, including domain event creation, transactional event listeners, Kafka producer/consumer configuration, and the outbox pattern for reliable distributed messaging. Use it when building event-driven microservices, publishing domain events from DDD aggregates, implementing async messaging with Kafka, or ensuring reliable event delivery across service boundaries.
git clone --depth 1 https://github.com/giuseppe-trisciuoglio/developer-kit /tmp/spring-boot-event-driven-patterns && cp -r /tmp/spring-boot-event-driven-patterns/plugins/developer-kit-java/skills/spring-boot-event-driven-patterns ~/.claude/skills/spring-boot-event-driven-patternsSKILL.md
# 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.save(product);
product.getDomainEvents().forEach(eventPublisher::publishEvent);
product.clearDomainEvents();
return product;
}
}
```
See [aggregate-root-patterns.md](references/aggregate-root-patterns.md) for DDD patterns.
### 3. Handle Events Transactionally
Use `@TransactionalEventListener` for reliable event handling:
```java
@Component
public class ProductEventHandler {
@TransactionalEventListener(phase = TransactionPhase.AFTER_COMMIT)
public void onProductCreated(ProductCreatedEvent event) {
notificationService.sendProductCreatedNotification(event.getName());
}
}
```
**Validate:** Confirm the event handler fires only after the transaction commits by checking that the database state is committed before the handler executes.
See [event-handling.md](references/event-handling.md) for handling patterns.
### 4. Configure Kafka Infrastructure
Configure KafkaTemplate for publishing, `@KafkaListener` for consuming:
```yaml
spring:
kafka:
bootstrap-servers: localhost:9092
producer:
value-serializer: org.springframework.kafka.support.serializer.JsonSerializer
```
**Validate:** Send a test event via `KafkaTemplate` and confirm it appears in the consumer logs before proceeding to production patterns.
See [dependency-setup.md](references/dependency-setup.md) and [configuration.md](references/configuration.md).
### 5. Implement Outbox Pattern
Create `OutboxEvent` entity for atomic event storage:
```java
@Entity
public class OutboxEvent {
private UUID id;
private String aggregateId;
private String eventType;
private String payload;
private LocalDateTime publishedAt;
}
```
**Validate:** Confirm the scheduled processor picks up pending events by checking the `publishedAt` timestamp is set after the scheduled run.
Scheduled processor publishes pending events. See [outbox-pattern.md](references/outbox-pattern.md).
### 6. Handle Failure Scenarios
Implement retry logic, dead-letter queues, idempotent handlers:
```java
@RetryableTopic(attempts = "3")
@KafkaListener(topics = "product-events")
public void handleProductEvent(ProductCreatedEventDto event) {
orderService.onProductCreated(event);
}
```
**Validate:** Confirm messages reach the dead-letter topic after exhausting retries before moving to observability.
### 7. Add Observability
Enable Spring Cloud Sleuth for distributed tracing, monitor metrics.
## Best Practices
- **Use past tense naming**: `ProductCreated` (not `CreateProduct`)
- **Keep events immutable**: All fields should be final
-Provides chunking strategies for RAG systems. Generates chunk size recommendations (256-1024 tokens), overlap percentages (10-20%), and semantic boundary detection methods. Validates semantic coherence and evaluates retrieval precision/recall metrics. Use when building retrieval-augmented generation systems, vector databases, or processing large documents.
>
Implements document chunking, embedding generation, vector storage, and retrieval pipelines for Retrieval-Augmented Generation systems. Use when building RAG applications, creating document Q&A systems, or integrating AI with knowledge bases.
Provides AWS CloudFormation patterns for Auto Scaling including EC2, ECS, and Lambda. Use when creating Auto Scaling groups, launch configurations, launch templates, scaling policies, lifecycle hooks, and predictive scaling. Covers template structure with Parameters, Outputs, Mappings, Conditions, cross-stack references, and best practices for high availability and cost optimization.
Provides AWS CloudFormation patterns for Amazon Bedrock resources including agents, knowledge bases, data sources, guardrails, prompts, flows, and inference profiles. Use when creating Bedrock agents with action groups, implementing RAG with knowledge bases, configuring vector stores, setting up content moderation guardrails, managing prompts, orchestrating workflows with flows, and configuring inference profiles for model optimization.
Provides AWS CloudFormation patterns for CloudFront distributions, origins (ALB, S3, Lambda@Edge, VPC Origins), CacheBehaviors, Functions, SecurityHeaders, parameters, Outputs and cross-stack references. Use when creating CloudFront distributions with CloudFormation, configuring multiple origins, implementing caching strategies, managing custom domains with ACM, configuring WAF, and optimizing performance.
Provides AWS CloudFormation patterns for CloudWatch monitoring, metrics, alarms, dashboards, logs, and observability. Use when creating CloudWatch metrics, alarms, dashboards, log groups, log subscriptions, anomaly detection, synthesized canaries, Application Signals, and implementing template structure with Parameters, Outputs, Mappings, Conditions, cross-stack references, and CloudWatch best practices for monitoring production infrastructure.
Provides AWS CloudFormation patterns for DynamoDB tables, GSIs, LSIs, auto-scaling, and streams. Use when creating DynamoDB tables with CloudFormation, configuring primary keys, local/global secondary indexes, capacity modes (on-demand/provisioned), point-in-time recovery, encryption, TTL, and implementing template structure with Parameters, Outputs, Mappings, Conditions, cross-stack references.