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

當(dāng)前位置:首頁 > 科技  > 軟件

Spring事件如何異步執(zhí)行?

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

環(huán)境:SpringBoot2.7.166Ds28資訊網(wǎng)——每日最新資訊28at.com

1. 簡介

ApplicationContext 中的事件處理是通過 ApplicationEvent 類和 ApplicationListener 接口提供的。如果在上下文中部署了實現(xiàn) ApplicationListener 接口的 Bean,那么每次 ApplicationEvent 發(fā)布到 ApplicationContext 時,都會通知該 Bean。從本質(zhì)上講,這就是標(biāo)準(zhǔn)的觀察者設(shè)計模式。6Ds28資訊網(wǎng)——每日最新資訊28at.com

6Ds28資訊網(wǎng)——每日最新資訊28at.com

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

6Ds28資訊網(wǎng)——每日最新資訊28at.com

以下是一個簡單的事件應(yīng)用6Ds28資訊網(wǎng)——每日最新資訊28at.com

1.1 定義事件對象

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

1.2 定義事件監(jiān)聽

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

1.3 發(fā)布事件

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

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

2. 事件異步處理

2.1 通過@Async注解

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

開啟異步任務(wù)功能更6Ds28資訊網(wǎng)——每日最新資訊28at.com

@EnableAsyncpublic class AppApplication {}

基于注解事件監(jiān)聽6Ds28資訊網(wǎng)——每日最新資訊28at.com

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

執(zhí)行結(jié)果6Ds28資訊網(wǎng)——每日最新資訊28at.com

task-1 - 事件發(fā)生了...自定義Pack

線程名已經(jīng)變?yōu)榱藅ask-1。task-前綴是異步線程的默認名。關(guān)于異步任務(wù)執(zhí)行應(yīng)用的線程池配置,查看下面這篇文章。6Ds28資訊網(wǎng)——每日最新資訊28at.com

Spring任務(wù)調(diào)度&異步任務(wù)&Web異步請求三者如何配置線程池?6Ds28資訊網(wǎng)——每日最新資訊28at.com

上面是基于注解的方式應(yīng)用異步執(zhí)行事件處理。對于在簡介中通過實現(xiàn)ApplicationListener接口的方式又該如何處理呢?6Ds28資訊網(wǎng)——每日最新資訊28at.com

對于這種方式,我們可以通過兩種方式進行處理:6Ds28資訊網(wǎng)——每日最新資訊28at.com

2.2 自定義線程池

  • 在事件監(jiān)聽處理程序中開啟異步線程
@Componentpublic class PackEventListener implements ApplicationListener<PackEvent> {  @Override  public void onApplicationEvent(PackEvent event) {    new Thread(() -> {      System.out.printf("%s觸發(fā)事件...%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 ;}

通過這種方式也可以實現(xiàn)事件處理程序異步執(zhí)行。而這種方式的實現(xiàn)原理如下:6Ds28資訊網(wǎng)——每日最新資訊28at.com

容器啟動中的核心方法refresh中6Ds28資訊網(wǎng)——每日最新資訊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 {      // 如果不存在則創(chuàng)建一個同步的執(zhí)行器。      this.applicationEventMulticaster = new SimpleApplicationEventMulticaster(beanFactory);      beanFactory.registerSingleton(APPLICATION_EVENT_MULTICASTER_BEAN_NAME, this.applicationEventMulticaster);    }  }}

以上是本篇文章的全部內(nèi)容,希望對你有幫助。6Ds28資訊網(wǎng)——每日最新資訊28at.com

完畢!!!6Ds28資訊網(wǎng)——每日最新資訊28at.com

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

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

上一篇: Spring中Cron表達式的優(yōu)雅實現(xiàn)方案

下一篇: OpenFeign奪命連環(huán)九問

標(biāo)簽:
  • 熱門焦點
Top 主站蜘蛛池模板: 永胜县| 东乌珠穆沁旗| 敦煌市| 定安县| 清徐县| 彩票| 乐昌市| 星座| 珠海市| 万全县| 广南县| 宕昌县| 厦门市| 吐鲁番市| 通城县| 榆林市| 丽水市| 理塘县| 临潭县| 萍乡市| 胶南市| 青阳县| 汨罗市| 日照市| 黄石市| 宜兴市| 嘉定区| 甘德县| 仁寿县| 永丰县| 龙口市| 类乌齐县| 驻马店市| 龙江县| 息烽县| 孟连| 炎陵县| 精河县| 安吉县| 佛山市| 丽江市|