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

发布于:2025-03-11 ⋅ 阅读:(165) ⋅ 点赞:(0)

一、@Async 的核心机制

1. 基本用法

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

@Service
public class MyService {
    @Async
    public void asyncTask() {
        // 异步执行的代码(如发送邮件、处理文件)
        System.out.println("Async task executed by thread: " + Thread.currentThread().getName());
    }
}
2. 调用方式
@RestController
public class MyController {
    @Autowired
    private 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(); // 直接调用异步方法不会生效!
        }
    
        @Async
        public 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 {
    @Override
    public AsyncUncaughtExceptionHandler getAsyncUncaughtExceptionHandler() {
        return (ex, method, params) -> {
            System.err.println("Async method error: " + method.getName());
            ex.printStackTrace();
        };
    }
}

网站公告

今日签到

点亮在社区的每一天
去签到