Spring Boot application that handles custom events


A guide to creating and triggering events in Spring Boot applications.

Introduction

In the Spring Boot application, the Application Events allow you to trigger or send an ApplicationEvent to other components so they can interact with other components in a specific scenario.

What are application events?

Application can handle various events, such as application startup and shutdown. For example, we may need to initialize certain resources or send alerts when the system goes down. The Spring Framework provides support for application events, publishing events, listening events, and handling events.

We can trigger events based on specific conditions. We can trigger an event when we delete a record from the database, or we can send a mail when we complete a transaction.
These events can be used to perform tasks like logging, auditing, caching, or even sending notifications.

Publish-subscribe model

Spring Boot follows the publish-subscribe model. The publishing component notifies all subscribers about the occurrence of an event, allowing them to react accordingly. The event publication occurs synchronously.

The publisher publishes the event without knowing who the receiver will be. Similarly, the receiver does not know who the sender is. This loosely couples the publisher and receiver enabling maintenance and flexibility.

The event receiver or event listener can listen to multiple events from different publishers at the same time.

Create an event

We can create a model class that extends the ApplicationEvent class. This model class acts as a custom event that stores information about the event. The handler can use this information to perform various tasks
.

import org.springframework.context.ApplicationEvent;

// before 4.2
public class AlertEvent extends ApplicationEvent {

  private String eventType;

  public AlertEvent(String eventType) {
    super(eventType);
    this.eventType = eventType;
  }

  public String getEventType() {
    return eventType;
  }

}

If you are using Spring 4.2, we don't need to extend the ApplicationEvent class.


public class AlertEvent {

  private String eventType;

  public AlertEvent(String eventType) {
    super(eventType);
    this.eventType = eventType;
  }
}

Publish an event

We will create a Publisher class that @Autowired the ApplicationEventPublisher and use the publishEvent() method to publish the event.


import org.springframework.beans.factory.annotation.Autowired;
import org.springframework.context.ApplicationEventPublisher;
import org.springframework.stereotype.Component;
import com.springboot.example.model.AlertEvent;

@Component
public class AlertEventPublisher {

  @Autowired
  private ApplicationEventPublisher publisher;

  public void publish(String message) {
    AlertEvent event = new AlertEvent(message);
    publisher.publishEvent(event);
  }
  
}

Handle Event

The listener class must implement ApplicationListener and override the onApplicationEvent() method, which handles the event. By default, Spring Boot sends all events to the listener. Thus, we have to filter and handle the events accordingly.

The ApplicationListener takes the generics class, so Spring will send an event that matches the generics class. Here, AlertEvent is the generic class, so whenever an alert event occurs, the Spring Boot will notify the AlertEventListener.


import org.springframework.context.ApplicationListener;
import org.springframework.stereotype.Component;
import com.springboot.example.model.AlertEvent;

@Component
public class AlertEventListener implements ApplicationListener < AlertEvent > {

  @Override
  public void onApplicationEvent(AlertEvent event) {
    System.out.println("Inside the Listener, got Alert Event " + event.getEventType());
  }

}

Using Annotation

With Spring 4.1, we can easily register an event listener by annotating a method with @EventListener.

The generic class can be defined either in the annotation or as a method argument. This allows the method to handle only the specified event. If we want our method to handle multiple events, then we can define them in the annotation.


import org.springframework.context.event.AlertEventListener;
import org.springframework.stereotype.Component;
import com.springboot.example.model.AlertEvent;
@Component public class AlertEventListener { @EventListener void handleAlertEvent(AlertEvent event) { System.out.println("Inside the Listener, got Alert Event " + event.getEventType()); } }

How to handle events in asynchronous

Application events are published and handled in a synchronous way. Publishers block until all listeners have finished processing events.

In some cases, we want an event handler to handle the events in an async way. We need to add @Async to the event listener method.


import org.springframework.context.event.AlertEventListener;
import org.springframework.stereotype.Component;
import org.springframework.scheduling.annotation.Async;
import com.springboot.example.model.AlertEvent;

@Component
public class AlertEventListener {

  @Async
  @EventListener
  void handleAlertEvent(AlertEvent event) {
    System.out.println("Inside the Listener, got Alert Event " + event.getEventType());
  }

}


For the @Async annotation to work, we need to add one more annotation to our @SpringBootApplication class with @EnableAsync.


import org.springframework.boot.SpringApplication;
import org.springframework.boot.autoconfigure.SpringBootApplication;
import org.springframework.scheduling.annotation.EnableAsync;

@SpringBootApplication
@EnableAsync
public class SpringBootCustomEventExample {

  public static void main(String[] args) {
    SpringApplication.run(SpringBootCustomEventExample.class, args).close();
  }

}

Post a Comment

Previous Post Next Post

Recent Posts

Facebook