Why Your Spring Event Fails: Critical Tips for Reliable Service Shutdown and Startup
This article shares hard‑won production lessons on using Spring Event, explaining why graceful service shutdown, proper startup timing, consistency requirements, and retry mechanisms are essential for reliable event publishing in Java backend systems.
In this article the author presents valuable production experience with Spring Event, focusing on common pitfalls and best‑practice solutions for reliable event publishing in Java backend applications.
Why Must a Business System Gracefully Shut Down Before Using Spring Event?
When Spring broadcasts an event it looks up listeners in the ApplicationContext. During context shutdown, calling getBean is prohibited, otherwise an exception is thrown. A real incident showed a stack trace containing
Do not request a bean from a BeanFactory in a destroy method implementation, which occurred because events were published while the service was shutting down. High traffic during shutdown caused the failure. The recommendation is to cut off all entry traffic (HTTP, MQ, RPC) before closing the Spring context.
Why Do Spring Event Events Get Lost During Service Startup?
In the author's company, a Kafka consumer started consuming in the init-method phase, but EventListener registration happened later, after the same init-method. Consequently, events published by the consumer could not find any listeners and were lost. The solution is to start inbound traffic only after Spring has fully started, e.g., by registering services in SmartLifecycle or listening to ContextRefreshedEvent.
Which Business Scenarios Suit the Publish‑Subscribe Model?
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 and do not depend on each other.
The model decouples producers and consumers, but it is not suitable for strong‑consistency requirements.
Why Strong Consistency Scenarios Are Unsuitable for Publish‑Subscribe
In order‑creation workflows, inventory deduction and order placement must be atomic. If inventory deduction fails while the order is recorded, or vice‑versa, data inconsistency occurs. Spring Event cannot roll back the whole transaction when a subscriber fails, making it a poor fit for such strong‑consistency use cases.
Final Consistency Scenarios Are Ideal for Publish‑Subscribe
Events that only need eventual consistency, such as sending MQ messages after an order is successfully placed, fit well with Spring Event. Subscribers can retry until success, ensuring that follow‑up actions (e.g., releasing locks, notifying settlement systems) eventually complete without affecting the primary transaction.
Ensuring Additional Reliability When Using Spring Event
To guarantee reliability, publishing should be wrapped in applicationContext.publishEvent(event), which throws an exception if any subscriber fails. Three mitigation strategies are suggested:
Subscriber‑side retry : Use Spring Retry (e.g., @Retryable) to automatically retry failed methods.
@Retryable(value = Exception.class, maxAttempts = 3, backoff = @Backoff(delay = 100L, multiplier = 2))
public void performSuccess(PerformEvent event) {
// business logic
}Add the spring-retry dependency:
<dependency>
<groupId>org.springframework.retry</groupId>
<artifactId>spring-retry</artifactId>
<version>1.2.4.RELEASE</version>
</dependency>Kafka consumer group retry : Let Kafka handle retries by returning a consumption failure, or route failed messages to a dead‑letter queue.
Report failures to a fault‑management platform : After exceeding max retries, publish a fault message to an MQ that a monitoring system consumes, allowing operators to manually trigger a retry via RPC.
Spring Subscribers Must Ensure Idempotency
Because retries re‑execute all subscribers, each subscriber’s logic must be idempotent to avoid duplicate processing and data inconsistency.
Why Use Spring Event Even When You Have an MQ
MQ excels at inter‑service communication, while Spring Event is lightweight and ideal for intra‑application decoupling. Both can coexist: use MQ for cross‑service events and Spring Event for internal, fine‑grained publish‑subscribe needs.
https://juejin.cn/post/7281159113882468371
Signed-in readers can open the original source through BestHub's protected redirect.
This article has been distilled and summarized from source material, then republished for learning and reference. If you believe it infringes your rights, please contactand we will review it promptly.
Java High-Performance Architecture
Sharing Java development articles and resources, including SSM architecture and the Spring ecosystem (Spring Boot, Spring Cloud, MyBatis, Dubbo, Docker), Zookeeper, Redis, architecture design, microservices, message queues, Git, etc.
How this landed with the community
Was this worth your time?
0 Comments
Thoughtful readers leave field notes, pushback, and hard-won operational detail here.
