en un clic
spring-boot-messaging
Use when implementing event-driven or message-based integration in Spring Boot 4, publishing domain events, coordinating Kafka or broker messaging, or applying outbox and idempotency patterns for reliable delivery.
Menu
Use when implementing event-driven or message-based integration in Spring Boot 4, publishing domain events, coordinating Kafka or broker messaging, or applying outbox and idempotency patterns for reliable delivery.
Use when configuring Spring Boot Actuator for production-grade monitoring, health probes, secured management endpoints, readiness/liveness checks, and Micrometer metrics in Spring Boot 4 applications.
Use when building Model Context Protocol servers in Spring Boot with Spring AI, exposing tools or resources, configuring transports, or integrating AI tool-calling workflows.
Use when adding caching to Spring Boot 4 services, configuring cache providers and TTL policies, invalidating stale data, or diagnosing cache hit and miss behavior.
Use when integrating Neo4j into a Spring Boot 4 backend with graph models, Cypher queries, reactive repositories, relationship mapping, or graph-focused testing patterns.
Use when documenting reactive Spring Boot 4 HTTP APIs with SpringDoc OpenAPI, configuring Swagger UI, annotating endpoints, documenting security schemes, or defining request and response schemas.
Use when implementing reactive fault-tolerance patterns in Spring Boot 4 with native Spring Framework 7 resilience features or Resilience4j, including retries, concurrency limiting, circuit breakers, rate limiting, timeouts, and fallbacks for downstream calls.
| name | spring-boot-messaging |
| description | Use when implementing event-driven or message-based integration in Spring Boot 4, publishing domain events, coordinating Kafka or broker messaging, or applying outbox and idempotency patterns for reliable delivery. |
| allowed-tools | Read, Write, Edit, Bash |
Messaging and event-driven integration patterns for Spring Boot 4 + Spring Framework 7 + WebFlux + Kotlin coroutines.
This skill covers application events, transaction-bound events, asynchronous listeners, reliable publication patterns, and broker-oriented integration guidance with a reactive-first mindset.
From the official Spring Framework documentation:
@EventListener remains the base model for application events@TransactionalEventListener supports both imperative and reactive transaction models@EventListener @Async is supported, but has important limitations around exception propagation,
return-value event publication, and context propagationTransactionalOperator is the official reactive transaction toolUse companion skills instead when the main concern is:
spring-bootspring-boot-resiliencespring-boot-api-standardsspring-boot-testing-integrations@EventListener BasicsUse @EventListener for in-process event reactions inside a service boundary.
@Component
class WorkspaceNotificationListener {
@EventListener
fun handleWorkspaceCreated(event: WorkspaceCreatedEvent) {
// trigger lightweight local side effect
}
}
Spring supports publishing a new event by returning it from an @EventListener.
@EventListener
fun handleWorkspaceCreated(event: WorkspaceCreatedEvent): WorkspaceAuditEvent {
return WorkspaceAuditEvent(event.workspaceId)
}
This is convenient for simple in-process event chaining, but do not use it as a substitute for a real durable integration flow.
Use @TransactionalEventListener when event handling semantics must depend on transaction outcome.
@Component
class WorkspaceCreatedTransactionalListener {
@TransactionalEventListener
fun handleWorkspaceCreated(event: WorkspaceCreatedEvent) {
// runs after commit by default when transaction semantics are available
}
}
This is where many teams get burned.
According to the official docs:
@TransactionalEventListener supports reactive transactions too@TransactionalEventListener often feels straightforward.For write flows in reactive systems, prefer explicit transaction boundaries with
TransactionalOperator.
@Service
class WorkspaceLifecycleService(
private val repository: WorkspaceRepository,
private val eventPublisher: ApplicationEventPublisher,
private val transactionalOperator: TransactionalOperator,
) {
suspend fun createWorkspace(name: String): Workspace =
requireNotNull(
transactionalOperator.executeAndAwait {
val workspace = repository.save(Workspace.create(name))
eventPublisher.publishEvent(WorkspaceCreatedEvent(workspace.id, workspace))
workspace
},
) { "Reactive transaction completed without returning a workspace" }
}
Spring supports asynchronous listeners via @EventListener + @Async.
@Component
class EmailNotificationListener {
@Async
@EventListener
fun handleWorkspaceCreated(event: WorkspaceCreatedEvent) {
// asynchronous side effect
}
}
The Spring docs explicitly call out that async listeners:
When another service must consume the event reliably, prefer an explicit outbox.
Every serious message-driven system needs idempotency.
If using Kafka, RabbitMQ, or another broker:
| Need | Preferred approach |
|---|---|
| Local in-process decoupling | @EventListener |
| Transaction-outcome-sensitive local handling | @TransactionalEventListener with care |
| Reactive write-flow transaction control | TransactionalOperator |
| Cross-service reliable delivery | Outbox + broker |
| Fire-and-forget non-critical side effect | @EventListener + @Async |
@TransactionalEventListener works identically in imperative and reactive flows../SKILL.md — Core reactive persistence and transaction boundary rulesspring-boot-testing-integrations — Event-driven and outbox verification patternsspring-boot-resilience — Retry, timeout, and downstream protection patterns