Loading...

Spring Events: Decouple Your Application with @EventListener and ApplicationEvents

Spring
September 13, 2023
3 minutes to read
Share this post:

If you’re already working with the Spring Framework, you’ve undoubtedly recognized its power and versatility. One of the valuable - yet often overlooked - features of Spring is its event-handling system. In this article, we’ll delve deeper into how you can configure events in the Spring Framework using @EventListener. Moreover, we’ll illustrate how these events can be paired with transactions and asynchronicity.

Why Events in the Spring Framework?

Events are an integral component of the Spring Framework. They allow for the creation of loosely coupled applications. Spring Boot employs events to communicate the application’s status. An example of this is the ApplicationStartedEvent. However, you can also publish your own events. And this is possible out-of-the-box, without boilerplate and with minimal effort.

What is an Event?

An event in Spring, often referred to as an ApplicationEvent, is simply a signal indicating that something has transpired in the application. This signal can then be captured by one or multiple listeners that respond to it. With ApplicationEvents, the Observer or Publish-Subscribe Pattern described by the ‘Gang of Four’ in their renowned book on Design Patterns is implemented.

Every Java Object Can Be an Event

With the Spring Framework, declaring an event is straightforward. Any class can be an event. There’s no limitation; simply write a Plain Old Java Object (POJO) and, for easy handling, keep it immutable.

class CustomSpringEvent {
    private String parameter;
    
    public CustomSpringEvent(String parameter) {
        this.parameter = parameter;
    }
}

Publish an Event Using ApplicationEventPublisher

Spring Boot automatically registers an ApplicationEventPublisher bean. You can inject this into your services and use it to publish your event.

@Service
public class SomeService {

    private final ApplicationEventPublisher eventPublisher;

    public SomeService(ApplicationEventPublisher eventPublisher) {
        this.eventPublisher = eventPublisher;
    }

    public void someMethod() {
        eventPublisher.publishEvent(new CustomSpringEvent());
    }
}

Receive an Event with @EventListener

Once you’ve published your event, you can receive it in any Spring-managed bean using the @EventListener annotation.

@EventListener
public void handleCustomEvent(CustomSpringEvent event) {
    // Some logic
}

Events and Transactions

Handling events and transactions can sometimes be tricky. Fortunately, Spring offers the @TransactionalEventListener annotation to simplify this.

@TransactionalEventListener(phase = TransactionPhase.AFTER_COMMIT)
public void handleAfterCommit(CustomSpringEvent event) {
    // Some logic
}

In this example, the event listener is executed only after the transaction, which triggered the event, has been committed.

Asynchronous Events

@Async can be combined with @EventListener. This results in the event being processed in a separate thread.

@EventListener
@Async
public void handleAsyncEvent(CustomSpringEvent event) {
    System.out.println("Handled event asynchronously: " + event.getMessage());
}

Spring ApplicationEvents Decouple Your Modules

With event-driven architectures, you can decouple your modules from each other. Spring Application Events assist in accomplishing this. In a later development phase and once the need arises, an application using Application Events can easily transition to Spring Integration and external Message Queues.

Have you heard of Marcus' Backend Newsletter?

New ideas. Twice a week!
Top