@Async注解在SpringBoot项目中的使用

news/2025/3/15 0:07:51/

一、@Async 的核心机制

1. 基本用法

通过 @Async 注解标记方法,Spring 会自动将该方法的执行提交到线程池,实现异步调用:

@Service
public class MyService {@Asyncpublic void asyncTask() {// 异步执行的代码(如发送邮件、处理文件)System.out.println("Async task executed by thread: " + Thread.currentThread().getName());}
}
2. 调用方式
@RestController
public class MyController {@Autowiredprivate MyService myService;@GetMapping("/trigger")public String triggerAsync() {myService.asyncTask(); // 触发异步方法return "Task submitted!";}
}

二、必须的配置

1. 启用异步支持

需在配置类添加 @EnableAsync 注解:

@Configuration
@EnableAsync
public class AsyncConfig {}
2. 配置线程池(关键)

Spring 默认使用 SimpleAsyncTaskExecutor(每次新建线程),但生产环境需自定义线程池

@Configuration
@EnableAsync
public class AsyncConfig {@Bean("taskExecutor")public Executor taskExecutor() {ThreadPoolTaskExecutor executor = new ThreadPoolTaskExecutor();executor.setCorePoolSize(5);     // 核心线程数executor.setMaxPoolSize(10);     // 最大线程数executor.setQueueCapacity(100);  // 队列容量executor.setThreadNamePrefix("Async-Thread-");executor.initialize();return executor;}
}
3. 指定线程池

在 @Async 注解中指定线程池名称:

@Async("taskExecutor")
public void asyncTask() { ... }

三、底层原理

  • 代理机制:Spring 通过 AOP 代理拦截 @Async 方法,将任务提交到线程池。
  • 线程池管理:任务由 TaskExecutor 实现类(如 ThreadPoolTaskExecutor)调度执行。
  • 异步上下文@Async 方法需注意线程上下文传递(如 SecurityContext 需手动配置)。

四、关键注意事项

1. 方法调用限制
  • 同类内部调用失效

    public class MyService {public void methodA() {methodB(); // 直接调用异步方法不会生效!}@Asyncpublic void methodB() { ... }
    }
    

    需通过代理对象调用(如注入自身 Bean 或使用 AopContext.currentProxy())。

2. 返回值处理
  • 无返回值:直接使用 void
  • 有返回值:返回 Future<T> 或 CompletableFuture<T>
    @Async
    public CompletableFuture<String> asyncTaskWithResult() {return CompletableFuture.completedFuture("Result");
    }
    
3. 异常处理

异步方法抛出的异常需通过 AsyncUncaughtExceptionHandler 捕获:

@Configuration
public class AsyncExceptionConfig implements AsyncConfigurer {@Overridepublic AsyncUncaughtExceptionHandler getAsyncUncaughtExceptionHandler() {return (ex, method, params) -> {System.err.println("Async method error: " + method.getName());ex.printStackTrace();};}
}

http://www.ppmy.cn/news/1579174.html

相关文章

Synology 部署的 WordPress 無法升級至最新版本時,可以透過以下改良版指南進行排查和解決。

當 Synology 部署的 WordPress 無法升級至最新版本時&#xff0c;可以透過以下改良版指南進行排查和解決。我對內容進行了補充和重新組織&#xff0c;希望能幫助你更高效地處理這類問題&#xff1a; 權限相關問題處理 檢查文件和目錄權限&#xff1a; 確保 WordPress 安裝目錄…

C语言练习四(vscode)循环语句专练

一、用循环验证用户输入的数字 #include<stdio.h> int main(){int num;printf("请您猜一个正整数:");scanf("%d",&num);while (num>0&&num<100){if (num65){printf("恭喜您猜对了。");break;}else{printf("您猜错…

深度评测DeepSeek、ChatGPT O1和谷歌Gemini AI应用开发场景 - DeepSeek性能完胜!

下面我会展示我为期一周的实验结果&#xff0c;创作不宜&#xff0c;希望大家关注我&#xff0c;以后多多互3&#xff01;前一阵我在互联网上看到很多关于DeepSeek R1的讨论&#xff0c;这个开源模型据说可以媲美&#xff0c;甚至优于像OpenAI o1这样的付费模型。 由于我在日常…

DeepSeek如何赋能研究生学习:从科研到论文的全流程智能化支持

引言 在研究生阶段&#xff0c;学术研究是核心任务&#xff0c;但面对海量文献、复杂的实验设计以及论文写作的高要求&#xff0c;许多同学常常感到力不从心。DeepSeek作为一款国产人工智能大模型&#xff0c;凭借其强大的技术实力和丰富的应用场景&#xff0c;正在为研究生提…

deepseek为什么要开源

一、生态位的抢占与锁定&#xff1a;以 JDK 版本为例​ 在软件开发的世界里&#xff0c;生态位的抢占和先入为主的效应十分显著。就拿 Java 开发中的 JDK 版本来说&#xff0c;目前大多数开发者仍在广泛使用 JDK8。尽管 JDK17 和 JDK21 已经推出&#xff0c;且具备更多先进特性…

flink cdc同步mysql数据

一、api 添加依赖 <dependency><groupId>org.apache.flink</groupId><artifactId>flink-connector-mysql-cdc</artifactId><!-- 请使用已发布的版本依赖&#xff0c;snapshot 版本的依赖需要本地自行编译。 --><version>3.3-SNAP…

蓝桥杯刷题 Day1 高精度加法

蓝桥杯刷题 Day1 提示&#xff1a;写完文章后&#xff0c;目录可以自动生成&#xff0c;如何生成可参考右边的帮助文档 文章目录 蓝桥杯刷题 Day1前言一、大数加法1. 解题思路2. 代码2.1主函数2.2 去除前导02.3 大数相加2.4 完整代码 二、KMP字符串匹配0. 知识点速记1. 解题思路…

2024年第十五届蓝桥杯软件C/C++大学A组——五子棋对弈

蓝桥杯原题&#xff1a; 题目描述&#xff1a; “在五子棋的对弈中&#xff0c;友谊的小船说翻就翻&#xff1f; ” 不&#xff01;对小蓝和小桥来说&#xff0c;五子棋不仅是棋盘上的较量&#xff0c;更是心与心之间的沟通。这两位挚友秉承着 “ 友谊第一&#xff0c;比赛第二…