0


Spring Boot中@Async注解的使用及原理 + 常见问题及解决方案

在这里插入图片描述

😄 19年之后由于某些原因断更了三年,23年重新扬帆起航,推出更多优质博文,希望大家多多支持~
🌷 古之立大事者,不惟有超世之才,亦必有坚忍不拔之志
🎐 个人CSND主页——Micro麦可乐的博客
🐥《Docker实操教程》专栏以最新的Centos版本为基础进行Docker实操教程,入门到实战
🌺《RabbitMQ》专栏主要介绍使用JAVA开发RabbitMQ的系列教程,从基础知识到项目实战
🌸《设计模式》专栏以实际的生活场景为案例进行讲解,让大家对设计模式有一个更清晰的理解
💕《Jenkins实战》专栏主要介绍Jenkins+Docker的实战教程,让你快速掌握项目CI/CD,是2024年最新的实战教程
🌞《Spring Boot》专栏主要介绍我们日常工作项目中经常应用到的功能以及技巧,代码样例完整
如果文章能够给大家带来一定的帮助!欢迎关注、评论互动~

Spring Boot中@Async注解的使用以及注意事项

1、前言

在现代Java应用程序中,异步处理是提高性能和响应速度的重要手段之一,比如博主之前分享的【Spring Boot 使用自定义注解和自定义线程池实现异步日志记录】,就是采用了异步处理来实现日志记录,而在

Spring Boot

中它提供了

@Async

注解来简化异步编程,今天博主就来和小伙伴们分享本

@Async

注解的基本使用、实现原理以及应用场景。


2、@Async注解的基本使用

@Async

注解用于标注方法,使其在独立的线程中异步执行。

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

importorg.springframework.boot.SpringApplication;importorg.springframework.boot.autoconfigure.SpringBootApplication;importorg.springframework.scheduling.annotation.EnableAsync;@SpringBootApplication@EnableAsyncpublicclassAsyncApplication{publicstaticvoidmain(String[] args){SpringApplication.run(AsyncApplication.class, args);}}

❸ 定义异步方法

使用

@Async

注解定义异步方法。例如:创建一个服务类

AsyncService
importorg.springframework.scheduling.annotation.Async;importorg.springframework.stereotype.Service;@ServicepublicclassAsyncService{@AsyncpublicvoidasyncMethod(){try{Thread.sleep(5000);// 模拟耗时操作}catch(InterruptedException e){
            e.printStackTrace();}System.out.println("异步方法执行完成");}}

❹ 调用异步方法

在需要调用异步方法的地方,通过注入

AsyncService

并调用其异步方法

importorg.springframework.beans.factory.annotation.Autowired;importorg.springframework.web.bind.annotation.GetMapping;importorg.springframework.web.bind.annotation.RestController;@RestController@RequestMapping("/api")publicclassAsyncController{@AutowiredprivateAsyncService asyncService;@GetMapping("/async")publicStringcallAsyncMethod(){
        asyncService.asyncMethod();return"异步方法已调用";}}

最后请求访问Controller

/api/async

, 会发现Controller立即返回响应,而

asyncMethod

将在独立线程中执行,5秒后控制台输出:异步方法执行完成


3、@Async注解的实现原理

@Async

注解的实现依赖于Spring的

AOP

(面向切面编程)和

TaskExecutor

❶ TaskExecutor

Spring

使用

TaskExecutor

来处理异步任务。默认情况下,Spring Boot使用

SimpleAsyncTaskExecutor

,但我们也可以自定义

TaskExecutor

来控制线程池

自定义TaskExecutor
我们可以通过@Bean注解定义自定义的TaskExecutor

importorg.springframework.context.annotation.Bean;importorg.springframework.context.annotation.Configuration;importorg.springframework.scheduling.concurrent.ThreadPoolTaskExecutor;importjava.util.concurrent.Executor;@ConfigurationpublicclassAsyncConfig{@Bean(name ="taskExecutor")publicExecutortaskExecutor(){ThreadPoolTaskExecutor executor =newThreadPoolTaskExecutor();
        executor.setCorePoolSize(5);
        executor.setMaxPoolSize(10);
        executor.setQueueCapacity(25);
        executor.setThreadNamePrefix("AsyncThread-");
        executor.initialize();return executor;}}

❷ AOP代理

@Async注解通过Spring AOP代理来实现异步调用。当标注为@Async的方法被调用时,Spring AOP会拦截调用并在TaskExecutor的线程池中异步执行该方法

❸ 异步方法返回值

@Async

注解的方法可以返回

void

Future

CompletableFuture

等类型,如下代码

importorg.springframework.scheduling.annotation.Async;importorg.springframework.stereotype.Service;importjava.util.concurrent.CompletableFuture;@ServicepublicclassAsyncService{@AsyncpublicCompletableFuture<String>asyncMethodWithReturn(){try{Thread.sleep(5000);// 模拟耗时操作}catch(InterruptedException e){
            e.printStackTrace();}returnCompletableFuture.completedFuture("异步方法返回结果");}}

调用带返回值的异步方法:

importorg.springframework.beans.factory.annotation.Autowired;importorg.springframework.web.bind.annotation.GetMapping;importorg.springframework.web.bind.annotation.RestController;importjava.util.concurrent.CompletableFuture;@RestControllerpublicclassAsyncController{@AutowiredprivateAsyncService asyncService;@GetMapping("/asyncWithReturn")publicCompletableFuture<String>callAsyncMethodWithReturn(){return asyncService.asyncMethodWithReturn();}}

4、应用场景

@Async

注解适用于各种需要异步处理的场景,例如:

❶ 后台任务处理

在Web应用中,有些任务(如

发送邮件

生成报告

)耗时较长,可以使用

@Async

异步处理,使用户无需等待任务完成即可获得响应。

❷ 并行处理

对于可以并行处理的任务,如并行数据处理、并行调用多个外部服务,使用

@Async

可以提高效率。

❸ 提高系统吞吐量

通过异步调用,可以充分利用多线程资源,提高系统的吞吐量和响应速度。


5、常见问题及解决方案

5.1、@Async方法调用无效

如果在同一个类中调用

@Async

注解的方法,异步调用可能无效。这是因为Spring AOP代理无法拦截同一类中的

@Async

解决方法:将异步方法放到另一个类中,通过依赖注入进行调用

5.2、异常处理

异步方法中的异常不会自动传播到调用方。可以使用

CompletableFuture

处理异常,见下面演示代码

importorg.springframework.scheduling.annotation.Async;importorg.springframework.stereotype.Service;importjava.util.concurrent.CompletableFuture;@ServicepublicclassAsyncService{@AsyncpublicCompletableFuture<String>asyncMethodWithException(){try{Thread.sleep(5000);// 模拟耗时操作thrownewRuntimeException("异常发生");}catch(InterruptedException e){
            e.printStackTrace();}returnCompletableFuture.completedFuture("异步方法完成");}}

处理异常:

importorg.springframework.beans.factory.annotation.Autowired;importorg.springframework.web.bind.annotation.GetMapping;importorg.springframework.web.bind.annotation.RestController;importjava.util.concurrent.CompletableFuture;@RestControllerpublicclassAsyncController{@AutowiredprivateAsyncService asyncService;@GetMapping("/asyncWithException")publicCompletableFuture<String>callAsyncMethodWithException(){return asyncService.asyncMethodWithException().exceptionally(ex ->"处理异常:"+ ex.getMessage());}}

6、结语

Spring Boot

@Async

注解提供了一种简洁且强大的方式来实现异步处理。通过启用异步支持、定义异步方法并自定义

TaskExecutor

,可以高效地处理各种异步任务。掌握

@Async

注解的使用和原理,有助于提升应用程序的性能和响应速度。

如果本文对您有所帮助,希望 一键三连 给博主一点点鼓励,如果您有任何疑问或建议,请随时留言讨论!


在这里插入图片描述

标签: spring boot 后端 java

本文转载自: https://blog.csdn.net/lhmyy521125/article/details/140365158
版权归原作者 Micro麦可乐 所有, 如有侵权,请联系我们删除。

“Spring Boot中@Async注解的使用及原理 + 常见问题及解决方案”的评论:

还没有评论