一、@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();};}
}