幫助做ppt的網(wǎng)站上海aso優(yōu)化公司
😄 19年之后由于某些原因斷更了三年,23年重新?lián)P帆起航,推出更多優(yōu)質博文,希望大家多多支持~
🌷 古之立大事者,不惟有超世之才,亦必有堅忍不拔之志
🎐 個人CSND主頁——Micro麥可樂的博客
🐥《Docker實操教程》專欄以最新的Centos版本為基礎進行Docker實操教程,入門到實戰(zhàn)
🌺《RabbitMQ》專欄主要介紹使用JAVA開發(fā)RabbitMQ的系列教程,從基礎知識到項目實戰(zhàn)
🌸《設計模式》專欄以實際的生活場景為案例進行講解,讓大家對設計模式有一個更清晰的理解
💕《Jenkins實戰(zhàn)》專欄主要介紹Jenkins+Docker的實戰(zhàn)教程,讓你快速掌握項目CI/CD,是2024年最新的實戰(zhàn)教程
🌞《Spring Boot》專欄主要介紹我們日常工作項目中經(jīng)常應用到的功能以及技巧,代碼樣例完整
如果文章能夠給大家?guī)硪欢ǖ膸椭?#xff01;歡迎關注、評論互動~
Spring Boot中@Async注解的使用以及注意事項
- 1、前言
- 2、@Async注解的基本使用
- ? 引入依賴
- ? 啟用異步支持
- ? 定義異步方法
- ? 調用異步方法
- 3、@Async注解的實現(xiàn)原理
- ? TaskExecutor
- ? AOP代理
- ? 異步方法返回值
- 4、應用場景
- ? 后臺任務處理
- ? 并行處理
- ? 提高系統(tǒng)吞吐量
- 5、常見問題及解決方案
- 5.1、@Async方法調用無效
- 5.2、異常處理
- 6、結語
1、前言
在現(xiàn)代Java應用程序中,異步處理是提高性能和響應速度的重要手段之一,比如博主之前分享的【Spring Boot 使用自定義注解和自定義線程池實現(xiàn)異步日志記錄】,就是采用了異步處理來實現(xiàn)日志記錄,而在Spring Boot
中它提供了@Async
注解來簡化異步編程,今天博主就來和小伙伴們分享本@Async
注解的基本使用、實現(xiàn)原理以及應用場景。
2、@Async注解的基本使用
@Async
注解用于標注方法,使其在獨立的線程中異步執(zhí)行。Spring Boot
提供了一種簡單的方法來啟用異步方法調用,只需在配置類或主類上添加@EnableAsync
注解
? 引入依賴
在 Spring Boot
項目 pom.xml
文件中添加必要的依賴:
<dependency><groupId>org.springframework.boot</groupId><artifactId>spring-boot-starter-web</artifactId>
</dependency>
<dependency><groupId>org.springframework.boot</groupId><artifactId>spring-boot-starter-aop</artifactId>
</dependency>
? 啟用異步支持
在Spring Boot應用的配置類或主類上啟用異步支持 @EnableAsync
:
import org.springframework.boot.SpringApplication;
import org.springframework.boot.autoconfigure.SpringBootApplication;
import org.springframework.scheduling.annotation.EnableAsync;@SpringBootApplication
@EnableAsync
public class AsyncApplication {public static void main(String[] args) {SpringApplication.run(AsyncApplication.class, args);}
}
? 定義異步方法
使用@Async
注解定義異步方法。例如:創(chuàng)建一個服務類AsyncService
import org.springframework.scheduling.annotation.Async;
import org.springframework.stereotype.Service;@Service
public class AsyncService {@Asyncpublic void asyncMethod() {try {Thread.sleep(5000); // 模擬耗時操作} catch (InterruptedException e) {e.printStackTrace();}System.out.println("異步方法執(zhí)行完成");}
}
? 調用異步方法
在需要調用異步方法的地方,通過注入AsyncService
并調用其異步方法
import org.springframework.beans.factory.annotation.Autowired;
import org.springframework.web.bind.annotation.GetMapping;
import org.springframework.web.bind.annotation.RestController;@RestController
@RequestMapping("/api")
public class AsyncController {@Autowiredprivate AsyncService asyncService;@GetMapping("/async")public String callAsyncMethod() {asyncService.asyncMethod();return "異步方法已調用";}
}
最后請求訪問Controller/api/async
, 會發(fā)現(xiàn)Controller立即返回響應,而asyncMethod
將在獨立線程中執(zhí)行,5秒后控制臺輸出:異步方法執(zhí)行完成
3、@Async注解的實現(xiàn)原理
@Async
注解的實現(xiàn)依賴于Spring的AOP
(面向切面編程)和TaskExecutor
? TaskExecutor
Spring
使用TaskExecutor
來處理異步任務。默認情況下,Spring Boot使用SimpleAsyncTaskExecutor
,但我們也可以自定義TaskExecutor
來控制線程池
自定義TaskExecutor
我們可以通過@Bean注解定義自定義的TaskExecutor
import org.springframework.context.annotation.Bean;
import org.springframework.context.annotation.Configuration;
import org.springframework.scheduling.concurrent.ThreadPoolTaskExecutor;
import java.util.concurrent.Executor;@Configuration
public class AsyncConfig {@Bean(name = "taskExecutor")public Executor taskExecutor() {ThreadPoolTaskExecutor executor = new ThreadPoolTaskExecutor();executor.setCorePoolSize(5);executor.setMaxPoolSize(10);executor.setQueueCapacity(25);executor.setThreadNamePrefix("AsyncThread-");executor.initialize();return executor;}
}
? AOP代理
@Async注解通過Spring AOP代理來實現(xiàn)異步調用。當標注為@Async的方法被調用時,Spring AOP會攔截調用并在TaskExecutor的線程池中異步執(zhí)行該方法
? 異步方法返回值
@Async
注解的方法可以返回void
、Future
、CompletableFuture
等類型,如下代碼
import org.springframework.scheduling.annotation.Async;
import org.springframework.stereotype.Service;
import java.util.concurrent.CompletableFuture;@Service
public class AsyncService {@Asyncpublic CompletableFuture<String> asyncMethodWithReturn() {try {Thread.sleep(5000); // 模擬耗時操作} catch (InterruptedException e) {e.printStackTrace();}return CompletableFuture.completedFuture("異步方法返回結果");}
}
調用帶返回值的異步方法:
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;@RestController
public class AsyncController {@Autowiredprivate AsyncService asyncService;@GetMapping("/asyncWithReturn")public CompletableFuture<String> callAsyncMethodWithReturn() {return asyncService.asyncMethodWithReturn();}
}
4、應用場景
@Async
注解適用于各種需要異步處理的場景,例如:
? 后臺任務處理
在Web應用中,有些任務(如
發(fā)送郵件
、生成報告
)耗時較長,可以使用@Async
異步處理,使用戶無需等待任務完成即可獲得響應。
? 并行處理
對于可以并行處理的任務,如并行數(shù)據(jù)處理、并行調用多個外部服務,使用
@Async
可以提高效率。
? 提高系統(tǒng)吞吐量
通過異步調用,可以充分利用多線程資源,提高系統(tǒng)的吞吐量和響應速度。
5、常見問題及解決方案
5.1、@Async方法調用無效
如果在同一個類中調用@Async
注解的方法,異步調用可能無效。這是因為Spring AOP代理無法攔截同一類中的@Async
。
解決方法:將異步方法放到另一個類中,通過依賴注入進行調用
5.2、異常處理
異步方法中的異常不會自動傳播到調用方??梢允褂?code>CompletableFuture處理異常,見下面演示代碼
import org.springframework.scheduling.annotation.Async;
import org.springframework.stereotype.Service;
import java.util.concurrent.CompletableFuture;@Service
public class AsyncService {@Asyncpublic CompletableFuture<String> asyncMethodWithException() {try {Thread.sleep(5000); // 模擬耗時操作throw new RuntimeException("異常發(fā)生");} catch (InterruptedException e) {e.printStackTrace();}return CompletableFuture.completedFuture("異步方法完成");}
}
處理異常:
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;@RestController
public class AsyncController {@Autowiredprivate AsyncService asyncService;@GetMapping("/asyncWithException")public CompletableFuture<String> callAsyncMethodWithException() {return asyncService.asyncMethodWithException().exceptionally(ex -> "處理異常:" + ex.getMessage());}
}
6、結語
Spring Boot
的@Async
注解提供了一種簡潔且強大的方式來實現(xiàn)異步處理。通過啟用異步支持、定義異步方法并自定義TaskExecutor
,可以高效地處理各種異步任務。掌握@Async
注解的使用和原理,有助于提升應用程序的性能和響應速度。
如果本文對您有所幫助,希望 一鍵三連 給博主一點點鼓勵,如果您有任何疑問或建議,請隨時留言討論!