Close

Spring Framework - @EventListener Examples

Spring Framework 

Showing how to listen Spring built-in context related events using @EventListener annotation.

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(
BuildInAnnotationBasedEventExample.class);
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.print("context refreshed event fired: ");
System.out.println(event);
}

@EventListener
public void handleContextStarted (ContextStartedEvent event) {
System.out.print("context started event fired: ");
System.out.println(event);
}

@EventListener
public void handleContextStopped (ContextStoppedEvent event) {
System.out.print("context stopped event fired: ");
System.out.println(event);
}

@EventListener
public void handleContextClosed (ContextClosedEvent event) {
System.out.print("context closed event fired: ");
System.out.println(event);
}

}
}
Original Post




Filtering events with a condition

A listener method can filter events by specifying Spring Expression language (SpEL) with 'condition' element of @EventListener .

@Configuration
public class EventListenerExample2 {
@Bean
AListenerBean listenerBean () {
return new AListenerBean();
}


public static void main (String[] args) {

AnnotationConfigApplicationContext context =
new AnnotationConfigApplicationContext(
EventListenerExample2.class);
context.publishEvent(new MyEvent(1, "test message 1"));
context.publishEvent(new MyEvent(5, "test message 5"));

}

private static class AListenerBean {

@EventListener(condition = "#myEvent.code == 5")
public void handleContextEvent (MyEvent myEvent) {
System.out.println("event received: " + myEvent);
}
}

private static class MyEvent {
private String msg;
private int code;


public MyEvent (int code, String msg) {
this.code = code;
this.msg = msg;
}

public int getCode () {
return code;
}

public void setCode (int code) {
this.code = code;
}

public void setMsg (String msg) {
this.msg = msg;
}

public String getMsg () {
return msg;
}

@Override
public String toString () {
return "MyEvent{" +
"msg='" + msg + '\'' +
", code=" + code +
'}';
}
}
}
Original Post




Listener method returning non-void type

Demonstrating how to publish another event by returning another event instance. Note we can also return java.util.Collection of events to publish several events at once from the listener method.

@Configuration
public class EventListenerExample3 {
@Bean
AListenerBean listenerBean () {
return new AListenerBean();
}

@Bean
AnotherListenerBean anotherListenerBean () {
return new AnotherListenerBean();
}


public static void main (String[] args) {

AnnotationConfigApplicationContext context =
new AnnotationConfigApplicationContext(
EventListenerExample3.class);
context.publishEvent(new MyEvent("test message 1"));
}

private static class AListenerBean {

@EventListener
public MyAnotherEvent handleContextEvent (MyEvent myEvent) {
System.out.println("event received: " + myEvent);
return new MyAnotherEvent(LocalDateTime.now());
}
}

private static class AnotherListenerBean {

@EventListener
public void handleContextEvent (MyAnotherEvent myEvent) {
System.out.println("event received: " + myEvent);
}
}

private static class MyEvent {
private String msg;

public MyEvent (String msg) {
this.msg = msg;
}

public void setMsg (String msg) {
this.msg = msg;
}

public String getMsg () {
return msg;
}

@Override
public String toString () {
return "MyEvent{" +
"msg='" + msg + '\'' +
'}';
}
}

private static class MyAnotherEvent {
private LocalDateTime time;

public MyAnotherEvent (LocalDateTime time) {
this.time = time;
}

public LocalDateTime getTime () {
return time;
}

public void setTime (LocalDateTime time) {
this.time = time;
}

@Override
public String toString () {
return "MyAnotherEvent{" +
"time=" + time +
'}';
}
}
}
Original Post




Listening to multiple events

If a method is meant to listen to several events or if we want to have no parameter at all, an array of event classes can be specified with @EventListener annotation.

If only one class is specified we can still include the corresponding parameter as well but for multiple classes there should be no parameter.

Even without using this multiple class option, there has to be at most one parameter capturing the event type.

@Configuration
public class EventListenerExample1 {
@Bean
AListenerBean listenerBean () {
return new AListenerBean();
}

public static void main (String[] args) {

AnnotationConfigApplicationContext context =
new AnnotationConfigApplicationContext(EventListenerExample1.class);
System.out.println("-- stopping context --");
context.stop();
System.out.println("-- starting context --");
context.start();

}

private static class AListenerBean {

@EventListener({ContextRefreshedEvent.class, ContextStoppedEvent.class,
ContextStartedEvent.class})
public void handleContextEvent () {
System.out.println("context event fired: ");
}

}
}
Original Post




See Also