本节目标:用官方初始化器生成一个名为
demo的可构建项目,理解表单每个字段的含义,能读懂生成的pom.xml每一段在做什么,并说清 Spring Boot 4.x 生成物与 3.x 的关键差异。
适用版本:Spring Boot 4.1.x(Java 21)
2.2 用 start.spring.io 生成项目
上一节 2.1 JDK 与 Maven 环境准备
把 JDK 与 Maven 装好了,本节开始造项目。不要手写 pom.xml,也不要从别人博客里抄一个模板——用官方初始化器 start.spring.io 生成,它能保证依赖版本互相兼容、目录结构符合规范。本节从网页表单讲到 curl 命令,再把生成物逐段拆开。
为什么用官方初始化器
手写一个 Spring Boot 项目并不是不可能,但你得同时做对这几件事:parent 版本与各 starter 版本对齐、java.version 属性与 JDK 匹配、spring-boot-maven-plugin 配置正确、目录结构符合 Maven 约定。任何一处写错,你遇到的第一个报错就和「学 Spring Boot」无关了。
官方初始化器把这些问题一次性解决:它由 Spring 团队维护,生成的就是当前版本的「正确形态」。三种用法,效果完全等价:
| 用法 | 场景 | 入口 |
|---|---|---|
| 网页 | 第一次用,想看清每个字段 | start.spring.io |
curl 命令 | 脚本化、无图形界面、可复现 | 命令行拼参数 |
| IDE 向导 | 已在 IDEA/VS Code 里 | New Project → Spring Initializr |
本节不贴 IDE 向导截图,因为截图会随 IDE 版本变化而失效,而字段名和参数是稳定的。你只要记住:IDEA 的 Spring Initializr 向导里的每个输入框,都对应下面表单里的一个字段,也对应 curl 里的一个 -d 参数。
网页表单逐字段说明
打开 start.spring.io,把表单填成下面这样。每一项都解释「填什么」和「为什么」。
| 字段 | 本书取值 | 说明 |
|---|---|---|
| Project | Maven | 构建工具。入门卷统一 Maven;Gradle 见附录 C |
| Language | Java | 本书用 Java;Kotlin 需 2.2+,不在本书范围 |
| Spring Boot | 4.1.1 | 选最新稳定版,不要选 SNAPSHOT 或 M3 之类的里程碑 |
| Group | com.example | 组织标识,会拼进包名 |
| Artifact | demo | 项目标识,决定 jar 名与默认包名 |
| Name | demo | 显示名,默认与 Artifact 相同即可 |
| Description | Demo project for Spring Boot | 项目描述,写进 pom.xml |
| Package name | com.example.demo | 默认由 Group + Artifact 拼出,可改 |
| Packaging | Jar | 内嵌服务器打包成可执行 jar;war 只在部署到外部容器时用 |
| Java | 21 | 与上一节安装的 JDK 对齐 |
两个最容易选错的点:
- Spring Boot 版本:下拉里既有
4.1.1这样的稳定版,也有4.2.0-M2、4.2.0-SNAPSHOT这样的预览版。学习阶段一律选不带后缀的稳定版,预览版会引入你无法对照文档的行为变化。 - Java 版本:必须选 21。如果这里选了 25 而机器上只有 21,构建时会报
invalid target release: 25。
依赖选择:Spring Web 的新名字
表单右下角的 ADD DEPENDENCIES 里,搜索 web,勾选 Spring Web。本节只加这一个,先让项目能跑起来;数据库、校验、Actuator 等留到对应章节再加。
这里有个 4.x 必须知道的变化:你在界面里勾的「Spring Web」,落到 pom.xml 里是 spring-boot-starter-webmvc,而不是老教程里的 spring-boot-starter-web。
Spring Boot 4.0 做了一次模块化重构,把每个技术点的模块名统一成 spring-boot-<technology>,starter 名统一成 spring-boot-starter-<technology>。旧的 spring-boot-starter-web 目前仍能用,但已被标记为废弃。本书正文一律使用新名:
| 你可能见过的旧名 | 4.x 新名 | 用途 |
|---|---|---|
spring-boot-starter-web | spring-boot-starter-webmvc | Spring MVC Web 应用 |
spring-boot-starter-aop | spring-boot-starter-aspectj | AOP 支持 |
spring-boot-starter-web-services | spring-boot-starter-webservices | SOAP Web Services |
如果你正在把老项目迁到 4.x,Spring 官方提供了一个过渡方案 spring-boot-starter-classic,它会把旧名一次性映射到新名,方便你分步迁移。本书不依赖它,直接写新名。
用 curl 命令行生成
没有图形界面、或想让步骤可复现时,用 curl 打 start.spring.io 的 API 直接拿压缩包:
curl https://start.spring.io/starter.tgz \
-d type=maven-project \
-d language=java \
-d bootVersion=4.1.1 \
-d javaVersion=21 \
-d groupId=com.example \
-d artifactId=demo \
-d name=demo \
-d packageName=com.example.demo \
-d packaging=jar \
-d dependencies=web \
-o demo.tgz
逐个参数对照上面的表单:
type=maven-project对应 Project=Maven;bootVersion=4.1.1是框架版本,必须显式写,否则会拿到默认版本;javaVersion=21对应 Java=21;groupId/artifactId/packageName对应表单里的同名字段;dependencies=web里的web是 Spring Web 的依赖 id(不是 starter 名),多个依赖用逗号分隔,如web,validation,actuator。
下载完解压:
mkdir demo && tar -xzf demo.tgz -C demo
cd demo
得到的 demo/ 目录就是本节要用的项目。下一节会逐行拆解它的目录结构,这里先看 pom.xml。
生成的 pom.xml 逐段解读
下面是 4.1.1 生成的 pom.xml(依赖只保留了 Spring Web,去掉了测试依赖的注释噪音):
<?xml version="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>4.1.1</version>
<relativePath/>
</parent>
<groupId>com.example</groupId>
<artifactId>demo</artifactId>
<version>0.0.1-SNAPSHOT</version>
<name>demo</name>
<description>Demo project for Spring Boot</description>
<properties>
<java.version>21</java.version>
</properties>
<dependencies>
<dependency>
<groupId>org.springframework.boot</groupId>
<artifactId>spring-boot-starter-webmvc</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>
<parent> 段。 spring-boot-starter-parent 是整个项目的「版本总控」。它本身几乎不含代码,作用是把两个东西注入你的构建:一是 dependency management,让你写依赖时不用写 <version>——上面两个 starter 都没有版本号,版本由 parent 统一决定,因此不会出现 starter 之间版本打架;二是 plugin management 与一批合理默认值(编译级别、资源过滤、UTF-8 编码等)。<relativePath/> 空标签表示「不从本地上级目录找 parent,直接去仓库下载」,这是初始化器的标准写法。
<properties> 段。 <java.version>21</java.version> 会被 parent 读取,转成编译器的 source / target(现代 JDK 用 --release)。把它改成 17 或 25 就能切换编译目标——前提是你机器的 JDK 支持该版本。
<dependencies> 段。 两个依赖:spring-boot-starter-webmvc 带来 Spring MVC、内嵌 Tomcat、Jackson 等一整套 Web 能力;spring-boot-starter-test 带 JUnit 5、AssertJ、Mockito 等测试库,<scope>test</scope> 表示只在测试期可用,不会打进运行产物。
<build> 段。 只配了 spring-boot-maven-plugin 且没写版本号(由 parent 管理)。它的职责是把项目重新打包成可执行 jar:mvn package 后你得到的不只是普通 jar,还包含了内嵌服务器和 Main-Class 清单,能直接 java -jar 运行。第 3 章会实测这个产物。
Packaging:该选 Jar 还是 War
表单里 Packaging 只有两个选项,选错会直接影响部署方式。
| Packaging | 产物 | 服务器 | 适用场景 |
|---|---|---|---|
| Jar(默认) | 可执行 jar,内嵌 Tomcat | 自带 | 微服务、容器、绝大多数场景 |
| War | war 包,不含内嵌服务器 | 外部容器提供 | 必须部署进既有 Servlet 容器时 |
选 Jar 时,spring-boot-starter-webmvc 会传递引入内嵌 Tomcat,spring-boot-maven-plugin 负责把服务器和你的类打成一个能 java -jar 直接运行的文件。选 War 时,需要额外引入 spring-boot-starter-tomcat-runtime 并让启动类继承 SpringBootServletInitializer,配置更繁琐,而且失去「一个 jar 即一个应用」的简单性。本书所有示例统一用 Jar。
生成后先自检
生成项目后别急着写代码,先确认骨架是好的:
mvn -q compile
-q 只输出警告与错误,没有输出就是成功。想看到完整的启动过程则用:
mvn spring-boot:run
此刻项目还没有任何接口,你会看到 Spring Boot banner 与内嵌 Tomcat 的启动日志(4.1.1 实测启动约 1 秒),按 Ctrl+C 退出即可。这一步通过,说明 JDK、Maven、依赖三者已经串起来了。
常见生成坑
| 现象 | 原因 | 处理 |
|---|---|---|
构建报 invalid target release: 21 | 机器 JDK 低于 21 | 按 2.1 节修 JAVA_HOME |
| 依赖长时间拉不动 | 未配国内镜像 | 配 ~/.m2/settings.xml |
| 拿到的不是稳定版 | bootVersion 填了 4.2.0-M2 之类 | 改回 4.1.1 |
| 包名与预期不符 | packageName 没改,用了默认 | 重新生成或手动调整目录 |
jar 无法 java -jar 运行 | 缺少 spring-boot-maven-plugin | 检查 <build> 段 |
生成目录里没有 mvnw | 表单里取消了 wrapper 选项 | 重新生成,或本机装好 Maven |
3.x 与 4.x 生成物差异对照
把同一份「Spring Web + Java 21」表单分别交给 3.5.x 和 4.1.x,生成物的差异集中在下面几处:
| 维度 | 3.5.x | 4.1.x |
|---|---|---|
parent 版本 | 3.5.16 | 4.1.1 |
| Web starter 名 | spring-boot-starter-web | spring-boot-starter-webmvc |
| Spring Framework | 6.2.x | 7.0.x |
| Servlet 基线 | Servlet 6.0(Jakarta EE 10) | Servlet 6.1(Jakarta EE 11) |
| 内嵌 Tomcat | 10.1 | 11.0 |
| JSON 库 | Jackson 2(com.fasterxml.jackson) | Jackson 3(tools.jackson) |
| 测试替换 Bean | 旧注解已在 4.x 移除 | @MockitoBean |
<java.version> 默认 | 17 | 17(仍建议显式写 21) |
最需要留意的是 starter 名和 Jackson 包名:前者会让照抄老教程的人第一眼就疑惑「我的依赖怎么不一样」,后者会让任何手写 JSON 序列化配置的代码编译不过。这两点本书后续章节都会在对应位置重新强调。
生成物的目录结构在 3.x 与 4.x 之间没有变化,都是标准 Maven 布局——这正是下一节 2.3 目录结构与启动类 要展开的内容。
小结
- 用 start.spring.io 生成项目,网页、
curl、IDE 向导三种方式等价,字段一一对应。 - 表单关键项:Project=Maven、Spring Boot=4.1.1、Packaging=Jar、Java=21;版本一律选稳定版,不要选里程碑或快照。
- 4.x 中「Spring Web」对应
spring-boot-starter-webmvc,旧的spring-boot-starter-web已废弃;旧项目可用spring-boot-starter-classic过渡。 curl .../starter.tgz的-d dependencies=web里写的是依赖 id,不是 starter 名。pom.xml的parent提供版本总控,因此 starter 依赖无需写<version>;spring-boot-maven-plugin负责把项目打成可执行 jar。- 3.x 与 4.x 生成物的主要差异是 parent 版本、starter 名与 Jackson 大版本,目录结构不变。
- Packaging 默认选 Jar,内嵌服务器随应用走;War 只在必须部署进外部容器时才用。
- 生成后用
mvn -q compile做一次自检,无输出即骨架正确。
项目骨架有了,但里面的文件还没读懂。标准目录树长什么样、启动类那几行代码各自在做什么、包扫描为什么对放置位置这么敏感,见下一节 2.3 目录结构与启动类 。
阅读导航:上一节:2.1 JDK 与 Maven 环境准备 · 下一节:2.3 目录结构与启动类 。
继续阅读
探索更多技术文章
浏览归档,发现更多关于系统设计、工具链和工程实践的内容。