Spring Boot 01:main 如何變成一個可以接 HTTP 的應用
看到終端出現 Started,接著在瀏覽器輸入網址,為什麼 Java 方法就被呼叫了?中間至少有建置、啟動、HTTP 分派三件不同的事。這一課只把它們接起來,先不研究資料庫。
先分清 Maven、Spring 與 Boot
Maven 讀 pom.xml,取得相依套件、編譯 Java、執行測試並打包。Spring Framework 在程式執行時管理物件,提供 MVC 與交易等功能。Boot 則提供一組整合慣例、自動設定與啟動方式。把 pom 裡的版本換掉,只改了建置選擇,還不能說執行行為已經正確。
<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.5.16</version><relativePath/></parent>
<groupId>com.keeponfirst</groupId><artifactId>boot-learning-lab</artifactId><version>1.0.0</version>
<properties><java.version>21</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-validation</artifactId></dependency>
<dependency><groupId>org.springframework.boot</groupId><artifactId>spring-boot-starter-jdbc</artifactId></dependency>
<dependency><groupId>com.h2database</groupId><artifactId>h2</artifactId><scope>runtime</scope></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>這份 POM 的 parent 固定 Boot 3.5.16;java.version 選 Java 21。web 提供 MVC 與預設內嵌伺服器,validation、jdbc 與 H2 留給後面幾課,test 只放在測試範圍。parent 的版本管理不會替你憑空加入所有依賴;真正要使用的 starter 仍需宣告。plugin 負責把應用重新打包成可用 java -jar 執行的產物。
找到啟動入口與掃描邊界
// LabApplication.java
package com.keeponfirst.bootlab;
import org.springframework.boot.SpringApplication;
import org.springframework.boot.autoconfigure.SpringBootApplication;
import org.springframework.boot.context.properties.EnableConfigurationProperties;
@SpringBootApplication
@EnableConfigurationProperties(LabProperties.class)
public class LabApplication {
public static void main(String[] args) {
SpringApplication.run(LabApplication.class, args);
}
}SpringApplication.run 建立並啟動應用環境。@SpringBootApplication 結合設定類別、元件掃描與自動設定的入口。主類別放在 com.keeponfirst.bootlab,其他範例類別也放在這個 package;後面新增子 package 也在預設掃描範圍。把 Controller 搬到不相干的頂層 package,不能假設 Spring 仍會找到它。
main 啟動的是 JVM 內的一個應用,不是每次 HTTP 進來都重新啟動一次。對這個使用 web starter 的獨立程式,Boot 會啟動內嵌 HTTP 伺服器。EAP 部署 WAR 的入口不同,留到第六課再比較。
只讀 ping 這個方法
@GetMapping("/ping")
public Map<String, String> ping() {
return Map.of("service", properties.label());
}這段擷取自 TicketController。類別的 @RequestMapping("/api") 加上方法的 /ping,組成 /api/ping。@RestController 讓回傳值經由訊息轉換器寫入回應;這裡 Map 會輸出 JSON。properties.label() 目前來自 application.properties 的 lab.label,第三課會追這個值。
動手:啟動後觀察 HTTP
java -version
mvn -version
mvn package
java -jar target/boot-learning-lab-1.0.0.jar
# In another terminal:
curl -i http://127.0.0.1:8080/api/ping先下載範例並進入有 pom.xml 的目錄。java 與 mvn 顯示的 JDK 都應是 21;若不同,先調整目前終端的 JDK,再建置。預期收到 200 與 {"service":"boot-lab"}。按 Ctrl+C 停止應用後再呼叫,應連線失敗;原本回應確實來自剛剛那個程序。
| 現象 | 先檢查 |
|---|---|
| 編譯失敗 | Maven 使用的 JDK、第一個編譯錯誤 |
| 啟動時 port 被占用 | 停止自己的舊程序,或換未使用的 port |
| 連線失敗 | 應用是否仍執行、位址與 port |
| 404 | /api 前綴、mapping、掃描位置 |
自我檢查:改完 Java 檔,重打 curl 就會生效嗎?
先預測再試:改 ping 回傳的 key,卻只對已執行的 JAR 重打 curl。答案是這個範例不會自動更新;你需要停止、重新 package 並啟動新產物。IDE 的重載或 DevTools 是另外的機制,這份範例沒有啟用。把正在執行的檔案版本對上,才能把觀察結果歸給那次修改。
下載本系列完整工單 API 範例(ZIP)下一課:02:Bean、注入與自動設定