DEV Community

Sadiul Hakim
Sadiul Hakim

Posted on

Spring Boot Events Tutorial

1. What is a Spring Event?

Spring provides a built-in event-driven programming model that allows different parts of your application to communicate without being tightly coupled.

An event in Spring is an object that carries information about something that has happened, and it is published to notify interested listeners.

Examples:

  • User registered → send a welcome email
  • Order placed → reduce stock, send notification
  • File uploaded → trigger background processing

This is based on the Observer design pattern, where publishers don’t know who listens, and listeners don’t care who publishes.

2. How does it work?

The workflow looks like this:

  1. Event creation
  • A class extending ApplicationEvent (or any custom POJO since Spring 4.2).

    1. Event publishing
  • Use ApplicationEventPublisher to publish events.

    1. Event listening
  • Create a listener using @EventListener (or ApplicationListener).

    1. Event handling
  • Spring’s ApplicationEventMulticaster dispatches the event to listeners.

3. When and When Not to Use It?

When to use:

  • To decouple business logic. Example: a user service should not know how notifications or emails are handled.
  • For side effects after main actions (logging, auditing, sending alerts).
  • For extensibility, where other modules can subscribe without modifying the core logic.

When not to use:

  • For core business workflows where ordering and transaction boundaries are critical.
  • For synchronous dependencies that must always run. Example: payment → order confirmation → invoice. These should be service calls, not events.
  • For complex orchestration. Consider messaging solutions (Kafka, RabbitMQ, etc.) instead.

4. How to Create and Publish an Event

Example Domain: User Registration

a) Create an Event (Custom POJO)

public class UserRegisteredEvent {
    private final String email;

    public UserRegisteredEvent(String email) {
        this.email = email;
    }

    public String getEmail() {
        return email;
    }
}
Enter fullscreen mode Exit fullscreen mode

b) Publish an Event (Same Thread)

import org.springframework.context.ApplicationEventPublisher;
import org.springframework.stereotype.Service;

@Service
public class UserService {
    private final ApplicationEventPublisher publisher;

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

    public void registerUser(String email) {
        // main logic
        System.out.println("User registered: " + email);

        // publish event
        publisher.publishEvent(new UserRegisteredEvent(email));
    }
}
Enter fullscreen mode Exit fullscreen mode

Note: By default, events are synchronous. The publisher and listener run in the same thread.

c) Publish an Event (Different Thread – Asynchronous)

Enable async event handling:

import org.springframework.context.annotation.Configuration;
import org.springframework.scheduling.annotation.EnableAsync;

@Configuration
@EnableAsync
public class AsyncConfig {
}
Enter fullscreen mode Exit fullscreen mode

Use @Async on listener:

import org.springframework.context.event.EventListener;
import org.springframework.scheduling.annotation.Async;
import org.springframework.stereotype.Component;

@Component
public class EmailListener {

    @Async
    @EventListener
    public void handleUserRegistered(UserRegisteredEvent event) {
        System.out.println("Sending email to: " + event.getEmail());
    }
}
Enter fullscreen mode Exit fullscreen mode

Now, the email sending runs on a separate thread (from Spring’s async executor pool).

5. How to Catch an Event

There are two main approaches:

a) Using @EventListener

import org.springframework.context.event.EventListener;
import org.springframework.stereotype.Component;

@Component
public class WelcomeEmailListener {

    @EventListener
    public void onUserRegistered(UserRegisteredEvent event) {
        System.out.println("Welcome email sent to: " + event.getEmail());
    }
}
Enter fullscreen mode Exit fullscreen mode

b) Using ApplicationListener

import org.springframework.context.ApplicationListener;
import org.springframework.stereotype.Component;

@Component
public class AuditLogListener implements ApplicationListener<UserRegisteredEvent> {

    @Override
    public void onApplicationEvent(UserRegisteredEvent event) {
        System.out.println("Audit log: User registered with email " + event.getEmail());
    }
}
Enter fullscreen mode Exit fullscreen mode

Summary

  • Spring Events help decouple components using an event-driven approach.
  • Publisher fires events, and listeners react to them.
  • Events are synchronous by default but can be made asynchronous with @Async.
  • Use them for side effects, extensibility, and decoupling, but avoid them in core transactional workflows.

Top comments (0)