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

SpringEvents與異步事件驅(qū)動(dòng)案例詳解

 更新時(shí)間:2024年09月23日 08:51:50   作者:五官一體即忢  
本文深入探討了SpringBoot中的事件驅(qū)動(dòng)架構(gòu),特別是通過(guò)Spring事件機(jī)制實(shí)現(xiàn)組件解耦和系統(tǒng)擴(kuò)展性增強(qiáng),介紹了事件的發(fā)布者、事件本身、事件監(jiān)聽(tīng)器和事件處理器的概念,感興趣的朋友跟隨小編一起看看吧

引言

在開(kāi)發(fā)基于Spring Boot的應(yīng)用程序時(shí),事件驅(qū)動(dòng)架構(gòu)是一個(gè)非常重要的概念。通過(guò)使用Spring框架提供的事件機(jī)制,我們可以輕松地解耦組件并提高系統(tǒng)的可擴(kuò)展性。本文將深入探討Spring事件(SpringEvent)的實(shí)現(xiàn),并通過(guò)一個(gè)實(shí)際的業(yè)務(wù)場(chǎng)景來(lái)展示如何使用它。

1. Spring Event機(jī)制簡(jiǎn)介

Spring事件機(jī)制主要由以下幾個(gè)部分組成:

  • 事件發(fā)布者 (ApplicationEventPublisher): 發(fā)布事件的對(duì)象。

  • 事件 (ApplicationEvent): 事件的具體內(nèi)容。

  • 事件監(jiān)聽(tīng)器 (ApplicationListener): 處理事件的對(duì)象。

  • 事件處理器 (ApplicationEventMulticaster): 負(fù)責(zé)將事件發(fā)送給所有注冊(cè)的監(jiān)聽(tīng)器。

2. 實(shí)際業(yè)務(wù)案例 - 訂單創(chuàng)建通知

假設(shè)我們正在構(gòu)建一個(gè)簡(jiǎn)單的電子商務(wù)平臺(tái),當(dāng)用戶成功創(chuàng)建訂單后,我們需要通知其他系統(tǒng)(如庫(kù)存系統(tǒng)和支付系統(tǒng))進(jìn)行相應(yīng)的處理。

3. 技術(shù)棧

  • Spring Boot 3.x

  • Java 17

4. 創(chuàng)建項(xiàng)目

首先,我們需要?jiǎng)?chuàng)建一個(gè)新的Spring Boot項(xiàng)目。這里我們使用Spring Initializr來(lái)快速生成項(xiàng)目骨架。

5. 定義事件

為了定義我們的事件,我們需要?jiǎng)?chuàng)建一個(gè)繼承自ApplicationEvent的新類。

import org.springframework.context.ApplicationEvent;
3public class OrderCreatedEvent extends ApplicationEvent {
    private final String orderId;
    private final String userId;
    public OrderCreatedEvent(Object source, String orderId, String userId) {
        super(source);
        this.orderId = orderId;
        this.userId = userId;
    }
    public String getOrderId() {
        return orderId;
    }
    public String getUserId() {
        return userId;
    }
}

6. 創(chuàng)建事件監(jiān)聽(tīng)器

接下來(lái),我們需要?jiǎng)?chuàng)建監(jiān)聽(tīng)器來(lái)處理事件。為了確保多個(gè)處理器能夠獨(dú)立運(yùn)行,我們將使用@Async注解來(lái)確保每個(gè)監(jiān)聽(tīng)器都能夠在自己的線程中獨(dú)立運(yùn)行。

import org.springframework.context.event.EventListener;
import org.springframework.scheduling.annotation.Async;
import org.springframework.stereotype.Component;
@Component
public class OrderEventListener {
    @Async
    @EventListener
    public void handleOrderCreated(OrderCreatedEvent event) {
        System.out.println("Received order created event: " + event.getOrderId());
        // 這里可以調(diào)用其他服務(wù),比如通知庫(kù)存系統(tǒng)或支付系統(tǒng)
        try {
            Thread.sleep(2000); // 模擬耗時(shí)操作
        } catch (InterruptedException e) {
            Thread.currentThread().interrupt();
            throw new RuntimeException(e);
        }
    }
}

為了展示多處理器的情況,我們可以添加另一個(gè)監(jiān)聽(tīng)器,它會(huì)執(zhí)行不同的任務(wù)。

import org.springframework.context.event.EventListener;
import org.springframework.scheduling.annotation.Async;
import org.springframework.stereotype.Component;
@Component
public class PaymentEventListener {
    @Async
    @EventListener
    public void handleOrderCreated(OrderCreatedEvent event) {
        System.out.println("Payment processing for order: " + event.getOrderId());
        // 這里可以調(diào)用支付服務(wù)
        try {
            Thread.sleep(3000); // 模擬耗時(shí)操作
        } catch (InterruptedException e) {
            Thread.currentThread().interrupt();
            throw new RuntimeException(e);
        }
    }
}

7. 添加異步支持

為了讓事件處理異步進(jìn)行,我們需要添加Spring的異步支持。為此,我們需要?jiǎng)?chuàng)建一個(gè)配置類來(lái)啟用異步執(zhí)行,并指定一個(gè)線程池用于處理事件。

import org.springframework.aop.interceptor.AsyncUncaughtExceptionHandler;
import org.springframework.context.annotation.Configuration;
import org.springframework.scheduling.annotation.AsyncConfigurer;
import org.springframework.scheduling.concurrent.ThreadPoolTaskExecutor;
6import java.util.concurrent.Executor;
@Configuration
public class AsyncConfig implements AsyncConfigurer {
    @Override
    public Executor getAsyncExecutor() {
        ThreadPoolTaskExecutor executor = new ThreadPoolTaskExecutor();
        executor.setCorePoolSize(2);
        executor.setMaxPoolSize(2);
        executor.setQueueCapacity(500);
        executor.setThreadNamePrefix("AsyncExecutor-");
        executor.initialize();
        return executor;
    }
    @Override
    public AsyncUncaughtExceptionHandler getAsyncUncaughtExceptionHandler() {
        return (throwable, method, objects) -> throwable.printStackTrace();
    }
}

8. 發(fā)布事件

最后,我們需要在訂單服務(wù)中發(fā)布事件。

import org.springframework.beans.factory.annotation.Autowired;
import org.springframework.context.ApplicationEventPublisher;
import org.springframework.stereotype.Service;
@Service
public class OrderService {
    private final ApplicationEventPublisher publisher;
    @Autowired
    public OrderService(ApplicationEventPublisher publisher) {
        this.publisher = publisher;
    }
    public void createOrder(String orderId, String userId) {
        // 創(chuàng)建訂單邏輯...
        // 發(fā)布事件
        publisher.publishEvent(new OrderCreatedEvent(this, orderId, userId));
    }
}

9. 測(cè)試

為了測(cè)試我們的實(shí)現(xiàn),可以在控制器中調(diào)用createOrder方法。

import org.springframework.web.bind.annotation.GetMapping;
import org.springframework.web.bind.annotation.RestController;
@RestController
public class OrderController {
    private final OrderService orderService;
    @Autowired
    public OrderController(OrderService orderService) {
        this.orderService = orderService;
    }
    @GetMapping("/orders")
    public String createOrder() {
        orderService.createOrder("12345", "user123");
        return "Order created!";
    }
}

10. 總結(jié)

通過(guò)上述步驟,我們已經(jīng)成功地實(shí)現(xiàn)了基于Spring事件機(jī)制的通知功能。這不僅可以幫助我們構(gòu)建更加松散耦合的應(yīng)用程序,還能讓我們的代碼更易于擴(kuò)展和維護(hù)。更重要的是,通過(guò)引入異步處理機(jī)制,我們確保了即使一個(gè)處理器出現(xiàn)異?;驁?zhí)行失敗,也不會(huì)影響到其他處理器的執(zhí)行。這是因?yàn)槊總€(gè)處理器都在獨(dú)立的線程中運(yùn)行,并且異常會(huì)被
AsyncUncaughtExceptionHandler捕獲并記錄,而不會(huì)中斷其他處理器的執(zhí)行。

注意:在生產(chǎn)環(huán)境中,你需要根據(jù)實(shí)際情況調(diào)整線程池的大小和配置。此外,確保異常處理邏輯符合你的需求,例如記錄異常到日志系統(tǒng)或發(fā)送錯(cuò)誤通知。

到此這篇關(guān)于SpringEvents與異步事件驅(qū)動(dòng)的文章就介紹到這了,更多相關(guān)SpringEvents與異步事件驅(qū)動(dòng)內(nèi)容請(qǐng)搜索腳本之家以前的文章或繼續(xù)瀏覽下面的相關(guān)文章希望大家以后多多支持腳本之家!

相關(guān)文章

  • SpringBoot如何使用內(nèi)嵌Tomcat問(wèn)題

    SpringBoot如何使用內(nèi)嵌Tomcat問(wèn)題

    這篇文章主要介紹了SpringBoot如何使用內(nèi)嵌Tomcat問(wèn)題,具有很好的參考價(jià)值,希望對(duì)大家有所幫助。如有錯(cuò)誤或未考慮完全的地方,望不吝賜教
    2023-06-06
  • Java實(shí)現(xiàn)年獸大作戰(zhàn)游戲詳解

    Java實(shí)現(xiàn)年獸大作戰(zhàn)游戲詳解

    春節(jié)要到了,看慣了前端各種小游戲,確實(shí)做得很好,很精致。本文將為大家介紹一款java版本的年獸大作戰(zhàn)游戲,感興趣的小伙伴可以試一試
    2022-01-01
  • RabbitMQ的安裝和配置可視化界面的詳細(xì)步驟

    RabbitMQ的安裝和配置可視化界面的詳細(xì)步驟

    這篇文章主要介紹了RabbitMQ的安裝和配置可視化界面的詳細(xì)步驟,本文給大家介紹的非常詳細(xì),對(duì)大家的學(xué)習(xí)或工作具有一定的參考借鑒價(jià)值,需要的朋友可以參考下
    2022-06-06
  • Java8 Stream中間操作實(shí)例解析

    Java8 Stream中間操作實(shí)例解析

    這篇文章主要介紹了Java8 Stream中間操作實(shí)例解析,文中通過(guò)示例代碼介紹的非常詳細(xì),對(duì)大家的學(xué)習(xí)或者工作具有一定的參考學(xué)習(xí)價(jià)值,需要的朋友可以參考下
    2019-12-12
  • java中Calendar.add()方法的使用

    java中Calendar.add()方法的使用

    本文主要介紹了java中Calendar.add()方法的使用,文中通過(guò)示例代碼介紹的非常詳細(xì),對(duì)大家的學(xué)習(xí)或者工作具有一定的參考學(xué)習(xí)價(jià)值,需要的朋友們下面隨著小編來(lái)一起學(xué)習(xí)學(xué)習(xí)吧
    2023-04-04
  • Java編程求二叉樹(shù)的鏡像兩種方法介紹

    Java編程求二叉樹(shù)的鏡像兩種方法介紹

    這篇文章主要介紹了Java編程求二叉樹(shù)的鏡像兩種方法介紹,分享了兩種方法,遞歸與非遞歸,每種方法又分別介紹了兩種解決思路,具有一定參考價(jià)值,需要的朋友可以了解下。
    2017-11-11
  • Java的動(dòng)態(tài)代理模式之Cglib代理詳解

    Java的動(dòng)態(tài)代理模式之Cglib代理詳解

    這篇文章主要介紹了Java的動(dòng)態(tài)代理模式之Cglib代理詳解,Cglib代理也叫作?子類代理,它是在內(nèi)存中構(gòu)建一個(gè)子類對(duì)象從而實(shí)現(xiàn)對(duì)目標(biāo)對(duì)象功能擴(kuò)展,?有些書(shū)也將Cglib代理歸屬到動(dòng)態(tài)代理,需要的朋友可以參考下
    2023-11-11
  • java判斷l(xiāng)ist不為空的實(shí)現(xiàn),和限制條數(shù)不要在一起寫(xiě)

    java判斷l(xiāng)ist不為空的實(shí)現(xiàn),和限制條數(shù)不要在一起寫(xiě)

    這篇文章主要介紹了java判斷l(xiāng)ist不為空的實(shí)現(xiàn),和限制條數(shù)不要在一起寫(xiě)。具有很好的參考價(jià)值,希望對(duì)大家有所幫助。一起跟隨小編過(guò)來(lái)看看吧
    2021-01-01
  • springboot中如何使用自定義兩級(jí)緩存

    springboot中如何使用自定義兩級(jí)緩存

    本話題主要就是討論如何在springboot的基礎(chǔ)上,無(wú)縫集成ehcache和redis作為一二級(jí)緩存,并且實(shí)現(xiàn)緩存同步。
    2021-05-05
  • 使用spring+maven不同環(huán)境讀取配置方式

    使用spring+maven不同環(huán)境讀取配置方式

    這篇文章主要介紹了使用spring+maven不同環(huán)境讀取配置方式,具有很好的參考價(jià)值,希望對(duì)大家有所幫助,如有錯(cuò)誤或未考慮完全的地方,望不吝賜教
    2023-08-08

最新評(píng)論