Event publishing lets parts of your app talk to each other without being tightly connected. It helps keep your code clean and organized.
Event publishing with ApplicationEventPublisher in Spring Boot
public class MyEvent extends ApplicationEvent { public MyEvent(Object source) { super(source); } } @Component public class MyEventPublisher { private final ApplicationEventPublisher eventPublisher; public MyEventPublisher(ApplicationEventPublisher eventPublisher) { this.eventPublisher = eventPublisher; } public void publish() { MyEvent event = new MyEvent(this); eventPublisher.publishEvent(event); } }
The event class extends ApplicationEvent and usually has a constructor with a source object.
The publisher class uses ApplicationEventPublisher to send events.
public class UserRegisteredEvent extends ApplicationEvent { private final String username; public UserRegisteredEvent(Object source, String username) { super(source); this.username = username; } public String getUsername() { return username; } }
@Component
public class UserEventPublisher {
private final ApplicationEventPublisher eventPublisher;
public UserEventPublisher(ApplicationEventPublisher eventPublisher) {
this.eventPublisher = eventPublisher;
}
public void publishUserRegistered(String username) {
UserRegisteredEvent event = new UserRegisteredEvent(this, username);
eventPublisher.publishEvent(event);
}
}This Spring Boot app publishes a user registered event and listens to it. When you run it, it prints messages before and after publishing the event.
import org.springframework.boot.SpringApplication; import org.springframework.boot.autoconfigure.SpringBootApplication; import org.springframework.context.ApplicationEvent; import org.springframework.context.ApplicationEventPublisher; import org.springframework.context.event.EventListener; import org.springframework.stereotype.Component; @SpringBootApplication public class EventDemoApplication { public static void main(String[] args) { var context = SpringApplication.run(EventDemoApplication.class, args); UserEventPublisher publisher = context.getBean(UserEventPublisher.class); System.out.println("Publishing user registered event..."); publisher.publishUserRegistered("alice"); } } class UserRegisteredEvent extends ApplicationEvent { private final String username; public UserRegisteredEvent(Object source, String username) { super(source); this.username = username; } public String getUsername() { return username; } } @Component class UserEventPublisher { private final ApplicationEventPublisher eventPublisher; public UserEventPublisher(ApplicationEventPublisher eventPublisher) { this.eventPublisher = eventPublisher; } public void publishUserRegistered(String username) { UserRegisteredEvent event = new UserRegisteredEvent(this, username); eventPublisher.publishEvent(event); } } @Component class UserEventListener { @EventListener public void handleUserRegistered(UserRegisteredEvent event) { System.out.println("User registered event received for user: " + event.getUsername()); } }
Publishing an event is fast and usually runs in the same thread by default.
Listeners can be synchronous or asynchronous if configured.
Common mistake: forgetting to annotate listener methods with @EventListener.
Use ApplicationEventPublisher to send events inside your app.
Create event classes by extending ApplicationEvent.
Listeners react to events using @EventListener annotation.
Practice
ApplicationEventPublisher in a Spring Boot application?Solution
Step 1: Understand the purpose of ApplicationEventPublisher
This interface is designed to publish events to listeners within the Spring application context.Step 2: Differentiate from listeners and other components
Listeners handle events, but ApplicationEventPublisher only sends or publishes them.Final Answer:
To send or publish events within the application -> Option DQuick Check:
Event sending = ApplicationEventPublisher [OK]
- Confusing publisher with listener
- Thinking it manages HTTP or database
- Assuming it handles event processing
ApplicationEventPublisher in a Spring Boot component?Solution
Step 1: Recall Spring dependency injection syntax
Spring uses @Autowired to inject beans automatically into components.Step 2: Check each option for correctness
@Autowired private ApplicationEventPublisher publisher; uses @Autowired correctly. private ApplicationEventPublisher publisher = new ApplicationEventPublisher(); tries to instantiate interface (not allowed). @Inject ApplicationEventPublisher publisher = null; mixes @Inject with assignment (not typical in Spring). ApplicationEventPublisher publisher = ApplicationEventPublisher.getInstance(); uses a non-existent getInstance method.Final Answer:
@Autowired private ApplicationEventPublisher publisher; -> Option AQuick Check:
@Autowired injects beans properly [OK]
- Trying to instantiate ApplicationEventPublisher directly
- Mixing injection annotations incorrectly
- Using static getInstance() which doesn't exist
publishEvent() is called?public class MyEvent extends ApplicationEvent {
public MyEvent(Object source) { super(source); }
}
@Component
public class MyPublisher {
@Autowired
private ApplicationEventPublisher publisher;
public void publishEvent() {
publisher.publishEvent(new MyEvent(this));
}
}
@Component
public class MyListener {
@EventListener
public void handleMyEvent(MyEvent event) {
System.out.println("Event received");
}
}Solution
Step 1: Understand event publishing and listening
The publisher sends a MyEvent instance. The listener listens for MyEvent and prints "Event received".Step 2: Confirm no errors in code
Code uses correct annotations and event class extending ApplicationEvent, so no errors or exceptions.Final Answer:
Event received -> Option CQuick Check:
Listener prints message on event [OK]
- Forgetting @EventListener annotation
- Not extending ApplicationEvent in event class
- Expecting output without publishing event
@Component
public class EventSender {
private ApplicationEventPublisher publisher;
public void send() {
publisher.publishEvent(new CustomEvent(this));
}
}
public class CustomEvent extends ApplicationEvent {
public CustomEvent(Object source) { super(source); }
}Solution
Step 1: Check ApplicationEventPublisher usage
The publisher field is declared but never injected or assigned, so it remains null.Step 2: Consequence of null publisher
Calling publishEvent on null causes NullPointerException at runtime.Final Answer:
ApplicationEventPublisher is not injected, so publisher is null -> Option BQuick Check:
Missing injection causes null publisher [OK]
- Forgetting @Autowired on publisher
- Assuming interface can be instantiated
- Thinking method must be static
UserCreatedEvent and ensure multiple listeners react differently. Which approach correctly implements this in Spring Boot?Solution
Step 1: Define event class properly
Custom events should extend ApplicationEvent for Spring to recognize them.Step 2: Publish event and create multiple listeners
Inject ApplicationEventPublisher to publish event. Use @EventListener on multiple methods to react differently.Step 3: Evaluate other options
Create UserCreatedEvent as a simple POJO, call listeners manually without publishing events skips event system, losing decoupling. Use ApplicationEventPublisher to publish String messages instead of event objects misuses publisher with Strings. Create UserCreatedEvent but do not extend ApplicationEvent; rely on @EventListener to catch any object breaks event contract, listeners may not work.Final Answer:
Create UserCreatedEvent extending ApplicationEvent, inject ApplicationEventPublisher, publish event, and annotate multiple methods with @EventListener for UserCreatedEvent -> Option AQuick Check:
Proper event class + publisher + listeners = correct [OK]
- Not extending ApplicationEvent for custom events
- Calling listeners manually instead of publishing
- Publishing wrong object types like String
Ready to prove it?
Pass the test and this pattern moves unknown
