Close

Spring - Publishing and Consuming Custom Events

[Last Updated: Dec 22, 2023]

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;
        }
    }
}

Output

event 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;
        }
    }
}

Output

event 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;
        }
    }
}

Output

event received: A test message

Example Project

Dependencies and Technologies Used:

  • spring-context 6.1.2 (Spring Context)
     Version Compatibility: 4.2.0.RELEASE - 6.1.2Version List
    ×

    Version compatibilities of spring-context with this example:

    • 4.2.0.RELEASE
    • 4.2.1.RELEASE
    • 4.2.2.RELEASE
    • 4.2.3.RELEASE
    • 4.2.4.RELEASE
    • 4.2.5.RELEASE
    • 4.2.6.RELEASE
    • 4.2.7.RELEASE
    • 4.2.8.RELEASE
    • 4.2.9.RELEASE
    • 4.3.0.RELEASE
    • 4.3.1.RELEASE
    • 4.3.2.RELEASE
    • 4.3.3.RELEASE
    • 4.3.4.RELEASE
    • 4.3.5.RELEASE
    • 4.3.6.RELEASE
    • 4.3.7.RELEASE
    • 4.3.8.RELEASE
    • 4.3.9.RELEASE
    • 4.3.10.RELEASE
    • 4.3.11.RELEASE
    • 4.3.12.RELEASE
    • 4.3.13.RELEASE
    • 4.3.14.RELEASE
    • 4.3.15.RELEASE
    • 4.3.16.RELEASE
    • 4.3.17.RELEASE
    • 4.3.18.RELEASE
    • 4.3.19.RELEASE
    • 4.3.20.RELEASE
    • 4.3.21.RELEASE
    • 4.3.22.RELEASE
    • 4.3.23.RELEASE
    • 4.3.24.RELEASE
    • 4.3.25.RELEASE
    • 4.3.26.RELEASE
    • 4.3.27.RELEASE
    • 4.3.28.RELEASE
    • 4.3.29.RELEASE
    • 4.3.30.RELEASE
    • 5.0.0.RELEASE
    • 5.0.1.RELEASE
    • 5.0.2.RELEASE
    • 5.0.3.RELEASE
    • 5.0.4.RELEASE
    • 5.0.5.RELEASE
    • 5.0.6.RELEASE
    • 5.0.7.RELEASE
    • 5.0.8.RELEASE
    • 5.0.9.RELEASE
    • 5.0.10.RELEASE
    • 5.0.11.RELEASE
    • 5.0.12.RELEASE
    • 5.0.13.RELEASE
    • 5.0.14.RELEASE
    • 5.0.15.RELEASE
    • 5.0.16.RELEASE
    • 5.0.17.RELEASE
    • 5.0.18.RELEASE
    • 5.0.19.RELEASE
    • 5.0.20.RELEASE
    • 5.1.0.RELEASE
    • 5.1.1.RELEASE
    • 5.1.2.RELEASE
    • 5.1.3.RELEASE
    • 5.1.4.RELEASE
    • 5.1.5.RELEASE
    • 5.1.6.RELEASE
    • 5.1.7.RELEASE
    • 5.1.8.RELEASE
    • 5.1.9.RELEASE
    • 5.1.10.RELEASE
    • 5.1.11.RELEASE
    • 5.1.12.RELEASE
    • 5.1.13.RELEASE
    • 5.1.14.RELEASE
    • 5.1.15.RELEASE
    • 5.1.16.RELEASE
    • 5.1.17.RELEASE
    • 5.1.18.RELEASE
    • 5.1.19.RELEASE
    • 5.1.20.RELEASE
    • 5.2.0.RELEASE
    • 5.2.1.RELEASE
    • 5.2.2.RELEASE
    • 5.2.3.RELEASE
    • 5.2.4.RELEASE
    • 5.2.5.RELEASE
    • 5.2.6.RELEASE
    • 5.2.7.RELEASE
    • 5.2.8.RELEASE
    • 5.2.9.RELEASE
    • 5.2.10.RELEASE
    • 5.2.11.RELEASE
    • 5.2.12.RELEASE
    • 5.2.13.RELEASE
    • 5.2.14.RELEASE
    • 5.2.15.RELEASE
    • 5.2.16.RELEASE
    • 5.2.17.RELEASE
    • 5.2.18.RELEASE
    • 5.2.19.RELEASE
    • 5.2.20.RELEASE
    • 5.2.21.RELEASE
    • 5.2.22.RELEASE
    • 5.2.23.RELEASE
    • 5.2.24.RELEASE
    • 5.2.25.RELEASE
    • 5.3.0
    • 5.3.1
    • 5.3.2
    • 5.3.3
    • 5.3.4
    • 5.3.5
    • 5.3.6
    • 5.3.7
    • 5.3.8
    • 5.3.9
    • 5.3.10
    • 5.3.11
    • 5.3.12
    • 5.3.13
    • 5.3.14
    • 5.3.15
    • 5.3.16
    • 5.3.17
    • 5.3.18
    • 5.3.19
    • 5.3.20
    • 5.3.21
    • 5.3.22
    • 5.3.23
    • 5.3.24
    • 5.3.25
    • 5.3.26
    • 5.3.27
    • 5.3.28
    • 5.3.29
    • 5.3.30
    • 5.3.31
    • Compatible Java Version: 17+
    • 6.0.0
    • 6.0.1
    • 6.0.2
    • 6.0.3
    • 6.0.4
    • 6.0.5
    • 6.0.6
    • 6.0.7
    • 6.0.8
    • 6.0.9
    • 6.0.10
    • 6.0.11
    • 6.0.12
    • 6.0.13
    • 6.0.14
    • 6.0.15
    • 6.1.0
    • 6.1.1
    • 6.1.2

    Versions in green have been tested.

  • JDK 17
  • Maven 3.8.1

Spring - Custom Events Examples Select All Download
  • spring-custom-events
    • src
      • main
        • java
          • com
            • logicbig
              • example
                • CustomEventWithApplicationEvent.java

    See Also