Saturday, January 8, 2022

Event Handling in Spring

Spring's event handling is single-threaded so if an event is published,  until and unless all the receivers get the message, the processes are blocked and the flow will not continue. [Synchronous]

Four things necessary for an event:

  • Source : to publish the event in Spring - ApplicationEventPublisher object
  • Event : event must extends from ApplicationEvent // springframework 4.2 + - - any object 
  • Listener : IOC container
  • Handler : Handler method must annotated with @EventListener


Creating, publishing and handling custom events in Spring

Create an event class, `CustomEvent` by extending `ApplicationEvent`. This class must define a default constructor which should inherit constructor from ApplicationEvent class.

import org.springframework.context.ApplicationEvent;
public class CustomEvent extends ApplicationEvent{
    public CustomEvent(Object source) {
        super(source);
   }
   public String toString(){
        return "My Custom Event";
   }
}

Once your event class is defined, you can publish it from any class, let us say `EventClassPublisher` which implements `ApplicationEventPublisherAware`. You will also need to declare this class in XML configuration file as a bean so that the container can identify the bean as an event publisher because it implements the ApplicationEventPublisherAware interface.

import org.springframework.context.ApplicationEventPublisher;
import org.springframework.context.ApplicationEventPublisherAware;
public class CustomEventPublisher implements ApplicationEventPublisherAware {
    private ApplicationEventPublisher publisher;
    public void setApplicationEventPublisher (ApplicationEventPublisher publisher) {
        this.publisher = publisher;
    }
    public void publish() {
        CustomEvent ce = new CustomEvent(this);
        publisher.publishEvent(ce);
    }
}

A published event can be handled in a class, let us say `EventClassHandler` which implements `ApplicationListener` interface and implements `onApplicationEvent` method for the custom event.

import org.springframework.context.ApplicationListener;
public class CustomEventHandler implements ApplicationListener<CustomEvent> {
    public void onApplicationEvent(CustomEvent event) {
        System.out.println(event.toString());
    }
}

A main file/controller file to trigger events:

import org.springframework.context.ConfigurableApplicationContext;
import org.springframework.context.support.ClassPathXmlApplicationContext;
public class MainApp {
    public static void main(String[] args) {
        ConfigurableApplicationContext context = new ClassPathXmlApplicationContext("Beans.xml");
       CustomEventPublisher cvp = (CustomEventPublisher) context.getBean("customEventPublisher");
       cvp.publish();
   }
}

Beans.xml for DI:

<?xml version = "1.0" encoding = "UTF-8"?>
<beans xmlns = "http://www.springframework.org/schema/beans"
             xmlns:xsi = "http://www.w3.org/2001/XMLSchema-instance"
             xsi:schemaLocation = "http://www.springframework.org/schema/beans"
             http://www.springframework.org/schema/beans/spring-beans-3.0.xsd">
    <bean id = "customEventHandler" class = "com.CustomEventHandler"/>
    <bean id = "customEventPublisher" class = "com.CustomEventPublisher"/>
</beans>

In springboot, same architecture is being followed under the hood with annotations.

Event Handling in Spring

Spring's event handling is single-threaded so if an event is published,  until and unless all the receivers get the message, the process...