ARTICLE · INTELLIGENCE

战地情报 · 详情页

来自尧图项目组的一线实战观察与深度解析

Spring Boot项目创建全攻略:从Maven配置到首个接口实战

Spring Boot项目创建全攻略:从Maven配置到首个接口实战

很多朋友找我帮看 Spring 项目,十个里有八个都卡在“项目创建”这一步。你以为 IDEA 里 New Project 点两下就结束了?真正的问题是从依赖下载失败、版本不兼容、启动找不到主类这些地方开始的。所以我一直觉得,创建 Spring 项目这件事,值得单独写一篇操作向的文章,把背后的逻辑和那些没人明说的坑一起讲清楚。文章不会只教你怎么点按钮,而是把每一步为什么这么做、出现问题去哪里排查,一次性说透。

这篇内容适合刚开始学 Spring Boot 的同学,也适合已经用过 IDEA 但每次创建项目都要折腾半天的朋友。我尽量用大白话讲,复杂的地方就配上比喻,保证你能照着做出来一个能跑、能改、能加接口的 Spring Web 项目。

1. 先想明白:创建 Spring 项目到底是在创建什么

很多人一上来就点 File -> New -> Project,其实没想明白一件事:Spring 项目不是“空文件夹 + 手写代码”,它是一整套骨架。骨架里包含依赖管理、启动逻辑、配置文件、测试目录、资源目录,这些东西如果全靠自己从零搭建,没有半天时间根本搞不定。

1.1 骨架先行:为什么 Spring 项目不能从空目录开始

你可以把创建一个 Spring 项目理解成买房之后的基础装修。空目录就像清水房,你说我要住,但水电、墙面、地板全没有。Spring 官方和 IDEA 做的事,就是给你一套已经布好水电的样板间:Maven 或 Gradle 作为“施工队”,pom.xml是“材料清单”,Spring Boot 的启动类相当于“总开关”。

这套骨架好在哪?它把约定固定下来了。比如src/main/java放代码、src/main/resources放配置、src/test/java放测试,这是 Maven 的标准目录结构。Spring Boot 又在这个基础上自动装配了内嵌 Web 容器,你写一个带@RestController的类,改一行配置,项目就能对外提供接口。如果这些全靠手动搭,配置文件写错一个标签,依赖缺一个版本,排查起来非常痛苦。

1.2 工具链选型:JDK、IDEA 和构建工具之间的版本关系

创建项目前,第一个要面对的是 JDK 版本。很多人直接下载最新版 JDK,然后创建 Spring Boot 项目就报错,因为 Spring Boot 3.x 要求 JDK 17 及以上,如果你的项目指定的是 JDK 8,启动时各种UnsupportedClassVersionError就来了。

我的建议很直接:新项目一律用 Spring Boot 3.x 配上 JDK 17 或 JDK 21。JDK 8 的项目就继续用 Spring Boot 2.7.x,不要为了追新强行升版本。IDEA 这边,能用新版本就用新版本,因为它的 Spring Initializr 内置模板会跟随 Spring 版本更新,旧版 IDEA 生成的模板在依赖版本上经常踩坑。

构建工具我推荐 Maven。Gradle 构建速度快、脚本灵活,但国内公司用 Maven 的比例更高,资料也更多,新手遇到问题搜答案容易得多。Maven 只要配置好一次,后续创建项目基本不会卡。

2. 两条创建路线:手动搭建 Maven 项目和 Spring Initializr 快速生成

创建 Spring 项目一共有两条主流路线,各有自己的适用场景。我不是让你二选一,而是建议两条都走一遍,尤其是手动方式,走一次你对项目结构的理解会清楚很多。

2.1 手动创建 Maven 项目再引依赖:初学者的必修课

手动创建的路径是:IDEA 里新建一个普通 Maven 项目,不要选任何骨架模板,直接创建空项目。创建后在pom.xml里手动引入 Spring Boot 的父工程和 Web 启动器。

关键代码是这样的:

<parent> <groupId>org.springframework.boot</groupId> <artifactId>spring-boot-starter-parent</artifactId> <version>3.2.5</version> <relativePath/> </parent> <dependencies> <dependency> <groupId>org.springframework.boot</groupId> <artifactId>spring-boot-starter-web</artifactId> </dependency> </dependencies>

引入之后,还要自己新建启动类,写@SpringBootApplication注解。这种方式最大的价值,是让你亲眼看到依赖是从哪进来的、启动类是怎么被识别的、src/main/resources下的配置文件是什么角色。踩一遍手动创建,后面再遇到任何奇怪问题,你脑子里会有一个完整的结构图,不会两眼一抹黑。

2.2 Spring Initializr 快速生成:效率优先的选择

第二种方式就是 IDEA 自带的 Spring Initializr。它的本质是给你提供一个在线问卷:项目类型、语言、Spring Boot 版本、依赖列表,填完了它把项目和依赖“打包”好给你下载到本地。IDEA 里新建项目时选择 Spring Initializr,填完信息点 Finish,它就自动完成了依赖导入和目录生成,基本不需要你动 pom.xml。

这种方式快、稳、不容易手滑。但你要注意,它生成的是“标准答案”,不会帮你考虑内部网络环境下的依赖下载速度,也不会管你的 JDK 版本是否兼容。所以用 Initializr 创建成功后,第一件事仍然是把整个项目结构看一遍,尤其是 pom.xml 里的版本号,不要直接当成万能模板。

对比项手动 Maven 创建Spring Initializr 创建
创建速度慢,要手工写 pom 和启动类快,向导式生成
结构理解深,每个文件的来源都清楚浅,容易变成“只会下一步”
出错概率高,依赖坐标容易写错低,官方帮你保证兼容
适用场景学习原理、维护老项目新项目起步、日常开发

我个人建议的学习顺序是先手动建一次,再用 Initializr 建一次,两个都跑通了,Spring 项目的创建环节就彻底过关了。

3. 完整实操:在 IDEA 里从零跑通一个 Spring Web 项目

这一节我会按真实操作顺序,从环境准备到项目落地完整走一遍。每一步我都标注了容易出错的位置,你跟着做,大概率能一次通过。

3.1 环境准备:JDK、Maven 基础配置与 IDEA 设置

先说 JDK。IDEA 的 Project Structure 里可以配置项目 SDK,不同项目用不同 JDK。我习惯把多个 JDK 都装在本地,然后在 IDEA 设置里把 Java SDK 的路径全部添加进来,按项目需求切换,非常方便。

Maven 的配置更关键。打开 Maven 的conf/settings.xml,你需要做两件事:第一是配置本地仓库目录,也就是依赖下载后存放的位置;第二是配置镜像仓库。默认的中央仓库在国外,下载 Spring Boot 依赖动不动就卡住,我一般会换成国内公共镜像仓库,这样速度会有质的提升。

IDEA 里也需要设置 Maven 的路径和配置文件,位置在Settings -> Build, Execution, Deployment -> Build Tools -> Maven。这里最容易犯的错是:系统里有多个 Maven,IDEA 默认用自己内嵌的版本,导致命令行装的 Maven 和 IDEA 里用的不是同一个,本地仓库路径对不上,依赖重复下载。我处理这个问题的方法很笨但有效:让 IDEA 和命令行指向同一个 settings.xml。

3.2 创建步骤:通过 IDEA 内置初始化器生成项目

环境配置好之后,开始正式创建。打开 IDEA,选择 File -> New -> Project。左侧选择 Spring Initializr(不同版本 IDEA 显示略有差异,有的叫 Spring Boot)。

在这个界面里,你需要填这几个信息:

  • JDK:选你准备使用的 JDK 版本,Spring Boot 3.x 就选 17 或 21
  • 语言:Java
  • Group 和 Artifact:Group 一般填公司或个人域名倒序,比如com.example;Artifact 填项目名,比如demo-api
  • 项目名称和包名:IDEA 会自动生成
  • 依赖选择:先勾选 Spring Web,再勾选 Spring Boot DevTools。数据库相关的后面再加

点 Finish 之后,IDEA 会开始下载依赖。第一次会特别慢,不是因为网络,而是因为要把 Spring Boot 相关的几十个依赖全部拉到本地仓库。如果你之前配置了镜像,这里几分钟就能完成。

3.3 看懂生成的项目结构:不要急着写代码

项目创建完,先别急着写代码,花五分钟把目录结构看一遍。核心文件就四个:

第一个是pom.xml,这里是整个项目的“材料清单”。第二个是启动类,名字通常是项目名 + Application,带有@SpringBootApplication注解,这是整个程序的入口。第三个是application.properties,Spring Boot 的全局配置文件,端口、数据库连接、日志全在这里改。第四个是src/test目录,下面有 IDEA 自动生成的测试类,用@SpringBootTest注解启动整个上下文。

很多人遇到“启动后访问不到页面”这种问题,就是没分清楚:src/main/resources下的static文件夹放静态页面,templates文件夹放模板引擎页面,Controller 返回的字符串不会自动跳转到页面。这个结构认知差,能省下你后面好几个小时的排查时间。

4. 动手写第一个接口:让项目真正跑起来

项目创建完成后,你需要立刻证明一件事:它真的能运行。最快的验证方式不是跑测试,而是写一个最简单的接口,然后启动、访问、拿到结果。这一节我带你走完这个闭环。

4.1 写一个带 REST 接口的 Controller

在启动类同级的目录下,新建一个包,比如controller,在这个包下新建一个类,名字随便,但要有意义。我通常叫它HelloController。把下面的代码粘进去:

package com.example.demo.controller; import org.springframework.web.bind.annotation.GetMapping; import org.springframework.web.bind.annotation.RestController; @RestController public class HelloController { @GetMapping("/hello") public String hello() { return "Hello Spring, it works!"; } }

这里有两个关键注解。@RestController告诉 Spring 这个类是一个“Web 接口提供者”,它内部的方法返回值会被直接写进 HTTP 响应体,而且会自动转成 JSON 或字符串。@GetMapping("/hello")比较直白,它注册了一个路由:当客户端访问http://localhost:8080/hello时,会执行下面的方法。

这里我想提醒一句:写这个接口类是放在启动类的同层包下,还是子包里?都可以,但放在启动类的子包里最安全。Spring Boot 启动时默认扫描启动类所在包及以下的所有组件,如果你的 Controller 放到了其他包路径,扫描不到,接口永远是 404。

4.2 启动、访问与修改端口

写完接口直接运行启动类的main方法。注意看控制台输出,出现 “Tomcat started on port(s): 8080” 这样的日志,就说明启动成功了。这时候打开浏览器访问http://localhost:8080/hello,页面返回Hello Spring, it works!,你就完成了第一个 Spring Web 项目的完整闭环。

如果你本机的 8080 端口已经被别的程序占用,启动会直接报错,常见提示是Port 8080 was already in use。修改端口的方式很简单,在application.properties文件里加一行:

server.port=8081

改完端口重新启动,访问地址也要同步改成 8081。这里我建议你不要把端口改成 80,因为 1024 以下端口在某些系统上需要特殊权限,配合 IDEA 跑起来容易出现莫名其妙的问题。

4.3 再补充两个常用依赖:数据库和接口测试工具

真实项目不可能只有字符串接口。以数据库访问为例,你几乎一定会用到 MySQL,那就在pom.xml的 dependencies 标签里加两段:

<dependency> <groupId>com.mysql</groupId> <artifactId>mysql-connector-j</artifactId> <scope>runtime</scope> </dependency> <dependency> <groupId>org.springframework.boot</groupId> <artifactId>spring-boot-starter-data-jpa</artifactId> </dependency>

每次手动加依赖后,记得点击 IDEA 右上角 Maven 面板里的刷新按钮,或者用快捷键让它重新导入。这是个非常容易踩的坑:pom 改了但没刷新,IDEA 里一直报找不到类的错误。

5. 创建过程中的典型报错与排查技巧

创建 Spring 项目这件事,最耽误时间的从来不是创建本身,而是卡在报错里出不来。我把这几年见过频次最高的问题整理成排除清单,你按顺序对照排查,要比盲目搜索高效得多。

5.1 版本不匹配:JDK、Spring Boot、Maven 三者互相牵连

创建项目时最典型的报错,是 maven 编译时提示source option 7 is no longer supported或者运行时报UnsupportedClassVersionError。这两个错误指向同一个根源:编译和运行使用的 JDK 版本,跟 Spring Boot 要求的不一致。

快速解决方法是先把pom.xml里的 Java 版本属性固定下来,让 Maven 编译时使用明确的版本:

<properties> <java.version>17</java.version> </properties>

如果 Spring Boot 用的是 3.x,就把java.version设为 17 或 21。同时检查 IDEA 的Project Structure,把 Project SDK 和 Language Level 都改成对应的版本。很多人只改了一处,另一处没改,导致 IDEA 编译时用的 JDK 和 Maven 编译时不一致,就会一直报版本错误。

5.2 依赖下载失败:不要把锅全甩给网络

创建完项目,Maven 疯狂报红,多半是依赖没下载成功。这里有一个很多人不知道的关键设置:IDEA 里 Maven 的localRepository如果指向了一个无权写入的目录,下载会一直失败。Windows 上不要放在C:\Program Files这类受保护路径下面,放到用户目录或专门的仓库目录里,能省很多事。

另一个常见原因是镜像配置问题。我目前的设置方式是在settings.xml里配置 mirror,让所有中央仓库的请求都走国内公共镜像。这个配置要特别注意一个细节:有些镜像不支持部分仓库类型,你要确认镜像的*匹配不会误伤 Spring 的里程碑仓库。如果项目用的是里程碑版本,建议在 pom 里显式声明对应的 repository。

5.3 端口占用和编码问题:小问题有时最耗时间

端口占用前面提过,这里给个更快速的排查办法。Windows 上可以在终端执行:

netstat -ano | findstr 8080

Mac 和 Linux 上用:

lsof -i :8080

找到占用进程的 PID 之后,再用taskkill /PID或者kill -9把它结束。但注意,如果你本机同时在跑 Docker 容器,里面也有进程占用 8080,直接杀掉宿主机的进程也没用,要先去停对应的容器,否则重启还是失败。

编码问题主要体现为控制台中文乱码或接口返回中文乱码。新建项目时 IDEA 默认文件编码有时不是 UTF-8。我一般设置三处:Settings 里 File Encodings 把全局和项目编码都改为 UTF-8,application.properties文件里也可以显式设置:

server.servlet.encoding.charset=UTF-8 server.servlet.encoding.enabled=true

还有一个容易忽视的地方是 Maven 的编码配置,最好在pom.xml的 properties 里加上<project.build.sourceEncoding>UTF-8</project.build.sourceEncoding>,不然 Windows 平台编译中文资源文件时,可能出现资源加载乱码或是编译告警。

5.4 IDEA 内部缓存和索引导致的“玄学”问题

创建项目这段期间,IDEA 有时会表现得“精神失常”:代码完全没问题,但 IDE 里一直报红;启动类右键没有 Run 按钮;依赖已经存在于本地仓库,却提示找不到。这类问题大概率是 IDEA 缓存或索引损坏了。

我遇到这种情况,先File -> Invalidate Caches,勾上Clear file system cache and Local History,然后重启 IDE。如果还不行,就执行 Maven 面板里的Reload All Projects。90% 的“玄学”问题都能用这两个操作解决。

5.5 常见问题排查速查表

我把上面这些问题的核心信息整理成一个表格,你以后遇到问题直接查表,比翻聊天记录高效。

问题表现主要原因快速解决办法
启动报UnsupportedClassVersionErrorJDK 版本低于 Spring Boot 要求升级 JDK,或将 Spring Boot 版本降到与 JDK 兼容
依赖一直下载中或报红中央仓库太慢配置国内公共镜像,刷新 Maven 项目
端口被占用其他进程或容器占用端口用 netstat / lsof 排查,停止占用进程
访问接口返回 404Controller 不在启动类子包下把 Controller 移到启动类所在包或其子包
中文乱码编码不统一统一设置 UTF-8 编码
IDEA 一直报红但 Maven 正常缓存损坏Invalidate Caches 后重启

6. 创建项目时最值得下功夫的三个习惯

项目能跑起来之后,大多数人就停了。但我不想让你停在这里,因为创建项目只是起点,养成好的项目结构和操作习惯,后面写代码才会顺畅。

6.1 从一开始就规划好包结构

Spring Initializr 生成的默认包只有一层,实际项目里你要自己规划分层。我常用的分层方式是:

  • controller:接收请求,做参数校验
  • service:处理业务逻辑,事务边界放这里
  • mapper或repository:数据库访问
  • entity:数据库表对应的实体类
  • dto:接口入参和出参的对象
  • config:配置类
  • common:公共工具、统一返回体、异常处理

有人觉得项目小,不分层更快。但我的经验是,从一开始按这个结构放文件,后面加功能不会乱。控制器只负责接消息,业务逻辑放 service,SQL 相关的放 mapper,各司其职,找人改 bug 也快很多。

6.2 写好 application.properties 的基本配置

创建项目后,application.properties是空的。我一般第一件事就把基础配置写进去:

spring.application.name=demo-api server.port=8080 spring.output.ansi.enabled=ALWAYS

spring.application.name看着不起眼,但后面接注册中心、日志聚合的时候会用到,提前写上省得以后改。日志配置也建议早期就弄好,至少把日志级别调成 INFO,并且按天分割,不然排查线上问题的时候,没有日志真的是寸步难行。

6.3 善用 Maven 命令行配合 IDEA

IDEA 的图形界面是很方便,但有些场景下命令行更直接。我常用的命令是:

mvn clean package -DskipTests

它会把项目清理并重新打包,跳过测试,适合验证项目能不能完整构建。另一个是:

mvn dependency:tree

这条命令可以让你看到完整的依赖树,排查依赖冲突时非常好用。IDEA 里也有对应的 Maven 面板可视化展示,但命令行输出的信息更精确,建议你会用,不依赖图形界面也能干活。

还有一个小经验:创建完项目第一次启动前,先在命令行执行一次mvn compile。这一步如果成功,说明依赖、编码、插件这些基础环节都没问题,可以放心回到 IDEA 里启动。很多 IDEA 启动失败的问题,实际是 Maven 层面的问题,命令行会给出更多细节。

最后,说点创建项目之外的题外话

我见过太多人把“创建项目”和“写代码”割裂开,觉得框架搭好了,剩下就是闷头写代码。实际上,项目创建这一步的质量,直接影响后面几十天甚至几个月的开发体验。依赖版本乱、结构散、编码不统一,这些问题在项目初期不处理,后面就是天天救火。

根据我自己的折腾经验,创建 Spring 项目最快的路径不是背步骤,而是先理解三个东西:JDK 和 Spring Boot 版本的兼容关系、Maven 的依赖解析机制、Spring Boot 的自动装配入口。这三个底层逻辑通了,不管你是用 IDEA 还是命令行,不管你是创建 Web 项目还是微服务项目,都能很快上手。

这篇文章里的实验项目,我是用一个最普通的 Spring Web Demo 来演示的。你可以拿着这个 Demo,尝试把数据库依赖加进去,再加两个实体类和增删改查接口,整个过程其实就是对这篇文章内容的延伸练习。创建项目只是敲门,敲门之后的每一次改动,都是在帮你建立起对 Spring 框架更完整的认知。

RELATED READING

延伸阅读

更多一线实战笔记与深度复盘,助您持续精进