欧美bbbwbbbw肥妇,免费乱码人妻系列日韩,一级黄片

Spring注解驅(qū)動(dòng)之ApplicationListener異步處理事件說明

 更新時(shí)間:2022年09月30日 09:04:07   作者:融極  
這篇文章主要介紹了Spring注解驅(qū)動(dòng)之ApplicationListener異步處理事件說明,具有很好的參考價(jià)值,希望對(duì)大家有所幫助。如有錯(cuò)誤或未考慮完全的地方,望不吝賜教

概述

之前我們講過簡(jiǎn)單使用ApplicationListener發(fā)布事件,處理事件,但是發(fā)現(xiàn)是同一個(gè)線程發(fā)送事件并自己處理事件的。

下面我們就來(lái)說下如何使用自定義的線程池來(lái)異步處理接收的事件。

示例

實(shí)現(xiàn)一個(gè)ApplicationListener用于處理事件

package com.atguigu.ext;

import org.springframework.context.ApplicationListener;
import org.springframework.context.PayloadApplicationEvent;
import org.springframework.stereotype.Component;

@Component
public class MyApplicationListener implements ApplicationListener<PayloadApplicationEvent> {

    public void onApplicationEvent(PayloadApplicationEvent applicationEvent) {
        System.out.println("exe thread start:" + Thread.currentThread().getName() + ", time:" + System.currentTimeMillis());
        System.out.println("收到事件:" + applicationEvent);
        System.out.println(applicationEvent.getPayload());
        try {
            Thread.sleep(3000);
        } catch (InterruptedException e) {
            e.printStackTrace();
        }
        System.out.println("exe thread end:" + Thread.currentThread().getName() + ", time:" + System.currentTimeMillis());
    }
}

自定義事件多波器

package com.atguigu.config;

import org.springframework.context.annotation.Bean;
import org.springframework.context.annotation.ComponentScan;
import org.springframework.context.annotation.Configuration;
import org.springframework.context.event.SimpleApplicationEventMulticaster;

import java.util.concurrent.BlockingQueue;
import java.util.concurrent.LinkedBlockingDeque;
import java.util.concurrent.ThreadPoolExecutor;
import java.util.concurrent.TimeUnit;

@Configuration
@ComponentScan("com.atguigu.ext")
public class ExtConfig {

    @Bean
    public SimpleApplicationEventMulticaster applicationEventMulticaster() {
        SimpleApplicationEventMulticaster simpleApplicationEventMulticaster = new SimpleApplicationEventMulticaster();
        BlockingQueue<Runnable> blockingQueue = new LinkedBlockingDeque<>(1000);
        ThreadPoolExecutor threadPoolExecutor = new ThreadPoolExecutor(5, 5, 10, TimeUnit.SECONDS, blockingQueue);
        simpleApplicationEventMulticaster.setTaskExecutor(threadPoolExecutor);
        return simpleApplicationEventMulticaster;
    }
}

之前看源碼可以發(fā)現(xiàn),在容器創(chuàng)建的refresh方法中的initApplicationEventMulticaster()方法執(zhí)行時(shí),先從容器中獲取name為applicationEventMulticaster的組件,如果獲取不到就好創(chuàng)建一個(gè)默認(rèn)的applicationEventMulticaster組件,該組件默認(rèn)是不會(huì)設(shè)置taskExecutor任務(wù)執(zhí)行器的,所以這里我們自定義一個(gè)設(shè)置了TaskExecutor的多波器,當(dāng)執(zhí)行initApplicationEventMulticaster方法從beanFactory中獲取applicationEventMulticaster組件時(shí),走getBean邏輯。

BeanFactory.getBean()邏輯是先從容器查看是否有該組件,如果沒有獲取該組件的定義,如果有定義就會(huì)創(chuàng)建一個(gè)組件返回并把組件保存到容器中。

測(cè)試用例

package com.atguigu;

import com.atguigu.config.ExtConfig;
import org.springframework.context.annotation.AnnotationConfigApplicationContext;

/**
 * @Description :
 * @Version : V1.0.0
 * @Date : 2022/9/1 15:07
 */
public class AnnotationTest {
    public static void main(String[] args) {
        final AnnotationConfigApplicationContext applicationContext
                = new AnnotationConfigApplicationContext(ExtConfig.class);
        System.out.println("main thread start:" + Thread.currentThread().getName() + ", time:" + System.currentTimeMillis());
        applicationContext.publishEvent("發(fā)送事件");
        System.out.println("main thread end:" + Thread.currentThread().getName() + ", time:" + System.currentTimeMillis());
        applicationContext.close();
    }
}

測(cè)試結(jié)果

main thread start:main, time:1663499481185
main thread end:main, time:1663499481188
exe thread start:pool-1-thread-1, time:1663499481188
收到事件:org.springframework.context.PayloadApplicationEvent[source=org.springframework.context.annotation.AnnotationConfigApplicationContext@5ebec15: startup date [Sun Sep 18 19:11:20 CST 2022]; root of context hierarchy]
發(fā)送事件
九月 18, 2022 7:11:21 下午 org.springframework.context.annotation.AnnotationConfigApplicationContext doClose
信息: Closing org.springframework.context.annotation.AnnotationConfigApplicationContext@5ebec15: startup date [Sun Sep 18 19:11:20 CST 2022]; root of context hierarchy
exe thread end:pool-1-thread-1, time:1663499484198

通過測(cè)試結(jié)果可以看出,main線程很快就返回了,而實(shí)際處理事件的線程是pool-1-thread-1,等待了3s多才返回。

ApplicationListener異步執(zhí)行源碼分析

參考:Spring注解驅(qū)動(dòng)之ApplicationListener用法

與上面同步執(zhí)行不同的地方就是使用了自定義的多波器里面的線程池執(zhí)行了事件處理。

多波器的獲取。

以上為個(gè)人經(jīng)驗(yàn),希望能給大家一個(gè)參考,也希望大家多多支持腳本之家。

相關(guān)文章

最新評(píng)論