最新国产好看的视频,伊人天堂AV在线,国产Aaaaaa视频,蜜臀视频在线观看一区,人妻av色图,密臀久久久精品影片,青青视频免费观看毛片,久草在线观看视,国产三级精品色情在线

Spring中事件機(jī)制的實(shí)現(xiàn)示例

 更新時(shí)間:2025年10月09日 08:30:33   作者:我也有魚魚蒸  
Spring中的事件機(jī)制是基于觀察者模式實(shí)現(xiàn)的一種組件間通信機(jī)制,用于解耦不同組件,實(shí)現(xiàn)松耦合的消息傳遞,下面就來(lái)了解一下Spring中事件機(jī)制的實(shí)現(xiàn),感興趣的可以了解一下

Spring中的事件機(jī)制是基于觀察者模式實(shí)現(xiàn)的一種組件間通信機(jī)制,用于解耦不同組件,實(shí)現(xiàn)松耦合的消息傳遞,它允許一個(gè)組件發(fā)送事件,其他組件接收并處理事件,而無(wú)需直接依賴彼此。

事件機(jī)制的組成

Spring事件機(jī)制包含三個(gè)核心部分:

  • 事件:繼承ApplicationEvent的對(duì)象,封裝需要傳遞的數(shù)據(jù)。Spring4.2+可以省略,任意對(duì)象都可以作為事件。
  • 事件發(fā)布者:通過(guò)ApplicationEventPublisher接口發(fā)布事件,通常由spring管理的bean實(shí)現(xiàn)。
  • 事件監(jiān)聽(tīng)器:監(jiān)聽(tīng)并處理事件的組件,通過(guò)@EventListener注解或?qū)崿F(xiàn)ApplicationListener接口定義。

示例

事件:

首先自定義一個(gè)事件類,去實(shí)現(xiàn)ApplicationEvent,該父類沒(méi)有無(wú)參構(gòu)造:

public class MyEvent extends ApplicationEvent {
    
    public MyEvent(Object source) {
        super(source);
    }
}

發(fā)布者:

在業(yè)務(wù)代碼內(nèi)注入ApplicationEventPublisher,通過(guò)它去發(fā)布事件:

@Autowired
    private ApplicationEventPublisher applicationEventPublisher;
    public void enent(){
        //業(yè)務(wù)代碼
        //發(fā)送事件
        applicationEventPublisher.publishEvent(new MyEvent(this));
    }

監(jiān)聽(tīng)器:

監(jiān)聽(tīng)事件類型,兩種方式都試一遍:

@Component
public class MyLin implements ApplicationListener<MyEvent> {
    @Override
    public void onApplicationEvent(MyEvent event) {
        System.out.println("監(jiān)聽(tīng)到事件");
    }
}
@Component
public class MyLin2 {
    //注意方法的參數(shù)類型是監(jiān)聽(tīng)的類型
    @EventListener
    public void onApplicationEvent(MyEvent event) {
        System.out.println("監(jiān)聽(tīng)到事件2");
    }
}

接下來(lái)模擬異步的情況:

SimpleApplicationEventMulticaster

SimpleApplicationEventMulticaster是 Spring 框架中事件機(jī)制的核心組件,負(fù)責(zé)將發(fā)布的事件多播(multicast) 給所有訂閱該事件的監(jiān)聽(tīng)器,是事件從發(fā)布者傳遞到監(jiān)聽(tīng)器的 “中介”。

它的主要職責(zé)是:

  1. 接收發(fā)布者發(fā)布的事件;
  2. 找到所有監(jiān)聽(tīng)該事件類型的監(jiān)聽(tīng)器;
  3. 將事件分發(fā)給這些監(jiān)聽(tīng)器執(zhí)行處理邏輯。

特性:

  • 事件發(fā)布后,它會(huì)直接發(fā)布在事件的線程中調(diào)研監(jiān)聽(tīng)器的處理方法,發(fā)布者需等待所有的監(jiān)聽(tīng)器完畢后才能繼續(xù),可以過(guò)setTaskExector(Executor)設(shè)置線程池,會(huì)將監(jiān)聽(tīng)器的處理邏輯交到線程池執(zhí)行,發(fā)布者無(wú)需等待。
  • 支持通過(guò) addApplicationListener(ApplicationListener) 手動(dòng)注冊(cè)監(jiān)聽(tīng)器;

配置好SimpleApplicationEventMulticaster后,通過(guò)ApplicationEventPublish發(fā)送事件后會(huì)提交到配置的線程池中執(zhí)行。

    @Bean
    public SimpleApplicationEventMulticaster applicationEventMulticaster(ThreadPoolExecutor executor){
        SimpleApplicationEventMulticaster multicaster = new SimpleApplicationEventMulticaster();
        multicaster.setTaskExecutor(executor);
        return multicaster;
    }

異步事件監(jiān)聽(tīng)器

@Component
public class AsyncEventListener {
    
    private static final Logger logger = LoggerFactory.getLogger(AsyncEventListener.class);
    
    /**
     * 異步處理事件 - 不會(huì)阻塞主線程
     */
    @Async("taskExecutor")  // 指定使用配置的線程池
    @EventListener
    public void handleAsyncEvent(MyEvent event) {
        logger.info("異步事件處理開(kāi)始 - 事件: {}", event.getMessage());
        logger.info("當(dāng)前線程: {}", Thread.currentThread().getName());
        
        try {
            // 模擬耗時(shí)操作
            Thread.sleep(3000);
            logger.info("異步事件處理完成: {}", event.getMessage());
        } catch (InterruptedException e) {
            Thread.currentThread().interrupt();
            logger.error("異步事件處理被中斷", e);
        }
    }
    
    /**
     * 同步處理事件 - 會(huì)阻塞主線程
     */
    @EventListener
    public void handleSyncEvent(MyEvent event) {
        logger.info("同步事件處理開(kāi)始 - 事件: {}", event.getMessage());
        logger.info("當(dāng)前線程: {}", Thread.currentThread().getName());
        
        try {
            // 模擬耗時(shí)操作
            Thread.sleep(2000);
            logger.info("同步事件處理完成: {}", event.getMessage());
        } catch (InterruptedException e) {
            Thread.currentThread().interrupt();
            logger.error("同步事件處理被中斷", e);
        }
    }
}
@SpringBootTest
public class EventTest {
    
    @Autowired
    private BusinessService businessService;
    
    @Test
    public void testAsyncEvent() {
        System.out.println("測(cè)試開(kāi)始 - 主線程: " + Thread.currentThread().getName());
        
        long startTime = System.currentTimeMillis();
        businessService.doBusiness();
        long endTime = System.currentTimeMillis();
        
        System.out.println("業(yè)務(wù)方法執(zhí)行時(shí)間: " + (endTime - startTime) + "ms");
        
        // 給異步事件處理留出時(shí)間
        try {
            Thread.sleep(5000);
        } catch (InterruptedException e) {
            Thread.currentThread().interrupt();
        }
    }
}

Spring 內(nèi)置事件

Spring 框架自帶一些內(nèi)置事件,用于通知容器生命周期的關(guān)鍵節(jié)點(diǎn),常見(jiàn)的有:

事件類型觸發(fā)時(shí)機(jī)
ContextRefreshedEventSpring 容器初始化完成(所有 Bean 加載完成)
ContextStartedEvent容器啟動(dòng)時(shí)(調(diào)用start()方法)
ContextStoppedEvent容器停止時(shí)(調(diào)用stop()方法)
ContextClosedEvent容器關(guān)閉時(shí)(調(diào)用close()方法)
ApplicationFailedEvent應(yīng)用啟動(dòng)失敗時(shí)(Spring Boot 中常用)

到此這篇關(guān)于Spring中事件機(jī)制的實(shí)現(xiàn)示例的文章就介紹到這了,更多相關(guān)Spring 事件機(jī)制內(nèi)容請(qǐng)搜索腳本之家以前的文章或繼續(xù)瀏覽下面的相關(guān)文章希望大家以后多多支持腳本之家!

相關(guān)文章

  • mybatis if標(biāo)簽使用總結(jié)

    mybatis if標(biāo)簽使用總結(jié)

    這篇文章主要介紹了mybatis if標(biāo)簽使用總結(jié),文中通過(guò)示例代碼介紹的非常詳細(xì),對(duì)大家的學(xué)習(xí)或者工作具有一定的參考學(xué)習(xí)價(jià)值,需要的朋友們下面隨著小編來(lái)一起學(xué)習(xí)學(xué)習(xí)吧
    2019-12-12
  • 使用Java實(shí)現(xiàn)在Excel中添加動(dòng)態(tài)數(shù)組公式

    使用Java實(shí)現(xiàn)在Excel中添加動(dòng)態(tài)數(shù)組公式

    動(dòng)態(tài)數(shù)組公式是?Excel?引入的一項(xiàng)重要功能,它允許用戶從單個(gè)單元格中的公式返回多個(gè)結(jié)果值,并將這些值自動(dòng)填充到與公式單元格相鄰的單元格中,本文主要介紹了如何使用Java實(shí)現(xiàn)在Excel中添加動(dòng)態(tài)數(shù)組公式,x需要的可以參考下
    2023-12-12
  • 解決SpringBoot2.1.0+RocketMQ版本沖突問(wèn)題

    解決SpringBoot2.1.0+RocketMQ版本沖突問(wèn)題

    這篇文章主要介紹了解決SpringBoot2.1.0+RocketMQ版本沖突問(wèn)題,具有很好的參考價(jià)值,希望對(duì)大家有所幫助,如有錯(cuò)誤或未考慮完全的地方,望不吝賜教
    2024-06-06
  • 基于XML的Spring聲明事務(wù)控制

    基于XML的Spring聲明事務(wù)控制

    這篇文章主要為大家詳細(xì)介紹了基于XML的Spring聲明事務(wù)控制,文中示例代碼介紹的非常詳細(xì),具有一定的參考價(jià)值,感興趣的小伙伴們可以參考一下
    2022-07-07
  • java9學(xué)習(xí)系列之在docker中如何運(yùn)行java9

    java9學(xué)習(xí)系列之在docker中如何運(yùn)行java9

    最近在學(xué)習(xí)java9,所以將學(xué)習(xí)中遇到的一些知識(shí)點(diǎn)分享給大家,下面這篇文章主要給大家介紹了java9學(xué)習(xí)系列之在docker中如何運(yùn)行java9的相關(guān)資料,文中通過(guò)示例代碼介紹的非常詳細(xì),需要的朋友可以參考下。
    2017-09-09
  • Java日常練習(xí)題,每天進(jìn)步一點(diǎn)點(diǎn)(62)

    Java日常練習(xí)題,每天進(jìn)步一點(diǎn)點(diǎn)(62)

    下面小編就為大家?guī)?lái)一篇Java基礎(chǔ)的幾道練習(xí)題(分享)。小編覺(jué)得挺不錯(cuò)的,現(xiàn)在就分享給大家,也給大家做個(gè)參考。一起跟隨小編過(guò)來(lái)看看吧,希望可以幫到你
    2021-08-08
  • Java成員變量與局部變量(動(dòng)力節(jié)點(diǎn)Java學(xué)院整理)

    Java成員變量與局部變量(動(dòng)力節(jié)點(diǎn)Java學(xué)院整理)

    這篇文章主要介紹了Java成員變量與局部變量的相關(guān)資料,非常不錯(cuò),具有參考借鑒價(jià)值,需要的朋友可以參考下
    2017-04-04
  • java基礎(chǔ)之NIO介紹及使用

    java基礎(chǔ)之NIO介紹及使用

    這篇文章主要介紹了java基礎(chǔ)之NIO介紹及使用,文中有非常詳細(xì)的代碼示例,對(duì)正在學(xué)習(xí)java基礎(chǔ)的小伙伴們有非常好的幫助,需要的朋友可以參考下
    2021-04-04
  • Spring的RedisTemplate存儲(chǔ)的key和value有特殊字符的處理

    Spring的RedisTemplate存儲(chǔ)的key和value有特殊字符的處理

    這篇文章主要介紹了Spring的RedisTemplate存儲(chǔ)的key和value有特殊字符的處理方式,具有很好的參考價(jià)值,希望對(duì)大家有所幫助,如有錯(cuò)誤或未考慮完全的地方,望不吝賜教
    2023-12-12
  • Java中的StringBuilder()常見(jiàn)方法詳解

    Java中的StringBuilder()常見(jiàn)方法詳解

    StringBuilder是一個(gè)可變的字符序列,此類提供一個(gè)與 StringBuffer 兼容的 API,但不保證同步,這篇文章主要介紹了StringBuilder()常見(jiàn)方法,需要的朋友可以參考下
    2023-09-09

最新評(píng)論

巴马| 天台县| 绥德县| 加查县| 吉安市| 怀仁县| 璧山县| 贵阳市| 崇信县| 静海县| 通河县| 阿拉善右旗| 浪卡子县| 阳山县| 建湖县| 巧家县| 福州市| 西宁市| 和平县| 瑞安市| 兰溪市| 蓝田县| 南木林县| 沁阳市| 太白县| 元谋县| 唐山市| 巴林右旗| 水城县| 祥云县| 河南省| 成安县| 鄂伦春自治旗| 普兰店市| 环江| 于田县| 成都市| 崇明县| 东丽区| 江城| 卢氏县|