读完本文,你能做到:敢用、会用、讲得明明白白。 语速不快,信息全到。笑点有,废话无。
🧩 事件是什么?一句话 事件 = 我说一句,你听到了你再做事。
👉 发布事件的人 不关心 谁来处理。 👉 处理事件的人 不耦合 谁发的。
这就是解耦。 也是优雅。
👫 场景类比(超级好记)
你喊:“开饭啦!”(事件)
你妈、你爸、你弟 都可能来吃 (监听器)
你不管谁来,也不关心来不来。
Spring 就是按照这个来的。
🎭 主角三件套
名称
干啥的
类比
自定义事件
你要说的话
开饭啦!
ApplicationEventPublisher
扩音器
帮你喊出去
@EventListener
谁听到了谁行动
各自来吃饭
🎯 示例(最小可运行示例) ① 定义事件(随便一个类即可) 1 2 3 4 5 public class UserRegisteredEvent { private final Long userId; public UserRegisteredEvent(Long userId) { this.userId = userId; } public Long getUserId() { return userId; } }
② 发布事件(谁触发谁发布) 1 2 3 4 5 6 7 8 9 10 @Component public class UserService { @Autowired private ApplicationEventPublisher publisher; public void register(Long id) { System.out.println("✅ 用户注册成功: " + id); publisher.publishEvent(new UserRegisteredEvent(id)); } }
谁需要让别人知道,就谁发事件。
③ 监听事件(谁关心谁就监听) 1 2 3 4 5 6 7 @Component public class WelcomeMailListener { @EventListener public void onUserRegistered(UserRegisteredEvent e) { System.out.println("📩 欢迎邮件已发送给用户: " + e.getUserId()); } }
监听的关键点是参数类型决定了监听哪个事件。
🚀 启动后执行一次(内置事件) Spring Boot 启动成功自动发布 ApplicationReadyEvent。
1 2 3 4 5 6 7 @Component public class AppStarted { @EventListener public void onReady(ApplicationReadyEvent e) { System.out.println("🎉 服务已就绪,开始搬砖!"); } }
📌 这个不用你发事件。Spring 会自动发。
⚡ 让监听异步执行(不堵主线程) 默认事件监听是同步 的(你不说,我也不忍)。
想异步?两个操作:
① 开启异步 1 2 3 @EnableAsync @Configuration public class AsyncConfig {}
② 监听器上加 @Async 1 2 3 4 5 6 7 8 9 10 11 @Component public class WelcomeMailListener { @Async @EventListener public void onUserRegistered(UserRegisteredEvent e) { System.out.println("📩(异步) 准备发邮件... " + Thread.currentThread().getName()); try { Thread.sleep(2000); } catch (Exception ignored) {} System.out.println("✅ 邮件发送完成!"); } }
输出示例:
1 2 3 ✅ 用户注册成功: 1 -- main 📩(异步) 准备发邮件... event-async-1 ✅ 邮件发送完成!
主线程不被阻塞。
🧵 自定义线程池(生产建议) 1 2 3 4 5 6 7 8 9 10 11 12 13 14 @EnableAsync @Configuration public class AsyncPoolConfig { @Bean("eventExecutor") public Executor pool() { ThreadPoolTaskExecutor exec = new ThreadPoolTaskExecutor(); exec.setCorePoolSize(4); exec.setMaxPoolSize(8); exec.setQueueCapacity(200); exec.setThreadNamePrefix("evt-"); exec.initialize(); return exec; } }
1 2 3 @Async("eventExecutor") @EventListener public void onUserRegistered(UserRegisteredEvent e) {...}
🧠 一句话总复盘(建议截图)
事件 = 解耦。 谁触发,谁发布;谁关心,谁监听。 启动就绪事件 Spring 自己发。 加 @Async 就能飞,配线程池才能稳。