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