Zum Hauptinhalt springen
tsecurity.de LIVE
Echtzeit-Radar & Feeds
Alle RSS Feeds
👥 Community & Social
Sichere ProgrammierungRefreshed repository pull requests page generally available(22.09.2026 um 03:25 Uhr)
Sichere ProgrammierungThe Joy of Learning the Basics Again(22.09.2026 um 03:28 Uhr)
Sichere ProgrammierungZero-Code OpenTelemetry Tracing for Dagster(22.09.2026 um 03:39 Uhr)
Linux Tipps & Hardening`prime-all`(22.09.2026 um 02:28 Uhr)
IT Security Toolsopensoho v0.15.2(22.09.2026 um 03:33 Uhr)
IT Security NachrichtenUS Proposes AI Incident Alert System in Talks With China, Bessent Says(22.09.2026 um 04:01 Uhr)
Sichere ProgrammierungRefreshed repository pull requests page generally available(22.09.2026 um 03:25 Uhr)
Sichere ProgrammierungThe Joy of Learning the Basics Again(22.09.2026 um 03:28 Uhr)
Sichere ProgrammierungZero-Code OpenTelemetry Tracing for Dagster(22.09.2026 um 03:39 Uhr)
Linux Tipps & Hardening`prime-all`(22.09.2026 um 02:28 Uhr)
IT Security Toolsopensoho v0.15.2(22.09.2026 um 03:33 Uhr)
IT Security NachrichtenUS Proposes AI Incident Alert System in Talks With China, Bessent Says(22.09.2026 um 04:01 Uhr)
Intelligence View
⚡ tsecurity.de Intelligence

Desacoplamento e Reatividade: Implementando o Design Pattern Observer com Spring Events

Em nossa jornada como desenvolvedores, frequentemente nos deparamos com a necessidade de orquestrar múltiplas ações a partir de um único evento central. Este é um desafio clássico que, se não for abordado corretamente, pode levar a um alto …

0
↗ Quelle (dev.to)
Reagiere als Erste:r — dein Feedback zählt!

Em nossa jornada como desenvolvedores, frequentemente nos deparamos com a necessidade de orquestrar múltiplas ações a partir de um único evento central. Este é um desafio clássico que, se não for abordado corretamente, pode levar a um alto acoplamento e à temida "bola de lama" de código.



Neste post, vou compartilhar um cenário real de pagamento em um sistema e como o Design Pattern Observer, implementado através do Spring Event, se mostrou a solução elegante e robusta para garantir a reatividade e o desacoplamento de nosso fluxo. O Problema: Acionamento Múltiplo e Consistência.



Imagine o fluxo de processamento de um pagamento. A etapa final retorna um status central: Success, Fail ou Pending. Com a chegada dessa resposta, várias operações de follow-up precisam ser disparadas simultaneamente e de forma independente:





  1. Notificação: Enviar um e-mail de confirmação ou erro ao cliente.


  2. Integração: Gerar um push de notificação para uma fila externa (ex: para processamento em um serviço de Notificações Assíncronas).



O problema aqui não é apenas executar as ações, mas fazê-lo sem que a classe de PaymentService precise conhecer ou ser responsável por cada uma delas. A solução deve permitir adicionar novas ações no futuro sem alterar o código principal do pagamento, seguindo o princípio Open/Closed do SOLID. A Solução Arquitetural escolhido foi o Padrão Observer.



O Observer é um padrão comportamental que define uma dependência um para muitos entre objetos.




  • Um objeto (Subject ou Publisher) notifica todos os seus dependentes (Observers ou Subscribers) sobre qualquer alteração de estado.

  • Os dependentes são notificados e reagem à mudança, sem que o Subject saiba a identidade ou o propósito específico de cada um.



Identificamos que essa era a abstração perfeita para o nosso cenário.






Implementação Prática com Spring Events.



No ecossistema Spring Boot, a maneira mais idiomática e gerenciada de implementar o padrão Observer é através dos Spring Events. O framework assume a responsabilidade pela orquestração do padrão, simplificando drasticamente a implementação.



Para isso, definimos três componentes principais:






1. O Evento (ApplicationEvent):



Criamos o objeto que encapsula o dado a ser transmitido. Ele deve estender de ApplicationEvent, permitindo que o Spring Context o monitore.




public class PaymentEvent extends ApplicationEvent {
private final PaymentResponse paymentResponse;
public PaymentEvent(Object source, PaymentResponse paymentResponse) {
super(source);
this.paymentResponse = paymentResponse;
}

public PaymentResponse getPaymentResponse() {
return paymentResponse;
}
}









2. O Publicador (ApplicationEventPublisher):



O serviço que conclui o pagamento (nosso Subject) passa a ter uma dependência no publisher do Spring. É ele quem realiza o disparo no momento crucial do fluxo.




@Service
public class PaymentService {
private ApplicationEventPublisher publisher;

public PaymentService(ApplicationEventPublisher publisher) {
this.publisher = publisher;
}

public void processPayment(PaymentResponse response) {
publisher.publishEvent(new PaymentEvent(this, response));
}
}









3. Os Listeners (Os Observers):



As classes de NotificationListener e EmailListener se tornam os nossos observadores. Utilizaremos duas anotações poderosas para o desacoplamento:




  • @EventListener: Marca o método como um ouvinte para o tipo de evento específico.


  • @async: Crucial para a performance. Garante que o Listener será executado em uma thread separada, liberando a thread principal do request de pagamento para finalizar rapidamente.





@Component
@Slf4j
public class EmailListener {
@Async
@EventListener
public void handlePayment(PaymentEvent event) {
log.info("Email send for payment: " + event.getPaymentResponse().paymentStatus());
}
}









@Component
@Slf4j
public class NotificationListener {
@Async
@EventListener
public void handlePayment(PaymentEvent event) {
log.info("Notification send for payment: " + event.getPaymentResponse().paymentStatus());
}
}









Controle Fino e Consistência Transacional



Para um projeto não basta apenas que funcione; precisamos de controle e garantia de consistência. O Spring Event oferece recursos para isso.






Ordem de Execução



Se, em um cenário futuro, for necessário que a Notificação seja processada antes do E-mail, podemos forçar a ordem utilizando a anotação @Order(1) (ou qualquer número) no método listener. O Spring respeitará a ordem de prioridade definida. O Listener Transacional @TransactionalEventListener faz parte de um dos maiores desafios em sistemas distribuídos é garantir que as ações reativas (como enviar um e-mail) só ocorram se a transação do banco de dados (o commit do pagamento) for bem-sucedida.



É aqui que entra o @TransactionalEventListener. Ao utilizá-lo com phase = TransactionPhase.AFTER_COMMIT, garantimos queo listener só será disparado após a transação de banco de dados ser efetivamente comitada. Se o commit falhar (um rollback), o evento nunca será disparado, prevenindo o envio de e-mails sobre pagamentos que nunca foram registrados no banco.




@Component
@Slf4j
public class OtherListener {
@Async
@TransactionalEventListener(phase = TransactionPhase.AFTER_COMMIT)
public void handlePaymentSuccess(PaymentSuccessEvent event) {
log.info("Other notification: {}", event.getPayment().getUserEmail());
// Ex: push SMS
}
}









Considerações de Escalabilidade e Resiliência



Embora o Spring Event seja uma ferramenta excelente para o desacoplamento dentro do mesmo serviço (monolito ou microsserviço), há ressalvas importantes que se deve considerar.






Gerenciamento de Threads Assíncronas



O uso de @async consome threads do pool interno do Spring. Sem a configuração correta de um pool dedicado (AsyncConfig), podemos ter um cenário de Thread Pool Exhaustion.




  • Risco: Estratégias de retry mal planejadas ou listeners que demoram muito para executar podem exaurir o pool, levando a thread locks e, em casos extremos, à queda do sistema.

  • Mitigação: É fundamental definir um AsyncConfig com limites controlados de threads e um RejectedExecutionHandler adequado para lidar com a sobrecarga.




@Configuration
@EnableAsync
public class AsyncConfig implements AsyncConfigurer {

@Override
@Bean(name = "taskExecutor") // Name for @Async("taskExecutor")
public Executor getAsyncExecutor() {
ThreadPoolTaskExecutor executor = new ThreadPoolTaskExecutor();

// Limited pool: 4 always-living threads
executor.setCorePoolSize(4);
executor.setMaxPoolSize(8); // Max 8 threads under load
// LIMITED QUEUE: avoids overload
executor.setQueueCapacity(25); // Maximum 25 tasks in the queue
// Prefix for debugging (see logs: Async-1, Async-2...)
executor.setThreadNamePrefix("Payment-Async-");
// Handler: rejects extra tasks (not an infinite queue)
executor.setRejectedExecutionHandler(new ThreadPoolExecutor.CallerRunsPolicy());
// Shutdown: wait for tasks to finish
executor.setWaitForTasksToCompleteOnShutdown(true);
executor.setAwaitTerminationSeconds(60);
executor.initialize();
return executor;
}
}









Limitações de Volume e Arquitetura



É crucial entender que o Spring Event é uma solução de evento local (In-Process Messaging). Isso significa que:




  • Ele tem um limite natural de escalabilidade. Em cenários de altíssimo volume (como acima de 200K requisições/minuto), a sobrecarga do thread pool se torna um gargalo.

  • Ele não resolve problemas de comunicação entre microsserviços (arquiteturas distribuídas).



Nesses casos de extrema escala ou arquitetura distribuída, a solução ideal migra para o uso de um Message Broker dedicado (como Kafka, RabbitMQ ou SQS).






Conclusão



O Spring Event é uma ferramenta de produtividade fantástica que permite implementar o poderoso Design Pattern Observer de forma simples e gerenciável. Ele é ideal para desacoplar ações secundárias e dar reatividade aos fluxos dentro de um mesmo serviço. No entanto, é importante ir além do uso básico, configurando corretamente os aspectos assíncronos e entendendo os limites de sua escalabilidade e a diferença entre eventos locais e arquiteturas de mensageria distribuída.



Com essa estrutura e esses cuidados, seu sistema estará mais robusto, escalável (dentro do contexto do serviço) e, o mais importante, fácil de manter e evoluir.



Até a próxima!

Ähnliche Beiträge
🔍 Verwandte News

Auch interessante Nachrichten Desacoplamento e Reatividade: Implementando o Design Pattern Observer com Spring Events

Thematisch verwandte Begriffe: Desacoplamento, Reatividade, Implementando, Design · 6 Treffer

Laden...

Videos werden geladen ...

Laden...

Beiträge werden geladen ...

Laden...

Videos werden geladen ...

Laden...

Beiträge werden geladen ...

Laden...

Videos werden geladen ...

Laden...

Beiträge werden geladen ...

Laden...

Videos werden geladen ...

Laden...

Beiträge werden geladen ...

Laden...

Videos werden geladen ...

Zum Aktualisieren ziehen
ZERO-DAY CVE-2026-49449 | Joplin is an open source note-taking and to-do application that organise…
Advisory →
TTS Reader • tsecurity.de Voice
tsecurity.de Icon
tsecurity.de App
Offline-Lesen, Eilmeldungen & 0ms Ladezeit

Installiere tsecurity.de direkt auf deinen Home-Bildschirm für das ultimative Vollbild-Magazinerlebnis ohne Browser-Leisten.

Nächster Beitrag
Themen-Radar & Intelligence Matrix
Echtzeit-Taxonomie nach Angriffsvektoren & Plattformen

tsecurity.de Live Threat Radar

🔴 LIVE RADAR
MONITORING
AKTIV
CVE-DATENBANK
LIVE
🔍
Community Radar & Live Chat
Sentinel Bot online • Live-Stream
Dein Cluster: Security Explorer
Match:
lädt…
Verbindung zum Community-Stream wird aufgebaut...
Bearbeitungsmodus — Senden überschreibt deine Nachricht
Community-Puls — was gerade passiert
lädt…
Aktivitäten deiner Analysten
lädt…
Neues Thema oder Eilmeldung einreichen

Reiche interessante Links, Zero-Days oder Debatten ein. Die Community entscheidet per Upvote über die Veröffentlichung.

Heiß diskutierte Einreichungen
🔖 Gespeicherte Artikel
📂 Keine gespeicherten Artikel vorhanden.
Zurück Ziehen Vor
Links: vorheriger Artikel Rechts: nächster Artikel unten: schließen
News NIS-2 Frühwarnung Tier-1 Intel ⏱️ 3 Min vor 10 Min
Artikeldaten werden geladen...

Zurück: vorheriger Vor: nächster
↗ Original-Quelle
Social Reaktionen Deine Reaktion zählt
Einstufung & Relevanz-Poll 0 Stimmen
In sozialen Netzwerken teilen 1-Klick