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

一文詳解SpringBoot如何優(yōu)雅地實(shí)現(xiàn)異步調(diào)用

 更新時(shí)間:2023年03月17日 10:26:54   作者:JAVA旭陽(yáng)  
SpringBoot想必大家都用過(guò),但是大家平時(shí)使用發(fā)布的接口大都是同步的,那么你知道如何優(yōu)雅的實(shí)現(xiàn)異步呢?這篇文章就來(lái)和大家詳細(xì)聊聊

前言

SpringBoot想必大家都用過(guò),但是大家平時(shí)使用發(fā)布的接口大都是同步的,那么你知道如何優(yōu)雅的實(shí)現(xiàn)異步呢?

這篇文章就是關(guān)于如何在Spring Boot中實(shí)現(xiàn)異步行為的。但首先,讓我們看看同步和異步之間的區(qū)別。

  • 同步編程:在同步編程中,任務(wù)一次執(zhí)行一個(gè),只有當(dāng)一個(gè)任務(wù)完成時(shí),下一個(gè)任務(wù)才會(huì)被解除阻塞。
  • 異步編程:在異步編程中,可以同時(shí)執(zhí)行多個(gè)任務(wù)。您可以在上一個(gè)任務(wù)完成之前轉(zhuǎn)到另一個(gè)任務(wù)。

Spring Boot中,我們可以使用@Async注解來(lái)實(shí)現(xiàn)異步行為。

實(shí)現(xiàn)步驟

1.定義一個(gè)異步服務(wù)接口AsyncService.java

public interface AsyncService {

    void asyncMethod() throws InterruptedException;

    Future<String> futureMethod() throws InterruptedException;
}

2.實(shí)現(xiàn)定義的接口AsyncServiceImpl.java

@Service
@Slf4j
public class AsyncServiceImpl implements AsyncService  {

    @Async
    @Override
    public void asyncMethod() throws InterruptedException {
        Thread.sleep(3000);
        log.info("Thread: [{}], Calling other service..", Thread.currentThread().getName());
    }

    @Async
    @Override
    public Future<String> futureMethod() throws InterruptedException {
        Thread.sleep(5000);
        log.info("Thread: [{}], Calling other service..", Thread.currentThread().getName());
        return new AsyncResult<>("task Done");
    }
}
  • AsyncServiceImpl 是一個(gè) spring 管理的 bean。
  • 您的異步方法必須是公共的,而且是被@Async注解修飾。
  • 返回類(lèi)型被限制為 void 或 Future

3.定義一個(gè)控制器AsyncController.java

@EnableAsync
@RestController
@Slf4j
public class AsyncController {
    @Autowired
    AsyncService asyncService;

    @GetMapping("/async")
    public String asyncCallerMethod() throws InterruptedException {
        long start = System.currentTimeMillis();
        log.info("call async method, thread name: [{}]", Thread.currentThread().getName());
        asyncService.asyncMethod();
        String response = "task completes in :" +
                (System.currentTimeMillis() - start) + "milliseconds";
        return response;
    }

    @GetMapping("/asyncFuture")
    public String asyncFuture() throws InterruptedException, ExecutionException {
        long start = System.currentTimeMillis();
        log.info("call async method, thread name: [{}]", Thread.currentThread().getName());
        Future<String> future = asyncService.futureMethod();
        // 阻塞獲取結(jié)果
        String taskResult = future.get();
        String response = taskResult + "task completes in :" +
                (System.currentTimeMillis() - start) + "milliseconds";
        return response;
    }
}
  • 關(guān)鍵點(diǎn),需要添加啟用異步的注解@EnableAsync ,當(dāng)然這個(gè)注解加在其他地方也ok得。
  • 當(dāng)外部調(diào)用該接口時(shí),asyncMethod()將由默認(rèn)任務(wù)執(zhí)行程序創(chuàng)建的另一個(gè)線(xiàn)程執(zhí)行,主線(xiàn)程不需要等待完成異步方法執(zhí)行。

4.運(yùn)行一下

現(xiàn)在我們運(yùn)行一下看看,是不是異步返回的。

可以看到調(diào)用/async接口,最終一步調(diào)用了方法。

調(diào)用/asyncFuture,發(fā)現(xiàn)返回5秒多,難道不是異步的嗎?其實(shí)也是異步的,看日志可以看出來(lái),只不過(guò)我們返回的是Future,調(diào)用Futrue.get()是阻塞的。

自定義異步任務(wù)執(zhí)行器和異常處理

我們現(xiàn)在看看如果異常方法中報(bào)錯(cuò)了會(huì)怎么樣?修改異步代碼如下所示,會(huì)拋運(yùn)行時(shí)異常:

再次執(zhí)行異步接口,如下所示,會(huì)使用默認(rèn)的線(xiàn)程池和異常處理。

我們也可以自定義異步方法的處理異常和異步任務(wù)執(zhí)行器,我們需要配置 AsyncUncaughtExceptionHandler,如下代碼所示:

@Configuration
public class AsynConfiguration extends AsyncConfigurerSupport {
   @Override
   public Executor getAsyncExecutor() {
      ThreadPoolTaskExecutor executor = new 
                ThreadPoolTaskExecutor();
      executor.setCorePoolSize(3);
      executor.setMaxPoolSize(4);
      executor.setThreadNamePrefix("asyn-task-thread-");
      executor.setWaitForTasksToCompleteOnShutdown(true);
      executor.initialize();
      return executor;
  }
  @Override
  public AsyncUncaughtExceptionHandler  
         getAsyncUncaughtExceptionHandler() {
     return new AsyncUncaughtExceptionHandler() {
   
        @Override
        public void handleUncaughtException(Throwable ex, 
           Method method, Object... params) {
           System.out.println("Exception: " + ex.getMessage());
           System.out.println("Method Name: " + method.getName());
           ex.printStackTrace();
        }
    };
  }
}

再次運(yùn)行,得到的結(jié)果如下:

@Async如何工作的

必須通過(guò)使用 @EnableAsync注解注解主應(yīng)用程序類(lèi)或任何直接或間接異步方法調(diào)用程序類(lèi)來(lái)啟用異步支持。主要通過(guò)代理模式實(shí)現(xiàn),默認(rèn)模式是 Proxy,另一種是 AspectJ。代理模式只允許通過(guò)代理攔截調(diào)用。永遠(yuǎn)不要從定義它的同一個(gè)類(lèi)調(diào)用異步方法,它不會(huì)起作用。

當(dāng)使用 @Async對(duì)方法進(jìn)行注解時(shí),它會(huì)根據(jù)“proxyTargetClass”屬性為該對(duì)象創(chuàng)建一個(gè)代理。當(dāng) spring 執(zhí)行這個(gè)方法時(shí),默認(rèn)情況下它會(huì)搜索關(guān)聯(lián)的線(xiàn)程池定義。上下文中唯一的 spring 框架 TaskExecutor bean 或名為“taskExecutor”的 Executor bean。如果這兩者都不可解析,默認(rèn)會(huì)使用spring框架SimpleAsyncTaskExecutor來(lái)處理異步方法的執(zhí)行。

總結(jié)

在本文中,我們演示了在 spring boot 中如何使用 @Async 注解和異步方法中的異常處理實(shí)現(xiàn)異步行為。我們可以在一個(gè)接口中,需要訪(fǎng)問(wèn)不同的資源,比如異步調(diào)用各個(gè)其他服務(wù)的接口,可以使用@Async,然后將結(jié)果通過(guò)Future的方式阻塞匯總,不失為一個(gè)提高性能的好方法。

到此這篇關(guān)于一文詳解SpringBoot如何優(yōu)雅地實(shí)現(xiàn)異步調(diào)用的文章就介紹到這了,更多相關(guān)SpringBoot異步調(diào)用內(nèi)容請(qǐng)搜索腳本之家以前的文章或繼續(xù)瀏覽下面的相關(guān)文章希望大家以后多多支持腳本之家!

相關(guān)文章

  • Java中二維數(shù)組的正確使用方法介紹

    Java中二維數(shù)組的正確使用方法介紹

    Java中有一維數(shù)組,二維數(shù)組以及多維數(shù)組,在這篇文章中,將給大家詳細(xì)介紹一下如何正確使用Java中的二維數(shù)組,感興趣的小伙伴跟著小編一起學(xué)習(xí)吧
    2023-05-05
  • java線(xiàn)程中synchronized和Lock區(qū)別及介紹

    java線(xiàn)程中synchronized和Lock區(qū)別及介紹

    這篇文章主要為大家介紹了java線(xiàn)程中synchronized和Lock區(qū)別及介紹,有需要的朋友可以借鑒參考下,希望能夠有所幫助,祝大家多多進(jìn)步,早日升職加薪
    2023-06-06
  • Jmeter如何添加循環(huán)控制器

    Jmeter如何添加循環(huán)控制器

    這篇文章主要介紹了Jmeter如何添加循環(huán)控制器,文中通過(guò)示例代碼介紹的非常詳細(xì),對(duì)大家的學(xué)習(xí)或者工作具有一定的參考學(xué)習(xí)價(jià)值,需要的朋友可以參考下
    2020-02-02
  • SpringBoot中的ApplicationRunner與CommandLineRunner問(wèn)題

    SpringBoot中的ApplicationRunner與CommandLineRunner問(wèn)題

    這篇文章主要介紹了SpringBoot中的ApplicationRunner與CommandLineRunner問(wèn)題,具有很好的參考價(jià)值,希望對(duì)大家有所幫助。如有錯(cuò)誤或未考慮完全的地方,望不吝賜教
    2022-09-09
  • Javaweb基礎(chǔ)入門(mén)requse原理與使用

    Javaweb基礎(chǔ)入門(mén)requse原理與使用

    Request對(duì)象的作用是與客戶(hù)端交互,收集客戶(hù)端的Form、Cookies、超鏈接,或者收集服務(wù)器端的環(huán)境變量,接下來(lái)本篇將詳細(xì)講述
    2021-11-11
  • Spring如何基于注解配置使用ehcache

    Spring如何基于注解配置使用ehcache

    這篇文章主要介紹了Spring如何基于注解配置使用ehcache,文中通過(guò)示例代碼介紹的非常詳細(xì),對(duì)大家的學(xué)習(xí)或者工作具有一定的參考學(xué)習(xí)價(jià)值,需要的朋友可以參考下
    2020-10-10
  • Java基礎(chǔ)知識(shí)精通各種運(yùn)算符

    Java基礎(chǔ)知識(shí)精通各種運(yùn)算符

    計(jì)算機(jī)的最基本用途之一就是執(zhí)行數(shù)學(xué)運(yùn)算,作為一門(mén)計(jì)算機(jī)語(yǔ)言,Java也提供了一套豐富的運(yùn)算符來(lái)操縱變量,本篇對(duì)大家的學(xué)習(xí)或工作具有一定的價(jià)值,需要的朋友可以參考下
    2022-04-04
  • Java中的==使用方法詳解

    Java中的==使用方法詳解

    這篇文章主要介紹了Java中“==”的使用方法,,==可以使用在基本數(shù)據(jù)類(lèi)型變量和引用數(shù)據(jù)類(lèi)型變量中,equals()是方法,只能用于引用數(shù)據(jù)類(lèi)型,需要的朋友可以參考下
    2022-09-09
  • Java CompletableFuture如何實(shí)現(xiàn)超時(shí)功能

    Java CompletableFuture如何實(shí)現(xiàn)超時(shí)功能

    這篇文章主要為大家介紹了實(shí)現(xiàn)超時(shí)功能的基本思路以及CompletableFuture(之后簡(jiǎn)稱(chēng)CF)是如何通過(guò)代碼實(shí)現(xiàn)超時(shí)功能的,需要的小伙伴可以了解下
    2025-01-01
  • 如何在Java中讀取resources下的文件及資源路徑

    如何在Java中讀取resources下的文件及資源路徑

    本文介紹了如何在Java中讀取resources下的文件以及獲取resource文件的路徑,通過(guò)使用ClassLoader或Class的getResourceAsStream方法,可以輕松地讀取resources目錄下的文件,感興趣的朋友跟隨小編一起看看吧
    2023-06-06

最新評(píng)論

金华市| 佳木斯市| 云龙县| 朝阳县| 通城县| 峨眉山市| 吉木萨尔县| 滨海县| 平舆县| 大兴区| 肇州县| 大宁县| 穆棱市| 内黄县| 建德市| 南川市| 德安县| 浠水县| 天全县| 石林| 吕梁市| 南靖县| 册亨县| 康马县| 雅江县| 新乡市| 木里| 苍溪县| 佛坪县| 红桥区| 八宿县| 石首市| 垣曲县| 石屏县| 卢龙县| 祁东县| 和平县| 全椒县| 冀州市| 蓬溪县| 西青区|