@Async
是 Spring 提供的一个用于实现异步方法调用的注解,它可以帮助开发者在不阻塞主线程的情况下执行某些耗时操作。其底层原理主要依赖于 Spring AOP(面向切面编程)和动态代理技术。
一、@Async 的作用
通过 @Async
注解的方法会被 Spring 自动封装成一个异步任务,在指定的线程池中异步执行,而不是在调用线程中同步执行。
@Service
public class MyService {
@Async
public void asyncMethod() {
System.out.println("异步方法执行,线程:" + Thread.currentThread().getName());
}
}
二、使用前提条件
- 需要启用异步支持:在配置类或启动类上添加
@EnableAsync
- 方法必须是
public
的(因为 AOP 只能拦截 public 方法) - 方法不能被
private
、static
、final
修饰 - 异步方法不能与调用者在同一个类中(否则不会触发代理)
三、@Async 的核心原理
1. 启用异步:@EnableAsync
@Configuration
@EnableAsync
public class AsyncConfig {
}
@EnableAsync
注解会导入AsyncConfigurationSelector
类。- 最终会注册一个
AsyncAnnotationBeanPostProcessor
到 Spring 容器中。
2. 动态代理机制
Spring 使用 JDK 动态代理 或 CGLIB 代理 来为标注了 @Async
的 Bean 创建代理对象。
当调用带有 @Async
注解的方法时,实际调用的是代理对象中的增强逻辑。
3. 代理逻辑:提交到任务执行器
当调用 @Async
方法时,代理对象并不会直接执行该方法,而是:
- 将方法封装成一个任务(Runnable/Callable)
- 提交给配置好的
TaskExecutor
(默认是SimpleAsyncTaskExecutor
) - 在新的线程中执行目标方法
四、源码
1. @EnableAsync
导入配置
@Target(ElementType.TYPE)
@Retention(RetentionPolicy.RUNTIME)
@Documented
@Import(AsyncConfigurationSelector.class)
public @interface EnableAsync {
}
2. AsyncConfigurationSelector
注册处理器
/**
* AsyncConfigurationSelector 是 @EnableAsync 注解的核心处理器。
* 它的作用是根据 @EnableAsync 的配置,决定导入哪些异步支持的配置类。
*/
public class AsyncConfigurationSelector extends AdviceModeImportSelector<EnableAsync> {
private static final String ASYNC_ANNOTATION_CONFIGURER_CLASS_NAME =
"org.springframework.scheduling.annotation.ProxyAsyncConfiguration";
private static final String JTA_ASYNC_CONFIGURER_CLASS_NAME =
"org.springframework.transaction.aspectj.JtaAsyncConfiguration";
/**
* 根据 @EnableAsync 注解的 mode 属性选择不同的配置类:
*
* - 如果 mode = AdviceMode.PROXY(默认) → 导入 ProxyAsyncConfiguration(基于代理)
* - 如果 mode = AdviceMode.ASPECTJ → 导入 JtaAsyncConfiguration(基于 AspectJ 编织)
*
* @param importingClassMetadata 注解元数据
* @return 要导入的配置类名称数组
*/
@Override
public String[] selectImports(AnnotationMetadata importingClassMetadata) {
// 获取 @EnableAsync 注解的属性值
Class<?> annoType = EnableAsync.class;
AnnotationAttributes attributes = AnnotationConfigUtils.attributesFor(importingClassMetadata, annoType);
// 获取 mode 属性,默认是 AdviceMode.PROXY
AdviceMode adviceMode = attributes.getEnum("mode");
// 获取 proxyTargetClass 属性,决定是否使用 CGLIB 代理(默认 false)
boolean proxyTargetClass = attributes.getBoolean("proxyTargetClass");
// 存放要导入的类名
List<String> candidateNames = new ArrayList<>();
// 添加 ProxyAsyncConfiguration,这是标准的基于代理的异步支持类
candidateNames.add(ASYNC_ANNOTATION_CONFIGURER_CLASS_NAME);
// 如果启用了 AspectJ 模式,则额外添加 JTA 异步支持类
if (adviceMode == AdviceMode.ASPECTJ) {
candidateNames.add(JTA_ASYNC_CONFIGURER_CLASS_NAME);
}
// 验证目标类是否存在(比如项目是否引入了 AspectJ 或 JTA 相关依赖)
for (String candidate : candidateNames) {
if (!ClassUtils.isPresent(candidate, getClass().getClassLoader())) {
throw new IllegalArgumentException("Class not found: " + candidate);
}
}
// 返回要导入的类名数组
return candidateNames.toArray(new String[0]);
}
/**
* 返回要注册的 ImportSelector 的顺序,用于控制导入顺序。
*/
@Override
public int getOrder() {
return LOWEST_PRECEDENCE;
}
}
3. ProxyAsyncConfiguration
配置类
/**
* ProxyAsyncConfiguration 是 @EnableAsync 注解导入的配置类之一。
* 它负责注册 AsyncAnnotationBeanPostProcessor,并从容器中获取用户自定义的异步配置(如线程池和异常处理器)。
*/
@Configuration
public class ProxyAsyncConfiguration extends AbstractAsyncConfiguration {
/**
* 自动注入容器中所有的 AsyncConfigurer Bean。
* AsyncConfigurer 接口允许开发者自定义线程池和异常处理器。
*
* 这个方法会在容器启动时被调用。
*
* @param configurers 容器中所有实现了 AsyncConfigurer 接口的 Bean
*/
@Autowired(required = false)
void setConfigurers(Collection<AsyncConfigurer> configurers) {
if (CollectionUtils.isEmpty(configurers)) {
// 如果没有找到任何 AsyncConfigurer,使用默认配置(即 null)
this.setAsyncExecutor(null);
this.setExceptionHandler(null);
} else if (configurers.size() == 1) {
// 如果只有一个 AsyncConfigurer,则使用它提供的配置
AsyncConfigurer configurer = configurers.iterator().next();
this.setAsyncExecutor(configurer.getAsyncExecutor());
this.setExceptionHandler(configurer.getAsyncUncaughtExceptionHandler());
} else {
// 如果有多个 AsyncConfigurer,抛出异常,避免歧义
throw new IllegalStateException("...");
}
}
/**
* 注册 AsyncAnnotationBeanPostProcessor Bean。
* 这个后置处理器会为标注了 @Async 的方法创建代理对象,从而实现异步调用。
*
* @return AsyncAnnotationBeanPostProcessor 实例
*/
@Bean(name = AsyncAnnotationBeanPostProcessor.BEAN_NAME)
@Role(BeanDefinition.ROLE_INFRASTRUCTURE)
public AsyncAnnotationBeanPostProcessor asyncAnnotationBeanPostProcessor() {
AsyncAnnotationBeanPostProcessor bpp = new AsyncAnnotationBeanPostProcessor();
// 设置线程池,优先使用用户自定义的 Executor,否则使用默认的
bpp.setExecutor(this.asyncExecutor);
// 设置异常处理器,优先使用用户自定义的 AsyncUncaughtExceptionHandler
bpp.setExceptionHandler(this.asyncUncaughtExceptionHandler);
return bpp;
}
}
4. AsyncAnnotationBeanPostProcessor
创建代理
该处理器会在 Bean 初始化阶段判断是否包含 @Async
注解,并创建代理对象。
/**
* BeanPostProcessor 实现类,用于为标注了 @Async 注解的方法创建代理对象。
* 它会在 Bean 初始化阶段对符合条件的 Bean 进行 AOP 增强,从而实现异步调用。
*/
public class AsyncAnnotationBeanPostProcessor implements BeanPostProcessor, Ordered, BeanFactoryAware {
// 切面对象,用于匹配带有 @Async 注解的方法
private final Advisor advisor;
// 线程池执行器,默认使用 SimpleAsyncTaskExecutor
@Nullable
private Executor executor;
// 异常处理器,用于处理异步方法中的未捕获异常
@Nullable
private AsyncUncaughtExceptionHandler exceptionHandler;
/**
* 默认构造函数,创建一个支持标准 @Async 注解的切面
*/
public AsyncAnnotationBeanPostProcessor() {
this(null, null);
}
/**
* 构造函数,允许传入自定义线程池和异常处理器
*/
public AsyncAnnotationBeanPostProcessor(@Nullable Executor executor,
@Nullable AsyncUncaughtExceptionHandler exceptionHandler) {
this.executor = executor;
this.exceptionHandler = exceptionHandler;
// 设置优先级,确保异步增强在其他 AOP 拦截之前生效
setBeforeExistingAdvisors(true);
// 创建 AsyncAnnotationAdvisor,这是真正负责匹配 @Async 方法并织入异步逻辑的核心组件
this.advisor = new AsyncAnnotationAdvisor(this.executor, this.exceptionHandler);
}
/**
* 设置 BeanFactory,注入容器上下文
*/
@Override
public void setBeanFactory(BeanFactory beanFactory) {
// 调用父类设置 BeanFactory(如果有的话)
if (this.advisor instanceof BeanFactoryAware) {
((BeanFactoryAware) this.advisor).setBeanFactory(beanFactory);
}
}
/**
* 在 Bean 初始化完成后进行处理:
* 如果该 Bean 匹配 AsyncAnnotationAdvisor 的 Pointcut(即包含 @Async 方法),
* 则为其创建代理对象(JDK 动态代理或 CGLIB 代理),织入异步逻辑。
*/
@Override
public Object postProcessAfterInitialization(Object bean, String beanName) {
// 如果没有配置 Advisor 或者是 AopInfrastructureBean 类型(Spring 内部使用的 Bean),则跳过
if (this.advisor == null || bean instanceof AopInfrastructureBean) {
return bean;
}
// 获取目标类(防止被代理影响类型判断)
Class<?> targetClass = ProxyFactory.getProxyTargetClass(bean);
// 判断当前类是否符合 Async 的 Pointcut 条件(即是否有 @Async 方法)
if (AopUtils.canApply(this.advisor.getPointcut(), targetClass)) {
// 创建代理工厂
ProxyFactory proxyFactory = new ProxyFactory(bean);
// 添加 Async 的切面逻辑
proxyFactory.addAdvisor(this.advisor);
// 根据是否是 CGLIB 代理来决定是否代理目标类
proxyFactory.setProxyTargetClass(AopUtils.isCglibProxyClassName(bean.getClass().getName()));
// 返回代理后的对象
return proxyFactory.getProxy();
}
// 否则返回原始对象
return bean;
}
/**
* 设置是否在已有 Advisor 之前应用此增强器
*/
protected void setBeforeExistingAdvisors(boolean beforeExistingAdvisors) {
if (this.advisor instanceof AbstractPointcutAdvisor) {
((AbstractPointcutAdvisor) this.advisor).setOrder(
beforeExistingAdvisors ? Ordered.HIGHEST_PRECEDENCE : Ordered.LOWEST_PRECEDENCE);
}
}
/**
* 设置自定义线程池
*/
public void setExecutor(Executor executor) {
this.executor = executor;
if (this.advisor instanceof AsyncAnnotationAdvisor) {
((AsyncAnnotationAdvisor) this.advisor).setExecutor(executor);
}
}
/**
* 设置自定义异常处理器
*/
public void setExceptionHandler(AsyncUncaughtExceptionHandler exceptionHandler) {
this.exceptionHandler = exceptionHandler;
if (this.advisor instanceof AsyncAnnotationAdvisor) {
((AsyncAnnotationAdvisor) this.advisor).setExceptionHandler(exceptionHandler);
}
}
/**
* 返回当前排序顺序,保证 Async 增强优先于其他 Advisor
*/
@Override
public int getOrder() {
return Ordered.HIGHEST_PRECEDENCE;
}
}
5. AsyncAnnotationAdvisor
创建AsyncExecutionInterceptor
/**
* AsyncAnnotationAdvisor 是一个切面(Advisor),用于识别标注了 @Async 注解的方法,
* 并为其织入异步执行逻辑(由 AsyncExecutionInterceptor 实现)。
*/
@SuppressWarnings("serial")
class AsyncAnnotationAdvisor extends AbstractPointcutAdvisor implements BeanFactoryAware {
// 切点(Pointcut),用于匹配标注了 @Async 注解的方法
private final Pointcut pointcut;
// 增强逻辑(Advice),真正负责异步方法的拦截与执行
private final Advice advice;
// 当前 BeanFactory,用于获取容器中的线程池等配置
@Nullable
private BeanFactory beanFactory;
/**
* 构造函数,创建 AsyncAnnotationAdvisor 实例。
*
* @param executor 可选的线程池,如果不传,默认使用 SimpleAsyncTaskExecutor
* @param exceptionHandler 可选的异常处理器
*/
public AsyncAnnotationAdvisor(@Nullable Executor executor,
@Nullable AsyncUncaughtExceptionHandler exceptionHandler) {
// 创建 Pointcut:匹配所有标注了 @Async 注解的方法
this.pointcut = buildPointcut();
// 创建 Advice:实际增强逻辑,负责将方法调用提交到线程池中异步执行
this.advice = buildAdvice(executor, exceptionHandler);
}
/**
* 构建切点(Pointcut),用于匹配带有 @Async 注解的方法。
*
* 默认实现是使用 AnnotationMatchingPointcut 匹配 @Async 注解
*/
protected Pointcut buildPointcut() {
return new AnnotationMatchingPointcut(Async.class);
}
/**
* 构建增强逻辑(Advice),即 AsyncExecutionInterceptor。
* 它会在调用目标方法时将其封装为任务并提交到线程池中执行。
*
* @param executor 线程池
* @param exceptionHandler 异常处理器
*/
protected Advice buildAdvice(@Nullable Executor executor,
@Nullable AsyncUncaughtExceptionHandler exceptionHandler) {
// 创建 AsyncExecutionInterceptor 实例
AsyncExecutionInterceptor interceptor = new AsyncExecutionInterceptor();
// 设置默认使用的线程池
interceptor.setDefaultExecutor(executor);
// 设置未捕获异常的处理方式
interceptor.setExceptionLogger(exceptionHandler);
return interceptor;
}
/**
* 获取切点(Pointcut)
*/
@Override
public Pointcut getPointcut() {
return this.pointcut;
}
/**
* 获取增强逻辑(Advice)
*/
@Override
public Advice getAdvice() {
return this.advice;
}
/**
* 设置 BeanFactory,注入容器上下文。
* 供内部使用的 Advice 可以通过它获取容器中的 Bean(如自定义线程池等)
*/
@Override
public void setBeanFactory(BeanFactory beanFactory) {
this.beanFactory = beanFactory;
if (this.advice instanceof BeanFactoryAware) {
((BeanFactoryAware) this.advice).setBeanFactory(beanFactory);
}
}
/**
* AsyncAnnotationAdvisor 使用的 MethodMatcher,用于判断方法是否被 @Async 注解标注。
*/
private static class AsyncClassOrMethodRuleMethodMatcher extends StaticMethodMatcher {
@Override
public boolean matches(Method method, Class<?> targetClass) {
// 判断当前方法或类上是否有 @Async 注解
return AnnotatedElementUtils.hasAnnotation(method, Async.class) ||
AnnotatedElementUtils.hasAnnotation(targetClass, Async.class);
}
}
}
6. AsyncExecutionInterceptor
拦截方法调用
当调用 @Async
方法时,由 AsyncExecutionInterceptor
拦截并处理异步逻辑:
/**
* AsyncExecutionInterceptor 是 Spring 中负责拦截 @Async 注解方法的核心类。
* 它将目标方法封装为异步任务,并提交到线程池中执行。
*/
@SuppressWarnings("serial")
public class AsyncExecutionInterceptor extends AsyncExecutionAspectSupport implements MethodInterceptor {
/**
* 构造函数,创建一个 AsyncExecutionInterceptor 实例。
*
* @param defaultExecutor 默认的线程池(Executor)
* @param exceptionHandler 异常处理器,用于处理异步方法中未捕获的异常
*/
public AsyncExecutionInterceptor(Executor defaultExecutor, AsyncUncaughtExceptionHandler exceptionHandler) {
super(defaultExecutor);
this.exceptionHandler = exceptionHandler;
}
/**
* 这是核心的拦截方法。
* 当调用标注了 @Async 注解的方法时,会进入这个方法。
*
* @param invocation MethodInvocation 对象,包含目标方法信息
* @return 方法执行结果(通常是 Future 或 CompletableFuture 类型)
* @throws Throwable 如果目标方法抛出异常
*/
@Override
@Nullable
public Object invoke(final MethodInvocation invocation) throws Throwable {
// 获取目标方法对象
Method method = invocation.getMethod();
// 确定当前方法使用的线程池(优先使用方法级别的配置,否则使用默认)
Executor executor = determineAsyncExecutor(method);
if (executor == null) {
throw new IllegalStateException(
"No executor specified for async method '" + method.toGenericString() + "'");
}
// 将目标方法封装成 Callable 任务
Callable<Object> task = () -> {
try {
// 执行目标方法
Object result = invocation.proceed();
if (result instanceof Future) {
// 如果返回值是 Future 类型,则等待其完成以确保异常传播
Future<?> futureResult = (Future<?>) result;
return futureResult.get();
}
return result;
} catch (Throwable ex) {
// 处理目标方法抛出的异常
handleUnexpectedAsyncException(ex, method, invocation.getArguments());
return null;
}
};
// 提交任务到线程池执行,并根据方法返回类型决定如何包装结果
return doSubmit(task, executor, method.getReturnType());
}
/**
* 根据目标方法的返回类型,将 Callable 任务提交到线程池中执行。
*
* @param task 要执行的任务(Callable)
* @param executor 使用的线程池
* @param returnType 目标方法的返回类型
* @return 返回值可能是 Future、CompletableFuture 或 void
*/
protected Object doSubmit(Callable<Object> task, final Executor executor, Class<?> returnType) {
if (CompletableFuture.class.isAssignableFrom(returnType)) {
// 如果方法返回 CompletableFuture 类型,则使用 supplyAsync 包装任务
return CompletableFuture.supplyAsync(() -> {
try {
return task.call();
} catch (Throwable ex) {
throw new AsyncExecutionException(ex);
}
}, executor);
} else if (ListenableFuture.class.isAssignableFrom(returnType)) {
// 如果返回 ListenableFuture(Spring 自定义扩展),则使用 TaskExecutorAdapter 包装
return new TaskExecutorAdapter(executor).submitListenable(task);
} else if (Future.class.isAssignableFrom(returnType)) {
// 如果返回 Future 类型,则使用线程池 submit 提交任务
return executor.submit(task);
} else {
// 如果返回 void 或其他类型,直接提交任务并返回 null
executor.execute(task);
return null;
}
}
/**
* 处理异步方法中发生的未预期异常。
* 默认情况下会调用 AsyncUncaughtExceptionHandler 来处理。
*
* @param ex 异常对象
* @param method 发生异常的方法
* @param params 方法参数
*/
protected void handleUnexpectedAsyncException(Throwable ex, Method method, Object[] params) {
if (this.exceptionHandler != null) {
// 使用用户自定义的异常处理器
this.exceptionHandler.handleUncaughtException(ex, method, params);
} else {
// 否则抛出运行时异常
throw new AsyncExecutionException("Unexpected exception occurred invoking async method: " + method, ex);
}
}
/**
* 设置默认线程池。
*/
public void setDefaultExecutor(@Nullable Executor defaultExecutor) {
super.setDefaultExecutor(defaultExecutor);
}
/**
* 设置异常处理器。
*/
public void setExceptionLogger(@Nullable AsyncUncaughtExceptionHandler exceptionHandler) {
this.exceptionHandler = exceptionHandler;
}
/**
* 内部异常类,用于封装异步执行中的异常。
*/
static final class AsyncExecutionException extends RuntimeException {
AsyncExecutionException(Throwable cause) {
super(cause);
}
}
}
五、自定义线程池配置
可以通过自定义 TaskExecutor
来控制异步方法使用的线程池:
@Configuration
@EnableAsync
public class AsyncConfig implements AsyncConfigurer {
@Override
public Executor getAsyncExecutor() {
ThreadPoolTaskExecutor executor = new ThreadPoolTaskExecutor();
executor.setCorePoolSize(5);
executor.setMaxPoolSize(10);
executor.setQueueCapacity(100);
executor.setThreadNamePrefix("async-pool-");
executor.initialize();
return executor;
}
@Override
public AsyncUncaughtExceptionHandler getAsyncUncaughtExceptionHandler() {
return (ex, method, params) -> {
System.err.println("异步方法异常: " + ex.getMessage());
};
}
}
六、注意事项 & 常见问题
问题 | 原因 |
---|---|
@Async 不生效 | 方法不是 public / 被 final/static 修饰 / 同一个类中调用 |
默认线程池性能差 | 使用 SimpleAsyncTaskExecutor ,每个任务都新建线程 |
异常无法捕获 | 异步方法抛出的异常需要自定义 AsyncUncaughtExceptionHandler 处理 |
七、完整代码
1. 启动类
@SpringBootApplication
@EnableAsync
public class Application {
public static void main(String[] args) {
SpringApplication.run(Application.class, args);
}
}
2. Service 层
@Service
public class DemoService {
@Async
public void sayHelloAsync(String name) {
System.out.println("Hello " + name + " from thread: " + Thread.currentThread().getName());
}
}
3. Controller 层
@RestController
@RequestMapping("/api")
public class DemoController {
@Autowired
private DemoService demoService;
@GetMapping("/hello")
public String hello(@RequestParam String name) {
demoService.sayHelloAsync(name);
return "请求已异步发送";
}
}
八、总结
组件 | 作用 |
---|---|
@EnableAsync | 开启异步功能 |
AsyncAnnotationBeanPostProcessor | 创建带有异步能力的代理对象 |
AsyncExecutionInterceptor | 拦截方法调用,提交到线程池执行 |
TaskExecutor | 执行异步任务的线程池 |
@Async | 标记某个方法为异步方法 |
如需进一步深入源码,可以查看以下类:
org.springframework.aop.interceptor.AsyncExecutionInterceptor
org.springframework.context.annotation.EnableAsync
org.springframework.scheduling.annotation.AsyncAnnotationBeanPostProcessor