@EnableAsync
和 @Async
注解的使用方法
@EnableAsync
和 @Async
是Spring框架中的兩個注解,用于啟用和使用異步方法執行。它們可以幫助你在Spring應用程序中實現異步編程,從而提高應用程序的性能和響應速度。
@EnableAsync
@EnableAsync
注解用于啟用Spring的異步方法執行功能。你需要在配置類或主應用程序類上添加這個注解,以便Spring能夠掃描并處理 @Async
注解的方法。
@Async
@Async
注解用于標記一個方法為異步方法。當Spring調用這個方法時,它會在一個獨立的線程中執行,而不會阻塞調用者的線程。
使用步驟
- 啟用異步支持:在配置類或主應用程序類上添加
@EnableAsync
注解。 - 標記異步方法:在需要異步執行的方法上添加
@Async
注解。
示例代碼
1. 啟用異步支持
在主應用程序類或配置類上添加 @EnableAsync
注解。
import org.springframework.boot.SpringApplication;
import org.springframework.boot.autoconfigure.SpringBootApplication;
import org.springframework.scheduling.annotation.EnableAsync;@SpringBootApplication
@EnableAsync
public class MyApplication {public static void main(String[] args) {SpringApplication.run(MyApplication.class, args);}
}
2. 標記異步方法
在需要異步執行的方法上添加 @Async
注解。
import org.springframework.scheduling.annotation.Async;
import org.springframework.stereotype.Service;@Service
public class MyService {@Asyncpublic void performAsyncTask() {// 這個方法將在一個獨立的線程中執行System.out.println("執行異步任務");try {Thread.sleep(5000); // 模擬耗時操作} catch (InterruptedException e) {e.printStackTrace();}System.out.println("異步任務完成");}
}
3. 調用異步方法
在其他地方調用異步方法。
import org.springframework.beans.factory.annotation.Autowired;
import org.springframework.web.bind.annotation.GetMapping;
import org.springframework.web.bind.annotation.RestController;@RestController
public class MyController {@Autowiredprivate MyService myService;@GetMapping("/async")public String executeAsyncTask() {myService.performAsyncTask();return "異步任務已提交";}
}
注意事項
- 返回類型:異步方法可以返回
void
、Future
或CompletableFuture
。如果需要獲取異步方法的結果,可以使用Future
或CompletableFuture
。
@Async
public CompletableFuture<String> performAsyncTaskWithResult() {// 這個方法將在一個獨立的線程中執行System.out.println("執行異步任務");try {Thread.sleep(5000); // 模擬耗時操作} catch (InterruptedException e) {e.printStackTrace();}return CompletableFuture.completedFuture("異步任務完成");
}
- 線程池配置:默認情況下,Spring使用一個簡單的線程池來執行異步任務。你可以自定義線程池,以滿足特定的性能需求。
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 {@Bean(name = "taskExecutor")public Executor taskExecutor() {ThreadPoolTaskExecutor executor = new ThreadPoolTaskExecutor();executor.setCorePoolSize(5);executor.setMaxPoolSize(10);executor.setQueueCapacity(25);executor.setThreadNamePrefix("Async-");executor.initialize();return executor;}
}
- 類級別的
@Async
:你也可以在類級別上使用@Async
注解,表示該類中的所有方法都將異步執行。
import org.springframework.scheduling.annotation.Async;
import org.springframework.stereotype.Service;@Service
@Async
public class MyService {public void performAsyncTask() {// 這個方法將在一個獨立的線程中執行System.out.println("執行異步任務");}
}
通過使用 @EnableAsync
和 @Async
注解,你可以輕松地在Spring應用程序中實現異步方法執行,從而提高應用程序的性能和響應速度。
獲取異步結果
主線程可以通過 CompletableFuture 的方法來獲取異步任務的結果。
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.CompletableFuture;
import java.util.concurrent.ExecutionException;@RestController
public class MyController {@Autowiredprivate MyService myService;@GetMapping("/async")public String executeAsyncTask() throws ExecutionException, InterruptedException {// 調用異步方法,立即返回一個 CompletableFuture 對象CompletableFuture<String> future = myService.performAsyncTaskWithResult();// 主線程不會被阻塞,可以繼續執行其他操作System.out.println("異步任務已提交");// 獲取異步任務的結果(會阻塞直到結果可用)String result = future.get();return result;}
}
總結
- 調用異步方法時:由于
@Async
注解,異步方法將在一個獨立的線程中執行,調用該方法的主線程不會被阻塞。 - 立即返回
CompletableFuture
對象:調用異步方法后,主線程會立即返回一個CompletableFuture
對象,表示異步任務的結果。 - 獲取結果:主線程可以通過
CompletableFuture
的方法來獲取異步任務的結果,而不需要等待異步任務完成。