成人免费xxxxx在线视频软件_久久精品久久久_亚洲国产精品久久久_天天色天天色_亚洲人成一区_欧美一级欧美三级在线观看

Spring Boot 中的異步請求和異步調用詳解

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

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

一、異步請求

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. 創建異步方法:

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); // 模擬長時間任務
           } catch (InterruptedException e) {
               e.printStackTrace();
           }
           System.out.println("異步方法結束: " + Thread.currentThread().getName());
       }
   }

4. 調用異步方法:

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 引入的一個強大的異步工具類,Spring 也對其提供了良好的支持。

示例:

1. 創建返回 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); // 模擬長時間任務
           } catch (InterruptedException e) {
               e.printStackTrace();
           }
           System.out.println("異步方法結束: " + Thread.currentThread().getName());
           return CompletableFuture.completedFuture("異步任務完成");
       }
   }

2. 調用異步方法并獲取結果:

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();
       }
   }

二、異步調用

異步調用不僅可以應用在請求中,也可以在方法之間的調用中使用。

2.1 使用 @Async 進行方法調用

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

示例:

1. 創建異步調用方法:

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); // 模擬長時間任務
           } catch (InterruptedException e) {
               e.printStackTrace();
           }
           System.out.println("異步方法結束: " + Thread.currentThread().getName());
       }
   }

2. 在其他類中調用異步方法:

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("主線程結束: " + Thread.currentThread().getName());
       }
   }

3. 在控制器中調用服務方法: 

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 "任務已提交";
       }
   }

三、常見問題和注意事項

1.異步和同步請求的主要區別

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

異步請求是會一直等待response相應的,需要返回結果給客戶端的;而異步調用我們往往會馬上返回給客戶端響應,完成這次整個的請求,至于異步調用的任務后臺自己慢慢跑就行,客戶端不會關心。

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

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

3.注意事項

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

4.什么情況下會導致@Async異步方法會失效?

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

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

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

四、總結

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

責任編輯:華軒 來源: 微技術之家
相關推薦

2024-10-15 10:28:43

2020-01-02 16:30:02

Spring BootJava異步請求

2021-03-29 09:26:44

SpringBoot異步調用@Async

2024-08-12 10:13:01

2022-09-27 12:01:56

Spring異步調用方式

2010-01-11 17:24:19

VB.NET異步調用

2022-09-28 14:54:07

Spring注解方式線程池

2021-02-17 09:09:15

異步請求

2018-06-21 14:46:03

Spring Boot異步調用

2009-10-20 16:48:30

C#委托

2009-11-09 10:50:30

WCF異步調用

2009-12-21 14:10:26

WCF異步調用

2009-07-01 14:37:14

JavaScript異

2009-07-01 14:23:46

JavaScript異

2009-11-06 15:54:15

WCF異步調用

2009-07-01 13:58:00

JavaScript異

2009-08-21 13:18:25

C#異步調用

2009-07-01 14:31:01

JavaScript異

2022-07-01 08:14:28

Dubbo異步代碼

2009-08-21 11:02:55

C#異步調用
點贊
收藏

51CTO技術棧公眾號

主站蜘蛛池模板: 91av亚洲| 日韩电影a | 韩日一区二区 | 91精品国产日韩91久久久久久 | 欧美一区免费 | 久久男人 | 亚洲成人久久久 | 亚洲精品视频在线 | 国产精品久久久久久久久久 | 伊人春色在线 | 综合网中文字幕 | 久久久这里只有17精品 | 免费的av | 一区二区三区视频在线观看 | 在线精品一区二区 | 欧美黑人一级爽快片淫片高清 | 国产一区二区三区四区五区3d | 亚洲精品成人av久久 | 国产美女精品视频 | 日日想夜夜操 | 青青久在线视频 | 天天色综| 欧美日韩国产在线 | 久久久久久久国产精品视频 | 一区二区精品在线 | 国产成人免费在线 | 中文字幕一区二区三区乱码在线 | 亚洲 中文 欧美 日韩 在线观看 | 久久一区| 欧洲精品码一区二区三区免费看 | 中文字幕高清av | 午夜成人在线视频 | 成人在线免费网站 | 欧美成人精品激情在线观看 | 国产亚洲网站 | 精品小视频 | 国产黄色一级片 | 日韩在线观看中文字幕 | 日韩高清一区 | 成人免费视频在线观看 | 亚洲精品一区中文字幕乱码 |