事件总线模式通过解耦模块依赖实现高内聚低耦合:模块仅依赖 EventBus,事件轻量语义明确,监听异步可监控;按规模选用 Spring 事件、内存 EventBus 或 Kafka/RabbitMQ;严格约束事件结构与监听行为。

核心思路是:让模块只依赖事件总线,不互相持有引用;事件本身轻量、语义明确;监听逻辑异步执行且可监控。
用事件总线替代直接注册
避免被观察者(如订单服务)维护 Observer 列表或调用 update() 方法。改为在状态变更时,仅向统一的 EventBus 发布一个事件对象,例如:
- 订单创建完成 → 发布 UserRegisteredEvent
- 积分变动 → 发布 PointsUpdatedEvent
- 事件名用动词过去时,字段只保留必要上下文(如 userId、amount),不带业务逻辑
- Subject 类只需注入 EventBus,完全不知道谁会响应
订阅端按需监听,异步处理
观察者不再主动注册到具体 Subject,而是向 EventBus 订阅事件类型:
Java Maven 项目审查工作流的通用输入处理。当 Java Maven 项目以 ZIP压缩包或 GitLab 仓库 URL 形式提供且需要...时使用。
- 邮件服务订阅 UserRegisteredEvent
- 积分服务订阅 UserRegisteredEvent 和 OrderPaidEvent
- 所有监听方法加 @Async,并配置专用线程池(非默认 SimpleAsyncTaskExecutor)
- 关键业务监听(如发短信)建议加上 @TransactionalEventListener(phase = TransactionPhase.AFTER_COMMIT),防止事务未提交就读不到新数据
分层设计,兼顾单机与扩展性
根据项目规模选择实现方式:
立即学习“Java免费学习笔记(深入)”;
- 小型项目:用 Spring 的 ApplicationEventPublisher + @EventListener,开箱即用,无需额外依赖
- 中大型项目:自建内存 EventBus(如基于 Disruptor 或 BlockingQueue),支持重试、失败告警、消费延迟监控
- 跨服务场景:EventBus 底层对接 Kafka/RabbitMQ,保持 API 一致(publish/subscribe 接口不变),仅替换实现
- 所有事件类保持无逻辑纯数据结构,便于序列化和版本演进
规避常见陷阱
低耦合不是靠删代码实现的,关键在约束和规范:
- 禁止在事件中传递 Service 或 Repository 实例——只传 ID 或 DTO
- 监听器内不做耗时阻塞操作(如 HTTP 调用),应封装为异步任务或投递到消息队列
- 避免循环触发:A 发事件 → B 响应 → B 发新事件 → A 再响应,需通过事件类型隔离或加防重标识
- 监听器生命周期由 Spring 管理,不要手动 new,否则无法注入依赖或启用 @Async

















