In this tutorial, we will see how to define custom event types and publish/consume them.
Defining custom events
One way to defined a custom event type is to extend ApplicationEvent class.
public class MyEvent extends ApplicationEvent{
//custom fields
public MyEvent (Object source, <custom params>) {
super(source);
//initialize custom fields
}
//getters and setters
}
Starting Spring 4.2, no need to extends ApplicationEvent anymore
Starting from Spring 4.2, we can use any arbitrary object as event object, i.e. it doesn't need to extend ApplicationEvent any more:
public class MyEvent{
//custom fields
public MyEvent (<custom params>) {
//initialize custom fields
}
//getters and setters
}
Publishing custom events
To publish custom events, we will need an instance of ApplicationEventPublisher and then call the method ApplicationEventPublisher#publishEvent(..) .
There are two ways to get the instance of ApplicationEventPublisher, inject it as a bean in any spring managed bean or extends ApplicationEventPublisherAware and implement it's setApplicationEventPublisher method. First method is recommended, and here's how we are going to use that:
public class MyEvenPublisherBean{
@Autowired
ApplicationEventPublisher publisher;
public void sendMsg(String msg){
publisher.publishEvent(new MyEvent(this, msg));
}
}
Another way to publish event is to use ApplicationContext#publishEvent(....) . ApplicationContext implements ApplicationEventPublisher , so events can directly be fired with 'context' instance.
AnnotationConfigApplicationContext context =
new AnnotationConfigApplicationContext(.....);
context.publishEvent(.....);
Consuming custom events
We can consume custom events just like we consume Spring standard events. We can do that either by using @EventListener or implementing ApplicationListener<E extends ApplicationEvent> .
Here's a summary of the recommended way to create custom events:
Examples
Creating custom event by extending ApplicationEvent
Showing how to create custom event by extending ApplicationEvent and autowiring ApplicationEventPublisher for firing the custom event.
package com.logicbig.example;
import org.springframework.beans.factory.annotation.Autowired;
import org.springframework.context.ApplicationEvent;
import org.springframework.context.ApplicationEventPublisher;
import org.springframework.context.annotation.AnnotationConfigApplicationContext;
import org.springframework.context.annotation.Bean;
import org.springframework.context.event.EventListener;
public class CustomEventWithApplicationEvent {
@Bean
AListenerBean listenerBean () {
return new AListenerBean();
}
@Bean
MyEvenPublisherBean publisherBean () {
return new MyEvenPublisherBean();
}
public static void main (String[] args) {
AnnotationConfigApplicationContext context = new AnnotationConfigApplicationContext(
CustomEventWithApplicationEvent.class);
MyEvenPublisherBean bean = context.getBean(MyEvenPublisherBean.class);
bean.sendMsg("A test message");
}
private static class MyEvenPublisherBean{
@Autowired
ApplicationEventPublisher publisher;
public void sendMsg(String msg){
publisher.publishEvent(new MyEvent(this, msg));
}
}
private static class AListenerBean {
@EventListener
public void onMyEvent (MyEvent event) {
System.out.print("event received: "+event.getMsg());
System.out.println(" -- source: "+event.getSource());
}
}
private static class MyEvent extends ApplicationEvent{
private final String msg;
public MyEvent (Object source, String msg) {
super(source);
this.msg = msg;
}
public String getMsg () {
return msg;
}
}
}
Outputevent received: A test message -- source: com.logicbig.example.CustomEventWithApplicationEvent$MyEvenPublisherBean@1bd4b875
Creating custom event without extending ApplicationEvent
Showing how to create custom event without extending ApplicationEvent, just using a POJO and autowiring ApplicationEventPublisher for firing the custom event.
package com.logicbig.example;
import org.springframework.beans.factory.annotation.Autowired;
import org.springframework.context.ApplicationEventPublisher;
import org.springframework.context.annotation.AnnotationConfigApplicationContext;
import org.springframework.context.annotation.Bean;
import org.springframework.context.event.EventListener;
public class CustomEventWithoutApplicationEvent {
@Bean
AListenerBean listenerBean () {
return new AListenerBean();
}
@Bean
MyEvenPublisherBean publisherBean () {
return new MyEvenPublisherBean();
}
public static void main (String[] args) {
AnnotationConfigApplicationContext context = new AnnotationConfigApplicationContext(
CustomEventWithoutApplicationEvent.class);
MyEvenPublisherBean bean = context.getBean(MyEvenPublisherBean.class);
bean.sendMsg("A test message");
}
private static class MyEvenPublisherBean{
@Autowired
ApplicationEventPublisher publisher;
public void sendMsg(String msg){
publisher.publishEvent(new MyEvent(msg));
}
}
private static class AListenerBean {
@EventListener
public void onMyEvent (MyEvent event) {
System.out.print("event received: "+event.getMsg());
}
}
private static class MyEvent{
private final String msg;
public MyEvent (String msg) {
this.msg = msg;
}
public String getMsg () {
return msg;
}
}
}
Outputevent received: A test message
Publishing event by using ApplicationEventPublisherAware
We are not autowiring ApplicationEventPublisher but implementing ApplicationEventPublisherAware this time
package com.logicbig.example;
import org.springframework.context.ApplicationEventPublisher;
import org.springframework.context.ApplicationEventPublisherAware;
import org.springframework.context.annotation.AnnotationConfigApplicationContext;
import org.springframework.context.annotation.Bean;
import org.springframework.context.event.EventListener;
public class CustomEventWithoutApplicationEvent2 {
@Bean
AListenerBean listenerBean () {
return new AListenerBean();
}
@Bean
MyEvenPublisherBean publisherBean () {
return new MyEvenPublisherBean();
}
public static void main (String[] args) {
AnnotationConfigApplicationContext context = new AnnotationConfigApplicationContext(
CustomEventWithoutApplicationEvent2.class);
MyEvenPublisherBean bean = context.getBean(MyEvenPublisherBean.class);
bean.sendMsg("A test message");
}
//we are not autowiring ApplicationEventPublisher but implementing ApplicationEventPublisherAware this time
private static class MyEvenPublisherBean implements ApplicationEventPublisherAware {
ApplicationEventPublisher publisher;
public void sendMsg (String msg) {
publisher.publishEvent(new MyEvent(msg));
}
@Override
public void setApplicationEventPublisher (
ApplicationEventPublisher applicationEventPublisher) {
this.publisher = applicationEventPublisher;
}
}
private static class AListenerBean {
@EventListener
public void onMyEvent (MyEvent event) {
System.out.print("event received: " + event.getMsg());
}
}
private static class MyEvent {
private final String msg;
public MyEvent (String msg) {
this.msg = msg;
}
public String getMsg () {
return msg;
}
}
}
Outputevent received: A test message
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
|