🎓 事件总线与Mock测试详解 - 从小白到专家
📋 目录
🎯 事件总线基础概念
什么是事件总线?
最简单的比喻:事件总线就像微信群聊
- 发消息的人:不需要知道谁会看到消息
- 看消息的人:不需要知道是谁发的消息
- 微信群:就是"事件总线",负责传递消息
在我们的系统中:
- 发布事件:就像在群里发消息
- 监听事件:就像在群里看消息
- 事件总线:就像微信群,负责传递
为什么需要事件总线?
没有事件总线的问题
class UserRegistrationService {
fun registerUser(email: String, password: String) {
val user = createUser(email, password)
userRepository.save(user)
// 直接调用其他服务 - 紧耦合!
emailService.sendWelcomeEmail(user.email)
statisticsService.incrementUserCount()
notificationService.sendNotification(user.id)
auditService.logUserRegistration(user.id)
// 如果要加新功能,必须修改这里!
}
}
问题:
- 🔴 紧耦合:注册服务必须知道所有其他服务
- 🔴 难扩展:加新功能必须修改现有代码
- 🔴 难测试:必须mock所有依赖服务
有事件总线的解决方案
class UserRegistrationService {
fun registerUser(email: String, password: String) {
val user = createUser(email, password)
userRepository.save(user)
// 只发布事件 - 松耦合!
domainEventPublisher.publish(UserRegisteredEvent(user))
// 要加新功能?只需要添加新的事件监听器!
}
}
优势:
- ✅ 松耦合:注册服务不需要知道其他服务
- ✅ 易扩展:加新功能只需添加监听器
- ✅ 易测试:只需mock事件发布器
🏗️ 代码结构解析
文件位置
src/main/kotlin/com/purchase/shared/kernel/infrastructure/EventBusConfig.kt
1. 配置类
@Configuration // 告诉Spring:这里有配置
class EventBusConfig {
@Bean // 告诉Spring:帮我创建这个对象,以后其他地方需要时就给它们
fun eventBus(applicationEventPublisher: ApplicationEventPublisher): EventBus {
return SpringEventBus(applicationEventPublisher)
}
@Bean
fun domainEventPublisher(eventBus: EventBus): DomainEventPublisher {
return SpringDomainEventPublisher(eventBus)
}
}
2. 事件总线接口
interface EventBus {
fun publish(event: Any) // 发布事件(发消息)
fun register(listener: Any) // 注册监听器(加入群聊)
fun unregister(listener: Any) // 取消注册(退出群聊)
}
3. Spring实现
@Component
class SpringEventBus(
private val applicationEventPublisher: ApplicationEventPublisher
) : EventBus {
override fun publish(event: Any) {
// 使用Spring自带的事件发布机制
applicationEventPublisher.publishEvent(event)
}
// 其他方法实现...
}
4. 领域事件发布器
interface DomainEventPublisher {
fun publish(event: Any) // 发布单个事件
fun publishAll(events: List<Any>) // 批量发布事件
}
@Component
class SpringDomainEventPublisher(
private val eventBus: EventBus
) : DomainEventPublisher {
override fun publish(event: Any) {
eventBus.publish(event)
}
override fun publishAll(events: List<Any>) {
events.forEach {
event ->
eventBus.publish(event)
}
}
}
🎯 实际使用场景
场景:用户注册成功
1. 定义事件
data class UserRegisteredEvent(
val userId: String,
val email: String,
val registrationTime: LocalDateTime = LocalDateTime.now()
)
2. 用户注册服务发布事件
@Service

最低0.47元/天 解锁文章
727

被折叠的 条评论
为什么被折叠?



