spring事件监听基于观察者模式,通过applicationevent和applicationlistener(或@eventlistener)实现松耦合通信:自定义事件需继承applicationevent,监听器用@component管理并支持@eventlistener、applicationlistener接口或动态注册,事件由applicationeventpublisher发布,默认同步执行。

Spring 的事件监听机制基于观察者模式,通过 ApplicationEvent 和 ApplicationListener(或 @EventListener)实现松耦合的组件通信。核心是:自定义事件继承 ApplicationEvent,监听器订阅该事件,事件发布时由 Spring 容器自动触发监听逻辑。
定义自定义事件(继承 ApplicationEvent)
所有 Spring 事件必须是 ApplicationEvent 的子类。通常封装业务数据,构造器中调用 super(source),source 一般传入事件发起者(如当前对象、Service 实例,或直接用 this):
public class UserRegisteredEvent extends ApplicationEvent {
private final String username;
private final String email;
public UserRegisteredEvent(Object source, String username, String email) {
super(source); // source 必须非 null
this.username = username;
this.email = email;
}
// getter...
}
编写监听器(三种常用方式)
监听器无需实现特定接口即可工作,但需被 Spring 管理(加 @Component):
-
@EventListener 注解(推荐):最简洁,支持条件过滤、异步执行(配合
@Async)和泛型推导:
@Component
public class UserRegistrationListener {
@EventListener
public void handleUserRegistered(UserRegisteredEvent event) {
System.out.println("发送欢迎邮件给:" + event.getEmail());
}
// 条件监听(仅当用户名长度 > 5 时触发)
@EventListener(condition = "#event.username.length() > 5")
public void handleLongUsername(UserRegisteredEvent event) {
System.out.println("长用户名用户:" + event.getUsername());
}
}
- 实现 ApplicationListener 接口:较老方式,类型安全但不够灵活:
@Component
public class SmsNotificationListener implements ApplicationListener<userregisteredevent> {
@Override
public void onApplicationEvent(UserRegisteredEvent event) {
System.out.println("发送短信通知:" + event.getPhone());
}
}</userregisteredevent>
- 使用 ApplicationEventPublisher 手动注册(不常用):适合运行时动态添加监听器,一般用于框架扩展。
发布事件(注入 ApplicationEventPublisher)
在任意 Spring Bean 中注入 ApplicationEventPublisher,调用 publishEvent() 即可触发广播:
@Service
public class UserService {
@Autowired
private ApplicationEventPublisher eventPublisher;
public void registerUser(String username, String email) {
// 保存用户逻辑...
// ...
// 发布事件(事件对象自动被 Spring 捕获并分发)
eventPublisher.publishEvent(new UserRegisteredEvent(this, username, email));
}
}
注意:publishEvent() 是同步调用,默认所有监听器按注册顺序依次执行;如需异步,监听方法上加 @Async 并开启异步支持(@EnableAsync)。
关键细节与注意事项
- 事件对象的
source参数不能为null,否则抛IllegalArgumentException;建议传入当前 Bean 实例(如this)或上下文相关对象。 - 监听器方法参数类型即事件类型,Spring 通过泛型或参数类型匹配事件;多个监听器可监听同一事件。
- 默认事件传播是同步的,若某监听器抛异常,会中断后续监听器执行(除非捕获处理);异步监听需自行处理异常。
- Spring 5.3+ 支持泛型事件(如
UserEvent<t></t>),配合@EventListener可更精准匹配。
Java免费学习笔记:立即使用
解锁 Java 大师之旅:从入门到精通的终极指南











