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

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

Spring事件如何異步執行?

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

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

1. 簡介

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

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

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

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

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

2. 事件異步處理

2.1 通過@Async注解

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

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

@EnableAsyncpublic class AppApplication {}

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

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

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

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

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

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

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

對于這種方式,我們可以通過兩種方式進行處理:jSs28資訊網——每日最新資訊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 ;}

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

容器啟動中的核心方法refresh中jSs28資訊網——每日最新資訊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);    }  }}

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

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

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

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

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

下一篇: OpenFeign奪命連環九問

標簽:
  • 熱門焦點
Top 主站蜘蛛池模板: 西华县| 孝感市| 长兴县| 西乡县| 潢川县| 靖边县| 玉龙| 郯城县| 根河市| 房产| 岢岚县| 城固县| 连山| 瑞金市| 九龙城区| 广东省| 尚志市| 阳高县| 津市市| 琼结县| 明溪县| 宜都市| 兴海县| 沽源县| 万年县| 靖西县| 金沙县| 视频| 鄂托克前旗| 托克逊县| 邮箱| 环江| 郧西县| 台中市| 绿春县| 寿光市| 博乐市| 江门市| 新乐市| 当阳市| 巴青县|