java事件驱动架构需以业务边界为核心,接口定义纯契约(如publish/handle),事件封装不可变事实,依赖仅面向接口注入,多变逻辑交由策略接口实现,从而实现高内聚低耦合。

用Java接口设计高度内聚的事件驱动架构,关键不是堆接口或加消息队列,而是让每个模块只守好自己的“业务边界”,再通过事件把它们松散但可靠地串起来。接口负责定义“谁该响应什么”,事件负责传递“发生了什么”,两者配合才能真正解耦分布式核心链路。
接口聚焦契约,不掺杂实现与分支
事件驱动中的接口必须是纯业务契约,不能成为逻辑中转站。
- 定义事件源接口时,只暴露
publish(Event event),不暴露消息中间件细节(如KafkaProducer或RabbitTemplate) - 定义事件处理器接口时,用语义化命名,如
OrderCreatedHandler,方法签名统一为handle(OrderCreatedEvent event),禁止在接口里写if (event.getChannel() == SMS) - 每个接口只对应一个限界上下文内的职责:比如
InventoryReservationService只管扣减/回滚库存,不处理通知、积分或日志
事件即事实,结构稳定、可演进
事件对象不是DTO,而是不可变的业务事实快照,其结构需兼顾当前需要与未来兼容性。
- 事件类用
record或final字段定义,包含版本号(如v1)、发生时间、聚合根ID和关键业务字段(如orderId、status) - 避免在事件中传递实体类或Map;用专用事件类,如
UserRegisteredV1,而非User或Map<string object></string> - 新增字段采用可选方式(如
Optional<string> sourceChannel</string>),旧消费者忽略,新消费者按需读取
依赖只面向接口注入,运行时动态组合
模块之间不持有具体实现,也不感知事件投递机制,所有协作都通过接口+构造器注入完成。
- 订单服务发布事件,只依赖
EventPublisher接口,Spring中用@RequiredArgsConstructor注入private final EventPublisher publisher - 库存服务消费事件,只实现
InventoryReservationHandler接口,并由框架自动注册为@EventListener或绑定到Kafka topic listener - 测试时,直接传入
new MockEventPublisher()或内存SimpleApplicationEventMulticaster,完全脱离MQ环境
多变逻辑策略化,事件触发后交由策略接口执行
当同一事件需触发多种行为(如不同用户类型发不同券),不要在监听器里写if-else,而应抽象为策略接口。
- 定义
CouponIssuanceStrategy接口,含canApply(User user)和issue(Order order) - 各实现类(
VipCouponStrategy、NewUserStrategy)独立开发、测试、配置 - 监听器中只持
Collection<couponissuancestrategy></couponissuancestrategy>,遍历调用canApply筛选并执行,新增策略无需改监听器代码
不复杂但容易忽略:高内聚来自对“一件事”的反复确认,低耦合来自对“不关心什么”的坚定舍弃。接口和事件一起,帮你守住这条线。
Java免费学习笔记:立即使用
解锁 Java 大师之旅:从入门到精通的终极指南











