自拍偷在线精品自拍偷,亚洲欧美中文日韩v在线观看不卡

Spring Boot 中的異步請求和異步調(diào)用詳解

開發(fā) 前端
在現(xiàn)代應(yīng)用程序中,異步處理可以顯著提升性能和響應(yīng)速度。除了異步請求,一般上我們用的比較多的應(yīng)該是異步調(diào)用。通常在開發(fā)過程中,會遇到一個方法是和實(shí)際業(yè)務(wù)無關(guān)的,沒有緊密性的。比如記錄日志信息等業(yè)務(wù)。

在現(xiàn)代應(yīng)用程序中,異步處理可以顯著提升性能和響應(yīng)速度。除了異步請求,一般上我們用的比較多的應(yīng)該是異步調(diào)用。通常在開發(fā)過程中,會遇到一個方法是和實(shí)際業(yè)務(wù)無關(guān)的,沒有緊密性的。比如記錄日志信息等業(yè)務(wù)。這個時候正常就是啟一個新線程去做一些業(yè)務(wù)處理,讓主線程異步的執(zhí)行其他業(yè)務(wù)。本文將詳細(xì)介紹如何在 Spring Boot 中實(shí)現(xiàn)異步請求和異步調(diào)用,幫助大家在實(shí)際項(xiàng)目中應(yīng)用這些技術(shù)。

一、異步請求

1.1 使用 @Async 注解

Spring 提供了 @Async注解,使得我們可以簡單地將一個方法變成異步方法。為了啟用異步支持,需要在配置類上添加 @EnableAsync注解。

步驟:

1. 添加依賴:

<dependency>
       <groupId>org.springframework.boot</groupId>
       <artifactId>spring-boot-starter</artifactId>
   </dependency>

2. 啟用異步支持:

import org.springframework.context.annotation.Configuration;
   import org.springframework.scheduling.annotation.EnableAsync;
   @Configuration
   @EnableAsync
   public class AsyncConfig {
   }

3. 創(chuàng)建異步方法:

import org.springframework.scheduling.annotation.Async;
   import org.springframework.stereotype.Service;
   @Service
   public class AsyncService {
       @Async
       public void asyncMethod() {
           System.out.println("異步方法開始: " + Thread.currentThread().getName());
           try {
               Thread.sleep(2000); // 模擬長時間任務(wù)
           } catch (InterruptedException e) {
               e.printStackTrace();
           }
           System.out.println("異步方法結(jié)束: " + Thread.currentThread().getName());
       }
   }

4. 調(diào)用異步方法:

import org.springframework.beans.factory.annotation.Autowired;
   import org.springframework.web.bind.annotation.GetMapping;
   import org.springframework.web.bind.annotation.RestController;
   @RestController
   public class AsyncController {
       @Autowired
       private AsyncService asyncService;
       @GetMapping("/async")
       public String callAsync() {
           asyncService.asyncMethod();
           return "請求已提交";
       }
   }

1.2 使用 CompletableFuture

CompletableFuture 是 Java 8 引入的一個強(qiáng)大的異步工具類,Spring 也對其提供了良好的支持。

示例:

1. 創(chuàng)建返回 CompletableFuture 的異步方法:

import org.springframework.scheduling.annotation.Async;
   import org.springframework.stereotype.Service;
   import java.util.concurrent.CompletableFuture;
   @Service
   public class AsyncService {
       @Async
       public CompletableFuture<String> asyncMethodWithResult() {
           System.out.println("異步方法開始: " + Thread.currentThread().getName());
           try {
               Thread.sleep(2000); // 模擬長時間任務(wù)
           } catch (InterruptedException e) {
               e.printStackTrace();
           }
           System.out.println("異步方法結(jié)束: " + Thread.currentThread().getName());
           return CompletableFuture.completedFuture("異步任務(wù)完成");
       }
   }

2. 調(diào)用異步方法并獲取結(jié)果:

import org.springframework.beans.factory.annotation.Autowired;
   import org.springframework.web.bind.annotation.GetMapping;
   import org.springframework.web.bind.annotation.RestController;
   import java.util.concurrent.CompletableFuture;
   import java.util.concurrent.ExecutionException;
   @RestController
   public class AsyncController {
       @Autowired
       private AsyncService asyncService;
       @GetMapping("/asyncResult")
       public String callAsyncWithResult() throws ExecutionException, InterruptedException {
           CompletableFuture<String> result = asyncService.asyncMethodWithResult();
           return result.get();
       }
   }

二、異步調(diào)用

異步調(diào)用不僅可以應(yīng)用在請求中,也可以在方法之間的調(diào)用中使用。

2.1 使用 @Async 進(jìn)行方法調(diào)用

可以直接在類的方法上使用 @Async 注解,使其成為異步方法。

示例:

1. 創(chuàng)建異步調(diào)用方法:

import org.springframework.scheduling.annotation.Async;
   import org.springframework.stereotype.Component;
   @Component
   public class AsyncComponent {
       @Async
       public void asyncMethod() {
           System.out.println("異步方法開始: " + Thread.currentThread().getName());
           try {
               Thread.sleep(2000); // 模擬長時間任務(wù)
           } catch (InterruptedException e) {
               e.printStackTrace();
           }
           System.out.println("異步方法結(jié)束: " + Thread.currentThread().getName());
       }
   }

2. 在其他類中調(diào)用異步方法:

import org.springframework.beans.factory.annotation.Autowired;
   import org.springframework.stereotype.Service;
   @Service
   public class SomeService {
       @Autowired
       private AsyncComponent asyncComponent;
       public void performAsyncTask() {
           System.out.println("主線程開始: " + Thread.currentThread().getName());
           asyncComponent.asyncMethod();
           System.out.println("主線程結(jié)束: " + Thread.currentThread().getName());
       }
   }

3. 在控制器中調(diào)用服務(wù)方法: 

import org.springframework.beans.factory.annotation.Autowired;
   import org.springframework.web.bind.annotation.GetMapping;
   import org.springframework.web.bind.annotation.RestController;
   @RestController
   public class SomeController {
       @Autowired
       private SomeService someService;
       @GetMapping("/performTask")
       public String performTask() {
           someService.performAsyncTask();
           return "任務(wù)已提交";
       }
   }

三、常見問題和注意事項(xiàng)

1.異步和同步請求的主要區(qū)別

兩者的使用場景不同,異步請求用來解決并發(fā)請求對服務(wù)器造成的壓力,從而提高對請求的吞吐量;而異步調(diào)用是用來做一些非主線流程且不需要實(shí)時計(jì)算和響應(yīng)的任務(wù),比如同步日志到kafka中做日志分析等。

異步請求是會一直等待response相應(yīng)的,需要返回結(jié)果給客戶端的;而異步調(diào)用我們往往會馬上返回給客戶端響應(yīng),完成這次整個的請求,至于異步調(diào)用的任務(wù)后臺自己慢慢跑就行,客戶端不會關(guān)心。

2.使用方式(基于spring下)

  • 需要在啟動類加入@EnableAsync使異步調(diào)用@Async注解生效
  • 在需要異步執(zhí)行的方法上加入此注解即可@Async("threadPool"),threadPool為自定義線程池
  • 代碼略。。。就倆標(biāo)簽,自己試一把就可以了

3.注意事項(xiàng)

  • 在默認(rèn)情況下,未設(shè)置TaskExecutor時,默認(rèn)是使用SimpleAsyncTaskExecutor這個線程池,但此線程不是真正意義上的線程池,因?yàn)榫€程不重用,每次調(diào)用都會創(chuàng)建一個新的線程??赏ㄟ^控制臺日志輸出可以看出,每次輸出線程名都是遞增的。所以最好我們來自定義一個線程池。
  • 調(diào)用的異步方法,不能為同一個類的方法(包括同一個類的內(nèi)部類),簡單來說,因?yàn)镾pring在啟動掃描時會為其創(chuàng)建一個代理類,而同類調(diào)用時,還是調(diào)用本身的代理類的,所以和平常調(diào)用是一樣的。其他的注解如@Cache等也是一樣的道理,說白了,就是Spring的代理機(jī)制造成的。所以在開發(fā)中,最好把異步服務(wù)單獨(dú)抽出一個類來管理。下面會重點(diǎn)講述。。

4.什么情況下會導(dǎo)致@Async異步方法會失效?

  1. 調(diào)用同一個類下注有@Async異步方法:在spring中像@Async和@Transactional、cache等注解本質(zhì)使用的是動態(tài)代理,其實(shí)Spring容器在初始化的時候Spring容器會將含有AOP注解的類對象“替換”為代理對象(簡單這么理解),那么注解失效的原因就很明顯了,就是因?yàn)檎{(diào)用方法的是對象本身而不是代理對象,因?yàn)闆]有經(jīng)過Spring容器,那么解決方法也會沿著這個思路來解決。
  2. 調(diào)用的是靜態(tài)(static )方法
  3. 調(diào)用(private)私有化方法

5.解決4中問題a的方式(其它b,c兩個問題自己注意下就可以了)

  1. 將要異步執(zhí)行的方法單獨(dú)抽取成一個類,原理就是當(dāng)你把執(zhí)行異步的方法單獨(dú)抽取成一個類的時候,這個類肯定是被Spring管理的,其他Spring組件需要調(diào)用的時候肯定會注入進(jìn)去,這時候?qū)嶋H上注入進(jìn)去的就是代理類了。
  2. 其實(shí)我們的注入對象都是從Spring容器中給當(dāng)前Spring組件進(jìn)行成員變量的賦值,由于某些類使用了AOP注解,那么實(shí)際上在Spring容器中實(shí)際存在的是它的代理對象。那么我們就可以通過上下文獲取自己的代理對象調(diào)用異步方法。

四、總結(jié)

在 Spring Boot 中實(shí)現(xiàn)異步請求和異步調(diào)用可以顯著提升應(yīng)用程序的性能和響應(yīng)速度。通過使用 @Async注解和 CompletableFuture,我們可以輕松地將同步方法轉(zhuǎn)換為異步方法。本文介紹了具體的實(shí)現(xiàn)步驟和示例,希望能幫助你在項(xiàng)目中更好地應(yīng)用異步處理技術(shù)。

責(zé)任編輯:華軒 來源: 微技術(shù)之家
相關(guān)推薦

2024-10-15 10:28:43

2020-01-02 16:30:02

Spring BootJava異步請求

2021-03-29 09:26:44

SpringBoot異步調(diào)用@Async

2024-08-12 10:13:01

2022-09-27 12:01:56

Spring異步調(diào)用方式

2010-01-11 17:24:19

VB.NET異步調(diào)用

2022-09-28 14:54:07

Spring注解方式線程池

2021-02-17 09:09:15

異步請求

2018-06-21 14:46:03

Spring Boot異步調(diào)用

2009-10-20 16:48:30

C#委托

2009-11-09 10:50:30

WCF異步調(diào)用

2009-12-21 14:10:26

WCF異步調(diào)用

2009-07-01 14:23:46

JavaScript異

2009-07-01 14:37:14

JavaScript異

2009-11-06 15:54:15

WCF異步調(diào)用

2009-07-01 13:58:00

JavaScript異

2009-08-21 13:18:25

C#異步調(diào)用

2009-07-01 14:31:01

JavaScript異

2022-07-01 08:14:28

Dubbo異步代碼

2009-08-21 11:02:55

C#異步調(diào)用
點(diǎn)贊
收藏

51CTO技術(shù)棧公眾號