π What Are Spring Events?
Spring Events provide a way for different components of a Spring application to communicate with each other in a loosely coupled way using the Publisher-Listener model. It follows the Observer Design Pattern.
π§ Why Use Spring Events?
β
Loose coupling
β
Asynchronous event handling (if needed)
β
Clean separation of concerns
β
Easy to extend & test
π¦ Core Concepts
Component | Description |
---|---|
ApplicationEvent |
The event object (can also be a POJO from Spring 4.2+) |
ApplicationEventPublisher |
Used to publish events |
@EventListener |
Used to listen and act on events |
π§± Use Case Example: User Registration System
Letβs build a real-world example:
When a user registers, send a welcome email and log an audit trail using Spring Events.
1οΈβ£ Create a Custom Event
// src/main/java/com/example/events/UserRegisteredEvent.java
package com.example.events;
public class UserRegisteredEvent {
private final String email;
private final String username;
public UserRegisteredEvent(String email, String username) {
this.email = email;
this.username = username;
}
public String getEmail() { return email; }
public String getUsername() { return username; }
}
2οΈβ£ Create an Event Publisher
// src/main/java/com/example/service/UserService.java
package com.example.service;
import com.example.events.UserRegisteredEvent;
import org.springframework.context.ApplicationEventPublisher;
import org.springframework.stereotype.Service;
@Service
public class UserService {
private final ApplicationEventPublisher publisher;
public UserService(ApplicationEventPublisher publisher) {
this.publisher = publisher;
}
public void registerUser(String email, String username) {
// Logic to save user to DB (skipped)
System.out.println("β
User registered: " + username);
// Fire event
publisher.publishEvent(new UserRegisteredEvent(email, username));
}
}
3οΈβ£ Create Event Listeners
a. Email Notification Listener
// src/main/java/com/example/listeners/EmailNotificationListener.java
package com.example.listeners;
import com.example.events.UserRegisteredEvent;
import org.springframework.context.event.EventListener;
import org.springframework.stereotype.Component;
@Component
public class EmailNotificationListener {
@EventListener
public void handleUserRegistered(UserRegisteredEvent event) {
System.out.println("π§ Sending welcome email to " + event.getEmail());
// Logic to send email
}
}
b. Audit Log Listener
// src/main/java/com/example/listeners/AuditLogListener.java
package com.example.listeners;
import com.example.events.UserRegisteredEvent;
import org.springframework.context.event.EventListener;
import org.springframework.stereotype.Component;
@Component
public class AuditLogListener {
@EventListener
public void logUserRegistration(UserRegisteredEvent event) {
System.out.println("π Audit: New user - " + event.getUsername());
// Write to audit log
}
}
4οΈβ£ Make It Asynchronous (Optional)
If you want to asynchronously handle events:
a. Enable Async support
// src/main/java/com/example/DemoApplication.java
@SpringBootApplication
@EnableAsync
public class DemoApplication {
public static void main(String[] args) {
SpringApplication.run(DemoApplication.class, args);
}
}
b. Annotate listener with @Async
@Async
@EventListener
public void handleUserRegistered(UserRegisteredEvent event) {
// async logic
}
π§ͺ 5οΈβ£ Triggering the Event
Letβs wire this into a controller:
// src/main/java/com/example/controller/UserController.java
package com.example.controller;
import com.example.service.UserService;
import org.springframework.web.bind.annotation.*;
@RestController
@RequestMapping("/api/users")
public class UserController {
private final UserService userService;
public UserController(UserService userService) {
this.userService = userService;
}
@PostMapping("/register")
public String register(@RequestParam String email, @RequestParam String username) {
userService.registerUser(email, username);
return "User registration successful!";
}
}
π Summary
Step | Action |
---|---|
β 1 | Create event class |
β 2 | Publish event from business logic |
β 3 | Create one or more listeners |
β 4 | (Optional) Use @Async for async handling |
βοΈ Project Structure
src/main/java/com/example
βββ controller
β βββ UserController.java
βββ events
β βββ UserRegisteredEvent.java
βββ listeners
β βββ AuditLogListener.java
β βββ EmailNotificationListener.java
βββ service
β βββ UserService.java
βββ DemoApplication.java
π Real-World Use Cases
- Notification systems (email, SMS)
- Audit logging
- Domain-driven design (domain events)
- Metrics/logging hooks
- Microservices communication with event sourcing (with external brokers)
β Best Practices
- Keep events immutable
- Avoid business logic in listeners
- Use
@Async
wisely (thread pool tuning) - Consider bounded context and domain event separation in complex systems
Top comments (0)
Some comments may only be visible to logged-in visitors. Sign in to view all comments.