当前位置: 首页 > news >正文

Spring Boot 事件发布与监听 观察者模式的实际应用

文章目录

      • 一、核心概念
      • 1.1 事件模型组成
        • 1.2 核心接口
      • 二、实现方案
        • 1. 创建自定义事件
        • 2. 创建事件监听器
          • 方式1:实现 ApplicationListener 接口
          • 方式2:使用 @EventListener 注解(推荐)
        • 3. 发布事件
      • 三、高级特性
        • 3.1 异步事件处理
        • 3.2 事务绑定事件
        • 3.3 条件事件监听
        • 3.4 事件处理顺序控制
      • 四、注意事项
      • 五、完整示例:用户注册流程
      • 六、总结

Spring Boot 提供了强大的事件发布与监听机制,基于观察者模式实现组件间的解耦通信。

一、核心概念

1.1 事件模型组成

  • 事件(Event):需要传递的消息对象
  • 发布者(Publisher):负责发布事件
  • 监听器(Listener):订阅并处理事件
1.2 核心接口
  • ApplicationEvent:事件基类
  • ApplicationEventPublisher:事件发布接口
  • ApplicationListener:事件监听接口

二、实现方案

1. 创建自定义事件
import org.springframework.context.ApplicationEvent;// 用户注册事件
public class UserRegisteredEvent extends ApplicationEvent {private final String username;private final String email;public UserRegisteredEvent(Object source, String username, String email) {super(source);this.username = username;this.email = email;}// Getterspublic String getUsername() { return username; }public String getEmail() { return email; }
}// 订单创建事件
public class OrderCreatedEvent extends ApplicationEvent {private final Long orderId;private final BigDecimal amount;public OrderCreatedEvent(Object source, Long orderId, BigDecimal amount) {super(source);this.orderId = orderId;this.amount = amount;}// Getterspublic Long getOrderId() { return orderId; }public BigDecimal getAmount() { return amount; }
}
2. 创建事件监听器
方式1:实现 ApplicationListener 接口
import org.springframework.context.ApplicationListener;
import org.springframework.stereotype.Component;@Component
public class EmailNotificationListener implements ApplicationListener<UserRegisteredEvent> {@Overridepublic void onApplicationEvent(UserRegisteredEvent event) {System.out.println("发送欢迎邮件给: " + event.getEmail());// 实际邮件发送逻辑}
}@Component
public class OrderProcessingListener implements ApplicationListener<OrderCreatedEvent> {@Overridepublic void onApplicationEvent(OrderCreatedEvent event) {System.out.println("处理订单 #" + event.getOrderId());// 订单处理逻辑}
}
方式2:使用 @EventListener 注解(推荐)
import org.springframework.context.event.EventListener;
import org.springframework.scheduling.annotation.Async;
import org.springframework.stereotype.Component;@Component
public class CompositeEventListener {// 监听用户注册事件@EventListenerpublic void handleUserRegistered(UserRegisteredEvent event) {System.out.println("记录用户注册日志: " + event.getUsername());// 日志记录逻辑}// 监听订单创建事件(异步执行)@Async@EventListenerpublic void handleOrderCreatedAsync(OrderCreatedEvent event) {System.out.println("异步处理订单 #" + event.getOrderId());// 耗时操作}// 监听多个事件@EventListener(classes = {UserRegisteredEvent.class, OrderCreatedEvent.class})public void handleMultipleEvents(ApplicationEvent event) {if (event instanceof UserRegisteredEvent) {System.out.println("处理用户注册事件");} else if (event instanceof OrderCreatedEvent) {System.out.println("处理订单创建事件");}}
}
3. 发布事件
import org.springframework.context.ApplicationEventPublisher;
import org.springframework.stereotype.Service;@Service
public class UserService {private final ApplicationEventPublisher eventPublisher;public UserService(ApplicationEventPublisher eventPublisher) {this.eventPublisher = eventPublisher;}public void registerUser(String username, String email) {// 用户注册逻辑...// 发布用户注册事件eventPublisher.publishEvent(new UserRegisteredEvent(this, username, email));}
}@Service
public class OrderService {private final ApplicationEventPublisher eventPublisher;public OrderService(ApplicationEventPublisher eventPublisher) {this.eventPublisher = eventPublisher;}public void createOrder(Long orderId, BigDecimal amount) {// 订单创建逻辑...// 发布订单创建事件eventPublisher.publishEvent(new OrderCreatedEvent(this, orderId, amount));}
}

三、高级特性

3.1 异步事件处理
import org.springframework.context.annotation.Bean;
import org.springframework.context.annotation.Configuration;
import org.springframework.core.task.TaskExecutor;
import org.springframework.scheduling.annotation.EnableAsync;
import org.springframework.scheduling.concurrent.ThreadPoolTaskExecutor;@Configuration
@EnableAsync
public class AsyncConfig {@Bean(name = "eventTaskExecutor")public TaskExecutor taskExecutor() {ThreadPoolTaskExecutor executor = new ThreadPoolTaskExecutor();executor.setCorePoolSize(5);executor.setMaxPoolSize(10);executor.setQueueCapacity(25);executor.setThreadNamePrefix("Event-Executor-");return executor;}
}// 在监听器中使用
@Component
public class AsyncEventListener {@Async("eventTaskExecutor") // 指定线程池@EventListenerpublic void handleAsyncEvent(UserRegisteredEvent event) {// 异步处理逻辑}
}
3.2 事务绑定事件
import org.springframework.transaction.event.TransactionalEventListener;
import org.springframework.transaction.event.TransactionPhase;@Component
public class TransactionalEventListener {// 在事务提交后执行@TransactionalEventListener(phase = TransactionPhase.AFTER_COMMIT)public void handleAfterCommit(OrderCreatedEvent event) {System.out.println("事务提交后处理订单事件");}// 在事务回滚后执行@TransactionalEventListener(phase = TransactionPhase.AFTER_ROLLBACK)public void handleAfterRollback(OrderCreatedEvent event) {System.out.println("事务回滚后处理订单事件");}
}
3.3 条件事件监听
@Component
public class ConditionalEventListener {@EventListener(condition = "#event.amount > 1000")public void handleLargeOrder(OrderCreatedEvent event) {System.out.println("处理大额订单: " + event.getOrderId());}@EventListener(condition = "#event.username.startsWith('admin')")public void handleAdminUser(UserRegisteredEvent event) {System.out.println("处理管理员用户注册: " + event.getUsername());}
}
3.4 事件处理顺序控制
import org.springframework.core.annotation.Order;
import org.springframework.stereotype.Component;@Component
public class OrderedEventListeners {@Order(1)@EventListenerpublic void firstListener(UserRegisteredEvent event) {System.out.println("第一个监听器执行");}@Order(2)@EventListenerpublic void secondListener(UserRegisteredEvent event) {System.out.println("第二个监听器执行");}@Order(Ordered.LOWEST_PRECEDENCE) // 最低优先级@EventListenerpublic void lastListener(UserRegisteredEvent event) {System.out.println("最后一个监听器执行");}
}

四、注意事项

  1. 事件命名规范

    • 使用过去时态表示已完成的事件:UserRegisteredEvent, OrderCreatedEvent
    • 保持事件类名清晰表达业务含义
  2. 事件内容设计

    • 包含足够的信息供监听器处理
    • 避免包含大型对象或敏感数据
    • 保持事件对象不可变
  3. 错误处理

    @EventListener
    public void handleEventWithError(UserRegisteredEvent event) {try {// 业务逻辑} catch (Exception e) {// 记录错误并处理System.err.println("处理事件失败: " + e.getMessage());// 可选择重试或通知监控系统}
    }
    
  4. 性能优化

    • 对于耗时操作使用异步监听
    • 根据业务需求合理设置线程池参数
    • 避免在事件处理中执行阻塞操作

五、完整示例:用户注册流程

// 事件定义
public class UserRegisteredEvent extends ApplicationEvent {private final User user;public UserRegisteredEvent(Object source, User user) {super(source);this.user = user;}public User getUser() { return user; }
}// 服务层
@Service
public class UserService {private final ApplicationEventPublisher eventPublisher;private final UserRepository userRepository;public UserService(ApplicationEventPublisher eventPublisher, UserRepository userRepository) {this.eventPublisher = eventPublisher;this.userRepository = userRepository;}@Transactionalpublic User registerUser(UserRegistrationDto dto) {User user = new User(dto.getUsername(), dto.getEmail(), dto.getPassword());user = userRepository.save(user);// 发布用户注册事件eventPublisher.publishEvent(new UserRegisteredEvent(this, user));return user;}
}// 监听器
@Component
public class UserEventListeners {// 发送欢迎邮件@Async@EventListenerpublic void sendWelcomeEmail(UserRegisteredEvent event) {User user = event.getUser();emailService.sendWelcomeEmail(user.getEmail(), user.getUsername());}// 初始化用户资料@EventListenerpublic void initUserProfile(UserRegisteredEvent event) {User user = event.getUser();profileService.createDefaultProfile(user.getId());}// 记录注册日志@TransactionalEventListener(phase = TransactionPhase.AFTER_COMMIT)public void logUserRegistration(UserRegisteredEvent event) {User user = event.getUser();auditLogService.log(Action.REGISTER, user.getId(), "用户注册");}// 给推荐人奖励(条件监听)@EventListener(condition = "#event.user.referrerId != null")public void rewardReferrer(UserRegisteredEvent event) {User user = event.getUser();rewardService.giveReferralReward(user.getReferrerId(), user.getId());}
}

六、总结

Spring Boot 事件机制提供了强大的解耦能力,通过事件驱动架构可以实现:

  1. 业务解耦:分离核心业务与辅助功能
  2. 可扩展性:轻松添加新功能而不修改现有代码
  3. 异步处理:提高系统响应速度
  4. 事务管理:精确控制事件处理时机

在实际应用中,应根据业务需求合理选择同步/异步处理、事务绑定等特性,并注意事件对象的合理设计和错误处理机制。

http://www.dtcms.com/a/406055.html

相关文章:

  • Sui Stack Messaging SDK:为 Web3 打造可编程通信
  • 光谱相机的未来趋势
  • 【Java后端】《Spring Boot Starter 原理详解》博客
  • 设计与绘制一个网站首页同学录wordpress
  • Vue2的生命周期
  • MySQL学习笔记04:MySQL InnoDB存储引擎核心机制深度解析
  • 中国企业网站建设响应式网站管理
  • 遇到不会的事,先写一写
  • 心理咨询 网站模版嘉兴网站建设技术开发
  • 【面试】Kafka / RabbitMQ / ActiveMQ
  • 新网站建设的工作总结文化网站建设需要的功能
  • 11.WPF 的命令处理事件--参数介绍
  • 旅游管理虚拟仿真实训室:打通理论与实践壁垒
  • FreeLong-无需训练即可延长视频生成时长
  • Lynx:新一代个性化视频生成模型,单图即可生成视频,重新定义身份一致性与视觉质量
  • 关于机器视觉中的”果冻效应“讲解:全局曝光 vs 卷帘曝光
  • 如何做百度的网站网站开发技术的雏形 cgi
  • 织梦医院网站源码6731官方网站下载
  • Transformer模型/注意力机制/目标检测/语义分割/图神经网络/强化学习/生成式模型/自监督学习/物理信息神经网络等
  • 公司网站 域名seo快速提高网站转化率
  • Planner Agent 和 PlanReAct 的区别
  • Google Play合规指南:您的应用所使用的原生库不支持 16 KB 内存页面大小.快速解决
  • 什么是覆盖索引?PostgreSQL 是否支持覆盖索引?
  • 谨慎地迭代函数所收到的参数 (Effective Python 第31条)
  • ESP32 NTC热敏电阻测温全攻略:从ADC采样到线性插值算法详解
  • 介绍 τ-bench:一个评估语言智能体在真实场景中与人、工具、规则交互能力的新基准
  • 网站模版建设教程效果好网站建设哪家好
  • 20-for循环案例练习
  • 华策影视 AIGC 实战:剧本分镜 1 小时生成,影视创作告别熬夜改稿时代
  • 移动固态硬盘无法被电脑识别怎么办?