spring-boot-event-driven-patterns

Событийное взаимодействие в Spring Boot

giuseppe-trisciuoglio/developer-kitАвторский скилл
357звёзд41форковУ всего репозитория

Что получите

Реализация публикации и обработки событий в Spring Boot с выбранным механизмом доставки и обработки ошибок.

Что передать

Spring Boot-проект, бизнес-сценарий, границы транзакций и требования к доставке событий.

Автопроверка файлов

Проверен состав файлов. Запуск не тестировался. Что проверено

Оценки пользователей

Загрузка оценок…
Ваш опыт
Обсудить →

Как использовать

Помогает разработчикам Spring Boot заменить прямые вызовы между частями системы обработкой событий. Охватывает события внутри приложения, обмен через Kafka и сохранение событий вместе с бизнес-данными для последующей отправки.

  1. Опишите свершившиеся бизнес-события и выберите локальную обработку либо обмен между сервисами.
  2. Настройте обработку после успешного завершения транзакции; для распределённой отправки при необходимости сохраняйте событие и бизнес-данные одной транзакцией.
  3. Предусмотрите повторную обработку без повторных побочных действий, повторные попытки и отдельную очередь неуспешных сообщений; проверьте доставку и поведение при сбоях.

Условия работы

  • Руководство рассчитано на Spring Boot 3.x; сценарии обмена через Kafka требуют настроенной инфраструктуры Kafka.
  • Обработчики Kafka должны учитывать дубликаты; порядок событий в распределённой системе не гарантирован.
  • Нельзя выполнять блокирующие операции в слушателях на основном потоке транзакции. Асинхронная обработка требует учёта конкурентного выполнения.

Пример запроса после установки

Переведи отправку уведомлений о заказе на события в Spring Boot: обрабатывай их после сохранения заказа и предусмотрите доставку через Kafka с повторными попытками.

Пример составлен по инструкции автора; результат запуска не проверялся.

Основание: инструкция закреплённой версии

Для установки

Node.js, npm и Git для команды выше. Подключения и инструменты для работы скилла настраиваются отдельно.

Совместимые агенты

Совместимость указана для инструкций. Запуск в каждом приложении не тестировался; для веб-чата способ подключения может отличаться.

Файлы скилла

GitHub
Читать инструкцию SKILL.md

Исходный текст закреплённой версии.

---
name: spring-boot-event-driven-patterns
description: 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.
allowed-tools: Read, Write, Edit, Bash
---

# 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
- **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](references/dependency-setup.md)** — Maven/Gradle dependencies
- **[configuration.md](references/configuration.md)** — Kafka and Spring Cloud Stream configuration
- **[domain-events-design.md](references/domain-events-design.md)** — Domain event design patterns
- **[aggregate-root-patterns.md](references/aggregate-root-patterns.md)** — Aggregate root with event publishing
- **[event-publishing.md](references/event-publishing.md)** — Local and distributed event publishing
- **[event-handling.md](references/event-handling.md)** — Event handling and consumption patterns
- **[outbox-pattern.md](references/outbox-pattern.md)** — Transactional outbox pattern for reliability
- **[testing-strategies.md](references/testing-strategies.md)** — Unit and integration testing approaches
- **[examples.md](references/examples.md)** — Complete working examples
- **[event-driven-patterns-reference.md](references/event-driven-patterns-reference.md)** — Detailed reference documentation

## Constraints and Warnings

- Events published with `@TransactionalEventListener` only 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 publishing
- `spring-boot-test-patterns` — Testing event-driven applications
- `aws-sdk-java-v2-lambda` — Event-driven processing with AWS Lambda
- `langchain4j-tool-function-calling-patterns` — AI-driven event processing

Проверка и особенности

Автоматическая проверка источника и файлов

Автоматически проверены публичный репозиторий, лицензия, заголовок SKILL.md, состав текстового пакета и Git-хеш каждого файла. Пакеты с исполняемыми файлами и срабатываниями применённых статических правил не включены. Ручной аудит всех инструкций и функциональный запуск не проводились. Внешние инструменты и сервисы не проверялись. Проверка не гарантирует безопасность.

В публичном списке установок на 2026-10-09 у скилла было 3 682 установок. Порог отбора — 1 000 установок. Число установок показывает распространённость, а не качество или безопасность инструкции.

Проверка состава
09.10.2026
Проверенная версия
fe73fb33a09e
Файлы с кодом
Не указаны в данных проверки
Изменения на GitHub
Нужна повторная проверкаПоследняя проверка: 11.10.2026
Как мы проверяем скиллы

Репозиторий и лицензия

giuseppe-trisciuoglio/developer-kit
357 звёзд41 форков

Это показатели всего репозитория, а не установки скилла. Снимок требует обновления.

Последняя активность GitHub
10.09.2026
Лицензия
MIT
Добавлен в каталог
09.10.2026
Полный текст лицензии
MIT License

Copyright (c) 2025 Giuseppe Trisciuoglio

Permission is hereby granted, free of charge, to any person obtaining a copy
of this software and associated documentation files (the "Software"), to deal
in the Software without restriction, including without limitation the rights
to use, copy, modify, merge, publish, distribute, sublicense, and/or sell
copies of the Software, and to permit persons to whom the Software is
furnished to do so, subject to the following conditions:

The above copyright notice and this permission notice shall be included in all
copies or substantial portions of the Software.

THE SOFTWARE IS PROVIDED "AS IS", WITHOUT WARRANTY OF ANY KIND, EXPRESS OR
IMPLIED, INCLUDING BUT NOT LIMITED TO THE WARRANTIES OF MERCHANTABILITY,
FITNESS FOR A PARTICULAR PURPOSE AND NONINFRINGEMENT. IN NO EVENT SHALL THE
AUTHORS OR COPYRIGHT HOLDERS BE LIABLE FOR ANY CLAIM, DAMAGES OR OTHER
LIABILITY, WHETHER IN AN ACTION OF CONTRACT, TORT OR OTHERWISE, ARISING FROM,
OUT OF OR IN CONNECTION WITH THE SOFTWARE OR THE USE OR OTHER DEALINGS IN THE
SOFTWARE.

Ещё в этой категории

Все в категории

Обсуждение

Правила

Пользовались этим скиллом? Делитесь опытом без регистрации. Все комментарии проверяет модератор.

Мои комментарии