高效初始化!Spring Boot 3.3借助DAG加速Spring Beans加載!
在現(xiàn)代軟件開發(fā)中,異步編程已成為提升系統(tǒng)性能和用戶體驗的重要手段。特別是在高并發(fā)場景下,異步任務(wù)的處理能夠有效降低響應(yīng)時間,提高系統(tǒng)的可伸縮性。Spring Boot 3.3 提供了便捷的異步編程支持,使得開發(fā)者可以輕松實現(xiàn)高效的任務(wù)調(diào)度。本篇文章將詳細(xì)探討如何在 Spring Boot 項目中優(yōu)雅地實現(xiàn)異步任務(wù),包括配置、實現(xiàn)和調(diào)用的最佳實踐。
運(yùn)行效果:
圖片
若想獲取項目完整代碼以及其他文章的項目源碼,且在代碼編寫時遇到問題需要咨詢交流,歡迎加入下方的知識星球。
在本文中,我們將通過具體的代碼示例,講解如何配置 YAML 文件、創(chuàng)建配置屬性類、實現(xiàn)異步任務(wù)的服務(wù)類,以及如何通過前端頁面調(diào)用異步接口。通過這些步驟,你將能夠構(gòu)建一個響應(yīng)快速且高效的 Spring Boot 應(yīng)用。
項目結(jié)構(gòu)
首先,確保你的項目結(jié)構(gòu)如下:
src
├── main
│ ├── java
│ │ └── com
│ │ └── icoderoad
│ │ └── async
│ │ ├── AsyncApplication.java
│ │ ├── config
│ │ │ ├── AsyncConfig.java
│ │ │ └── TaskProperties.java
│ │ ├── controller
│ │ │ └── TaskController.java
│ │ └── service
│ │ └── TaskService.java
│ └── resources
│ ├── application.yml
│ └── templates
│ └── index.html
└── pom.xml
項目 pom.xml 配置
確保在 pom.xml 中引入必要的依賴:
<?xml versinotallow="1.0" encoding="UTF-8"?>
<project xmlns="http://maven.apache.org/POM/4.0.0" xmlns:xsi="http://www.w3.org/2001/XMLSchema-instance"
xsi:schemaLocation="http://maven.apache.org/POM/4.0.0 https://maven.apache.org/xsd/maven-4.0.0.xsd">
<modelVersion>4.0.0</modelVersion>
<parent>
<groupId>org.springframework.boot</groupId>
<artifactId>spring-boot-starter-parent</artifactId>
<version>3.3.4</version>
<relativePath/> <!-- lookup parent from repository -->
</parent>
<groupId>com.icoderoad</groupId>
<artifactId>async-spring-boot</artifactId>
<version>0.0.1-SNAPSHOT</version>
<name>async-spring-boot</name>
<description>Demo project for Spring Boot</description>
<properties>
<java.version>17</java.version>
</properties>
<dependencies>
<dependency>
<groupId>org.springframework.boot</groupId>
<artifactId>spring-boot-starter-web</artifactId>
</dependency>
<dependency>
<groupId>org.springframework.boot</groupId>
<artifactId>spring-boot-starter-thymeleaf</artifactId>
</dependency>
<dependency>
<groupId>org.projectlombok</groupId>
<artifactId>lombok</artifactId>
<optional>true</optional>
</dependency>
<dependency>
<groupId>org.springframework.boot</groupId>
<artifactId>spring-boot-starter-validation</artifactId>
</dependency>
<dependency>
<groupId>org.springframework.boot</groupId>
<artifactId>spring-boot-starter-test</artifactId>
<scope>test</scope>
</dependency>
</dependencies>
<build>
<plugins>
<plugin>
<groupId>org.springframework.boot</groupId>
<artifactId>spring-boot-maven-plugin</artifactId>
</plugin>
</plugins>
</build>
</project>
YAML 屬性文件配置
在 src/main/resources/application.yml 中添加以下配置:
server:
port: 8080
task:
pool:
core-size: 5 # 線程池核心大小
max-size: 10 # 線程池最大大小
queue-capacity: 25 # 隊列容量
timeout: 5000 # 任務(wù)超時時間,單位毫秒
創(chuàng)建配置屬性類
創(chuàng)建 TaskProperties.java 來讀取 YAML 配置:
package com.icoderoad.async.config;
import org.springframework.boot.context.properties.ConfigurationProperties;
import org.springframework.stereotype.Component;
import lombok.Data;
@Data
@Component
@ConfigurationProperties(prefix = "task.pool") // 讀取 task 下的配置
public class TaskProperties {
private int coreSize;
private int maxSize;
private int queueCapacity;
private int timeout;
}
創(chuàng)建異步配置類
在 AsyncConfig.java 中使用配置屬性類進(jìn)行任務(wù)初始化:
package com.icoderoad.async.config;
import org.springframework.beans.factory.annotation.Autowired;
import org.springframework.context.annotation.Bean;
import org.springframework.context.annotation.Configuration;
import org.springframework.scheduling.annotation.EnableAsync;
import org.springframework.scheduling.annotation.EnableScheduling;
import org.springframework.scheduling.concurrent.ThreadPoolTaskExecutor;
@Configuration
@EnableAsync // 啟用異步功能
@EnableScheduling // 啟用定時任務(wù)
public class AsyncConfig {
@Autowired
private TaskProperties taskProperties;
@Bean
public ThreadPoolTaskExecutor taskExecutor() {
ThreadPoolTaskExecutor executor = new ThreadPoolTaskExecutor();
executor.setCorePoolSize(taskProperties.getCoreSize());
executor.setMaxPoolSize(taskProperties.getMaxSize());
executor.setQueueCapacity(taskProperties.getQueueCapacity());
executor.setThreadNamePrefix("Async-");
executor.initialize();
return executor;
}
}
創(chuàng)建服務(wù)類
在 TaskService.java 中創(chuàng)建更典型的異步任務(wù)配置:
package com.icoderoad.async.service;
import org.springframework.beans.factory.annotation.Autowired;
import org.springframework.scheduling.annotation.Async;
import org.springframework.stereotype.Service;
import com.icoderoad.async.config.TaskProperties;
import java.util.concurrent.CompletableFuture;
@Service
public class TaskService {
@Autowired
private TaskProperties taskProperties;
@Async // 表示該方法是異步執(zhí)行的
public CompletableFuture<String> executeAsyncTask() {
try {
Thread.sleep(taskProperties.getTimeout()); // 模擬耗時操作
return CompletableFuture.completedFuture("異步任務(wù)執(zhí)行完成!");
} catch (InterruptedException e) {
Thread.currentThread().interrupt();
return CompletableFuture.completedFuture("任務(wù)被中斷!");
}
}
}
創(chuàng)建控制器
在 TaskController.java 中創(chuàng)建一個控制器來調(diào)用異步服務(wù)并返回 JSON 格式的接口:
package com.icoderoad.async.controller;
import java.util.concurrent.CompletableFuture;
import org.springframework.http.ResponseEntity;
import org.springframework.web.bind.annotation.PostMapping;
import org.springframework.web.bind.annotation.RequestMapping;
import org.springframework.web.bind.annotation.RestController;
import com.icoderoad.async.service.TaskService;
@RestController
@RequestMapping("/tasks")
public class TaskController {
private final TaskService taskService;
public TaskController(TaskService taskService) {
this.taskService = taskService;
}
@PostMapping("/async-task")
public ResponseEntity<CompletableFuture<String>> asyncTask() {
CompletableFuture<String> result = taskService.executeAsyncTask(); // 調(diào)用異步任務(wù)
return ResponseEntity.ok(result);
}
}
創(chuàng)建前端頁面
在 src/main/resources/templates/index.html 中添加以下代碼,并使用 jQuery 調(diào)用 JSON 接口:
<!DOCTYPE html>
<html xmlns:th="http://www.thymeleaf.org">
<head>
<meta charset="UTF-8">
<title>異步任務(wù)示例</title>
<link rel="stylesheet" >
<script src="https://code.jquery.com/jquery-3.3.1.min.js"></script>
<script src="https://stackpath.bootstrapcdn.com/bootstrap/4.3.1/js/bootstrap.min.js"></script>
</head>
<body>
<div class="container">
<h1>異步任務(wù)示例</h1>
<button id="startTask" class="btn btn-primary">開始異步任務(wù)</button>
<p id="result"></p>
</div>
<script>
$(document).ready(function() {
$('#startTask').click(function() {
$.ajax({
url: '/tasks/async-task',
type: 'POST',
contentType: 'application/json', // 設(shè)置請求內(nèi)容類型為 JSON
dataType: 'json', // 期望的響應(yīng)數(shù)據(jù)類型
success: function(data) {
$('#result').text(data); // 顯示返回結(jié)果
},
error: function() {
$('#result').text('任務(wù)執(zhí)行失敗!');
}
});
});
});
</script>
</body>
</html>
啟動測試
- 啟動 Spring Boot 應(yīng)用:運(yùn)行 AsyncApplication.java,確保應(yīng)用成功啟動。
- 訪問前端頁面:打開瀏覽器并訪問 http://localhost:8080/index.html。
- 點擊按鈕:點擊“開始異步任務(wù)”按鈕,觸發(fā)異步任務(wù)的執(zhí)行。
- 觀察行為:
立即返回:在點擊按鈕后,接口會立即返回,而不是等任務(wù)執(zhí)行完。這是因為任務(wù)是異步執(zhí)行的。
注意
這種設(shè)計允許用戶在等待異步任務(wù)完成時,繼續(xù)與頁面進(jìn)行其他交互,提升了用戶體驗。這意味著,即使后臺任務(wù)還在執(zhí)行,用戶也可以繼續(xù)操作頁面,而不會被阻塞。這樣,可以在高并發(fā)場景下有效提升系統(tǒng)的響應(yīng)能力。
結(jié)論
本文詳細(xì)介紹了如何在 Spring Boot 3.3 中實現(xiàn)異步執(zhí)行任務(wù)的最佳實踐。我們通過配置 YAML 文件、創(chuàng)建配置屬性類、實現(xiàn)異步任務(wù)服務(wù)類和控制器,最后使用前端 jQuery 調(diào)用異步接口,展示了異步任務(wù)的完整實現(xiàn)流程。
異步任務(wù)不僅提高了系統(tǒng)的響應(yīng)速度,還能夠有效管理后臺處理任務(wù),降低用戶等待時間。通過合理的線程池配置和異步執(zhí)行的設(shè)計,我們可以使應(yīng)用程序在高并發(fā)情況下依然表現(xiàn)出色。希望本文能為大家在實際項目中實現(xiàn)異步處理提供有效的參考,提升開發(fā)效率和用戶體驗。