Why Graceful Shutdown Is Essential for Spring Event and How to Avoid Common Pitfalls

This article shares hard‑learned production experience on using Spring Event, explaining why services must shut down gracefully before publishing events, how startup timing can cause event loss, which business scenarios fit the publish‑subscribe model, and practical reliability techniques such as retries and idempotency.

Architect
Architect
Architect
Why Graceful Shutdown Is Essential for Spring Event and How to Avoid Common Pitfalls

Background

Spring Event provides an in‑process publish‑subscribe mechanism. Listeners are beans retrieved from ApplicationContext. Real‑world production use reveals critical pitfalls.

1. Graceful Service Shutdown

During event publishing Spring calls ApplicationContext.getBean. If the context is closing, getBean throws an exception such as “Do not request a bean from a BeanFactory in a destroy method implementation”. In high‑traffic services, a few requests may still arrive while the service is shutting down, causing event publishing to fail.

Spring shutdown error log
Spring shutdown error log

Recommendation: Stop inbound traffic (HTTP, MQ, RPC) before closing the Spring context, then shut down the service.

2. Event Loss During Startup

If a Kafka consumer starts in an init‑method before @EventListener beans are registered, events published early have no listeners and are lost.

Timeline of init‑method vs listener registration
Timeline of init‑method vs listener registration

Best practice: Open inbound traffic only after Spring has fully started, e.g., in a SmartLifecycle start method or a ContextRefreshedEvent listener.

3. Suitable Scenarios for Spring Event

Publishers do not need to know how events are processed.

Publishers do not care about processing results.

Multiple subscribers can handle events synchronously or asynchronously.

Subscribers are independent.

Strong‑consistency use cases (e.g., order placement where inventory deduction must be atomic) are not suitable because Spring Event cannot roll back a failed subscriber.

4. Eventual‑Consistency Use Cases

When the main transaction succeeds and subsequent cleanup can be retried, Spring Event is appropriate. Examples:

After order placement, publish an MQ message to release locks.

Notify settlement systems after fulfillment; failures can be retried without affecting the original order.

Using @EventListener keeps the code concise compared with a manual observer pattern.

5. Adding Reliability Guarantees

Spring Event propagates exceptions from listeners via applicationContext.publishEvent(event). One strategy is subscriber‑side retry with Spring Retry.

@Retryable(value = Exception.class, maxAttempts = 3, backoff = @Backoff(delay = 100L, multiplier = 2))
public void performSuccess(PerformEvent event) {
    // business logic that may throw
}

Add the following Maven dependency:

<dependency>
    <groupId>org.springframework.retry</groupId>
    <artifactId>spring-retry</artifactId>
    <version>1.2.4.RELEASE</version>
</dependency>

6. Idempotency Requirement

Because a retry re‑executes all listeners, each listener must be idempotent to avoid duplicate processing or data inconsistency.

7. Spring Event vs Message Queue

Message queues excel at inter‑service decoupling, while Spring Event is lightweight for intra‑service communication. They can coexist: use MQ for cross‑service events and Spring Event for internal decoupling.

Spring Event and MQ share the publish‑subscribe model; MQ offers richer features for inter‑service scenarios, whereas Spring Event is simpler for intra‑service use.

Original article: https://juejin.cn/post/7281159113882468371

Original Source

Signed-in readers can open the original source through BestHub's protected redirect.

Sign in to view source
Republication Notice

This article has been distilled and summarized from source material, then republished for learning and reference. If you believe it infringes your rights, please contactadmin@besthub.devand we will review it promptly.

javaSpringReliabilityEventPubSub
Architect
Written by

Architect

Professional architect sharing high‑quality architecture insights. Topics include high‑availability, high‑performance, high‑stability architectures, big data, machine learning, Java, system and distributed architecture, AI, and practical large‑scale architecture case studies. Open to ideas‑driven architects who enjoy sharing and learning.

0 followers
Reader feedback

How this landed with the community

Sign in to like

Rate this article

Was this worth your time?

Sign in to rate
Discussion

0 Comments

Thoughtful readers leave field notes, pushback, and hard-won operational detail here.