Replace RabbitMQ with Spring Events for Cleaner Order Processing
This article explains how to refactor a monolithic order‑creation method by using Spring's built‑in ApplicationEvent mechanism, separating core logic from side‑effects such as SMS, points, and notifications, and clarifies when to choose Spring events over a message queue.
Introduction
The author shares a recent experience of overusing RabbitMQ for simple asynchronous tasks and discovers that Spring already provides a lightweight event‑driven mechanism suitable for intra‑JVM decoupling.
Problem with a monolithic method
public void createOrder(OrderDTO dto) {
// save order
orderService.save(dto);
// send SMS
smsService.sendOrderSuccessSms(dto.getPhone());
// add points
pointsService.addPoints(dto.getUserId(), 100);
// push notification
notificationService.push(dto.getUserId(), "订单创建成功");
// record log
logService.record("下单成功", dto.getOrderId());
}All side‑effects are hard‑coded inside the method, making the core flow tightly coupled with non‑essential logic and hard to extend.
Spring Event Mechanism
Spring’s ApplicationEvent follows the Observer pattern (publish‑subscribe). The publisher throws an event and immediately continues; listeners handle the event independently, optionally asynchronously.
Three‑step implementation
1. Define an event
public class OrderCreatedEvent extends ApplicationEvent {
private final String orderId;
private final String phone;
private final Long userId;
public OrderCreatedEvent(Object source, String orderId, String phone, Long userId) {
super(source);
this.orderId = orderId;
this.phone = phone;
this.userId = userId;
}
// getters omitted
}2. Publish the event in the core service
@Service
@RequiredArgsConstructor
public class OrderService {
private final ApplicationEventPublisher eventPublisher;
public void createOrder(OrderDTO dto) {
// core: persist order only
orderRepository.save(buildOrder(dto));
// publish event for side‑effects
eventPublisher.publishEvent(new OrderCreatedEvent(
this, dto.getOrderId(), dto.getPhone(), dto.getUserId()));
}
}3. Implement listeners
@Component
public class OrderEventListener {
@EventListener @Async
public void sendSms(OrderCreatedEvent event) {
smsService.sendOrderSuccessSms(event.getPhone());
}
@EventListener @Async
public void addPoints(OrderCreatedEvent event) {
pointsService.addPoints(event.getUserId(), 100);
}
@EventListener @Async
public void recordLog(OrderCreatedEvent event) {
logService.record("下单成功", event.getOrderId());
}
}Enable asynchronous execution by adding @EnableAsync to the main application class:
@SpringBootApplication
@EnableAsync
public class Application {
public static void main(String[] args) {
SpringApplication.run(Application.class, args);
}
}Adding new functionality without touching core code
To add a notification after order creation, simply add another listener method; the createOrder method stays unchanged.
@EventListener @Async
public void sendNotification(OrderCreatedEvent event) {
notificationService.push(event.getUserId(), "您的订单已提交成功");
}When to use Spring events vs. MQ
Use Spring events for intra‑service asynchronous decoupling where persistence, cross‑service delivery, and guaranteed delivery are not required. Use a message queue (RabbitMQ, RocketMQ, etc.) when you need cross‑service consumption, reliable delivery, scaling of consumers, delayed or dead‑letter handling.
Conclusion: By moving side‑effects to dedicated listeners, the core business logic remains clean, maintainable, and easy to extend, while Spring’s built‑in event system provides a lightweight alternative to heavyweight MQ solutions for suitable scenarios.
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.
Architect's Tech Stack
Java backend, microservices, distributed systems, containerized programming, and more.
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.
