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

spring事件

事件机制的核心概念

  1. 事件(Event)

    • 是一个表示特定动作或状态的对象。
    • 在 Spring 中,ApplicationEvent 是所有事件的基类,开发者可以继承它创建自定义事件对象。
    • 例如:鼠标点击、键盘按下等都是事件的具体表现形式。
  2. 事件监听器(Event Listener)

    • 负责接收并处理事件的对象。
    • 在 Spring 中,可以通过以下两种方式实现:
      • 实现 ApplicationListener 接口。
      • 使用 @EventListener 注解的方法。
    • 监听器的作用是当某个事件触发时,执行相应的逻辑处理。
  3. 事件发布者(Event Publisher)

    • 负责发布事件的对象。
    • 在 Spring 中,通过 ApplicationEventPublisher 接口发布事件。
    • 任何 Spring Bean 都可以注入该接口,并在需要的时候发布事件。

事件机制的具体流程

以下是事件机制的完整流程:

  1. 定义事件对象
    创建一个继承 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 方法
    }
    
  2. 发布事件
    在服务层中注入 ApplicationEventPublisher,并通过其 publishEvent() 方法发布事件。

    @Service
    public class EventManagerService {
        @Autowired
        private ApplicationEventPublisher applicationEventPublisher;
    
        public Boolean mouseclick() {
            applicationEventPublisher.publishEvent(new MyEvent(this, "鼠标点击", "www.bing.com"));
            return true;
        }
    }
    
  3. 监听事件
    定义一个监听器类,并使用 @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);
        }
    }

}

关键点解析

  1. 事件条件过滤(Condition)

    • @EventListener 注解中,可以通过 condition 参数设置条件,只有满足条件的事件才会触发对应的方法。
    • 示例:"#event.url.contains('baidu')"
      这里的 #event 是 SpEL(Spring Expression Language)表达式中的变量,表示当前事件对象。
  2. 事件的异步处理

    • 默认情况下,事件监听是同步的,即事件发布后会阻塞直到监听器完成处理。
    • 如果希望监听器异步执行,可以在 @EnableAsync 注解下配置异步支持:
      @Configuration
      @EnableAsync
      public class AsyncConfig implements AsyncConfigurer {
          // 配置线程池等异步参数
      }
      
      然后在监听方法上添加 @Async 注解:
      @EventListener
      @Async
      public void handleMyEvent(MyEvent event) {
          // 异步处理逻辑
      }
      
  3. 事件的广播与多监听器

    • 一个事件可以被多个监听器同时监听。
    • 监听器的执行顺序默认是无序的,但如果需要控制顺序,可以通过 @Order 注解指定优先级:
      @Component
      @Order(1)
      public class FirstEventListener {
          @EventListener
          public void handleEvent(MyEvent event) {
              System.out.println("第一个监听器处理事件");
          }
      }
      
  4. @Order解析

  • 在 Spring 中,@Order 注解用于定义组件的优先级,数值越小优先级越高。因此,@Order(1) 的组件会比 @Order(2) 的组件先执行。

  • 具体规则

  • @Order 注解的值决定了组件的执行顺序。

  • 数值越小,优先级越高,越早执行。

  • 如果没有指定 @Order,默认值为 Ordered.LOWEST_PRECEDENCE(一个非常大的整数),表示最低优先级,最后执行。

实际应用场景

  • 用户登录事件
    当用户成功登录时,发布一个 UserLoginEvent,监听器可以记录日志、发送邮件通知等。
  • 订单状态变更事件
    当订单状态发生变化时,发布一个 OrderStatusChangeEvent,监听器可以更新库存、发送短信提醒等。
  • 系统异常捕获事件
    捕获到系统异常时,发布一个 SystemExceptionEvent,监听器可以记录错误日志、通知管理员等。

总结

事件机制是一种松耦合的设计模式,适用于复杂的业务场景中解耦组件之间的依赖关系。通过事件发布者、事件监听器和事件对象的协作,可以实现灵活的功能扩展和模块化开发。


http://www.kler.cn/a/565923.html

相关文章:

  • 15.13 AdaLoRA自适应权重矩阵微调:动态秩调整的智能革命
  • sqli-lab
  • 跨层逆向设计超线性资源投入
  • k8s环境搭建(从创建完一台虚拟机开始)
  • 蓝牙接近开关模块感应开锁手机靠近解锁支持HID低功耗
  • java23种设计模式-解释器模式
  • 动态规划 之 枚举型
  • Oracle 数据库基础入门(二):深入理解表的约束
  • [STM32]从零开始的STM32 DEBUG问题讲解及解决办法
  • 对比Grok3 普通账户与 30 美元 Super 账户:默认模式、Think 和 DeepSearch 次数限制以及如何升级
  • python-leetcode-删除并获得点数
  • CAS (Compare and swap “比较和交换“) [ Java EE 初阶 ]
  • 【Java基础】Java中new一个对象时,JVM到底做了什么?
  • 分布式系统中的关键技术解析:幂等性、负载均衡、限流算法及其实现
  • 做表格用什么软件?VeryReport让数据管理更高效!
  • 1.14 重叠因子:TRIMA三角移动平均线(Triangular Moving Average, TRIMA)概念与Python实战
  • 利用 Python 爬虫进行跨境电商数据采集
  • 1-8 gdb调试
  • 齿轮制造的“精密心脏”:蜗杆状砂轮磨齿机探秘
  • 回溯算法中的for循环和递归使用