Event handling in Spring is a powerful mechanism that allows different components of a Spring application to communicate with each other in a loosely coupled manner. This is achieved through the Observer Pattern, where a publisher sends events and multiple listeners react to them.
Event Handling in Spring Boot
Spring Event Handling enables various components of an application to communicate loosely. It utilizes the Observer Design Pattern, involving three main components:
1. Event: The Custom Event Class
The event in Spring represents something significant that has happened in the application. It could range from a user logging in to a file being uploaded. In Spring, custom events are typically subclasses of ApplicationEvent
.
Key Points:
- The event class can hold information related to the event, accessible by listeners.
- It extends the
ApplicationEvent
class.
Java
package com.gfg.springeventhandling.event;
import org.springframework.context.ApplicationEvent;
public class CustomSpringEvent extends ApplicationEvent {
private final String message;
public CustomSpringEvent(Object source, String message) {
super(source);
this.message = message;
}
public String getMessage() {
return message;
}
}
CustomSpringEvent
extends ApplicationEvent
.- It contains a
message
field to hold event-related information. - The constructor accepts the event source and the message.
- The
getMessage()
method allows listeners to retrieve the event message.
2. Publisher: Publishing the Event
The publisher generates and broadcasts events to the Spring context. This is usually done using the ApplicationEventPublisher
interface, which provides the publishEvent()
method.
Key Points:
- The publisher triggers the event and sends it to all interested listeners.
- It uses
ApplicationEventPublisher
to publish events.
Java
package com.gfg.springeventhandling.event;
import org.springframework.context.ApplicationEventPublisher;
import org.springframework.stereotype.Component;
@Component
public class CustomSpringEventPublisher {
private final ApplicationEventPublisher applicationEventPublisher;
public CustomSpringEventPublisher(ApplicationEventPublisher applicationEventPublisher) {
this.applicationEventPublisher = applicationEventPublisher;
}
public void publishEvent(final String message) {
System.out.println("Publishing custom event.");
CustomSpringEvent customSpringEvent = new CustomSpringEvent(this, message);
applicationEventPublisher.publishEvent(customSpringEvent);
}
}
CustomSpringEventPublisher
is a Spring component that acts as the event publisher.- It injects
ApplicationEventPublisher
through the constructor. - The
publishEvent()
method creates and publishes CustomSpringEvent
.
3. Listener: Reacting to the Event
Listeners react to specific events. In Spring, listeners are typically annotated with @EventListener
, which registers the method as an event handler for a specific event type.
Key Points:
- The listener component listens for specific events and executes logic when the event is received.
- It uses the
@EventListener
annotation to register the method as the event handler.
Java
package com.gfg.springeventhandling.event;
import org.springframework.context.event.EventListener;
import org.springframework.stereotype.Component;
@Component
public class CustomSpringEventListener {
@EventListener
public void handleCustomSpringEvent(CustomSpringEvent event) {
System.out.println("Received spring custom event - " + event.getMessage());
}
}
CustomSpringEventListener
is a Spring component that listens for CustomSpringEvent
.- The
handleCustomSpringEvent()
method, annotated with @EventListener
, prints the event message to the console.
Implementation of Event Handling in a Spring Boot Application
Step 1: Create a new Spring Boot Project
Create a new Spring Boot project using IntelliJ IDEA. Choose the following options:
Step 2: Add Dependencies
Add the following dependencies into the Spring Boot project.
Project Structure
After project creation done, the folder structure will look like the below image.
Step 3: Configure Application Properties
Update the application.properties
file.
spring.application.name=spring-event-handling
# application.properties
spring.main.banner-mode=console
Step 4: Create the CustomSpringEvent Class
Define the event class.
event/CustomSpringEvent.java:
Java
package com.gfg.springeventhandling.event;
import org.springframework.context.ApplicationEvent;
public class CustomSpringEvent extends ApplicationEvent {
private final String message;
public CustomSpringEvent(Object source, String message) {
super(source);
this.message = message;
}
public String getMessage() {
return message;
}
}
Step 5: Create the CustomSpringEventListener Class
Create the listener that listens for the custom event and react to it.
event/CustomSpringEventListener.java:
Java
package com.gfg.springeventhandling.event;
import org.springframework.context.event.EventListener;
import org.springframework.stereotype.Component;
@Component
public class CustomSpringEventListener {
@EventListener
public void handleCustomSpringEvent(CustomSpringEvent event) {
System.out.println("Received spring custom event - " + event.getMessage());
}
}
Step 6: Create the CustomSpringEventPublisher Class
The publisher will use the ApplicationEventPublisher to publish the event.
event/CustomSpringEventPublisher.java:
Java
package com.gfg.springeventhandling.event;
import org.springframework.context.ApplicationEventPublisher;
import org.springframework.stereotype.Component;
@Component
public class CustomSpringEventPublisher {
private final ApplicationEventPublisher applicationEventPublisher;
public CustomSpringEventPublisher(ApplicationEventPublisher applicationEventPublisher) {
this.applicationEventPublisher = applicationEventPublisher;
}
public void publishEvent(final String message) {
System.out.println("Publishing custom event.");
CustomSpringEvent customSpringEvent = new CustomSpringEvent(this, message);
applicationEventPublisher.publishEvent(customSpringEvent);
}
}
Step 7: Create the AppRunner Class
Trigger the event from the command-line runner.
runner/AppRunner.java:
Java
package com.gfg.springeventhandling.runner;
import com.gfg.springeventhandling.event.CustomSpringEventPublisher;
import org.springframework.boot.CommandLineRunner;
import org.springframework.stereotype.Component;
@Component
public class AppRunner implements CommandLineRunner {
private final CustomSpringEventPublisher publisher;
public AppRunner(CustomSpringEventPublisher publisher) {
this.publisher = publisher;
}
@Override
public void run(String... args) throws Exception {
publisher.publishEvent("Hello, Spring Event!");
}
}
Step 8: Main Class
No changes are required in the main class.
Java
package com.gfg.springeventhandling;
import org.springframework.boot.SpringApplication;
import org.springframework.boot.autoconfigure.SpringBootApplication;
@SpringBootApplication
public class SpringEventHandlingApplication {
public static void main(String[] args) {
SpringApplication.run(SpringEventHandlingApplication.class, args);
}
}
pom.xml file:
XML
<?xml version="1.0" encoding="UTF-8"?>
<project xmlns="http://maven.apache.org/POM/4.0.0" xmlns:xsi="http://www.w3.org/2001/XMLSchema-instance"
xsi:schemaLocation="http://maven.apache.org/POM/4.0.0 https://maven.apache.org/xsd/maven-4.0.0.xsd">
<modelVersion>4.0.0</modelVersion>
<parent>
<groupId>org.springframework.boot</groupId>
<artifactId>spring-boot-starter-parent</artifactId>
<version>3.3.2</version>
<relativePath/> <!-- lookup parent from repository -->
</parent>
<groupId>com.gfg</groupId>
<artifactId>spring-event-handling</artifactId>
<version>0.0.1-SNAPSHOT</version>
<name>spring-event-handling</name>
<description>spring-event-handling</description>
<url/>
<licenses>
<license/>
</licenses>
<developers>
<developer/>
</developers>
<scm>
<connection/>
<developerConnection/>
<tag/>
<url/>
</scm>
<properties>
<java.version>17</java.version>
</properties>
<dependencies>
<dependency>
<groupId>org.springframework.boot</groupId>
<artifactId>spring-boot-starter-web</artifactId>
</dependency>
<dependency>
<groupId>org.springframework.boot</groupId>
<artifactId>spring-boot-devtools</artifactId>
<scope>runtime</scope>
<optional>true</optional>
</dependency>
<dependency>
<groupId>org.projectlombok</groupId>
<artifactId>lombok</artifactId>
<optional>true</optional>
</dependency>
<dependency>
<groupId>org.springframework.boot</groupId>
<artifactId>spring-boot-starter-test</artifactId>
<scope>test</scope>
</dependency>
</dependencies>
<build>
<plugins>
<plugin>
<groupId>org.springframework.boot</groupId>
<artifactId>spring-boot-maven-plugin</artifactId>
<configuration>
<excludes>
<exclude>
<groupId>org.projectlombok</groupId>
<artifactId>lombok</artifactId>
</exclude>
</excludes>
</configuration>
</plugin>
</plugins>
</build>
</project>
Step 9: Run the Application
Start the application and it will run on port 8080.
This example project provides clear and practical demonstration of the Spring Event Handling of the Spring Boot application.
How These Components Work Together
- Event Creation: The event class,
CustomSpringEvent
, can be defined to represent the event in the application. - Event Publishing: The publisher component,
CustomSpringEventPublisher
, is responsible for creating and publishing this event to the Spring context. The event is typically published in response to some application logic. - Event Listening: The listener component,
CustomSpringEventListener
, is registered to listen for the specific event type, CustomSpringEvent
. When the event is published, the listener's method is triggered, allowing the application to respond to the event.
Advantages of Using Event Handling in Spring
- Loose Coupling: Publishers and listeners do not need to know about each other. They can communicate through events, making the system more modular and easier to maintain.
- Scalability: New listeners can be easily added without modifying the existing publishing logic.
- Flexibility: Different listeners can handle the same event in different ways, allowing for a variety of reactions to a single event.
Conclusion
Spring's event handling mechanism provides a flexible way to manage communication between different components of an application. By using custom events, publishers, and listeners, you can create a robust and loosely-coupled architecture. This approach enhances the maintainability and scalability of your Spring Boot applications.
Similar Reads
Event Handling in Java An event is a change in the state of an object triggered by some action such as Clicking a button, Moving the cursor, Pressing a key on the keyboard, Scrolling a page, etc. In Java, the java.awt.event package provides various event classes to handle these actions.Classification of Events Events in J
5 min read
Spring MVC - Exception Handling Prerequisites: Spring MVC When something goes wrong with your application, the server displays an exception page defining the type of exception, the server-generated exception page is not user-friendly. Spring MVC provides exception handling for your web application to make sure you are sending your
6 min read
Spring - MVC Form Handling Prerequisites: Spring MVC, Introduction to Spring Spring MVC is a Model-View-Controller framework, it enables the separation of modules into Model, View, and Controller and uniformly handles the application integration. In this article, we will create a student login form and see how Spring MVC hand
6 min read
Handling Errors in Spring WebFlux The Spring Boot Community Developed the Spring Reactive Web Framework. The SpringReactive allows developers to build asynchronous, non-blocking, and event-driven web applications. When compared with the Spring MVC framework the Spring Reactive Web framework provides more functionality. The Spring We
6 min read
Server - Sent Events in Spring When we design web applications, we generally have a client and a server model, where the client is always the initiator of the transaction or a request to the server. The server responds to these requests. However, in certain scenarios, there arises a need for the server to respond much more freque
5 min read