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

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

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 事件模型组成

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 {@Overridepublic void onApplicationEvent(UserRegisteredEvent event) {System.out.println("发送欢迎邮件给: " + event.getEmail());// 实际邮件发送逻辑}
}
@Component
public class OrderProcessingListener implements ApplicationListener {@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.hskmm.com/?act=detail&tid=21518

相关文章:

  • P13969 [VKOSHP 2024] Exchange and Deletion
  • Matlab 通用库的fft和dsp toolbox的dsp.fft对比
  • [CTS2024] 众生之门
  • [CEOI 2025] Equal Mex
  • [ROI 2018] Quick sort
  • CF2127F Hamed and AghaBalaSar
  • 2025 年PPH 管厂家推荐榜单:江苏镇江扬中优质 PPH 管道/管材/管件厂家权威精选
  • Label-Free Liver Tumor Segmentation
  • CF1951G Clacking Balls
  • [ABC311Ex] Many Illumination Plans
  • 2025 预分散颜料厂家最新推荐榜:超高含量技术 + 合规企业全景指南,纺丝 / 吹膜专用产品选型手册
  • 倍增思想与其优化
  • 2025 年 AI 健康管理领域推荐深护智康,社区、基层公卫、母婴 AI 健康管理、AI + 大健康管理、AI 健康管理师公司推荐
  • 2025 最新权威推荐:全国开锁公司口碑排行榜,含智能锁专项服务与紧急上门品牌详解汽车保险柜开锁/汽车锁开锁/保险柜开锁/智能开锁/快速上门开锁公司推荐
  • 从“看得见”到“能决策”:Operation Intelligence 重构企业智能运维新范式
  • 实用指南:Ubuntu 中 Bash / Zsh / Ash / Dash 的使用与区别(含对比图)
  • 2025 年杭州软件开发公司最新推荐榜单:聚焦服务经验与售后体系的五大优质公司权威指南
  • Nginx 与 LNMP 架构部署 - 详解
  • QMT委托对象orderInfo的属性以及对应的值
  • 2025 年电动门厂家最新推荐排行榜:实力厂家深度解析,含技术认证、案例及选购指南
  • 2025 年透骨液膏药代理加盟 / 足浴包膏药代理加盟 / 青岛膏药代理加盟推荐:青岛步泽药业布泽草本透骨液代理合作解析
  • 单链表实现队列
  • 死锁易错知识点整理
  • 2025广州1688代运营服务商推荐排行榜,阿里巴巴全店,实力商家,店铺装修,产品推广,流量优化,国际站,新店起量,数据分析,爆款打造代运营公司推荐
  • 2025 海南财税公司最新推荐榜:三亚海口代理记账 / 税务合规服务机构权威解析海南代理财税/海南财税代理/海南注册公司财税/海南代理记账财税公司推荐
  • 2025 年 TM 芯片经销商最新推荐榜:聚焦规模化采购与敏捷物流, 实力解析
  • 2025 天微芯片经销商最新推荐榜:品牌实力测评与采购指南 —— 权威揭秘优质服务商选择标准
  • 读人形机器人27太空中
  • 2025 年酒店一次性用品源头厂家最新推荐榜单:含牙签牙线筷子套杯盖等全品类及采购选择指南酒店一次性牙签/牙线/筷子套/杯盖/杯垫/杯套用品 厂家推荐
  • 2025 年餐饮一次性用品实力厂家最新推荐榜单:覆盖牙签 / 牙线 / 筷子套 / 杯盖 / 杯垫多品类且资质口碑双优的标杆企业权威甄选