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

SpringBoot中統(tǒng)一同步與異步執(zhí)行模型的示例詳解

 更新時(shí)間:2025年12月22日 08:53:34   作者:風(fēng)象南  
這篇文章主要為大家詳細(xì)介紹了SpringBoot中如何統(tǒng)一同步與異步執(zhí)行模型,文中的示例代碼講解詳細(xì),感興趣的小伙伴可以跟隨小編一起學(xué)習(xí)一下

背景

在項(xiàng)目開(kāi)發(fā)中,只要同時(shí)使用同步和異步執(zhí)行邏輯,很容易出現(xiàn)代碼混亂的問(wèn)題,一開(kāi)始大家覺(jué)得這只是“執(zhí)行方式不同”,沒(méi)什么大不了。但隨著業(yè)務(wù)復(fù)雜度上升,問(wèn)題逐漸暴露:

1、同步能實(shí)時(shí)拿到結(jié)果、捕獲異常,異步失敗了只能靠日志排查;

2、請(qǐng)求ID、操作人這些上下文信息,在異步執(zhí)行時(shí)經(jīng)常“丟失”;

3、新入隊(duì)同學(xué)需要刻意記住每個(gè)方法是同步還是異步,稍不注意就踩坑;

4、日志、審計(jì)、監(jiān)控這些通用邏輯,同步和異步要各加一遍。

其實(shí)根源不是“不能用異步”,而是大家把同步和異步當(dāng)成了兩套完全獨(dú)立的執(zhí)行體系——但對(duì)業(yè)務(wù)來(lái)說(shuō),它們本質(zhì)上都是“一次業(yè)務(wù)執(zhí)行”。

解決方案

換個(gè)思路:先把“業(yè)務(wù)執(zhí)行”本身抽象出來(lái),再用統(tǒng)一的引擎來(lái)處理“執(zhí)行方式”。

也就是說(shuō),業(yè)務(wù)只需要關(guān)心“做什么”,不需要關(guān)心“怎么執(zhí)行”;至于是同步還是異步,交給底層引擎決定。

這樣做的好處很明確:

  • 業(yè)務(wù)代碼更聚焦,不再混雜執(zhí)行細(xì)節(jié);
  • 同步/異步用同一種模型,上下文、異常、日志自然統(tǒng)一;
  • 未來(lái)切換執(zhí)行方式或擴(kuò)展能力(重試、限流等),無(wú)需修改業(yè)務(wù)代碼。

技術(shù)實(shí)現(xiàn)

1. 定義“執(zhí)行單元”:業(yè)務(wù)的最小執(zhí)行單位

先抽象出一個(gè)最簡(jiǎn)潔的接口,代表“一次業(yè)務(wù)執(zhí)行”:

public interface Execution<R> {
    R execute(ExecutionContext context) throws Exception;
}

這個(gè)接口只包含業(yè)務(wù)關(guān)心的元素:有上下文(ExecutionContext)、有執(zhí)行結(jié)果(R)、可能拋出異常。它不關(guān)心任何執(zhí)行細(xì)節(jié)——同步還是異步、用哪個(gè)線程池、怎么調(diào)度,都和它沒(méi)關(guān)系。

2. 統(tǒng)一“執(zhí)行上下文”:讓信息在執(zhí)行中流動(dòng)

上下文是業(yè)務(wù)執(zhí)行的“環(huán)境變量”,我們用ThreadLocal實(shí)現(xiàn)上下文的跨線程傳遞:

public class ExecutionContext {
    // 用 ThreadLocal 存儲(chǔ)當(dāng)前上下文
    private static final ThreadLocal<ExecutionContext> CONTEXT_HOLDER =
        ThreadLocal.withInitial(ExecutionContext::new);

    private String requestId;   // 鏈路跟蹤用的請(qǐng)求ID
    private String operator;    // 操作人,用于審計(jì)
    private Map<String, Object> attributes = new HashMap<>();  // 業(yè)務(wù)參數(shù)

    /** 獲取當(dāng)前上下文 */
    public static ExecutionContext current() {
        return CONTEXT_HOLDER.get();
    }

    /** 設(shè)置上下文 */
    public static void set(ExecutionContext context) {
        CONTEXT_HOLDER.set(context);
    }

    /** 清理上下文 */
    public static void clear() {
        CONTEXT_HOLDER.remove();
    }

    // getter/setter 省略
}

3.上下文的實(shí)際使用流程

請(qǐng)求入口設(shè)置上下文

在請(qǐng)求入口(如 Controller/Filter)統(tǒng)一初始化和設(shè)置上下文:

@RestController
public class OrderController {

    @PostMapping("/order")
    public String createOrder(@RequestBody Order order) {
        // 1. 構(gòu)建上下文
        ExecutionContext context = new ExecutionContext();
        context.setRequestId(UUID.randomUUID().toString()); // 生成或從請(qǐng)求頭獲取
        context.setOperator("currentUser"); // 從登錄信息獲取
        context.getAttributes().put("order", order);

        // 2. 綁定到當(dāng)前線程
        ExecutionContext.set(context);

        try {
            // 3. 提交業(yè)務(wù)執(zhí)行(同步/異步由引擎決定)
            ExecutionResult<Boolean> result = executorEngine.submit(ctx -> {
                Order orderFromCtx = ctx.getAttribute("order");
                orderService.createOrder(orderFromCtx);
                return true;
            });
            return "success";
        } finally {
            // 4. 請(qǐng)求結(jié)束清理上下文,避免內(nèi)存泄漏
            ExecutionContext.clear();
        }
    }
}

實(shí)現(xiàn)“執(zhí)行引擎”:統(tǒng)一的執(zhí)行入口

有了執(zhí)行單元和上下文,接下來(lái)需要一個(gè)統(tǒng)一的入口來(lái)執(zhí)行它們:

public interface ExecutorEngine {
    <R> ExecutionResult<R> submit(Execution<R> execution);
}

業(yè)務(wù)側(cè)只需要提交執(zhí)行單元,不需要關(guān)心執(zhí)行方式。執(zhí)行引擎會(huì)根據(jù)配置自動(dòng)處理同步或異步。

同步執(zhí)行引擎:最簡(jiǎn)單的實(shí)現(xiàn),直接在當(dāng)前線程執(zhí)行

public class SyncExecutorEngine implements ExecutorEngine {
    @Override
    public <R> ExecutionResult<R> submit(Execution<R> execution) {
        try {
            R result = execution.execute(ExecutionContext.current());
            return ExecutionResult.success(result);
        } catch (Exception e) {
            return ExecutionResult.failure(e);
        }
    }
}

異步執(zhí)行引擎:復(fù)用線程池,支持上下文傳遞

public class AsyncExecutorEngine implements ExecutorEngine {
    private final Executor executor;

    public AsyncExecutorEngine(Executor executor) {
        this.executor = executor;
    }

    @Override
    public <R> ExecutionResult<R> submit(Execution<R> execution) {
        // 捕獲當(dāng)前線程上下文并傳遞到異步線程
        ExecutionContext currentCtx = ExecutionContext.current();
        CompletableFuture<R> future = CompletableFuture.supplyAsync(() -> {
            try {
                ExecutionContext.set(currentCtx);
                return execution.execute(ExecutionContext.current());
            } catch (Exception e) {
                throw new RuntimeException(e);
            } finally {
                // 清理上下文避免內(nèi)存泄漏
                ExecutionContext.clear();
            }
        }, executor);
        return ExecutionResult.async(future);
    }
}

業(yè)務(wù)側(cè)的使用方式

業(yè)務(wù)只需要把原來(lái)的代碼封裝成執(zhí)行單元,交給引擎處理:

// 原來(lái)的同步/異步代碼無(wú)需再維護(hù)兩套
executorEngine.submit(ctx -> {
    Order order = ctx.getAttribute("order");
    orderService.createOrder(order);
    return true;
});

這段代碼:

  • 不關(guān)心是同步還是異步執(zhí)行;
  • 上下文自動(dòng)傳遞;
  • 異常由引擎統(tǒng)一處理;
  • 日志、審計(jì)等通用邏輯在引擎層一次性處理,自動(dòng)生效。

總結(jié)

通過(guò)統(tǒng)一執(zhí)行模型的設(shè)計(jì),我們可以將 業(yè)務(wù)邏輯執(zhí)行方式清晰分離,這套模型在項(xiàng)目中能解決幾個(gè)實(shí)際問(wèn)題:

1. 代碼可控:不再到處是 @AsyncCompletableFuture,所有執(zhí)行都有統(tǒng)一入口;

2. 上下文不丟:請(qǐng)求ID、操作人等信息在同步/異步中都能正確傳遞;

3. 擴(kuò)展方便:要加重試、限流、熔斷?在引擎層統(tǒng)一實(shí)現(xiàn)即可,業(yè)務(wù)代碼無(wú)需修改;

4. 降低認(rèn)知成本:新同學(xué)不需要刻意區(qū)分同步/異步方法,調(diào)用方式完全一致。

到此這篇關(guān)于SpringBoot中統(tǒng)一同步與異步執(zhí)行模型的示例詳解的文章就介紹到這了,更多相關(guān)SpringBoot統(tǒng)一同步與異步內(nèi)容請(qǐng)搜索腳本之家以前的文章或繼續(xù)瀏覽下面的相關(guān)文章希望大家以后多多支持腳本之家!

相關(guān)文章

  • Java WeakHashMap案例詳解

    Java WeakHashMap案例詳解

    這篇文章主要介紹了Java WeakHashMap案例詳解,本篇文章通過(guò)簡(jiǎn)要的案例,講解了該項(xiàng)技術(shù)的了解與使用,以下就是詳細(xì)內(nèi)容,需要的朋友可以參考下
    2021-08-08
  • 基于ZooKeeper實(shí)現(xiàn)隊(duì)列源碼

    基于ZooKeeper實(shí)現(xiàn)隊(duì)列源碼

    這篇文章主要介紹了基于ZooKeeper實(shí)現(xiàn)隊(duì)列源碼的相關(guān)內(nèi)容,包括其實(shí)現(xiàn)原理和應(yīng)用場(chǎng)景,以及對(duì)隊(duì)列的簡(jiǎn)單介紹,具有一定參考價(jià)值,需要的朋友可以了解下。
    2017-09-09
  • SpringBoot整合Mybatis自定義攔截器不起作用的處理方案

    SpringBoot整合Mybatis自定義攔截器不起作用的處理方案

    這篇文章主要介紹了SpringBoot整合Mybatis自定義攔截器不起作用的處理方案,具有很好的參考價(jià)值,希望對(duì)大家有所幫助。如有錯(cuò)誤或未考慮完全的地方,望不吝賜教
    2021-09-09
  • Java進(jìn)階之高并發(fā)核心Selector詳解

    Java進(jìn)階之高并發(fā)核心Selector詳解

    前幾篇文章介紹了Java高并發(fā)的一些基礎(chǔ)內(nèi)容,認(rèn)識(shí)了Channel,Buffer和Selector的基本用法,有了感性認(rèn)識(shí)之后,來(lái)看看Selector的底層是如何實(shí)現(xiàn)的。,需要的朋友可以參考下
    2021-05-05
  • Spring官網(wǎng)下載各版本jar包的方法

    Spring官網(wǎng)下載各版本jar包的方法

    這篇文章主要介紹了Spring官網(wǎng)下載各版本jar包的方法,小編覺(jué)得挺不錯(cuò)的,現(xiàn)在分享給大家,也給大家做個(gè)參考。一起跟隨小編過(guò)來(lái)看看吧
    2019-04-04
  • mybatis plus時(shí)間判斷問(wèn)題

    mybatis plus時(shí)間判斷問(wèn)題

    在MyBatisPlus中,時(shí)間判斷可以通過(guò)XML轉(zhuǎn)義的方式實(shí)現(xiàn),例如使用>、<、<>、>=、<=進(jìn)行比較,這種方法涉及到SQL符號(hào)的轉(zhuǎn)義,確保查詢語(yǔ)句的安全性和準(zhǔn)確性,特別是在處理大于、小于和等于等邏輯時(shí),正確的轉(zhuǎn)義能夠防止SQL注入等安全問(wèn)題
    2024-09-09
  • JavaWeb響應(yīng)下載功能實(shí)例代碼(包含工具類(lèi))

    JavaWeb響應(yīng)下載功能實(shí)例代碼(包含工具類(lèi))

    今天通過(guò)本文給大家分享的是關(guān)于javaweb的響應(yīng)(response)下載功能,需要的朋友參考下吧
    2017-07-07
  • 一篇文章帶你了解Java Stream流

    一篇文章帶你了解Java Stream流

    Stream流是數(shù)據(jù)渠道,用于操作數(shù)據(jù)源(集合、數(shù)組等)所生成的元素序列。這篇文章主要介紹了Java8新特性Stream流的相關(guān)資料,需要的朋友參考下吧
    2021-08-08
  • java通過(guò)控制鼠標(biāo)實(shí)現(xiàn)屏幕廣播的方法

    java通過(guò)控制鼠標(biāo)實(shí)現(xiàn)屏幕廣播的方法

    這篇文章主要介紹了java通過(guò)控制鼠標(biāo)實(shí)現(xiàn)屏幕廣播的方法,針對(duì)前面一篇Java屏幕共享功能進(jìn)行了改進(jìn),實(shí)現(xiàn)了鼠標(biāo)控制功能,具有一定的實(shí)用價(jià)值,需要的朋友可以參考下
    2014-12-12
  • spring boot創(chuàng)建和數(shù)據(jù)庫(kù)關(guān)聯(lián)模塊詳解

    spring boot創(chuàng)建和數(shù)據(jù)庫(kù)關(guān)聯(lián)模塊詳解

    這篇文章主要給大家介紹了關(guān)于spring boot創(chuàng)建和數(shù)據(jù)庫(kù)關(guān)聯(lián)模塊的相關(guān)資料,文中通過(guò)示例代碼介紹的非常詳細(xì),對(duì)大家的學(xué)習(xí)或者工作具有一定的參考學(xué)習(xí)價(jià)值,需要的朋友們下面隨著小編來(lái)一起學(xué)習(xí)學(xué)習(xí)吧
    2020-10-10

最新評(píng)論

许昌市| 泰兴市| 伊吾县| 缙云县| 邓州市| 开平市| 綦江县| 德州市| 白城市| 洛南县| 兴业县| 林甸县| 六盘水市| 沙田区| 汝城县| 团风县| 黄浦区| 成都市| 襄汾县| 宝丰县| 托克逊县| 洪雅县| 东阿县| 哈巴河县| 郑州市| 青河县| 阳原县| 盈江县| 东丽区| 娄烦县| 青岛市| 济南市| 来凤县| 汶川县| 临泽县| 五原县| 隆尧县| 通化县| 屯留县| 河北省| 行唐县|