Agent skill
spring-boot-event-driven-patterns
Provides Event-Driven Architecture (EDA) patterns for Spring Boot — creates domain events, configures ApplicationEvent and @TransactionalEventListener, sets up Kafka producers and consumers, and implements the transactional outbox pattern for reliable distributed messaging. Use when 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.
Install this agent skill to your Project
npx add-skill https://github.com/giuseppe-trisciuoglio/developer-kit/tree/main/plugins/developer-kit-java/skills/spring-boot-event-driven-patterns
SKILL.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):
@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):
@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 for complete working examples.
Instructions
1. Design Domain Events
Create immutable event classes extending a base DomainEvent class:
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 for patterns.
2. Publish Events from Aggregates
Add domain events to aggregate roots, publish via ApplicationEventPublisher:
@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 for DDD patterns.
3. Handle Events Transactionally
Use @TransactionalEventListener for reliable event handling:
@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 for handling patterns.
4. Configure Kafka Infrastructure
Configure KafkaTemplate for publishing, @KafkaListener for consuming:
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 and configuration.md.
5. Implement Outbox Pattern
Create OutboxEvent entity for atomic event storage:
@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.
6. Handle Failure Scenarios
Implement retry logic, dead-letter queues, idempotent handlers:
@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(notCreateProduct) - Keep events immutable: All fields should be final
- Include correlation IDs: For tracing events across services
- Use AFTER_COMMIT phase: Ensures events are published after successful database transaction
- Implement idempotent handlers: Handle duplicate events gracefully
- Add retry mechanisms: For failed event processing with exponential backoff
- Implement dead-letter queues: For events that fail processing after retries
- Log all failures: Include sufficient context for debugging
- Make handlers order-independent: Event ordering is not guaranteed in distributed systems
- Batch event processing: When handling high volumes
- Monitor event latencies: Set up alerts for slow processing
References
- dependency-setup.md — Maven/Gradle dependencies
- configuration.md — Kafka and Spring Cloud Stream configuration
- domain-events-design.md — Domain event design patterns
- aggregate-root-patterns.md — Aggregate root with event publishing
- event-publishing.md — Local and distributed event publishing
- event-handling.md — Event handling and consumption patterns
- outbox-pattern.md — Transactional outbox pattern for reliability
- testing-strategies.md — Unit and integration testing approaches
- examples.md — Complete working examples
- event-driven-patterns-reference.md — Detailed reference documentation
Constraints and Warnings
- Events published with
@TransactionalEventListeneronly fire after transaction commit - Avoid publishing large objects in events (memory pressure, serialization issues)
- Be cautious with async event handlers (separate threads, concurrency issues)
- Kafka consumers must handle duplicate messages (implement idempotent processing)
- Event ordering is not guaranteed in distributed systems (design handlers to be order-independent)
- Never perform blocking operations in event listeners on the main transaction thread
- Monitor for event processing backlogs (indicate system capacity issues)
Related Skills
spring-boot-security-jwt— JWT authentication for secure event publishingspring-boot-test-patterns— Testing event-driven applicationsaws-sdk-java-v2-lambda— Event-driven processing with AWS Lambdalangchain4j-tool-function-calling-patterns— AI-driven event processing
Recommended Agent Skills
Expand your agent's capabilities with these related and highly-rated skills.
aws-cli-beast
Provides advanced AWS CLI patterns for managing EC2, Lambda, S3, DynamoDB, RDS, VPC, IAM, and CloudWatch. Generates bulk operation scripts, automates cross-service workflows, validates security configurations, and executes JMESPath queries for complex filtering. Triggers on "aws cli help", "aws command line", "aws scripting", "aws automation", "aws batch operations", "aws bulk operations", "aws cli pagination", "aws multi-region", "aws profiles", "aws cli troubleshooting".
aws-cost-optimization
Provides structured AWS cost optimization guidance using five pillars (right-sizing, elasticity, pricing models, storage optimization, monitoring) and twelve actionable best practices with executable AWS CLI examples. Use when optimizing AWS costs, reviewing AWS spending, finding unused AWS resources, implementing FinOps practices, reducing EC2/EBS/S3 bills, configuring AWS Budgets, or performing AWS Well-Architected cost reviews.
aws-sam-bootstrap
Provides AWS SAM bootstrap patterns: generates `template.yaml` and `samconfig.toml` for new projects via `sam init`, creates SAM templates for existing Lambda/CloudFormation code migration, validates build/package/deploy workflows, and configures local testing with `sam local invoke`. Use when the user asks about SAM projects, `sam init`, `sam deploy`, serverless deployments, or needs to bootstrap/migrate Lambda functions with SAM templates.
aws-drawio-architecture-diagrams
Creates professional AWS architecture diagrams in draw.io XML format (.drawio files) using official AWS Architecture Icons (aws4 library). Use when the user asks for AWS diagrams, VPC layouts, multi-tier architectures, serverless designs, network topology, or draw.io exports involving Lambda, EC2, RDS, or other AWS services.
aws-cloudformation-bedrock
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.
aws-cloudformation-s3
Provides AWS CloudFormation patterns for Amazon S3. Use when creating S3 buckets, policies, versioning, lifecycle rules, and implementing template structure with Parameters, Outputs, Mappings, Conditions, and cross-stack references.
Didn't find tool you were looking for?