入門指南:從環(huán)境搭建到項(xiàng)目上線)
上個(gè)月一個(gè)讀者私信我說自己看了一個(gè)月的 Java 基礎(chǔ)卻連一個(gè)能跑起來的 Web 項(xiàng)目都搭不出來。翻遍教程要么是十幾年前的 SSH 老古董要么上來就甩一堆 XML 配置把人勸退。我跟他說直接學(xué) Spring Boot別繞彎路。Spring Boot 把 Java Web 開發(fā)里那些繁瑣的配置、復(fù)雜的依賴管理、麻煩的部署流程全部簡(jiǎn)化掉了你只要把業(yè)務(wù)流程寫清楚剩下的框架幫你兜底。這篇指南就是給真正零基礎(chǔ)的人準(zhǔn)備的我盡量用大白話把 Spring Boot 從環(huán)境搭建到項(xiàng)目上線的完整路徑講透你跟著一步步做半天時(shí)間就能體驗(yàn)到用 Java 做 Web 開發(fā)的爽感。1. 項(xiàng)目概述Spring Boot 到底解決什么問題1.1 從傳統(tǒng) SSM 到 Spring Boot省掉的到底是什么很多老教程還在講 SSMSpring SpringMVC MyBatis這套組合。不是說它不對(duì)而是它對(duì)新手太不友好了。當(dāng)年我學(xué) SSM 的時(shí)候光是 spring-config.xml、spring-mvc.xml、mybatis-config.xml 這幾個(gè)配置文件就能熬掉兩個(gè)通宵。你還沒寫一行業(yè)務(wù)代碼先要搞清楚 Bean 怎么裝配、事務(wù)管理器怎么配、Mapper 掃描路徑怎么填稍不留神就是 XML 里少寫一個(gè) namespace啟動(dòng)直接報(bào)錯(cuò)。Spring Boot 的思路完全不同。它的核心理念是約定優(yōu)于配置框架把常見的配置都預(yù)設(shè)好了你只要在 pom.xml 里引入對(duì)應(yīng)的依賴它就能自動(dòng)幫你完成初始化和裝配。這就好比以前你開一家餐館得自己搭灶臺(tái)、接水管、裝油煙機(jī)現(xiàn)在 Spring Boot 直接給你一個(gè)精裝鋪面你只需要決定菜單賣什么。1.2 為什么零基礎(chǔ)新手應(yīng)該直接上手 Spring Boot有人會(huì)擔(dān)心不學(xué) Spring 直接學(xué) Spring Boot會(huì)不會(huì)根基不穩(wěn)。我的看法是Spring Boot 本身就是 Spring 生態(tài)的一部分你學(xué) Spring Boot 的過程天然就在接觸 Spring 的核心概念比如依賴注入、AOP、事務(wù)管理。只是它把這些概念從手動(dòng)配置變成了自動(dòng)裝配你反而能更輕松地理解它們。更重要的是Spring Boot 能讓你在最短時(shí)間內(nèi)獲得正反饋。第一天就能跑起一個(gè)帶 RESTful API 的項(xiàng)目還能接上數(shù)據(jù)庫做增刪改查這種成就感是支撐你繼續(xù)深入學(xué)習(xí)的最大動(dòng)力。我見過不少從 SSM 入門的同學(xué)挫敗感太強(qiáng)直接轉(zhuǎn)行了反而是先上手 Spring Boot 的后來回去補(bǔ) Spring 原理時(shí)輕松很多。1.3 這篇全指南的適用范圍這篇文章適合完全沒接觸過 Spring Boot、甚至 Java 基礎(chǔ)都薄弱的讀者。我會(huì)帶你完成以下目標(biāo)搭建本地 Java 開發(fā)環(huán)境搞定 JDK、IDE、Maven通過 Spring Initializr 創(chuàng)建第一個(gè) Spring Boot 項(xiàng)目理解項(xiàng)目結(jié)構(gòu)和啟動(dòng)流程開發(fā)一個(gè)帶數(shù)據(jù)庫的完整 RESTful API 項(xiàng)目掌握打包、運(yùn)行和多環(huán)境配置整個(gè)過程我都用最直白的語言解釋代碼該有的注釋一條不少。2. 核心思路拆解先跑通再理解最后改造2.1 三步走學(xué)習(xí)策略我給初學(xué)者的建議永遠(yuǎn)是先讓項(xiàng)目跑起來再回頭理解原理最后動(dòng)手改造。第一步是跑通。你不用管背后發(fā)生了什么照著下面的步驟把項(xiàng)目啟動(dòng)起來訪問到頁面就算贏。這一步的目的是建立感性認(rèn)識(shí)知道 Java Web 開發(fā)是怎么回事。第二步是理解。當(dāng)你跑通了 Hello World再回頭去看項(xiàng)目結(jié)構(gòu)、看啟動(dòng)類、看自動(dòng)配置的機(jī)制之前的疑問會(huì)自然解開。因?yàn)榇藭r(shí)你的腦子已經(jīng)有一個(gè)運(yùn)行的系統(tǒng)在支撐想象而不是面對(duì)一堆靜態(tài)文件空想。第三步是改造。把 Hello World 改成自己的業(yè)務(wù)場(chǎng)景比如做一個(gè)待辦事項(xiàng)管理、一個(gè)學(xué)生信息查詢、一個(gè)博客文章發(fā)布。改造的過程中你會(huì)遇到真實(shí)的問題解決這些問題的過程才是真正的學(xué)習(xí)。2.2 為什么用 Maven 而不是 Gradle國(guó)內(nèi)絕大多數(shù)企業(yè)級(jí) Java 項(xiàng)目用的是 MavenSpring Boot 官方文檔也默認(rèn)以 Maven 為主。雖然 Gradle 在構(gòu)建速度上更快但 Maven 的約定優(yōu)于配置風(fēng)格更適合新手它的 pom.xml 結(jié)構(gòu)清晰依賴聲明簡(jiǎn)單直接。另一個(gè)現(xiàn)實(shí)因素是排查問題方便。你搜Maven 依賴下載失敗能搜到的解決方案比 Gradle 多一個(gè)數(shù)量級(jí)。遇到問題能快速找到答案對(duì)新手來說比性能更重要。2.3 為什么先選 H2 數(shù)據(jù)庫而不是 MySQL很多教程上來就讓新手裝 MySQL還得配賬號(hào)密碼、建庫建表這一套流程對(duì)小白來說又是一道坎。H2 是一個(gè)內(nèi)嵌的內(nèi)存數(shù)據(jù)庫你只要引入依賴不需要安裝任何東西項(xiàng)目啟動(dòng)時(shí)自動(dòng)創(chuàng)建數(shù)據(jù)庫項(xiàng)目停止時(shí)數(shù)據(jù)自動(dòng)釋放。對(duì)于學(xué)習(xí)階段來說H2 能讓你專注在 Spring Boot 本身的業(yè)務(wù)邏輯上而不是在數(shù)據(jù)庫配置上消耗精力。等你的項(xiàng)目成長(zhǎng)起來再切換成 MySQL 也只是改一行配置的事。Spring Data JPA 屏蔽了底層數(shù)據(jù)庫的差異這就是分層設(shè)計(jì)帶來的好處。3. 環(huán)境準(zhǔn)備JDK、IDE、Maven一個(gè)都不能缺3.1 JDK 版本怎么選Spring Boot 3.x 要求 JDK 17 起步Spring Boot 2.x 支持 JDK 8 到 21。我的建議是直接上 JDK 17因?yàn)?Spring Boot 3.x 已經(jīng)發(fā)布多年社區(qū)生態(tài)和排錯(cuò)資料都很成熟而且 JDK 17 是長(zhǎng)期支持版本技能棧更貼合當(dāng)下主流。下載 JDK 后一定要配置環(huán)境變量。Windows 下新建 JAVA_HOME 變量指向 JDK 安裝目錄然后把 %JAVA_HOME%\bin 追加到 Path 中。配置完成后打開命令行窗口輸入以下命令驗(yàn)證java -version如果能看到版本信息說明 JDK 配置成功。這一步卡住的人不少常見癥狀是命令找不到幾乎都是環(huán)境變量沒配上或者配錯(cuò)路徑。3.2 IDE 選擇IntelliJ IDEA 社區(qū)版就夠了現(xiàn)在開發(fā) Java 基本默認(rèn) IntelliJ IDEA。社區(qū)版免費(fèi)功能上對(duì)于學(xué)習(xí) Spring Boot 完全夠用。不要覺得社區(qū)版低人一等你日常用到的編碼輔助、Git 集成、Maven 面板它都有跟專業(yè)版的核心差異主要在 Spring 專屬的圖形化支持上比如依賴提示之類的便利功能對(duì)學(xué)習(xí)階段可以不用那么講究。打開 IDEA 后把 Maven 的配置指到你本地的 settings.xml。這一步是在設(shè)置里搜索 Maven修改 User settings file 為實(shí)際路徑。如果你沒改過IDEA 會(huì)用內(nèi)置的 Maven也可以繼續(xù)用。3.3 Maven 鏡像加速阿里云鏡像配置國(guó)內(nèi)直接訪問 Maven 中央倉庫那個(gè)速度下載一個(gè) Spring Boot 相關(guān)依賴能等五分鐘。建議修改 Maven 的 settings.xml 文件把鏡像切換成國(guó)內(nèi)源。在 .m2 目錄下找到 settings.xml沒有就新建一個(gè)加入以下內(nèi)容mirrors mirror idaliyunmaven/id mirrorOfcentral/mirrorOf name阿里云公共倉庫/name urlhttps://maven.aliyun.com/repository/public/url /mirror /mirrors配置完成后重啟 IDE再創(chuàng)建項(xiàng)目時(shí)依賴下載速度會(huì)有質(zhì)的提升。這個(gè)細(xì)節(jié)能讓你少等好幾個(gè)小時(shí)。4. 創(chuàng)建第一個(gè) Spring Boot 項(xiàng)目4.1 用 Spring Initializr 生成項(xiàng)目骨架打開 IDEA選擇 New Project左側(cè)選擇 Spring Initializr。這一步的關(guān)鍵是讓你理解腳手架的概念等熟悉了以后你完全可以手動(dòng)寫配置創(chuàng)建項(xiàng)目但初期用這個(gè)工具能省掉很多手寫錯(cuò)誤。關(guān)鍵配置項(xiàng)說明Project 選擇 MavenLanguage 選擇 JavaSpring Boot 版本選默認(rèn)的穩(wěn)定版本Group 填 com.exampleArtifact 填 demoJava 版本選擇 17依賴這一欄第一次創(chuàng)建只需要勾選 Spring Web因?yàn)槲覀兊哪繕?biāo)是先把接口跑起來。之后再勾選 Spring Data JPA 和 H2 Database用于后續(xù)數(shù)據(jù)庫操作。點(diǎn)擊 Create 后等待依賴下載完成第一個(gè) Spring Boot 項(xiàng)目就創(chuàng)建好了。4.2 項(xiàng)目目錄結(jié)構(gòu)逐層拆解生成的項(xiàng)目結(jié)構(gòu)是這樣的demo ├── pom.xml └── src ├── main │ ├── java │ │ └── com/example/demo │ │ └── DemoApplication.java │ └── resources │ └── application.properties └── test └── javapom.xml 是 Maven 的配置文件相當(dāng)于項(xiàng)目的清單聲明了所有依賴和插件。resources 目錄放配置文件比如 application.properties 就是 Spring Boot 的全局配置。java 目錄下放源代碼。DemoApplication.java 是啟動(dòng)類帶著 SpringBootApplication 注解main 方法就是整個(gè)應(yīng)用的入口。4.3 啟動(dòng)類上那三個(gè)注解的含義SpringBootApplication 是一個(gè)組合注解它等價(jià)于 Configuration、EnableAutoConfiguration、ComponentScan 三個(gè)注解加在一起。Configuration 表示當(dāng)前類可以作為配置來源EnableAutoConfiguration 是 Spring Boot 最核心的能力來源它負(fù)責(zé)開啟自動(dòng)配置ComponentScan 則告訴 Spring 從哪里掃描組件。記住一點(diǎn)主類必須放在包的根目錄上也就是所有其他代碼的上級(jí)目錄。否則 Spring 掃描不到你寫的 Controller接口請(qǐng)求就全部 404。4.4 第一個(gè) RESTful 接口三分鐘見到效果在 DemoApplication 同層的目錄下新建一個(gè) controller 包然后創(chuàng)建 HelloController 類RestController RequestMapping(/api) public class HelloController { GetMapping(/hello) public String sayHello() { return Hello, Spring Boot!; } }運(yùn)行 DemoApplication 的 main 方法控制臺(tái)會(huì)打印出 Spring Boot 啟動(dòng)成功的日志同時(shí)告訴你內(nèi)嵌 Tomcat 的端口是 8080。瀏覽器里訪問 http://localhost:8080/api/hello就能看到返回的字符串。這就是內(nèi)嵌服務(wù)器帶來的便利。以前你需要單獨(dú)裝 Tomcat再把項(xiàng)目打成 war 包丟進(jìn)去現(xiàn)在 main 方法一跑Web 服務(wù)器直接內(nèi)嵌啟動(dòng)。這也是第一個(gè)能給你帶來沖擊感的點(diǎn)。5. 自動(dòng)配置原理Spring Boot 的魔法到底是什么5.1 自動(dòng)配置的底層機(jī)制我前面用了魔法這個(gè)詞但其實(shí)它一點(diǎn)也不神秘。Spring Boot 啟動(dòng)時(shí)會(huì)掃描依賴中所有 jar 包里的 META-INF/spring/... 配置文件里面記錄了一堆配置類的全限定名。然后 EnableAutoConfiguration 通過 SpringFactoriesLoader 機(jī)制加載這些配置類再配合 ConditionalOnClass、ConditionalOnMissingBean 等條件注解根據(jù)你當(dāng)前引入的依賴和配置動(dòng)態(tài)決定要不要生效。舉個(gè)例子你引入了 spring-boot-starter-web自動(dòng)配置類就會(huì)檢測(cè)到 Servlet 相關(guān)的類存在于 classpath 上于是自動(dòng)創(chuàng)建一個(gè) Spring MVC 的 DispatcherServlet 和內(nèi)嵌 Tomcat。等你引入了 spring-boot-starter-data-jpa它又會(huì)自動(dòng)配置數(shù)據(jù)源、EntityManagerFactory、事務(wù)管理器。這些自動(dòng)配置類的加載過程你可以通過一個(gè)簡(jiǎn)單的開關(guān)偷窺到。在 application.properties 里添加debugtrue啟動(dòng)時(shí)控制臺(tái)會(huì)打印一份自動(dòng)配置報(bào)告里面用 Positive matches 和 Negative matches 分別列出了生效和未生效的自動(dòng)配置項(xiàng)。我建議你把這個(gè)報(bào)告好好翻一遍這是理解 Spring Boot 最直觀的窗口。5.2 Starter 依賴背后的聚合邏輯Spring Boot Starter 的本質(zhì)是一個(gè)依賴集合。spring-boot-starter-web 這個(gè)坐標(biāo)引入后會(huì)自動(dòng)把 spring-web、spring-webmvc、spring-boot-starter-tomcat、jackson-databind 等十幾個(gè)依賴一起拉進(jìn)來。這樣你就不用一個(gè)個(gè)去聲明版本號(hào)也避免了多個(gè)框架版本沖突的問題。通過 Maven 面板展開 External Libraries你可以看到一個(gè) starter 下面掛了哪些具體 jar 包。這里面有個(gè)實(shí)用技巧當(dāng)你需要排查某個(gè)依賴沖突時(shí)可以用 IDEA 的 Maven Helper 插件查看依賴樹找到?jīng)_突點(diǎn)直接 exclude 掉不需要的傳遞依賴。5.3 依賴注入的三種姿勢(shì)Spring Boot 里最常遇到的就是依賴注入。所謂依賴注入就是 Spring 容器把實(shí)例化的對(duì)象自動(dòng)送到需要的地方你不需要自己 new。最常見的三種方式字段注入直接加注解Autowired private UserService userService;構(gòu)造器注入則是把依賴放在構(gòu)造方法參數(shù)里public UserController(UserService userService) { this.userService userService; }Setter 注入通過 setter 方法實(shí)現(xiàn)。我的建議是優(yōu)先使用構(gòu)造器注入。它有幾個(gè)現(xiàn)實(shí)好處第一依賴關(guān)系在創(chuàng)建對(duì)象時(shí)就必須確立避免運(yùn)行時(shí)空指針第二依賴關(guān)系一目了然測(cè)試時(shí)往里傳 mock 對(duì)象很容易第三Spring 官方團(tuán)隊(duì)也更推薦這種方式。6. 實(shí)操環(huán)節(jié)開發(fā)一個(gè)完整的待辦事項(xiàng)管理 API6.1 項(xiàng)目需求說明光跑通 Hello World 還不夠我們做一個(gè)實(shí)際能用的小系統(tǒng)待辦事項(xiàng)管理。功能就三個(gè)查詢所有待辦事項(xiàng)、新增一個(gè)待辦事項(xiàng)、刪除一個(gè)待辦事項(xiàng)。麻雀雖小但覆蓋了 Controller、Service、Repository、Entity 的完整分層結(jié)構(gòu)。我先在 pom.xml 里補(bǔ)上數(shù)據(jù)訪問相關(guān)的依賴dependency groupIdorg.springframework.boot/groupId artifactIdspring-boot-starter-data-jpa/artifactId /dependency dependency groupIdcom.h2database/groupId artifactIdh2/artifactId scoperuntime/scope /dependency6.2 實(shí)體類對(duì)應(yīng)數(shù)據(jù)庫表的結(jié)構(gòu)創(chuàng)建一個(gè) Todo 實(shí)體類Entity Table(name todos) public class Todo { Id GeneratedValue(strategy GenerationType.IDENTITY) private Long id; NotBlank private String title; private boolean completed; // 省略 getter / setter }Entity 標(biāo)記這是一個(gè) JPA 實(shí)體Spring Boot 啟動(dòng)時(shí)會(huì)自動(dòng)在 H2 里建表。Id 表示主鍵GeneratedValue 表示主鍵自增。如果你沒加 Table 指定表名Hibernate 默認(rèn)用類名作為表名但表名大小寫在某些數(shù)據(jù)庫上會(huì)踩坑所以我一律手動(dòng)指定。6.3 數(shù)據(jù)訪問層Spring Data JPA 的魔力接著寫 Repository 接口。這是 Spring Data JPA 最有魔力的地方你只需要聲明一個(gè)接口框架會(huì)在運(yùn)行時(shí)自動(dòng)生成實(shí)現(xiàn)類public interface TodoRepository extends JpaRepositoryTodo, Long { }JpaRepository 已經(jīng)提供了 findAll、findById、save、deleteById 這些內(nèi)置方法你可以在 Service 里直接用。如果你要自定義查詢比如按標(biāo)題模糊搜索只需要聲明方法簽名ListTodo findAllByTitleContaining(String keyword);Spring Data JPA 會(huì)根據(jù)方法名自動(dòng)解析 SQL省掉寫一大堆 XML 映射文件的功夫。6.4 業(yè)務(wù)層與控制器分層到底分在哪里Service 層寫業(yè)務(wù)邏輯。這里放一個(gè)簡(jiǎn)單的列表查詢加新增方法Service public class TodoService { private final TodoRepository todoRepository; public TodoService(TodoRepository todoRepository) { this.todoRepository todoRepository; } public ListTodo getAllTodos() { return todoRepository.findAll(); } public Todo createTodo(Todo todo) { return todoRepository.save(todo); } public void deleteTodo(Long id) { todoRepository.deleteById(id); } }Controller 層負(fù)責(zé)接收請(qǐng)求和返回響應(yīng)。注意這里的返回對(duì)象就是實(shí)體類本身對(duì)于學(xué)習(xí)項(xiàng)目沒問題但在真實(shí)項(xiàng)目中規(guī)范做法是單獨(dú)建 DTO避免直接暴露實(shí)體內(nèi)所有字段。RestController RequestMapping(/api/todos) public class TodoController { private final TodoService todoService; public TodoController(TodoService todoService) { this.todoService todoService; } GetMapping public ListTodo listTodos() { return todoService.getAllTodos(); } PostMapping public Todo createTodo(RequestBody Valid Todo todo) { return todoService.createTodo(todo); } DeleteMapping(/{id}) public ResponseEntityVoid deleteTodo(PathVariable Long id) { todoService.deleteTodo(id); return ResponseEntity.noContent().build(); } }這塊代碼看著不大背后卻發(fā)生了非常多事。RequestBody 將請(qǐng)求體里的 JSON 轉(zhuǎn)成 Todo 對(duì)象PathVariable 從 URL 路徑里取出 idValid 觸發(fā)參數(shù)校驗(yàn)RestController 自動(dòng)把返回值序列化成 JSON。6.5 在 application.properties 里配置 H2為了讓 H2 更好用在 application.properties 里加幾行配置spring.datasource.urljdbc:h2:mem:testdb spring.datasource.driver-class-nameorg.h2.Driver spring.datasource.usernamesa spring.datasource.password spring.jpa.hibernate.ddl-autoupdate spring.h2.console.enabledtruespring.jpa.hibernate.ddl-autoupdate 的意思是每次啟動(dòng)時(shí)如果實(shí)體類和表結(jié)構(gòu)不一致就自動(dòng)更新表結(jié)構(gòu)。學(xué)習(xí)階段非常方便但生產(chǎn)環(huán)境千萬要改成 validate防止 Hibernate 給你亂改表結(jié)構(gòu)。spring.h2.console.enabledtrue 開啟了 H2 的 Web 控制臺(tái)訪問 http://localhost:8080/h2-console 可以直觀查看數(shù)據(jù)JDBC URL 填 jdbc:h2:mem:testdb 就能登錄。6.6 用 IDEA 的 HTTP Client 做接口測(cè)試啟動(dòng)項(xiàng)目后你可以在 IDEA 里直接新建一個(gè) .http 文件測(cè)試接口### 查詢所有待辦事項(xiàng) GET http://localhost:8080/api/todos ### 新增待辦事項(xiàng) POST http://localhost:8080/api/todos Content-Type: application/json { title: 學(xué)完 Spring Boot 基礎(chǔ), completed: false } ### 刪除待辦事項(xiàng) DELETE http://localhost:8080/api/todos/1這個(gè)工具比 Postman 更輕量直接把請(qǐng)求保存成文件還能納入 Git 版本管理。測(cè)試的樂趣在于當(dāng)你 POST 一條數(shù)據(jù)后再 GET 一次發(fā)現(xiàn)數(shù)據(jù)真的存進(jìn)去了那種成就感比看一百個(gè)教學(xué)視頻都強(qiáng)。7. 打包、運(yùn)行與多環(huán)境配置7.1 可執(zhí)行 jar 包的構(gòu)建流程開發(fā)階段一直用 main 方法啟動(dòng)沒問題但真正部署的時(shí)候我們需要把項(xiàng)目打包成一個(gè)可執(zhí)行的 jar 包。在 IDEA 右側(cè)的 Maven 面板里找到 Lifecycle雙擊 packageMaven 就會(huì)先執(zhí)行測(cè)試再打包。如果不希望測(cè)試階段阻塞打包可以執(zhí)行 mvn package -DskipTests。打包完成后target 目錄下會(huì)生成 demo-0.0.1-SNAPSHOT.jar。在命令行進(jìn)入 target 目錄執(zhí)行java -jar demo-0.0.1-SNAPSHOT.jar應(yīng)用就啟動(dòng)起來了效果跟 IDE 里跑 main 方法一模一樣。這個(gè) jar 包非常干凈包含了你引入的所有依賴和默認(rèn)配置你只需要裝有 JDK 17 的運(yùn)行環(huán)境就能跑。7.2 多環(huán)境配置dev、test、prod 的切換方法真實(shí)項(xiàng)目一定會(huì)有多套環(huán)境。開發(fā)環(huán)境用 H2 或本地 MySQL生產(chǎn)環(huán)境用云數(shù)據(jù)庫。Spring Boot 通過 profiles 機(jī)制處理這個(gè)問題。在 resources 目錄里新建 application-dev.properties 和 application-prod.properties然后在 application.properties 里激活spring.profiles.activedev啟動(dòng)時(shí)加上 --spring.profiles.activeprod 則臨時(shí)切換到生產(chǎn)環(huán)境。這就像給同一個(gè)項(xiàng)目準(zhǔn)備了多套鑰匙選哪套開門完全由配置文件決定。7.3 端口配置和上下文路徑默認(rèn)端口是 8080如果被占用在配置里改server.port9090 server.servlet.context-path/api改了 context-path 之后所有接口的訪問路徑都會(huì)加前綴。如果你給前端出接口加一個(gè)統(tǒng)一的 context-path 是常規(guī)做法后續(xù)版本迭代時(shí)便于路徑統(tǒng)一管理。8. 常見問題與排查技巧實(shí)錄8.1 啟動(dòng)失敗端口被占用啟動(dòng)時(shí)看到 Port 8080 is already in use 這行日志說明端口被其他程序占了。解決方法是換端口或者在命令行殺掉占用進(jìn)程。Windows 下用 netstat -ano | findstr 8080 查看占用端口的 PID然后 taskkill /PID /F 殺掉進(jìn)程。8.2 Lombok 注解不生效這個(gè)幾乎每個(gè)人都遇到。代碼里寫了 Data但 getter 和 setter 全部報(bào)錯(cuò)。原因多數(shù)是 IDE 里沒有安裝 Lombok 插件或者沒有開啟 annotation processing。在 IDEA 的 Settings 里搜索 annotation processing勾選 Enable annotation processing問題立刻解決。8.3 更新的 JSON 請(qǐng)求一直解析失敗POST 接口里加了 RequestBody結(jié)果一調(diào)接口就報(bào) HttpMessageNotReadableException。八成是因?yàn)檎?qǐng)求頭缺失 Content-Type: application/json。IDEA 的 HTTP Client 里記得加上請(qǐng)求頭Postman 里要選 Body 的類型為 raw JSON。8.4 Bean 注入失敗找不到類型的處理方式啟動(dòng)時(shí)拋 UnsatisfiedDependencyException后面跟著 No qualifying bean of type。這說明 Spring 容器里找不到你聲明的依賴對(duì)象。排查順序有三步第一確認(rèn)類上是否加了 Service、Repository、Component 這類注解第二確認(rèn)類是否在主類的同級(jí)包或子包下面不在掃描范圍內(nèi)直接注入失敗第三有多個(gè)實(shí)現(xiàn)類的時(shí)候用 Primary 或 Qualifier 指定用哪一個(gè)。8.5 常見問題一句話速查表癥狀常見原因快速解決端口被占用8080被其他程序使用改端口或殺進(jìn)程中文亂碼字符編碼未統(tǒng)一數(shù)據(jù)庫連接加上 characterEncodingutf8依賴下載超時(shí)默認(rèn)源太慢配置阿里云鏡像接口404Controller不在掃描路徑檢查包目錄結(jié)構(gòu)數(shù)據(jù)沒有保存沒加 Transactional事務(wù)注解標(biāo)注到Service層方法對(duì)象屬性為nullJSON字段名不匹配確認(rèn)前端傳來的是約定后的字段名打包后無法運(yùn)行缺少主屬性配置確認(rèn) pom.xml 里打了 spring-boot-maven-plugin9. 后續(xù)可以繼續(xù)深入的方向?qū)懙竭@里你已經(jīng)把 Spring Boot 的完整開發(fā)流程走通了。從環(huán)境搭建到接口開發(fā)從數(shù)據(jù)庫操作再到打包部署這條路雖然不算長(zhǎng)但每一步都走得扎實(shí)。如果你這個(gè)項(xiàng)目全部跑通了我建議你下一步做三件事。第一回去把 Spring 的核心原理補(bǔ)一補(bǔ)尤其是 IoC 容器和 AOP。你有了實(shí)戰(zhàn)體驗(yàn)再回頭學(xué)原理理解深度完全不一樣。第二把 H2 換成 MySQL答案就在配置文件里改幾個(gè)參數(shù)但你會(huì)經(jīng)歷驅(qū)動(dòng)加載、建庫授權(quán)這些真實(shí)項(xiàng)目必須面對(duì)的流程。第三嘗試給這個(gè)待辦事項(xiàng)項(xiàng)目加上 Spring Security實(shí)現(xiàn)一個(gè)最簡(jiǎn)單的登錄鑒權(quán)哪怕只是概念驗(yàn)證也能讓你對(duì) Web 開發(fā)的完整鏈路有更立體的認(rèn)識(shí)。最后分享我在帶新手時(shí)反復(fù)強(qiáng)調(diào)的一句話不要沉迷于看視頻一定要親手把代碼敲出來、把錯(cuò)誤踩一遍、把日志讀一遍。Spring Boot 的設(shè)計(jì)已經(jīng)足夠友好剩下的只是你愿不愿意邁出第一步。