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.

Architect's Tech Stack
Architect's Tech Stack
Architect's Tech Stack
Replace RabbitMQ with Spring Events for Cleaner Order Processing

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.

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.

JavaspringAsynchronousevent-drivenMQ Alternative
Architect's Tech Stack
Written by

Architect's Tech Stack

Java backend, microservices, distributed systems, containerized programming, and more.

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.