点击上方“程序员蜗牛g”,选择“设为星标”跟蜗牛哥一起,每天进步一点点
程序员蜗牛g大厂程序员一枚 跟蜗牛一起 每天进步一点点31篇原创内容**公众号
Spring Boot 提供了天然的事件发布与监听机制,它本质上是观察者设计模式的增强版本。
通过它,我们可以让业务主干专注于自身职责,而将“后续响应”广播给监听者,轻松实现解耦、异步与扩展性。
示例背景:一个典型的耦合式服务调用问题
设想我们在实现订单业务 /com/icoderoad/order/OrderService.java 时,创建订单后需依次完成:
- 更新库存
- 增加用户积分
- 发送邮件
- 写入日志
你可能写出如下代码:
@Servicepublic class OrderService { @Autowired private InventoryService inventoryService; @Autowired private UserService userService; @Autowired private MailService mailService; @Autowired private LogService logService;
public void createOrder(Order order) { orderRepository.save(order); System.out.println("订单创建成功:" + order.getId());
try { inventoryService.decreaseStock(order.getProductId(), order.getQuantity()); userService.addPoints(order.getUserId(), 100); mailService.sendMail(order.getUserId(), "订单成功", "感谢购买"); logService.logAction("CREATE_ORDER", order.getId()); } catch (Exception e) { logger.error("后续操作失败", e); } }}
这样做的问题是:
- 耦合严重:服务间依赖链条过长。
- 难以扩展:增加任何后续逻辑都需改动主服务。
- 单一职责被打破:核心逻辑与通知流程混杂。
重构策略:引入事件驱动模型
定义事件 /com/icoderoad/order/event/OrderCreatedEvent.java
package com.icoderoad.order.event;
import com.icoderoad.order.model.Order;import org.springframework.context.ApplicationEvent;
public class OrderCreatedEvent extends ApplicationEvent { private final Order order;
public OrderCreatedEvent(Object source, Order order) { super(source); this.order = order; }
public Order getOrder() { return order; }}
改造订单服务 /com/icoderoad/order/OrderService.java
@Servicepublic class OrderService {
private final ApplicationEventPublisher eventPublisher;
@Autowired public OrderService(ApplicationEventPublisher eventPublisher) { this.eventPublisher = eventPublisher; }
public void createOrder(Order order) { // 核心逻辑:保存订单 orderRepository.save(order); System.out.println("订单创建成功:" + order.getId());
// 发布事件 OrderCreatedEvent event = new OrderCreatedEvent(this, order); eventPublisher.publishEvent(event); System.out.println("已广播订单创建事件"); }}
监听器实现:模块解耦
每一个服务模块,都独立监听事件,路径结构如下:
/com/icoderoad/inventory/InventoryListener.java/com/icoderoad/user/UserListener.java/com/icoderoad/logging/LogListener.java/com/icoderoad/notification/MailListener.java@Componentpublic class InventoryListener { @Async @EventListener public void onOrderCreated(OrderCreatedEvent event) { System.out.println("【库存服务】处理订单:" + event.getOrder().getId()); }}@Componentpublic class UserListener { @EventListener public void onOrderCreated(OrderCreatedEvent event) { System.out.println("【用户服务】添加积分:" + event.getOrder().getUserId()); }}@Componentpublic class MailListener { @EventListener public void onOrderCreated(OrderCreatedEvent event) { System.out.println("【邮件服务】发送确认邮件:" + event.getOrder().getUserId()); }}@Componentpublic class LogListener { @EventListener public void onOrderCreated(OrderCreatedEvent event) { System.out.println("【日志服务】记录订单操作日志:" + event.getOrder().getId()); }}
⚠️ 注:若启用
@Async异步监听器,别忘记在主类上加@EnableAsync。
Spring 实现更接近发布-订阅模型,使用 ApplicationContext 作为事件调度中心,天然具备高扩展性和异步处理能力。
如果这篇文章对您有所帮助,或者有所启发的话,求一键三连:点赞、转发、在看。
关注公众号:woniuxgg,在公众号中回复:笔记 就可以获得蜗牛为你精心准备的java实战语雀笔记,回复面试、开发手册、有超赞的粉丝福利!