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

Spring事件如何異步執行?

開發 前端
從Spring 4.2開始,事件基礎設施得到了顯著改進,并提供了基于注釋的模型以及發布任意事件的能力(也就是說,不一定是從ApplicationEvent擴展的對象)。當這樣的對象被發布時,我們將它包裝在一個事件中。

環境:SpringBoot2.7.16

1. 簡介

ApplicationContext 中的事件處理是通過 ApplicationEvent 類和 ApplicationListener 接口提供的。如果在上下文中部署了實現 ApplicationListener 接口的 Bean,那么每次 ApplicationEvent 發布到 ApplicationContext 時,都會通知該 Bean。從本質上講,這就是標準的觀察者設計模式。

從Spring 4.2開始,事件基礎設施得到了顯著改進,并提供了基于注釋的模型以及發布任意事件的能力(也就是說,不一定是從ApplicationEvent擴展的對象)。當這樣的對象被發布時,我們將它包裝在一個事件中。

以下是一個簡單的事件應用

1.1 定義事件對象

public class PackEvent extends ApplicationEvent {


  private static final long serialVersionUID = 1L;


  public PackEvent(Object source) {
    super(source);
  }
}

1.2 定義事件監聽

@Component
public class PackEventListener implements ApplicationListener<PackEvent> {


  @Override
  public void onApplicationEvent(PackEvent event) {
    System.out.println("觸發事件...") ;
  }
}

1.3 發布事件

@Resource
private ApplicationEventMulticaster eventMulticaster ;
public void run(ApplicationArguments args) throws Exception {
  eventMulticaster.multicastEvent(new PackEvent("自定義Pack")) ;
}

以上Spring事件系統的完整應用實例。在默認情況下該種事件處理方式是同步的,也就是事件的發布者與事件的處理都是同一個線程中,那這就要求我們的事件處理程序不應該處理復雜耗時的任務,否則會影響我們的主業務系統。那如何異步處理事件呢?

2. 事件異步處理

2.1 通過@Async注解

該種方式是最簡單的方式了,開啟異步功能,在基于注解的事件監聽方法上使用@Async注解。

開啟異步任務功能更

@EnableAsync
public class AppApplication {}

基于注解事件監聽

@Async
@EventListener({PackEvent.class})
public void packEventListener(PackEvent event) {
  System.out.printf("%s - 事件發生了...%s%n", Thread.currentThread().getName(), event.getSource()) ;
}

執行結果

task-1 - 事件發生了...自定義Pack

線程名已經變為了task-1。task-前綴是異步線程的默認名。關于異步任務執行應用的線程池配置,查看下面這篇文章。

Spring任務調度&異步任務&Web異步請求三者如何配置線程池?

上面是基于注解的方式應用異步執行事件處理。對于在簡介中通過實現ApplicationListener接口的方式又該如何處理呢?

對于這種方式,我們可以通過兩種方式進行處理:

2.2 自定義線程池

  • 在事件監聽處理程序中開啟異步線程
@Component
public class PackEventListener implements ApplicationListener<PackEvent> {


  @Override
  public void onApplicationEvent(PackEvent event) {
    new Thread(() -> {
      System.out.printf("%s觸發事件...%n", Thread.currentThread().getName()) ;
    }).start() ;
  }
}
  • 自定義事件廣播器
@Bean
TaskExecutor taskExecutor() {
  ThreadPoolTaskExecutor taskExecutor = new ThreadPoolTaskExecutor() ;
  taskExecutor.setThreadNamePrefix("pack-event-") ;
  taskExecutor.setCorePoolSize(5) ;
  taskExecutor.setQueueCapacity(100) ;
  taskExecutor.setMaxPoolSize(5) ;
  taskExecutor.initialize() ;
  return taskExecutor ;
}


// 注意beanName必須為applicationEventMulticaster;下面的源碼中你將看到
@Bean(name  = AbstractApplicationContext.APPLICATION_EVENT_MULTICASTER_BEAN_NAME)
SimpleApplicationEventMulticaster eventMulticaster(BeanFactory beanFactory) {
  SimpleApplicationEventMulticaster eventMulticaster = new SimpleApplicationEventMulticaster(beanFactory) ;
  eventMulticaster.setTaskExecutor(taskExecutor()) ;
  return eventMulticaster ;
}

通過這種方式也可以實現事件處理程序異步執行。而這種方式的實現原理如下:

容器啟動中的核心方法refresh中

public abstract class AbstractApplicationContext {
  public void refresh() {
    // 初始化事件廣播器
    initApplicationEventMulticaster();
  }
  protected void initApplicationEventMulticaster() {
    ConfigurableListableBeanFactory beanFactory = getBeanFactory();
    // 判斷容器中是否存在beanName=applicationEventMulticaster
    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);
    }
  }
}

以上是本篇文章的全部內容,希望對你有幫助。

完畢?。?!

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

2013-04-01 15:25:41

異步編程異步EMP

2022-02-11 08:54:33

SpringWeb 應用執行表單

2023-02-07 07:25:36

Spring事件驅動

2020-07-02 07:44:27

Spring教程異步

2023-07-31 08:05:30

Spring任務調度

2010-08-04 13:23:29

Flex事件

2025-02-07 10:14:36

2020-11-01 17:10:46

異步事件開發前端

2013-03-08 09:33:25

JavaScript同步異步

2015-09-07 14:08:32

Java編程異步事件

2021-06-26 14:59:13

SpringTransaction執行

2009-07-22 10:13:31

異步ActionASP.NET MVC

2024-07-31 15:57:41

2024-10-15 10:28:43

2010-04-06 15:20:56

ASP.NET MVC

2009-08-20 17:47:54

C#異步編程模式

2020-01-02 16:30:02

Spring BootJava異步請求

2025-05-29 01:33:00

微服務架構系統

2024-12-17 00:00:00

Spring線程

2025-05-20 07:13:22

Spring異步解耦Event
點贊
收藏

51CTO技術棧公眾號

主站蜘蛛池模板: 色婷婷av777 av免费网站在线 | 综合久久综合久久 | 亚洲电影中文字幕 | 九色 在线| 成人精品鲁一区一区二区 | 91色在线 | 国产福利视频导航 | 99免费精品视频 | 99久久日韩精品免费热麻豆美女 | 久久精品国产久精国产 | 精品免费国产视频 | 久久99国产精一区二区三区 | 国产成人av在线 | 在线观看日韩av | 91久久久久久久久 | 午夜国产| 噜久寡妇噜噜久久寡妇 | 精品亚洲一区二区 | 国产日产久久高清欧美一区 | 91精品国产综合久久福利软件 | 成人在线免费视频 | 色婷婷一区二区三区四区 | 91欧美精品成人综合在线观看 | 日韩中文字幕在线观看 | 精品国产鲁一鲁一区二区张丽 | 毛片入口| 久久不卡 | 99免费看 | 国产99久久久国产精品 | 午夜视频在线免费观看 | 亚洲综合色视频在线观看 | 精品九九 | 狠狠干天天干 | 日日干夜夜操天天操 | 欧美一级二级三级视频 | 亚洲欧美在线观看 | 久久精品视频一区二区三区 | 国产精品一区2区 | 欧美亚洲国产日韩 | 亚洲精品视频在线 | 国产成人综合在线 |