在 Spring Boot 中实现异步处理可以通过使用 @Async
注解和 @EnableAsync
注解来实现。以下是如何配置和使用异步处理的步骤和示例代码。
步骤:
- 启用异步支持: 在 Spring Boot 配置类上使用
@EnableAsync
注解启用异步处理。 - 使用
@Async
注解异步方法: 在需要异步执行的方法上使用@Async
注解。 - 返回
Future
、CompletableFuture
或ListenableFuture
: 异步方法可以返回Future
、CompletableFuture
或ListenableFuture
类型的对象,这样可以获取异步执行结果。
示例代码:
1. 启用异步处理
首先,在 Spring Boot 的配置类(通常是主类)上添加 @EnableAsync
注解,启用异步处理。
import org.springframework.boot.SpringApplication;
import org.springframework.boot.autoconfigure.SpringBootApplication;
import org.springframework.scheduling.annotation.EnableAsync;@SpringBootApplication
@EnableAsync // 启用异步处理
public class AsyncApplication {public static void main(String[] args) {SpringApplication.run(AsyncApplication.class, args);}
}
2. 创建异步服务
接下来,创建一个服务类,其中的方法使用 @Async
注解进行异步处理。
import org.springframework.scheduling.annotation.Async;
import org.springframework.stereotype.Service;import java.util.concurrent.CompletableFuture;@Service
public class AsyncService {// 异步方法,返回一个 CompletableFuture@Asyncpublic CompletableFuture<String> processAsyncTask() throws InterruptedException {// 模拟长时间运行的任务Thread.sleep(3000); // 3秒钟延迟return CompletableFuture.completedFuture("Task completed");}// 异步方法,返回一个简单的结果@Asyncpublic void processVoidAsyncTask() throws InterruptedException {// 模拟长时间运行的任务Thread.sleep(2000); // 2秒钟延迟System.out.println("Void task completed");}
}
3. 在控制器中调用异步服务
在控制器类中,你可以调用这些异步方法。异步方法会在后台线程执行,不会阻塞主线程。
import org.springframework.beans.factory.annotation.Autowired;
import org.springframework.web.bind.annotation.GetMapping;
import org.springframework.web.bind.annotation.RestController;import java.util.concurrent.ExecutionException;@RestController
public class AsyncController {@Autowiredprivate AsyncService asyncService;@GetMapping("/async-task")public String executeAsyncTask() throws InterruptedException, ExecutionException {// 调用异步方法CompletableFuture<String> result = asyncService.processAsyncTask();// 返回异步方法执行结果return result.get(); // 这里会阻塞直到任务完成}@GetMapping("/async-void-task")public String executeVoidAsyncTask() throws InterruptedException {// 调用无返回值的异步方法asyncService.processVoidAsyncTask();return "Void async task initiated";}
}
4. 配置线程池(可选)
默认情况下,Spring Boot 会为异步方法使用一个简单的线程池。如果你需要自定义线程池配置,可以通过以下方式进行配置:
import org.springframework.context.annotation.Bean;
import org.springframework.context.annotation.Configuration;
import org.springframework.scheduling.annotation.EnableAsync;
import org.springframework.scheduling.concurrent.ThreadPoolTaskExecutor;import java.util.concurrent.Executor;@Configuration
@EnableAsync
public class AsyncConfig {@Beanpublic Executor taskExecutor() {ThreadPoolTaskExecutor executor = new ThreadPoolTaskExecutor();executor.setCorePoolSize(5); // 核心线程数executor.setMaxPoolSize(10); // 最大线程数executor.setQueueCapacity(25); // 队列容量executor.setThreadNamePrefix("Async-Executor-");executor.initialize();return executor;}
}
5. 运行和测试
现在,启动你的 Spring Boot 应用,并访问以下 URL 进行测试:
- 访问
/async-task
会触发一个异步任务,任务完成后返回结果。 - 访问
/async-void-task
会触发一个没有返回值的异步任务,控制台会打印相应的输出。
结果:
- 当你访问
/async-task
时,后台将异步处理processAsyncTask
方法,主线程不会被阻塞,直到异步任务完成。 - 访问
/async-void-task
时,任务会在后台执行,返回消息表示任务已启动。
注意事项:
- 异步方法必须运行在 Spring 管理的 Bean 上(如
@Service
或@Component
注解的类)。 @Async
注解的异步方法不能调用自身,因为 Spring AOP 代理机制只会代理不同类之间的调用。- 如果异步方法抛出异常,默认情况下,异常不会被抛出到调用者。你可以使用
CompletableFuture
或Future
来捕获异步结果和异常。
这样就实现了一个基本的 Spring Boot 异步处理功能。