成人免费xxxxx在线视频软件_久久精品久久久_亚洲国产精品久久久_天天色天天色_亚洲人成一区_欧美一级欧美三级在线观看

Spring事件機制,深入剖析,提升你的技術水平!

開發 前端
在Spring中,事件是主體,發布器負責發布事件,監聽器負責處理事件。事件對象封裝了事件源對象和事件相關信息,用于在事件源和監聽器之間傳遞信息。發布器通過注入事件發布者實現,使用事件發布者發布事件。監聽器通過實現ApplicationListener接口來定義,用于對事件進行處理。

環境:Spring5.3.23

1. 簡介

Spring事件機制是一種用于處理系統內部或者外部事件的機制,它是Spring框架的一部分。事件機制基于監聽者設計模式實現,包括事件、發布器和監聽器三個主要部分。

在Spring中,事件是主體,發布器負責發布事件,監聽器負責處理事件。事件對象封裝了事件源對象和事件相關信息,用于在事件源和監聽器之間傳遞信息。發布器通過注入事件發布者實現,使用事件發布者發布事件。監聽器通過實現ApplicationListener接口來定義,用于對事件進行處理。

Spring容器提供了事件管理機制,內部很多節點都會發布事件,也支持自定義事件。在Spring Boot中,你可以使用ApplicationEventPublisher接口來發布事件,通過繼承ApplicationEvent抽象類來定義事件對象,通過實現ApplicationListener接口來定義事件監聽器。

總之,Spring事件機制是一個非常有用的工具,可以幫助你更好地管理和處理系統中的事件。

2. 事件發布及監聽

創建并發布自己的自定義事件。通過ApplicationEvent

static class OrderEvent extends ApplicationEvent {
  private Order order ;
  public OrderEvent(Object source, Order order) {
    super(source) ;
    this.order = order ;
  }
  public Order getOrder() {
    return this.order;
  }
}

要接收自定義 ApplicationEvent,可以創建一個實現 ApplicationListener 的類,并將其注冊為 Spring Bean。

static class OrderListener implements ApplicationListener<OrderEvent> {
  @Override
  public void onApplicationEvent(OrderEvent event) {
    System.out.printf("監聽到定義事件:%s", event.getOrder().toString()) ;
  }
}

要發布自定義 ApplicationEvent,調用 ApplicationEventPublisher 上的 publishEvent() 方法。通常,可以通過創建一個實現 ApplicationEventPublisherAware 的類并將其注冊為 Spring Bean 來實現:

static class OrderService implements ApplicationEventPublisherAware {
  private ApplicationEventPublisher eventPublisher ;
  @Override
  public void setApplicationEventPublisher(ApplicationEventPublisher eventPublisher) {
    this.eventPublisher = eventPublisher ;
  }
  public void save(Order order) {
    this.eventPublisher.publishEvent(new OrderEvent("create oder event", new Order()));
  }
}

基于注解方式實現事件監聽

你可以使用 @EventListener 注解在任意Bean 的任何方法上注冊事件監聽器。示例如下:

static class MyEventListener {
    
  @EventListener
  public void receiveOrderEvent(OrderEvent event) {
    System.out.printf("監聽到定義事件:%s", event.getOrder().toString()) ;
  }
  
}

通過一個注解,實現了事件的監聽,在該方法中指定了要監聽的事件類型。

如果你的方法需要監聽多個事件,或者你想定義一個不帶任何參數的方法,也可以在注解中指定事件類型。示例如下:

@EventListener({OrderEvent.class, UserEvent.class})
public void receiveOrderEvent() {
  System.out.printf("監聽到定義事") ;
}

這里指明了只監聽OrderEvent, UserEvent兩個事件。

也可以直接通過ApplicationEvent攜帶參數,這樣可以通過判斷處理不同的事件類型,示例如下:

@EventListener({OrderEvent.class, UserEvent.class})
public void receiveOrderEvent(ApplicationEvent event) {
  System.out.printf("監聽到定義事件:%s", event.getSource()) ;
}

我們還可以通過SpEL表達式過濾事件,示例如下:

// User對象
static class User {
  private Integer type ;
  public User(Integer type) {
    this.type = type ;
  }
}
// UserEvent事件對象
static class UserEvent extends ApplicationEvent {
  private User user ;
  public UserEvent(Object source, User user) {
    super(source) ;
    this.user = user ;
  }
  public User getUser() {
    return user;
  }
} 
// 事件監聽; 過濾只有User對象的type屬性為1時才會觸發事件
@EventListener(condition = "#event.user.type == 1")
public void receiveOrderEvent(UserEvent event) {
  System.out.printf("監聽到定義事件:%s", event.getUser()) ;
}

3. 異步事件監聽

異步方式1:

如果想讓某個監聽器異步處理事件,可以通過 @Async 注解支持,示例如下:

@EventListener
@Async
public void receiveOrderEvent(UserEvent event) {
  System.out.printf("%s - 監聽到定義事件:%s", Thread.currentThread().getName(), event.getUser()) ;
}

執行結果:

SimpleAsyncTaskExecutor-1 - 監聽到定義事件:com.pack.main.events.EventMain$User@abb3dc

異步方式2:

自定義一個事件發布器

@Bean
public SimpleApplicationEventMulticaster applicationEventMulticaster() {
  SimpleApplicationEventMulticaster applicationEventMulticaster = new SimpleApplicationEventMulticaster();
  applicationEventMulticaster.setTaskExecutor(Executors.newSingleThreadExecutor()) ;
  return applicationEventMulticaster ;
}

有個該事件發布器,容器在初始化時會先從容器中查找注冊的自定義發布器,源碼如下:

protected void initApplicationEventMulticaster() {
    ConfigurableListableBeanFactory beanFactory = getBeanFactory();
    // 判斷容器中是否有beanName = applicationEventMulticaster 的Bean
    if (beanFactory.containsLocalBean(APPLICATION_EVENT_MULTICASTER_BEAN_NAME)) {
      this.applicationEventMulticaster =
          beanFactory.getBean(APPLICATION_EVENT_MULTICASTER_BEAN_NAME, ApplicationEventMulticaster.class);
    } else {
      // 如果不存在則注冊一個默認的,該默認的將使用默認的當前執行線程執行
      this.applicationEventMulticaster = new SimpleApplicationEventMulticaster(beanFactory);
      beanFactory.registerSingleton(APPLICATION_EVENT_MULTICASTER_BEAN_NAME, this.applicationEventMulticaster);
    }
  }

執行結果:

pool-1-thread-1 - 監聽到定義事件:com.pack.main.events.EventMain$User@50f8a6

異步事件注意事項:

  1. 如果異步事件監聽器拋出異常,它不會傳播給調用者。對于使用@Async的可以參考 AsyncUncaughtExceptionHandler。
  2. 異步事件監聽器方法不能通過返回值來發布后續事件。如果需要將另一個事件作為處理結果發布,請注入 ApplicationEventPublisher 以手動發布事件。

4. 事件監聽順序

如果需要在調用一個監聽器之前調用另一個監聽器,可以在方法聲明中添加 @Order 注解,示例如下:

@EventListener
@Order(1)
public void receiveOrderEvent1(UserEvent event) {
  System.out.printf("%s - 監聽到定義事件 - 1:%s%n", Thread.currentThread().getName(), event.getUser()) ;
}
@EventListener
@Order(0)
public void receiveOrderEvent2(UserEvent event) {
  System.out.printf("%s - 監聽到定義事件 - 2:%s%n", Thread.currentThread().getName(), event.getUser()) ;
}

@Order中指定的值越小優先級越高,執行結果如下:

main - 監聽到定義事件 - 2:com.pack.main.events.EventMain$User@96bacf
main - 監聽到定義事件 - 1:com.pack.main.events.EventMain$User@96bacf

完畢!!!

責任編輯:武曉燕 來源: Spring全家桶實戰案例源碼
相關推薦

2010-08-04 13:52:53

Flex事件機制

2022-06-01 14:10:46

物聯網5G蜂窩技術

2017-08-30 08:45:31

Web編程MySQL聊天機器人

2020-05-27 20:25:47

SpringSpringBoot數據

2020-11-20 07:55:55

Linux內核映射

2022-03-17 13:44:30

Git命令管理

2025-03-11 00:35:00

Spring事件機制

2021-07-19 22:51:28

Python開發編程

2010-09-17 12:39:51

JAVA反射機制

2021-08-16 07:26:42

服務訂閱機制

2025-02-25 11:12:53

2023-09-14 15:15:36

2023-09-07 10:31:27

2018-05-17 09:25:31

Java程序員技術水平

2009-11-17 11:48:56

IT服務管理

2024-08-26 08:36:53

2011-04-19 15:24:26

jQueryJavaScript插件

2025-02-12 00:29:58

2010-08-12 16:10:44

Flex應用程序
點贊
收藏

51CTO技術棧公眾號

主站蜘蛛池模板: 欧美视频在线看 | 亚洲精品乱码久久久久v最新版 | 亚洲一区二区三区高清 | 精品日韩一区二区 | 久久福利电影 | 日韩中文字幕在线播放 | 欧美黄色网 | 国产精品成人一区二区三区夜夜夜 | 亚洲国产成人精品久久久国产成人一区 | 一区视频在线 | www.色五月.com | 国产h在线 | 欧美成人精品一区二区三区 | 成人免费视频网站在线观看 | 久久免费精品 | 久久综合一区二区 | 国产精品一区二区在线播放 | 一级黄在线观看 | 91视频大全| 欧美日韩一区二区视频在线观看 | 日日夜夜精品视频 | 亚洲国产aⅴ成人精品无吗 综合国产在线 | 国产男女精品 | 99视频在线| 人妖一区 | 日本一区二区高清视频 | 日本免费视频在线观看 | 一区二区三区视频在线观看 | 久久在线精品 | 全免费a级毛片免费看视频免费下 | 爱爱无遮挡 | 日韩av网址在线观看 | 超碰伊人| 日韩无 | 久草资源在线 | 国产精品久久久久久久久久不蜜臀 | 一区二区三区四区在线 | 超碰电影 | 久久久久久久久久久成人 | 国产精品日韩欧美一区二区三区 | 久久精品免费 |