Desacoplando lógicas com PublishEvent + EventHandler no Spring Boot

Quando estamos desenvolvendo aplicações no Spring Boot, é comum nos depararmos com cenários em que uma única ação precisa disparar várias consequências.

Pense no caso de cadastro de usuário: além de salvar os dados no banco, talvez seja necessário env…


This content originally appeared on DEV Community and was authored by Ledson Oliveira da Silva

Quando estamos desenvolvendo aplicações no Spring Boot, é comum nos depararmos com cenários em que uma única ação precisa disparar várias consequências.

Pense no caso de cadastro de usuário: além de salvar os dados no banco, talvez seja necessário enviar um e-mail de boas-vindas, registrar um log, ou até notificar outro sistema.

A solução mais direta seria implementar tudo dentro do próprio UserService. Mas logo surge o problema: o método que deveria apenas cadastrar o usuário acaba assumindo várias responsabilidades, ficando cada vez mais difícil de manter e evoluir.

👉 E aí surge a pergunta: como podemos desacoplar essas lógicas sem transformar nosso código em um monólito cheio de dependências internas ou partir imediatamente para soluções complexas como Kafka ou microsserviços?

É exatamente aí que entram os eventos no Spring Boot.
Com o uso de publishEvent e @EventListener, conseguimos criar uma comunicação interna desacoplada, onde o serviço principal apenas publica o que aconteceu, e outros componentes ficam responsáveis por reagir a isso de forma independente.

Neste artigo, vou mostrar na prática:

  • Como usar eventos no Spring Boot.
  • Vantagens dessa abordagem.
  • Boas práticas e armadilhas comuns.
  • Como esse padrão se conecta com arquiteturas maiores, como CQRS e event-driven.

📌 Como usar eventos no Spring Boot

O Spring Boot já oferece suporte nativo a eventos, e o fluxo básico é bem simples:

Definimos um evento (geralmente representando algo que aconteceu no domínio).

Publicamos esse evento em algum ponto do sistema.

Criamos handlers/listeners que irão reagir a ele.

Vamos ver isso passo a passo em um exemplo prático de cadastro de usuário.

1. Criando o evento

Podemos representar um evento como uma classe simples.
No nosso caso, vamos criar um UserCreatedEvent para indicar que um novo usuário foi registrado.

public record UserCreatedEvent(Long userId, String email) {}

💡 Aqui usei um record para deixar o código mais conciso, mas você pode usar uma classe normal se preferir.

2. Publicando o evento

Dentro do UserService, assim que o usuário for cadastrado, vamos publicar o evento.

@Service
@RequiredArgsConstructor
public class UserService {

    private final ApplicationEventPublisher publisher;

    public void registerUser(String email) {
        // Simulação de cadastro
        User user = saveUser(email);

        // Publica o evento
        publisher.publishEvent(new UserCreatedEvent(user.getId(), user.getEmail()));
    }

    private User saveUser(String email) {
        // persistência fake só para exemplo
        return new User(1L, email);
    }
}

3. Reagindo ao evento

Agora podemos criar quantos handlers quisermos para reagir ao evento.
O Spring Boot cuida da mágica para chamar cada um deles automaticamente.

@Component
public class SendWelcomeEmailHandler {

    @EventListener
    public void handle(UserCreatedEvent event) {
        System.out.println("Enviando e-mail para: " + event.email());
    }
}
@Component
public class CreateLogHandler {

    @EventListener
    public void handle(UserCreatedEvent event) {
        System.out.println("Criando log para usuário: " + event.userId());
    }
}

🔎 Note como o UserService não tem conhecimento de como o e-mail é enviado ou onde o log é registrado. Ele apenas publica o evento, e cada handler faz o seu trabalho de forma independente.

Assim, com poucas linhas de código, já conseguimos um fluxo desacoplado e extensível: se amanhã você quiser adicionar mais uma ação (como notificar outro sistema via API), basta criar um novo handler, sem tocar no código de cadastro.

🚀 Vantagens de usar eventos no Spring Boot

Adotar a publicação e tratamento de eventos no Spring Boot traz diversos benefícios para a arquitetura da aplicação, mesmo em projetos que ainda são monólitos.

🔹 1. Desacoplamento

O serviço principal (ex.: UserService) não precisa conhecer os detalhes de como cada ação complementar será executada.
Ele só dispara o evento — e os handlers cuidam do resto.
Isso reduz dependências diretas entre classes e facilita a manutenção.

🔹 2. Extensibilidade

Se amanhã surgir a necessidade de enviar um push notification ou integrar com outro sistema, não é necessário modificar o código do cadastro de usuário.
Basta criar um novo handler para reagir ao mesmo evento.

Ou seja, o sistema cresce de forma aberta para extensão e fechada para modificação (princípio OCP do SOLID).

🔹 3. Organização do código

Cada responsabilidade fica em seu próprio componente, evitando métodos gigantes que fazem “tudo ao mesmo tempo”.
Isso deixa o código mais legível e as classes mais coesas.

🔹 4. Reuso e testabilidade

Handlers podem ser testados isoladamente, sem precisar passar por todo o fluxo do serviço principal.
Além disso, um mesmo evento pode ser usado para disparar múltiplas ações em contextos diferentes.

🔹 5. Preparação para arquiteturas maiores

Mesmo em um monólito, trabalhar com eventos já cria uma mentalidade event-driven, tornando a transição para soluções com mensageria (Kafka, RabbitMQ) ou padrões como CQRS bem mais natural.

⚠️ Armadilhas e boas práticas

Apesar de trazerem muitas vantagens, os eventos no Spring Boot também exigem atenção para evitar problemas de manutenção e comportamento inesperado.

⚠️ 1. Eventos são síncronos por padrão

Quando você usa publishEvent, o fluxo espera todos os handlers terminarem antes de seguir.

Se algum handler for lento (ex.: envio de e-mail externo) ou lançar exceção, pode impactar diretamente o serviço principal.

✅ Boas práticas:

Use @Async nos handlers que podem rodar em paralelo, evitando travar o fluxo principal.

Para isso, basta habilitar @EnableAsync na sua aplicação.

⚠️ 2. Cuidados com transações

Se você publicar o evento dentro de uma transação, ele será disparado imediatamente — mesmo que a transação ainda não tenha sido confirmada.
Isso pode causar inconsistência (ex.: handler tenta acessar dados que ainda não foram persistidos).

✅ Boas práticas:

Use @TransactionalEventListener para garantir que o handler só seja executado após o commit da transação.

Exemplo:

@Component
public class CreateLogHandler {

    @TransactionalEventListener
    public void handle(UserCreatedEvent event) {
        System.out.println("Criando log após commit para usuário: " + event.userId());
    }
}

⚠️ 3. Não transformar tudo em evento

É tentador usar eventos para “qualquer coisa”, mas isso pode deixar o sistema difícil de debugar e seguir o fluxo.

✅ Boas práticas:

Use eventos quando há múltiplos interessados em uma mesma ação.

Para lógicas simples e locais, prefira manter o código direto no serviço.

⚠️ 4. Tratamento de falhas

Por padrão, se um handler lançar exceção, ela pode se propagar e afetar o fluxo.
Isso pode ser crítico se o evento for parte de uma ação de negócio essencial.

✅ Boas práticas:

Isolar a lógica dos handlers com try/catch.

Para eventos assíncronos, configurar retries ou dead-letter (quando migrar para mensageria).

👉 Em resumo: eventos são poderosos, mas não são bala de prata. Usados com consciência, ajudam a manter a aplicação organizada e preparada para crescer.

🔗 Conexão com arquiteturas maiores

Trabalhar com publishEvent e @EventListener no Spring Boot pode parecer algo simples, mas na prática é um primeiro passo para arquiteturas mais robustas.

Esse padrão já introduz uma mentalidade event-driven, que facilita a migração futura para:

CQRS – separando comandos e queries.

Mensageria (Kafka, RabbitMQ) – distribuindo eventos entre microsserviços.

Escalabilidade – permitindo que novas funcionalidades sejam adicionadas sem acoplar ao core.

✅ Conclusão

Usar eventos no Spring Boot é uma forma prática de desacoplar responsabilidades, manter o código mais limpo e extensível, além de preparar o terreno para arquiteturas mais avançadas.

Mesmo em aplicações monolíticas, essa abordagem já traz ganhos reais de organização e manutenção.

👉 E você, já usou eventos no seu projeto com Spring Boot? Prefere manter tudo síncrono ou já partiu para mensageria com Kafka/RabbitMQ? Conta aí nos comentários!


This content originally appeared on DEV Community and was authored by Ledson Oliveira da Silva


Print Share Comment Cite Upload Translate Updates
APA

Ledson Oliveira da Silva | Sciencx (2025-09-10T12:14:49+00:00) Desacoplando lógicas com PublishEvent + EventHandler no Spring Boot. Retrieved from https://www.scien.cx/2025/09/10/desacoplando-logicas-com-publishevent-eventhandler-no-spring-boot/

MLA
" » Desacoplando lógicas com PublishEvent + EventHandler no Spring Boot." Ledson Oliveira da Silva | Sciencx - Wednesday September 10, 2025, https://www.scien.cx/2025/09/10/desacoplando-logicas-com-publishevent-eventhandler-no-spring-boot/
HARVARD
Ledson Oliveira da Silva | Sciencx Wednesday September 10, 2025 » Desacoplando lógicas com PublishEvent + EventHandler no Spring Boot., viewed ,<https://www.scien.cx/2025/09/10/desacoplando-logicas-com-publishevent-eventhandler-no-spring-boot/>
VANCOUVER
Ledson Oliveira da Silva | Sciencx - » Desacoplando lógicas com PublishEvent + EventHandler no Spring Boot. [Internet]. [Accessed ]. Available from: https://www.scien.cx/2025/09/10/desacoplando-logicas-com-publishevent-eventhandler-no-spring-boot/
CHICAGO
" » Desacoplando lógicas com PublishEvent + EventHandler no Spring Boot." Ledson Oliveira da Silva | Sciencx - Accessed . https://www.scien.cx/2025/09/10/desacoplando-logicas-com-publishevent-eventhandler-no-spring-boot/
IEEE
" » Desacoplando lógicas com PublishEvent + EventHandler no Spring Boot." Ledson Oliveira da Silva | Sciencx [Online]. Available: https://www.scien.cx/2025/09/10/desacoplando-logicas-com-publishevent-eventhandler-no-spring-boot/. [Accessed: ]
rf:citation
» Desacoplando lógicas com PublishEvent + EventHandler no Spring Boot | Ledson Oliveira da Silva | Sciencx | https://www.scien.cx/2025/09/10/desacoplando-logicas-com-publishevent-eventhandler-no-spring-boot/ |

Please log in to upload a file.




There are no updates yet.
Click the Upload button above to add an update.

You must be logged in to translate posts. Please log in or register.