Spring core framework provides application level event firing and event listening which is based on the standard Observer design pattern.
There are built-in application events available or we can create our own custom events in spring.
This tutorial focuses on built-in application events provided by Spring container.
Spring build-in events
Build-in Event |
Description |
ContextRefreshedEvent |
Event fired when an ApplicationContext gets initialized or refreshed (refreshed via context.refresh() call). |
ContextStartedEvent |
Event fired when context.start() method is called. |
ContextStoppedEvent |
Event fired when context.stop() method is called |
ContextClosedEvent. |
Event fired when context.close() method is called. |
RequestHandledEvent |
This event can only be used in spring MVC environment. It is called just after an HTTP request is completed. |
How to listen to the events?
There are two ways to listen to the events.
- Using annotation EventListener on any bean method and injecting the specific event parameter (typically a subtype of ApplicationEvent) to the method.
@Component
public class MyBean{
@EventListener
public void handleContextRefresh(ContextRefreshedEvent event) {
...
}
} This method is called when spring context is refreshed. When event is fired, a proper instance of ContextRefreshedEvent is passed by the framework. We can name the bean method whatever we want, that doesn't matter here. Note: The annotation support for event listener was added in Spring 4.2.
- Or We can implement ApplicationListener<E extends ApplicationEvent> to our bean and implement the method
onApplicationEvent(E event)
@Component
public class MyBean implements ApplicationListener <ContextRefreshedEvent> {
@Override
public void onApplicationEvent(ContextRefreshedEvent event) {
...
}
}
Examples
Listening to built-in events using @EventListener annotation
package com.logicbig.example;
import org.springframework.context.annotation.AnnotationConfigApplicationContext;
import org.springframework.context.annotation.Bean;
import org.springframework.context.annotation.Configuration;
import org.springframework.context.event.*;
@Configuration
public class BuildInAnnotationBasedEventExample {
@Bean
AListenerBean listenerBean() {
return new AListenerBean();
}
public static void main(String[] args) {
AnnotationConfigApplicationContext context = new AnnotationConfigApplicationContext();
context.register(BuildInAnnotationBasedEventExample.class);
System.out.println("-- refreshing context --");
context.refresh();
System.out.println("-- stopping context --");
context.stop();
System.out.println("-- starting context --");
context.start();
System.out.println("-- closing context --");
context.close();
}
private static class AListenerBean {
@EventListener
public void handleContextRefreshed(ContextRefreshedEvent event) {
System.out.println("context refreshed event received: " + event);
}
@EventListener
public void handleContextStarted(ContextStartedEvent event) {
System.out.println("context started event received: " + event);
}
@EventListener
public void handleContextStopped(ContextStoppedEvent event) {
System.out.println("context stopped event received: " + event);
}
@EventListener
public void handleContextClosed(ContextClosedEvent event) {
System.out.println("context closed event received: " + event);
}
}
}
Output-- refreshing context -- context refreshed event received: org.springframework.context.event.ContextRefreshedEvent[source=org.springframework.context.annotation.AnnotationConfigApplicationContext@25e6e3cc, started on Sat Jun 12 01:13:41 CDT 2021] -- stopping context -- context stopped event received: org.springframework.context.event.ContextStoppedEvent[source=org.springframework.context.annotation.AnnotationConfigApplicationContext@25e6e3cc, started on Sat Jun 12 01:13:41 CDT 2021] -- starting context -- context started event received: org.springframework.context.event.ContextStartedEvent[source=org.springframework.context.annotation.AnnotationConfigApplicationContext@25e6e3cc, started on Sat Jun 12 01:13:41 CDT 2021] -- closing context -- context closed event received: org.springframework.context.event.ContextClosedEvent[source=org.springframework.context.annotation.AnnotationConfigApplicationContext@25e6e3cc, started on Sat Jun 12 01:13:41 CDT 2021]
Listening to built-in events by implementing ApplicationListener
package com.logicbig.example;
import org.springframework.context.ApplicationEvent;
import org.springframework.context.ApplicationListener;
import org.springframework.context.annotation.AnnotationConfigApplicationContext;
import org.springframework.context.annotation.Bean;
import org.springframework.context.annotation.Configuration;
import org.springframework.context.event.ContextRefreshedEvent;
@Configuration
public class BuildInListenerBasedEventExample {
@Bean
AListenerBean listenerBean() {
return new AListenerBean();
}
public static void main(String[] args) {
AnnotationConfigApplicationContext context = new AnnotationConfigApplicationContext(
BuildInListenerBasedEventExample.class);
}
private static class AListenerBean implements ApplicationListener<ContextRefreshedEvent> {
@Override
public void onApplicationEvent(ContextRefreshedEvent event) {
System.out.println("context refreshed event received: " + event);
}
}
}
Outputcontext refreshed event received: org.springframework.context.event.ContextRefreshedEvent[source=org.springframework.context.annotation.AnnotationConfigApplicationContext@7443db83, started on Sat Jun 12 01:13:33 CDT 2021]
Following example shows that instead of a specific event ContextRefreshedEvent (in last example) we can consume multiple events by using ApplicationEvent . All Spring standard events implements this interface.
package com.logicbig.example;
import org.springframework.context.ApplicationEvent;
import org.springframework.context.ApplicationListener;
import org.springframework.context.annotation.AnnotationConfigApplicationContext;
import org.springframework.context.annotation.Bean;
import org.springframework.context.annotation.Configuration;
@Configuration
public class BuildInListenerBasedMultipleEventExample {
@Bean
AListenerBean listenerBean () {
return new AListenerBean();
}
public static void main (String[] args) {
AnnotationConfigApplicationContext context = new AnnotationConfigApplicationContext(
BuildInListenerBasedMultipleEventExample.class);
context.stop();
context.start();
context.close();
}
private static class AListenerBean implements ApplicationListener<ApplicationEvent> {
@Override
public void onApplicationEvent (ApplicationEvent event) {
System.out.println("event received: "+event);
}
}
}
Outputevent received: org.springframework.context.event.ContextRefreshedEvent[source=org.springframework.context.annotation.AnnotationConfigApplicationContext@29e6e416, started on Sat Jun 12 01:13:17 CDT 2021] event received: org.springframework.context.event.ContextStoppedEvent[source=org.springframework.context.annotation.AnnotationConfigApplicationContext@29e6e416, started on Sat Jun 12 01:13:17 CDT 2021] event received: org.springframework.context.event.ContextStartedEvent[source=org.springframework.context.annotation.AnnotationConfigApplicationContext@29e6e416, started on Sat Jun 12 01:13:17 CDT 2021] event received: org.springframework.context.event.ContextClosedEvent[source=org.springframework.context.annotation.AnnotationConfigApplicationContext@29e6e416, started on Sat Jun 12 01:13:17 CDT 2021]
Example ProjectDependencies and Technologies Used: - spring-context 6.1.2 (Spring Context)
Version Compatibility: 4.2.0.RELEASE - 6.1.2 Version compatibilities of spring-context with this example: Versions in green have been tested.
- JDK 17
- Maven 3.8.1
|