Spring Framework Tutorial

Software Setup and Configuration (STS/Eclipse/IntelliJ)

Core Spring

Spring Annotations

Spring Data

Spring JDBC

Spring Security

Spring - Application Events

In Spring, application events provide a way to create and listen to specific events in your application. This can be particularly useful when you want different parts of an application to communicate without tight coupling.

The core interfaces and classes involved in Spring's application event mechanism are:

  1. ApplicationEvent: All custom events should extend this class.
  2. ApplicationListener<E>: Implementations of this interface can consume or react to the events.
  3. ApplicationEventPublisher: Beans can have this injected to publish events.

Creating a Custom Event:

To create a custom event, you can extend the ApplicationEvent class:

public class CustomEvent extends ApplicationEvent {
    private String message;

    public CustomEvent(Object source, String message) {
        super(source);
        this.message = message;
    }

    public String getMessage() {
        return message;
    }
}

Listening to an Event:

To listen to this event, you create a listener by implementing the ApplicationListener interface:

@Component
public class CustomEventListener implements ApplicationListener<CustomEvent> {

    @Override
    public void onApplicationEvent(CustomEvent event) {
        System.out.println("Received custom event - " + event.getMessage());
    }
}

Publishing an Event:

To publish events, you can use the ApplicationEventPublisher:

@Service
public class CustomEventPublisher {

    @Autowired
    private ApplicationEventPublisher applicationEventPublisher;

    public void doSomethingAndPublishEvent() {
        // ... some logic
        CustomEvent customEvent = new CustomEvent(this, "This is my custom event");
        applicationEventPublisher.publishEvent(customEvent);
    }
}

When the doSomethingAndPublishEvent() method is called, it publishes a CustomEvent. Any bean in the same application context that implements ApplicationListener<CustomEvent> will then receive this event and can act upon it.

Using Annotations:

From Spring 4.2 onwards, you can use @EventListener annotation to define an event listener, which simplifies the configuration a bit:

@Component
public class AnnotatedEventListener {

    @EventListener
    public void handleCustomEvent(CustomEvent event) {
        System.out.println("Received custom event (with annotation) - " + event.getMessage());
    }
}

Benefits:

  1. Decoupling: Application events allow for loose coupling between modules. One bean can publish an event without knowing anything about the listeners (subscribers).

  2. Synchronous or Asynchronous Execution: By default, Spring's event handling is synchronous. It means the publisher thread blocks until all listeners have finished processing the event. However, starting from Spring 4.2, you can annotate your listener method with @Async to process events asynchronously or even use the SimpleApplicationEventMulticaster bean with a custom executor.

  3. Flexibility: It allows various components in the system to be notified upon certain state changes or specific activities, offering a more flexible way to react to changes in the system's state.

In summary, Spring's application event mechanism provides a simple yet powerful way to create, publish, and listen to events in your application, allowing for better modularization and decoupling of components.

  1. Publishing and subscribing to events in Spring:

    • To publish an event, use the ApplicationEventPublisher. Subscribers can listen to events using @EventListener or implementing the ApplicationListener interface.
    @Service
    public class MyEventPublisher {
    
        @Autowired
        private ApplicationEventPublisher eventPublisher;
    
        public void publishEvent(String message) {
            MyCustomEvent customEvent = new MyCustomEvent(this, message);
            eventPublisher.publishEvent(customEvent);
        }
    }
    
  2. Custom application events in Spring:

    • Define custom events by extending the ApplicationEvent class.
    public class MyCustomEvent extends ApplicationEvent {
    
        private String message;
    
        public MyCustomEvent(Object source, String message) {
            super(source);
            this.message = message;
        }
    
        public String getMessage() {
            return message;
        }
    }
    
  3. Spring ApplicationEvent example:

    • Example of using ApplicationEvent and publishing a custom event.
    @Service
    public class MyEventPublisher {
    
        @Autowired
        private ApplicationEventPublisher eventPublisher;
    
        public void publishEvent(String message) {
            MyCustomEvent customEvent = new MyCustomEvent(this, message);
            eventPublisher.publishEvent(customEvent);
        }
    }
    
  4. Event handling in Spring Boot:

    • Spring Boot simplifies event handling. Components can use @EventListener or implement ApplicationListener without additional configuration.
    @Service
    public class MyEventListener {
    
        @EventListener
        public void handleCustomEvent(MyCustomEvent event) {
            // Handle the custom event
        }
    }
    
  5. Asynchronous event processing in Spring:

    • Events can be processed asynchronously by using @Async annotation on the event handler method.
    @Service
    public class MyAsyncEventListener {
    
        @Async
        @EventListener
        public void handleAsyncCustomEvent(MyCustomEvent event) {
            // Asynchronously handle the custom event
        }
    }
    
  6. Listening to application events in Spring:

    • Components can listen to application events by implementing the ApplicationListener interface or using the @EventListener annotation.
    @Service
    public class MyEventListener implements ApplicationListener<MyCustomEvent> {
    
        @Override
        public void onApplicationEvent(MyCustomEvent event) {
            // Handle the custom event
        }
    }