news 2026/6/14 21:21:10

Async 注解原理分析

作者头像

张小明

前端开发工程师

1.2k 24
文章封面图
Async 注解原理分析

核心作用:Spring 提供的注解,标注在类或方法上,使方法在异步线程中执行,调用者无需等待方法完成即可继续执行后续逻辑。

使用两步走

  1. 启动类添加@EnableAsync,开启异步任务支持;
  2. 需异步执行的方法 / 类上添加@Async注解(示例中常用CompletableFuture处理异步结果)。

@Async 原理分析

@Async可以异步执行任务,本质上是使用动态代理来实现的。通过 Spring 中的后置处理器BeanPostProcessor为使用@Async注解的类创建动态代理,之后@Async注解方法的调用会被动态代理拦截,在拦截器中将方法的执行封装为异步任务提交给线程池处理。

开启异步:@EnableAsync 的作用

  • @EnableAsync通过@Import(AsyncConfigurationSelector.class)加载配置类;
  • AsyncConfigurationSelector根据AdviceMode(默认PROXY)选择加载ProxyAsyncConfiguration
  • ProxyAsyncConfiguration注册关键后置处理器AsyncAnnotationBeanPostProcessor

后置处理器:动态代理的核心

  • AsyncAnnotationBeanPostProcessor@Async生效的关键,会为标注@Async的类创建动态代理;
  • 该处理器通过setBeanFactory()方法创建AsyncAnnotationAdvisor(Spring AOP 的Advisor组件)。

创建Advisor:定义拦截规则与逻辑

dvisor包含Advice(通知逻辑)和Pointcut(切入点):

  • Advice:创建AnnotationAsyncExecutionInterceptor拦截器,负责异步执行逻辑;
  • Pointcut:通过AnnotationMatchingPointcut匹配类 / 方法上的@Async注解(类级别 + 方法级别)。

后置处理器逻辑:生成代理对象

  • Bean 初始化后,postProcessAfterInitialization()方法判断 Bean 是否符合Advisor规则;
  • 符合规则则通过ProxyFactory创建代理对象,后续@Async方法调用会被代理拦截。

@Async 注解方法的拦截

1. 确定异步执行器(线程池)

  • 优先从缓存获取,或通过@Asyncvalue限定符查找自定义线程池;
  • 无自定义线程池时,默认使用SimpleAsyncTaskExecutor风险提示:每次创建新线程,无复用,高并发下易导致资源耗尽)。

2. 封装异步任务

  • 将目标方法执行逻辑(invocation.proceed())封装为Callable任务;
  • 若方法返回Future类型,会阻塞等待结果(处理异步嵌套调用),其他类型执行后返回null

3. 提交异步任务

根据方法返回值类型选择提交方式:

  • CompletableFuture:用supplyAsync()提交;
  • ListenableFuture:用submitListenable()提交;
  • Future:直接submit()提交;
  • void或其他类型:submit()提交后返回null

总结

理解@Async原理的核心在于理解@EnableAsync注解,该注解开启了异步任务的功能。

主要流程如下图:

@Async 使用建议

必须自定义线程池

  • 避免使用默认的SimpleAsyncTaskExecutor,推荐ThreadPoolTaskExecutor
  • 可配置核心线程数、最大线程数、队列容量等(示例:创建executor1executor2等不同线程池,通过@Async("executor1")指定)。

避免 @Async 注解实效

失效场景

原因

解决方案

同一类内调用异步方法

绕过 Spring 代理,未触发拦截

将异步方法移至另一个 Spring Bean

异步方法用static修饰

代理无法拦截静态方法(不属于实例)

用非静态包装方法调用静态逻辑

未加@EnableAsync

未开启异步支持

启动类添加@EnableAsync

方法所在类非 Spring Bean

Spring 无法创建代理

确保类被@Service等注解管理

规范返回值类型

  • 无需结果:返回void
  • 需要结果:返回Future子类(如CompletableFutureListenableFuture);
  • 其他类型(如StringObject):无法获取方法执行结果。

处理异步方法异常

  • 全局处理:实现AsyncConfigurer重写getAsyncUncaughtExceptionHandler(),自定义异常处理器;
  • 局部处理:用CompletableFutureexceptionally()等方法捕获异常。

事务管理注意

  • 异步方法需事务时,需添加@Transactional(propagation = Propagation.REQUIRES_NEW),开启独立新事务(避免与调用方事务关联)。

控制执行顺序

  • 异步方法默认无序,需按顺序执行时,用CompletableFuturethenCompose()thenAccept()等方法串联任务(如先执行fetchDataAsync,再执行processDataAsync)。
版权声明: 本文来自互联网用户投稿,该文观点仅代表作者本人,不代表本站立场。本站仅提供信息存储空间服务,不拥有所有权,不承担相关法律责任。如若内容造成侵权/违法违规/事实不符,请联系邮箱:809451989@qq.com进行投诉反馈,一经查实,立即删除!
网站建设 2026/6/11 9:02:32

前端开发规范实践

文档总结了前端开发团队在代码规范、质量控制、版本管理和开发流程等方面的一些实践,旨在帮助团队建立统一的开发标准,提高代码质量和开发效率。1. 前端编码规范管理1.1 统一编码规范1.1.1 命名规范变量命名:使用小驼峰命名法(cam…

作者头像 李华
网站建设 2026/6/14 16:30:47

通达信支撑线

{}GUOQI:DATE>1110101; BAOLIU:DAY>24 AND DAY<30 AND FRACPART(MONTH/2)0.5; WUXIAO:GUOQI1 AND BAOLIU1; 五分:5; 十五分:五分*3; 三十分:十五分*2; 六十分:三十分*2; 日:六十分*4; 周:日*5; 月:周*4; 季:月*3; 半年:季*2; 年:半年*2; A:(OPENHIGHLOWCLOSECLOSE)/5;…

作者头像 李华
网站建设 2026/6/15 14:36:58

通达信周均线 源码

{}TYP:(HIGHLOWCLOSE)/3; CCI:(TYP-MA(TYP,14))/(0.015*AVEDEV(TYP,14)); 陡峭度:CCI-REF(CCI,1)/1;{} RSV:(CLOSE-LLV(LOW,9))/(HHV(HIGH,9)-LLV(LOW,9))*100; K:SMA(RSV,3,1); D:SMA(K,3,1); J:3*K-2*D; REF(CCI,1)<50 AND CCI>50 AND CCI<100 AND 陡峭度>N AND …

作者头像 李华
网站建设 2026/6/14 21:37:08

技术 | 在单台电脑上管理多个 GitHub 账户并解决推送问题(测试中)

在单台电脑上管理多个 GitHub 账户并解决推送问题在日常开发中&#xff0c;我们经常需要在同一台电脑上使用多个 GitHub 账户&#xff08;例如个人账号和工作账号&#xff09;&#xff0c;但默认配置下容易出现推送权限错误或提交记录关联到错误账户的问题。本文将详细介绍如何…

作者头像 李华
网站建设 2026/6/15 12:14:47

记一次 .NET 某光放测试系统 崩溃分析

一&#xff1a;背景 1. 讲故事 微信好友里有位朋友找到我&#xff0c;说他部署在windows上的程序&#xff0c;用debug模式正常&#xff0c;但用 release 模式跑程序就崩溃&#xff0c;如果把程序切到 .NET6 的话又都正常&#xff0c;所以很迷茫&#xff0c;让我看看怎么回事&…

作者头像 李华
网站建设 2026/6/15 12:16:39

9 款 AI 写论文哪个好?实测对比后,这款全流程神器成学术党首选! 毕业论文写作季,AI 写作工具已成学子 “救命稻草”。市面上百度智能云千帆大模型、科大讯

毕业论文写作季&#xff0c;AI 写作工具已成学子 “救命稻草”。市面上百度智能云千帆大模型、科大讯飞星火认知大模型、通义千问、文心一言、ChatGPT、豆包、WPS AI、Grammarly GO、虎贲等考 AI 等 9 款主流工具扎堆&#xff0c;“9 款 AI 写论文哪个好” 成为全网热议的焦点。…

作者头像 李华