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();
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);
}
}
}
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 EventListenerMultipleEventTypesExample {
@Bean
AListenerBean listenerBean() {
return new AListenerBean();
}

public static void main(String[] args) {
AnnotationConfigApplicationContext context =
new AnnotationConfigApplicationContext(EventListenerMultipleEventTypesExample.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 received ");
}
}
}
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 EventListenerConditionExample {
@Bean
AListenerBean listenerBean() {
return new AListenerBean();
}

public static void main(String[] args) {

AnnotationConfigApplicationContext context =
new AnnotationConfigApplicationContext(EventListenerConditionExample.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 String getMsg() {
return msg;
}

public int getCode() {
return code;
}

@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 EventTransformingExample {
@Bean
AListenerBean listenerBean() {
return new AListenerBean();
}

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


public static void main(String[] args) {
AnnotationConfigApplicationContext context =
new AnnotationConfigApplicationContext(EventTransformingExample.class);
context.publishEvent(new MyEvent("test message 1"));
}

private static class AListenerBean {
@EventListener
public MyAnotherEvent handleContextEvent(MyEvent myEvent) {
System.out.printf("event received by %s, event: %s%n", this.getClass().getSimpleName(), myEvent);
return new MyAnotherEvent("test message 2");
}
}

private static class AnotherListenerBean {
@EventListener
public void handleContextEvent(MyAnotherEvent myEvent) {
System.out.printf("event received by %s, event: %s%n", this.getClass().getSimpleName(), myEvent);
}
}

private static class MyEvent {
private String msg;

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


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

private static class MyAnotherEvent {
private String msg;

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

@Override
public String toString() {
return "MyAnotherEvent{" +
"msg='" + msg + '\'' +
'}';
}
}
}
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 EventListenerMultipleEventTypesExample2 {
@Bean
AListenerBean listenerBean () {
return new AListenerBean();
}

public static void main (String[] args) {
AnnotationConfigApplicationContext context =
new AnnotationConfigApplicationContext(EventListenerMultipleEventTypesExample2.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 (ApplicationEvent applicationEvent) {
System.out.println("context event received "+applicationEvent);
}
}
}
Original Post




See Also