在系統需要進行一些比較耗時的操作,比如用戶注冊后要調用郵件服務器給用戶發送個郵件,又比如上傳一個大數據量的 excel 並導入到數據庫。如果后端的這些工作比較耗時,那么前台的頁面便會一直處於等待狀態,讓用戶會以為頁面卡死了。
通常這種比較耗時的操作應該做異步處理,也就是在后台進行,而用戶可以不用等待。下面通過樣例演示 Spring Boot 中如何執行異步任務。
1,開啟線程池
這里我們使用 java 線程池 ExecutorService,首先在項目中添加如下配置類,其作用在於 Spring 啟動時自動加載一個 ExecutorService 對象。
1
2
3
4
5
6
7
8
|
@Configuration
public
class
ThreadPoolConfig {
@Bean
public
ExecutorService executorService() {
return
Executors.newCachedThreadPool();
}
}
|
2,創建異步任務
這里我們實現 Runnable 接口來創建一個異步任務,里面代碼很簡單,就是等待個 5 秒再結束:
注意:Runnable 和 Callable 在異步任務中的應用差別在於,一個不帶返回值,一個帶返回值而已。
1
2
3
4
5
6
7
8
9
10
11
12
13
14
15
16
17
18
|
public
class
EmailRunnable
implements
Runnable {
private
String name;
public
EmailRunnable(String name) {
this
.name = name;
}
@Override
public
void
run() {
System.out.println(
"正在給"
+ name +
"發送郵件......"
);
try
{
Thread.sleep(
5000
);
}
catch
(InterruptedException e) {
e.printStackTrace();
}
System.out.println(
"郵件發送完畢"
);
}
}
|
3,執行異步任務
(1)這里我們在一個 Cotroller 中通過線程池執行這個異步任務:
1
2
3
4
5
6
7
8
9
10
11
12
13
|
@RestController
public
class
HelloController {
@Autowired
ExecutorService executorService;
@GetMapping
(
"/hello"
)
public
void
hello() {
System.out.println(
"hello start"
);
executorService.execute(
new
EmailRunnable(
"hangge"
));
System.out.println(
"hello end"
);
}
}
|
(2)通過瀏覽器訪問 /hello 接口,可以看到控制台輸出如下: