日韩成人免费在线_国产成人一二_精品国产免费人成电影在线观..._日本一区二区三区久久久久久久久不

當前位置:首頁 > 科技  > 軟件

Spring事件如何異步執行?

來源: 責編: 時間:2024-03-18 09:42:49 184觀看
導讀環境:SpringBoot2.7.161. 簡介ApplicationContext 中的事件處理是通過 ApplicationEvent 類和 ApplicationListener 接口提供的。如果在上下文中部署了實現 ApplicationListener 接口的 Bean,那么每次 ApplicationEvent

環境:SpringBoot2.7.162gz28資訊網——每日最新資訊28at.com

1. 簡介

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

2gz28資訊網——每日最新資訊28at.com

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

2gz28資訊網——每日最新資訊28at.com

以下是一個簡單的事件應用2gz28資訊網——每日最新資訊28at.com

1.1 定義事件對象

public class PackEvent extends ApplicationEvent {  private static final long serialVersionUID = 1L;  public PackEvent(Object source) {    super(source);  }}

1.2 定義事件監聽

@Componentpublic class PackEventListener implements ApplicationListener<PackEvent> {  @Override  public void onApplicationEvent(PackEvent event) {    System.out.println("觸發事件...") ;  }}

1.3 發布事件

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

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

2. 事件異步處理

2.1 通過@Async注解

該種方式是最簡單的方式了,開啟異步功能,在基于注解的事件監聽方法上使用@Async注解。2gz28資訊網——每日最新資訊28at.com

開啟異步任務功能更2gz28資訊網——每日最新資訊28at.com

@EnableAsyncpublic class AppApplication {}

基于注解事件監聽2gz28資訊網——每日最新資訊28at.com

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

執行結果2gz28資訊網——每日最新資訊28at.com

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

線程名已經變為了task-1。task-前綴是異步線程的默認名。關于異步任務執行應用的線程池配置,查看下面這篇文章。2gz28資訊網——每日最新資訊28at.com

Spring任務調度&異步任務&Web異步請求三者如何配置線程池?2gz28資訊網——每日最新資訊28at.com

上面是基于注解的方式應用異步執行事件處理。對于在簡介中通過實現ApplicationListener接口的方式又該如何處理呢?2gz28資訊網——每日最新資訊28at.com

對于這種方式,我們可以通過兩種方式進行處理:2gz28資訊網——每日最新資訊28at.com

2.2 自定義線程池

  • 在事件監聽處理程序中開啟異步線程
@Componentpublic class PackEventListener implements ApplicationListener<PackEvent> {  @Override  public void onApplicationEvent(PackEvent event) {    new Thread(() -> {      System.out.printf("%s觸發事件...%n", Thread.currentThread().getName()) ;    }).start() ;  }}
  • 自定義事件廣播器
@BeanTaskExecutor 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 ;}

通過這種方式也可以實現事件處理程序異步執行。而這種方式的實現原理如下:2gz28資訊網——每日最新資訊28at.com

容器啟動中的核心方法refresh中2gz28資訊網——每日最新資訊28at.com

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);    }  }}

以上是本篇文章的全部內容,希望對你有幫助。2gz28資訊網——每日最新資訊28at.com

完畢!!!2gz28資訊網——每日最新資訊28at.com

本文鏈接:http://www.www897cc.com/showinfo-26-76561-0.htmlSpring事件如何異步執行?

聲明:本網頁內容旨在傳播知識,若有侵權等問題請及時與本網聯系,我們將在第一時間刪除處理。郵件:2376512515@qq.com

上一篇: Spring中Cron表達式的優雅實現方案

下一篇: OpenFeign奪命連環九問

標簽:
  • 熱門焦點
Top 主站蜘蛛池模板: 兰考县| 赤壁市| 晴隆县| 获嘉县| 雅江县| 潮安县| 临安市| 孝昌县| 白玉县| 万荣县| 顺义区| 铜陵市| 清苑县| 宜州市| 阿克苏市| 泰顺县| 玉门市| 内丘县| 岳阳县| 聂荣县| 沙湾县| 庆元县| 德化县| 宣城市| 中牟县| 筠连县| 盐源县| 保靖县| 修水县| 磐石市| 游戏| 高青县| 高邑县| 西宁市| 乌恰县| 洪湖市| 南阳市| 宜君县| 分宜县| 濮阳县| 达州市|