spring事件
事件机制的核心概念
-
事件(Event)
- 是一个表示特定动作或状态的对象。
- 在 Spring 中,
ApplicationEvent
是所有事件的基类,开发者可以继承它创建自定义事件对象。 - 例如:鼠标点击、键盘按下等都是事件的具体表现形式。
-
事件监听器(Event Listener)
- 负责接收并处理事件的对象。
- 在 Spring 中,可以通过以下两种方式实现:
- 实现
ApplicationListener
接口。 - 使用
@EventListener
注解的方法。
- 实现
- 监听器的作用是当某个事件触发时,执行相应的逻辑处理。
-
事件发布者(Event Publisher)
- 负责发布事件的对象。
- 在 Spring 中,通过
ApplicationEventPublisher
接口发布事件。 - 任何 Spring Bean 都可以注入该接口,并在需要的时候发布事件。
事件机制的具体流程
以下是事件机制的完整流程:
-
定义事件对象
创建一个继承ApplicationEvent
的自定义事件类,例如MyEvent
。public class MyEvent extends ApplicationEvent { private String name; private String url; public MyEvent(Object source, String name, String url) { super(source); this.name = name; this.url = url; } // Getter 和 Setter 方法 }
-
发布事件
在服务层中注入ApplicationEventPublisher
,并通过其publishEvent()
方法发布事件。@Service public class EventManagerService { @Autowired private ApplicationEventPublisher applicationEventPublisher; public Boolean mouseclick() { applicationEventPublisher.publishEvent(new MyEvent(this, "鼠标点击", "www.bing.com")); return true; } }
-
监听事件
定义一个监听器类,并使用@EventListener
注解指定要监听的事件类型。
@Component
public class MyEventListener {
@EventListener
@Order(1)
public void onApplicationEvent(MyEvent event) {
System.out.println("事件名称" + event.getName() +"跳转链接:"+ event.getName());
openWebPage(event.getUrl());
}
@Order(2)
@EventListener(condition = "#event.url.contains('baidu')")
public void onApplicationEvent2(MyEvent event) {
System.out.println("收到事件2:" + event.getName());
openWebPage(event.getUrl());
}
/**
* 打开网页
*
* @param url
*/
private void openWebPage(String url) {
try {
Runtime.getRuntime().exec("rundll32 url.dll,FileProtocolHandler " + url);
} catch (IOException e) {
throw new RuntimeException(e);
}
}
}
关键点解析
-
事件条件过滤(Condition)
- 在
@EventListener
注解中,可以通过condition
参数设置条件,只有满足条件的事件才会触发对应的方法。 - 示例:
"#event.url.contains('baidu')"
这里的#event
是 SpEL(Spring Expression Language)表达式中的变量,表示当前事件对象。
- 在
-
事件的异步处理
- 默认情况下,事件监听是同步的,即事件发布后会阻塞直到监听器完成处理。
- 如果希望监听器异步执行,可以在
@EnableAsync
注解下配置异步支持:
然后在监听方法上添加@Configuration @EnableAsync public class AsyncConfig implements AsyncConfigurer { // 配置线程池等异步参数 }
@Async
注解:@EventListener @Async public void handleMyEvent(MyEvent event) { // 异步处理逻辑 }
-
事件的广播与多监听器
- 一个事件可以被多个监听器同时监听。
- 监听器的执行顺序默认是无序的,但如果需要控制顺序,可以通过
@Order
注解指定优先级:@Component @Order(1) public class FirstEventListener { @EventListener public void handleEvent(MyEvent event) { System.out.println("第一个监听器处理事件"); } }
-
@Order解析
-
在 Spring 中,@Order 注解用于定义组件的优先级,数值越小优先级越高。因此,@Order(1) 的组件会比 @Order(2) 的组件先执行。
-
具体规则
-
@Order 注解的值决定了组件的执行顺序。
-
数值越小,优先级越高,越早执行。
-
如果没有指定 @Order,默认值为 Ordered.LOWEST_PRECEDENCE(一个非常大的整数),表示最低优先级,最后执行。
实际应用场景
- 用户登录事件
当用户成功登录时,发布一个UserLoginEvent
,监听器可以记录日志、发送邮件通知等。 - 订单状态变更事件
当订单状态发生变化时,发布一个OrderStatusChangeEvent
,监听器可以更新库存、发送短信提醒等。 - 系统异常捕获事件
捕获到系统异常时,发布一个SystemExceptionEvent
,监听器可以记录错误日志、通知管理员等。
总结
事件机制是一种松耦合的设计模式,适用于复杂的业务场景中解耦组件之间的依赖关系。通过事件发布者、事件监听器和事件对象的协作,可以实现灵活的功能扩展和模块化开发。