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.
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.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.
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.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:
<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.