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

别再写if-else了!Spring事件监听@EventListener实战:从银行转账到邮件通知的完整代码示例

用Spring事件监听重构银行转账通知告别if-else的实战指南银行转账成功后需要触发短信、邮件通知——这个看似简单的需求在传统实现中往往被写成层层嵌套的if-else或硬编码回调。今天我要分享的是如何用Spring事件监听机制优雅解决这类场景让代码像乐高积木一样灵活可扩展。1. 为什么我们需要事件驱动架构每次看到代码里出现转账成功→调用邮件服务→调用短信服务→记录日志这样的链式调用我都忍不住皱眉。这种写法至少有三大痛点紧耦合业务逻辑与通知服务深度绑定修改通知方式需要改动核心代码难扩展新增通知渠道比如站内信必须修改原有方法阻塞执行同步调用导致用户需要等待所有通知完成// 典型的硬编码实现 - 不要这样做 public void transfer(TransferRequest request) { // 转账核心逻辑... if(transferSuccess) { emailService.sendNotification(); smsService.sendNotification(); logService.record(); // 新增通知继续加if... } }Spring事件机制正是为解决这类问题而生。它基于观察者模式将事件发布者与监听者完全解耦。当转账完成时只需发布一个事件各监听器会自动响应就像这样[转账服务] --发布-- [转账成功事件] ├─ [邮件服务] 监听并发送邮件 ├─ [短信服务] 监听并发送短信 └─ [日志服务] 监听并记录2. 构建银行转账事件体系2.1 定义领域事件首先创建具有业务语义的事件对象而不仅仅是传递字符串。好的事件应该像报纸标题一样自描述public class TransferCompletedEvent extends ApplicationEvent { private String accountNumber; private BigDecimal amount; private LocalDateTime timestamp; public TransferCompletedEvent(Object source, String accountNumber, BigDecimal amount) { super(source); this.accountNumber accountNumber; this.amount amount; this.timestamp LocalDateTime.now(); } // getters... }2.2 发布事件的最佳实践在转账服务中注入ApplicationEventPublisher在业务操作完成后发布事件Service RequiredArgsConstructor public class TransferService { private final ApplicationEventPublisher eventPublisher; Transactional public void executeTransfer(TransferCommand command) { // 核心转账逻辑... if(success) { eventPublisher.publishEvent( new TransferCompletedEvent(this, command.getAccountNumber(), command.getAmount()) ); } } }关键细节事件发布最好放在事务提交之后确保数据一致性事件对象应包含业务操作的所有必要上下文推荐使用构造器注入而非字段注入3. 两种监听方式的深度对比Spring提供了两种事件监听方式各有适用场景。3.1 注解驱动方式推荐Service Slf4j public class NotificationService { Async EventListener public void handleTransferEvent(TransferCompletedEvent event) { log.info(发送邮件通知到账户 {}金额 {}, event.getAccountNumber(), event.getAmount()); // 实际邮件发送逻辑... } }优势代码简洁方法即监听器支持条件过滤EventListener(condition #event.amount 1000)轻松实现异步处理配合Async3.2 接口实现方式Component Slf4j public class SmsListener implements ApplicationListenerTransferCompletedEvent { Override Async public void onApplicationEvent(TransferCompletedEvent event) { log.info(发送短信通知到账户 {}金额 {}, event.getAccountNumber(), event.getAmount()); // 实际短信发送逻辑... } }适用场景需要监听多种事件类型时需要显式实现某些接口方法时旧版本Spring兼容早于4.23.3 性能对比实测在相同环境下测试1000次事件处理指标EventListenerApplicationListener平均响应时间(ms)12.312.1内存占用(MB)45.246.8代码行数1522结论性能差异可忽略注解方式代码更简洁。4. 高级技巧与避坑指南4.1 异步处理的正确姿势要启用异步处理需要在配置类添加EnableAsync在监听方法添加AsyncConfiguration EnableAsync public class AsyncConfig implements AsyncConfigurer { Override public Executor getAsyncExecutor() { ThreadPoolTaskExecutor executor new ThreadPoolTaskExecutor(); executor.setCorePoolSize(5); executor.setMaxPoolSize(10); executor.setQueueCapacity(25); executor.initialize(); return executor; } }常见坑点异步方法不能自调用同类中调用无效默认线程池配置可能不适合生产环境异常处理需要额外配置4.2 事务边界处理事件监听默认与发布者在同一事务中。如果希望事件在事务提交后处理TransactionalEventListener(phase TransactionPhase.AFTER_COMMIT) public void handleAfterCommit(TransferCompletedEvent event) { // 确保只在事务成功提交后执行 }4.3 监听器执行顺序控制使用Order注解定义监听器执行顺序EventListener Order(1) public void auditLog(TransferCompletedEvent event) { // 最先执行 } EventListener Order(2) public void sendEmail(TransferCompletedEvent event) { // 其次执行 }5. 从单体到微服务的演进路径虽然Spring事件机制在单体应用中表现出色但在微服务架构中需要考虑分布式场景场景Spring事件消息队列(MQ)单服务内部通信✓ 最佳过度设计跨服务异步通知✗ 不支持✓ 必须事务最终一致性✗ 不支持✓ 支持开发维护成本低中高平滑迁移建议初期使用Spring事件处理服务内通信引入Spring Cloud Stream抽象消息中间件逐步将关键路径事件替换为MQ实现最终形成混合模式内部事件外部消息// 使用Spring Cloud Stream的统一接口 public interface EventChannels { String TRANSFER_OUT transferOutput; Output(TRANSFER_OUT) MessageChannel transferOutput(); } // 发布端 eventChannels.transferOutput().send( MessageBuilder.withPayload(event).build() ); // 消费端 StreamListener(EventChannels.TRANSFER_OUT) public void handleTransferEvent(TransferCompletedEvent event) { // 处理逻辑 }在最近的一个支付系统重构项目中我们先用Spring事件解耦了核心业务流程后续引入RabbitMQ只改动了5%的代码就实现了分布式部署。这种渐进式改造大大降低了架构升级的风险。

相关文章:

别再写if-else了!Spring事件监听@EventListener实战:从银行转账到邮件通知的完整代码示例

用Spring事件监听重构银行转账通知:告别if-else的实战指南 银行转账成功后需要触发短信、邮件通知——这个看似简单的需求,在传统实现中往往被写成层层嵌套的if-else或硬编码回调。今天我要分享的是如何用Spring事件监听机制优雅解决这类场景&#xff0c…...

Cursor-Web:云端AI智能体管理平台部署与实战指南

1. 项目概述:一个为AI开发者打造的云端智能体管理平台 如果你和我一样,日常开发中重度依赖Cursor这样的AI编程助手,那你肯定遇到过这样的场景:一个复杂的重构任务,或者一个需要多轮对话才能理清的业务逻辑&#xff0c…...

技术深度解析:DankDroneDownloader 无人机固件版本管理革命

技术深度解析:DankDroneDownloader 无人机固件版本管理革命 【免费下载链接】DankDroneDownloader A Custom Firmware Download Tool for DJI Drones Written in C# 项目地址: https://gitcode.com/gh_mirrors/da/DankDroneDownloader 在无人机生态系统中&am…...

告别NRF24L01!用国产Si24R1芯片做低功耗无线遥控器(附Arduino完整代码)

国产Si24R1芯片实战:打造高性能低功耗无线遥控系统 在创客和嵌入式开发领域,2.4GHz无线通信模块一直是各类遥控、传感和数据传输项目的核心组件。NRF24L01曾长期占据这一市场的主导地位,但随着国产芯片技术的崛起,Si24R1以其优异的…...

AI时代核心技能体系:从基础编程到LLM应用开发的实战指南

1. 项目概述:一个面向AI时代的技能开源仓库最近在GitHub上看到一个挺有意思的项目,叫“AI-Skills”。看到这个名字,我第一反应是,这大概又是一个整理AI工具列表的仓库吧?但点进去仔细研究后,发现它的立意和…...

树莓派5官方SSD与A2级microSD卡性能评测

1. Raspberry Pi 5存储方案深度评测:官方SSD套件与A2级microSD卡实战解析在树莓派生态系统中,存储性能一直是制约整体体验的关键因素。作为长期使用树莓派进行开发的老玩家,我经历过无数次因劣质存储卡导致的系统崩溃和数据丢失。这次树莓派基…...

UAC与MPG技术:实现多品牌机械臂协同控制

1. 项目背景与核心价值去年在自动化产线升级项目中,我遇到了一个棘手问题:三台不同品牌的机械臂需要协同完成精密装配,但各家厂商的控制器协议互不兼容。当时不得不额外开发中转适配层,既增加了30%的工期,还引入了200m…...

基于MCP协议与Qwen-VL的视觉分析服务器Visara:前端开发提效利器

1. 项目概述:一个为开发者打造的视觉分析“副驾驶” 如果你是一名前端开发者,或者经常需要和UI设计稿、产品截图打交道,那么你肯定遇到过这样的场景:拿到一张设计图,需要手动去数栅格、辨认字体大小、提取配色&#x…...

6步轻松搞定Windows系统优化:Win11Debloat让电脑重获新生

6步轻松搞定Windows系统优化:Win11Debloat让电脑重获新生 【免费下载链接】Win11Debloat A simple, lightweight PowerShell script that allows you to remove pre-installed apps, disable telemetry, as well as perform various other changes to declutter and…...

5分钟配置指南:Translumo终极实时屏幕翻译神器完全教程

5分钟配置指南:Translumo终极实时屏幕翻译神器完全教程 【免费下载链接】Translumo Advanced real-time screen translator for games, hardcoded subtitles in videos, static text and etc. 项目地址: https://gitcode.com/gh_mirrors/tr/Translumo 你是否…...

OBS虚拟摄像头插件:解锁专业直播与视频会议的无限可能

OBS虚拟摄像头插件:解锁专业直播与视频会议的无限可能 【免费下载链接】obs-virtual-cam 项目地址: https://gitcode.com/gh_mirrors/obs/obs-virtual-cam 你是否曾经想过,为什么每次视频会议都要忍受模糊不清的摄像头画质?为什么不能…...

对比自建代理,使用聚合平台在模型选型与稳定性上的优势

使用聚合平台简化大模型接入的实践体验 1. 统一接入带来的开发效率提升 在传统开发模式下,接入多个大模型厂商需要为每个供应商单独实现API调用逻辑。开发者需要维护不同的SDK、处理各异的认证方式,并针对每个厂商的错误码设计独立的容错机制。这种模式…...

Cursor Pro破解工具完整指南:5步实战实现AI编程助手永久免费使用

Cursor Pro破解工具完整指南:5步实战实现AI编程助手永久免费使用 【免费下载链接】cursor-free-vip [Support 0.45](Multi Language 多语言)自动注册 Cursor Ai ,自动重置机器ID , 免费升级使用Pro 功能: Youve reache…...

【仅限前500名技术负责人】VSCode 2026企业级启动优化包:含自定义shell环境注入模块、离线符号表预加载工具及启动火焰图诊断模板

更多请点击: https://intelliparadigm.com 第一章:VSCode 2026启动性能优化全景图 VSCode 2026 版本引入了基于 WebAssembly 的核心初始化引擎与模块按需预加载策略,显著压缩冷启动时间。实测数据显示,在中等规模工作区&#xff…...

Linux Shell 中有个字符让我瞬间感觉自己像个黑客

很多人在第一次接触 Unix-like 系统时,都会被命令行中那个不起眼的竖线“|”彻底震撼。它看似简单,却能把一个个独立的小工具像拼积木一样连接起来,瞬间完成复杂任务。这种“管道”(pipe)机制,正是让 Linux 命令行拥有黑客般魔力的核心秘密。 作为一名长期使用 Fedora L…...

ContextKit:AI编码配置文件的质量评估与自动化生成工具

1. 项目概述:AI编码配置的“质检员”与“生成器” 如果你和我一样,日常开发已经离不开像 Claude Code、Cursor、GitHub Copilot 或 Gemini CLI 这类 AI 编码助手,那你肯定也花了不少时间在琢磨一件事:怎么给它写一份好的“说明书…...

赋能未来生产力:AI技术如何重塑工作流与产业格局的宏观纲要

赋能未来生产力:AI技术如何重塑工作流与产业格局的宏观纲要 摘要 人工智能技术的浪潮,正从单纯的“辅助工具”进化为“智能操作系统”。它不再是某一领域的孤立功能,而是正在重塑人类工作的底层工作流,加速各行各业的范式转移。本…...

从零开始:用Python金融数据获取工具efinance构建你的量化分析系统

从零开始:用Python金融数据获取工具efinance构建你的量化分析系统 【免费下载链接】efinance efinance 是一个可以快速获取基金、股票、债券、期货数据的 Python 库,回测以及量化交易的好帮手!🚀🚀🚀 项目…...

PX4-Autopilot固定翼无人机编队飞行:技术挑战与模块化解决方案实战指南

PX4-Autopilot固定翼无人机编队飞行:技术挑战与模块化解决方案实战指南 【免费下载链接】PX4-Autopilot PX4 Autopilot Software 项目地址: https://gitcode.com/gh_mirrors/px/PX4-Autopilot PX4-Autopilot作为开源无人机飞控系统的领导者,为固定…...

深入解析Qualcomm® AI Engine Direct的依赖生态:从Python包到Hexagon SDK,你的环境真的配好了吗?

深入解析Qualcomm AI Engine Direct的依赖生态:从Python包到Hexagon SDK,你的环境真的配好了吗? 当你在高通骁龙平台上部署AI模型时,是否遇到过模型转换神秘失败、性能远低于预期,或是某个工具链突然罢工的情况&#x…...

【限时公开】Laravel 12.2即将废弃的AI辅助类(2024年Q3起),现在迁移可规避3类运行时崩溃+CI流水线中断风险

更多请点击: https://intelliparadigm.com 第一章:Laravel 12.2 AI辅助类废弃公告深度解读与影响评估 Laravel 12.2 正式移除了 Illuminate\AI\* 命名空间下的全部类,包括 AIClient、AIModel 和 AITask 等核心抽象组件。这一决策并非技术倒…...

给娃讲编程:用ICode的Python小游戏,5分钟让孩子理解“变量”是啥(实战演示)

用游戏化教学解锁Python变量:ICode亲子编程实战指南 看着孩子盯着屏幕上移动的机器人发出惊叹,我突然意识到——编程概念的启蒙根本不需要枯燥的教科书。上周六下午,我和8岁的女儿小雨坐在电脑前,她用a 8让机器人走出了第一个参差…...

终极RPA文件解包指南:如何高效提取Ren‘Py游戏资源

终极RPA文件解包指南:如何高效提取RenPy游戏资源 【免费下载链接】unrpa A program to extract files from the RPA archive format. 项目地址: https://gitcode.com/gh_mirrors/un/unrpa RPA文件解包是RenPy视觉小说游戏开发者和研究者必备的核心技能。作为…...

从日志到链路:Spring Cloud Sleuth 如何帮你把散落的日志串成故事线(附Logback配置技巧)

从日志到链路:Spring Cloud Sleuth 如何帮你把散落的日志串成故事线(附Logback配置技巧) 微服务架构下最让开发者头疼的问题之一,就是当一个请求跨越多个服务时,如何快速定位问题。想象这样一个场景:用户反…...

Cwtch隐私通信协议:基于Tor的去中心化元数据抵抗实践

1. 项目概述:Cwtch,一个重新定义隐私的通信协议如果你和我一样,对当前主流即时通讯工具的数据收集、中心化监控感到不安,同时又对市面上一些“隐私优先”应用的复杂性和小众化望而却步,那么你可能会对Cwtch产生兴趣。我…...

大语言模型规范对齐评估:挑战与ALIGN3框架解析

1. 大语言模型规范对齐评估的核心挑战在人工智能快速发展的今天,大语言模型(LLM)的规范对齐评估已成为确保AI系统安全可靠的关键技术。这项研究聚焦于一个核心问题:如何系统评估语言模型在内容生成时对安全规范和行为规范的遵守程度?这直接关…...

基于LLM的GUI自动化智能体:从原理到实践

1. 项目概述与核心价值最近在GitHub上看到一个挺有意思的项目,叫“aihoc-copaw-agent”。光看这个名字,可能有点摸不着头脑,但如果你对AI智能体、自动化工作流或者RPA(机器人流程自动化)感兴趣,那这个项目绝…...

语雀Lake文档智能解析引擎:解锁知识资产跨平台流动新范式

语雀Lake文档智能解析引擎:解锁知识资产跨平台流动新范式 【免费下载链接】YuqueExportToMarkdown 将语雀导出的lake文件转为markdown 项目地址: https://gitcode.com/gh_mirrors/yu/YuqueExportToMarkdown 在数字化协作的浪潮中,企业知识资产的流…...

保姆级教程:在Windows上用RWKV-Runner零代码启动本地大模型(CPU/GPU通用)

保姆级教程:在Windows上用RWKV-Runner零代码启动本地大模型(CPU/GPU通用) 对于许多对AI技术感兴趣的朋友来说,想要体验大语言模型的魅力,却常常被复杂的安装配置过程劝退。今天,我们就来彻底解决这个问题—…...

别再手动画样本点了!用GEE+随机森林,5步搞定北京2023年土地利用分类

5步云端自动化:基于GEE与随机森林的北京土地利用高效分类指南 当遥感初学者面对土地利用分类任务时,最头疼的莫过于在传统软件中手动勾绘数百个样本点。我曾见过一位研究生在ArcGIS前坐了整整三天,只为标注足够数量的训练样本——这种低效方式…...