Reactor 事件流 vs. Spring 事件 ApplicationEvent
- Reactor 事件流 vs. Spring 事件 (`ApplicationEvent`)
Reactor 事件流 vs. Spring 事件 (ApplicationEvent
)
1️⃣ 核心区别
特性 | Spring ApplicationEvent |
Reactor Flux /Sinks.Many |
---|---|---|
数据处理方式 | 一次性事件(同步或异步) | 流式处理(持续事件流) |
是否支持多个订阅者 | ✅ 支持(多个 @EventListener ) |
✅ 支持(Sinks.Many 广播) |
是否支持流式操作 | ❌ 不支持 | ✅ 支持(map() , filter() , zip() ) |
是否支持回放历史事件 | ❌ 不支持 | ❌(默认不支持,但可用 ReplayProcessor ) |
适用场景 | 业务事件通知(用户注册、订单支付) | 高吞吐数据流处理(日志、消息队列、WebFlux) |
2️⃣ Spring 事件 (ApplicationEvent
)
🔹 特点
- 适用于应用内部组件通信,解耦业务逻辑。
- 默认同步,可使用
@Async
进行异步处理。 - 一次性事件,无法流式处理。
✅ 示例:Spring 事件发布 & 监听
1️⃣ 定义事件
public class UserRegisteredEvent extends ApplicationEvent {
private final String username;
public UserRegisteredEvent(Object source, String username) {
super(source);
this.username = username;
}
public String getUsername() {
return username; }
}
2️⃣ 发布事件
@Component
public class UserService {
@Autowired
private ApplicationEventPublisher eventPublisher;
public void registerUser(String username) {
eventPublisher.publishEvent(new UserRegisteredEvent(this, username));
}
}
3️⃣ 监听事件
@Component
public class WelcomeEmailListener {
@EventListener
public void handleUserRegisteredEvent(UserRegisteredEvent event) {
System.out.println("📧 发送欢迎邮件给: " + event.getUsername());
}
}
可多个 @EventListener
监听同一个事件,同时触发
@Component
public class LoggingListener {
@EventListener
public void logUserRegisteredEvent(UserRegisteredEvent event) {
System.out.println("📜 记录日志: 用户 " + event.getUsername() + " 已注册");
}
}
@Component
public class PointsRewardListener {
@EventListener
public void giveWelcomePoints(UserRegisteredEvent event) {
System.out.println("🎁 赠送 100 积分给: " + event.getUsername());
}
}
🔹 进阶:异步监听
🔹 1️⃣ 监听器可以指定异步 需要启用 Spring 异步,@EnableAsync
@Async
@EventListener
public void sendWelcomeEmail(UserRegisteredEvent event) {
System.out.println("📧 发送欢迎邮件给: " + event.getUsername() + " [异步]");
}
🔹 2️⃣ 监听多个事件 如果多个事件需要相同的处理逻辑,你可以用 classes
监听多个事件:
@EventListener(classes = {
UserRegisteredEvent.class, OrderPlacedEvent.class})
public void handleMultipleEvents(Object event) {
System.out.println("📢 事件触发: " + event.getClass(