亚洲乱码中文字幕综合,中国熟女仑乱hd,亚洲精品乱拍国产一区二区三区,一本大道卡一卡二卡三乱码全集资源,又粗又黄又硬又爽的免费视频

SpringBoot異步調(diào)用相同類的解決方案

 更新時間:2025年02月14日 11:15:12   作者:平凡的夢  
在SpringBoot中,同一個類中調(diào)用帶有@Async注解的方法時,異步調(diào)用會失效,因為直接通過this調(diào)用方法時,并沒有通過Spring的代理對象,下面給大家分享SpringBoot異步調(diào)用相同類的解決方案,感興趣的朋友一起看看吧

在之前的文章中,我們學(xué)習(xí)了Spring Boot中的異步調(diào)用機(jī)制,以及如何使用@Async注解來實現(xiàn)方法的異步執(zhí)行。然而,在實際開發(fā)中,我們可能會遇到這樣一個問題:在同一個類中調(diào)用帶有@Async注解的方法時,異步調(diào)用竟然失效了!這究竟是為什么呢?今天,我們就來深入探討一下這個問題,并給出幾種可行的解決方案。

一、問題介紹

在Spring Boot中,@Async注解被廣泛應(yīng)用于實現(xiàn)方法的異步執(zhí)行。通常,我們只需要在方法上添加@Async注解,并在啟動類上添加@EnableAsync注解,就可以實現(xiàn)方法的異步調(diào)用了。然而,當(dāng)我們在同一個類中調(diào)用帶有@Async注解的方法時,卻發(fā)現(xiàn)異步調(diào)用并沒有生效,方法仍然是同步執(zhí)行的。

原因分析

這個問題的根源在于Spring的AOP(面向切面編程)代理機(jī)制。在Spring中,@Async注解的實現(xiàn)依賴于AOP代理。當(dāng)我們在一個類中調(diào)用另一個方法時,如果直接通過this來調(diào)用(即類內(nèi)部調(diào)用),那么實際上并沒有通過Spring的代理對象來調(diào)用該方法,因此@Async注解也就無法生效了。

二、解決方案

2.1 將異步方法拆分到另一個Bean中

這是最簡單也是最推薦的一種解決方案。我們可以將帶有@Async注解的異步方法拆分到另一個Bean中,然后在原類中注入這個Bean,并通過調(diào)用這個Bean的方法來實現(xiàn)異步執(zhí)行。

步驟:

創(chuàng)建異步方法所在的Bean‌:

@Service
public class AsyncService {
    @Async
    public void asyncMethod() {
        // 異步方法的實現(xiàn)
        System.out.println("Async method starts");
        try { Thread.sleep(1000); } catch (InterruptedException e) {}
        System.out.println("Async method ends");
    }
}

在原類中注入異步Bean并調(diào)用‌:

@Service
public class MyService {
    @Autowired
    private AsyncService asyncService;
    public void myMethod() {
        System.out.println("My method starts");
        asyncService.asyncMethod();
        System.out.println("My method ends");
    }
}

實現(xiàn)效果:

  • 當(dāng)調(diào)用myMethod時,asyncMethod會在獨立的線程中異步執(zhí)行。
  • 控制臺輸出順序:My method starts -> My method ends -> Async method starts -> Async method ends(注意這里的順序可能會因為線程調(diào)度而有所差異)。

2.2 自注入當(dāng)前Bean

如果出于某種原因,我們不想將異步方法拆分到另一個Bean中,那么可以考慮使用自注入的方式。即在原類中注入自己,然后通過注入的實例來調(diào)用異步方法。

步驟: ‌在原類中注入自己‌:

@Service
public class MyService {
    @Autowired
    private MyService self;
    public void myMethod() {
        System.out.println("My method starts");
        self.asyncMethod();
        System.out.println("My method ends");
    }
    @Async
    public void asyncMethod() {
        // 異步方法的實現(xiàn)
        System.out.println("Async method starts");
        try { Thread.sleep(1000); } catch (InterruptedException e) {}
        System.out.println("Async method ends");
    }
}

注意‌:使用自注入需要確保沒有循環(huán)依賴的問題。通常,如果只是方法調(diào)用的話,可能不會有問題。但為了避免潛在的風(fēng)險,我們可以使用@Lazy注解來延遲Bean的加載。

實現(xiàn)效果:

  • 當(dāng)調(diào)用myMethod時,asyncMethod會在獨立的線程中異步執(zhí)行。
  • 控制臺輸出順序與上一種方案類似。

2.3 使用AopContext獲取代理對象

另一種解決方案是使用AopContext來獲取當(dāng)前類的代理對象,并通過代理對象來調(diào)用異步方法。但這種方法需要開啟exposeProxy選項,并且代碼可能不夠直觀。

步驟:

在啟動類上開啟exposeProxy‌:

@SpringBootApplication
@EnableAsync
@EnableAspectJAutoProxy(exposeProxy = true)
public class MyApplication {
    public static void main(String[] args) {
        SpringApplication.run(MyApplication.class, args);
    }
}

在方法中使用AopContext獲取代理對象‌:

@Service
public class MyService {
    public void myMethod() {
        System.out.println("My method starts");
        ((MyService) AopContext.currentProxy()).asyncMethod();
        System.out.println("My method ends");
    }
    @Async
    public void asyncMethod() {
        // 異步方法的實現(xiàn)
        System.out.println("Async method starts");
        try { Thread.sleep(1000); } catch (InterruptedException e) {}
        System.out.println("Async method ends");
    }
}

實現(xiàn)效果:

  • 當(dāng)調(diào)用myMethod時,asyncMethod會在獨立的線程中異步執(zhí)行。
  • 控制臺輸出順序與前面兩種方案類似。

注意‌:使用AopContext獲取代理對象的方法需要確保AOP代理已經(jīng)正確暴露,并且代碼中存在類型轉(zhuǎn)換,可能不夠安全。因此,在實際開發(fā)中需要謹(jǐn)慎使用。

2.4 使用ApplicationContext獲取Bean實例

還有一種方法是使用ApplicationContext來獲取Bean實例,并通過該實例來調(diào)用異步方法。但這種方法可能會有循環(huán)依賴的問題,或者代碼看起來不夠直觀。

步驟: ‌在類中注入ApplicationContext‌:

@Service
public class MyService {
    @Autowired
    private ApplicationContext applicationContext;
    public void myMethod() {
        System.out.println("My method starts");
        MyService myService = applicationContext.getBean(MyService.class);
        myService.asyncMethod();
        System.out.println("My method ends");
    }
    @Async
    public void asyncMethod() {
        // 異步方法的實現(xiàn)
        System.out.println("Async method starts");
        try { Thread.sleep(1000); } catch (InterruptedException e) {}
        System.out.println("Async method ends");
    }
}

實現(xiàn)效果:

  • 當(dāng)調(diào)用myMethod時,asyncMethod會在獨立的線程中異步執(zhí)行。
  • 控制臺輸出順序與前面幾種方案類似。

注意‌:使用ApplicationContext獲取Bean實例的方法可能會有循環(huán)依賴的問題,特別是在復(fù)雜的依賴關(guān)系中。因此,在實際開發(fā)中需要謹(jǐn)慎使用,并確保沒有引入新的問題。

總結(jié)

  • 推薦方案:將異步方法拆分到另一個Bean,代碼結(jié)構(gòu)清晰且符合Spring設(shè)計。
  • 自注入:適用于簡單場景,需注意循環(huán)依賴。
  • AopContext:靈活但需額外配置,適合無法修改類結(jié)構(gòu)的情況。

以上就是SpringBoot異步調(diào)用相同類的方法的詳細(xì)內(nèi)容,更多關(guān)于SpringBoot異步調(diào)用的資料請關(guān)注腳本之家其它相關(guān)文章!

到此這篇關(guān)于SpringBoot異步調(diào)用相同類的解決方案的文章就介紹到這了,更多相關(guān)SpringBoot異步調(diào)用內(nèi)容請搜索腳本之家以前的文章或繼續(xù)瀏覽下面的相關(guān)文章希望大家以后多多支持腳本之家!

相關(guān)文章

  • SpringMVC與前端交互案例教程

    SpringMVC與前端交互案例教程

    本篇文章主要介紹了SpringMVC前端和后端數(shù)據(jù)交互總結(jié),具有一定的參考價值,感興趣的小伙伴們可以參考一下。希望能給你帶來幫助
    2021-07-07
  • springboot整合rabbitmq的示例代碼

    springboot整合rabbitmq的示例代碼

    本篇文章主要介紹了springboot整合rabbitmq的示例代碼,小編覺得挺不錯的,現(xiàn)在分享給大家,也給大家做個參考。一起跟隨小編過來看看吧
    2017-12-12
  • java構(gòu)造函數(shù)示例(構(gòu)造方法)

    java構(gòu)造函數(shù)示例(構(gòu)造方法)

    這篇文章主要介紹了java構(gòu)造函數(shù)示例(構(gòu)造方法),需要的朋友可以參考下
    2014-03-03
  • 手把手教你搭建SpringMVC框架——最小化配置

    手把手教你搭建SpringMVC框架——最小化配置

    這篇文章主要介紹了手把手教你搭建SpringMVC框架——最小化配置,具有一定的參考價值,感興趣的小伙伴們可以參考一下。
    2017-02-02
  • 一文詳解SpringBoot中CommandLineRunner接口

    一文詳解SpringBoot中CommandLineRunner接口

    Spring Boot的CommandLineRunner接口是一個函數(shù)式接口,用于在Spring Boot應(yīng)用程序啟動后執(zhí)行一些初始化操作,它提供了一個run方法,該方法在應(yīng)用程序啟動后被調(diào)用,本文給大家詳細(xì)介紹了SpringBoot中CommandLineRunner接口,需要的朋友可以參考下
    2023-10-10
  • SpringBoot使用jasypt實現(xiàn)數(shù)據(jù)庫信息脫敏的方法詳解

    SpringBoot使用jasypt實現(xiàn)數(shù)據(jù)庫信息脫敏的方法詳解

    這篇文章主要介紹了SpringBoot使用jasypt實現(xiàn)數(shù)據(jù)庫信息的脫敏,以此來保護(hù)數(shù)據(jù)庫的用戶名username和密碼password(容易上手,詳細(xì)),文中有詳細(xì)的圖文講解和代碼示例供大家參考,需要的朋友可以參考下
    2024-06-06
  • spring boot 自定義參數(shù)過濾器,把傳入的空字符轉(zhuǎn)換成null方式

    spring boot 自定義參數(shù)過濾器,把傳入的空字符轉(zhuǎn)換成null方式

    這篇文章主要介紹了spring boot 自定義參數(shù)過濾器,把傳入的空字符轉(zhuǎn)換成null方式。具有很好的參考價值,希望對大家有所幫助。如有錯誤或未考慮完全的地方,望不吝賜教
    2021-08-08
  • MyBatis 實現(xiàn)數(shù)據(jù)的批量新增和刪除的操作

    MyBatis 實現(xiàn)數(shù)據(jù)的批量新增和刪除的操作

    這篇文章主要介紹了MyBatis 實現(xiàn)數(shù)據(jù)的批量新增和刪除的操作,具有很好的參考價值,希望對大家有所幫助。一起跟隨小編過來看看吧
    2021-02-02
  • Java多線程之等待隊列DelayQueue詳解

    Java多線程之等待隊列DelayQueue詳解

    這篇文章主要介紹了Java多線程之等待隊列DelayQueue詳解,    DelayQueue被稱作"等待隊列"或"JDK延遲隊列",存放著實現(xiàn)了Delayed接口的對象,對象需要設(shè)置到期時間,當(dāng)且僅當(dāng)對象到期,才能夠從隊列中被取走(并非一定被取走),需要的朋友可以參考下
    2023-12-12
  • Spring Boot2配置Swagger2生成API接口文檔詳情

    Spring Boot2配置Swagger2生成API接口文檔詳情

    這篇文章主要介紹了Spring Boot2配置Swagger2生成API接口文檔詳情,文章圍繞主題展開詳細(xì)的內(nèi)容介紹,具有一定的參考價值,需要的小伙伴可以參考一下
    2022-09-09

最新評論