摘要: 本文是Spring Boot入门实战指南,从零开始手把手教你创建第一个Spring Boot应用。文章详细介绍了Spring Boot的核心概念、自动配置机制、起步依赖原理,并通过Hello World和用户管理API两个完整示例,展示如何快速构建RESTful Web服务。同时涵盖项目结构解析、运行测试方法、JDK 21虚拟线程支持等实用内容,帮助Java开发者快速掌握现代Spring Boot开发流程。
关键词: Spring Boot, Java Web开发, REST API, 自动配置, 起步依赖
在上一篇文章中,我们学习了 JDBC,你知道了如何用 Java 程序连接数据库、执行 SQL、处理结果集。你已经掌握了持久层的基本技能。
但是,你有没有发现:JDBC 的代码写起来有点"笨重"?每次都要手动获取连接、创建 PreparedStatement、处理 ResultSet、还要小心翼翼地关闭资源......这些代码和你的业务逻辑混在一起,让代码变得臃肿且难以维护。
而且,如果你要写一个真正的 Web 应用,光有 JDBC 是远远不够的。你还需要:
- 一个 Web 服务器来处理 HTTP 请求和响应
- 一个路由机制把不同的 URL 映射到不同的处理方法
- 一个依赖注入容器来管理对象之间的依赖关系
- 一套数据绑定机制把 HTTP 参数自动转换成 Java 对象
- ......
如果这些都让你从头自己写,那工作量太大了。好消息是,Java 生态中有一个框架,几乎帮你做好了以上所有事情------Spring Boot。
今天,我们就来学习 Spring Boot------这个让 Java Web 开发变得前所未有的简单的框架。
1. 什么是 Spring Boot?------ Spring 的"一键启动"版
在理解 Spring Boot 之前,我们先简单了解一下 Spring 框架。
Spring 是 Java 企业级开发中最流行的框架。它提供了依赖注入(DI) 、面向切面编程(AOP) 、事务管理 、MVC Web 框架等核心功能。可以说,Spring 是 Java 后端开发的"基石"。
但是,传统的 Spring 项目配置相当繁琐。你需要写大量的 XML 配置文件(或者 Java 配置类),手动声明每个 Bean,配置数据源、事务管理器、视图解析器......一个简单的 Web 项目,光配置文件就可能上百行。这被称为"XML 地狱"。
Spring Boot 就是在 Spring 基础上构建的"一键启动"版本。它的核心理念是 "约定大于配置"(Convention over Configuration)------Spring Boot 为你提供了合理的默认配置,你只需要关注业务逻辑,不需要手动配置大部分基础设施。
打个比方:Spring 就像是一套高级的"乐高积木",零件很多、功能强大,但你需要自己看说明书把它们拼起来。Spring Boot 则是把这些零件提前拼好了一个"基础模型",你拿到手就能用,想改什么地方再微调就行了。
Spring Boot 的几个核心特点:
| 特点 | 说明 |
|---|---|
| 自动配置 | 根据你添加的依赖自动配置 Spring 和第三方库 |
| 起步依赖 | 一组预定义的依赖集合,一次引入就能获得某个功能的所有依赖 |
| 内嵌服务器 | 内置 Tomcat、Jetty 等 Web 服务器,无需部署 WAR 文件 |
| 生产就绪 | 提供健康检查、指标监控、外部化配置等生产级功能 |
| 零代码生成 | 不需要生成代码,也不需要 XML 配置 |
2. 准备工作:环境与工具
在开始写第一个 Spring Boot 应用之前,确保你的开发环境已经就绪。
- JDK :Spring Boot 3.x 需要 JDK 17 或更高版本。我们一直使用 JDK 21,完全满足要求。
- 构建工具 :Maven 3.8+ 或 Gradle 7.x。我们之前已经学过 Maven,就用它。
- IDE :IntelliJ IDEA(推荐,内置 Spring Initializr 支持)。
如果你用的是 IDEA 的 Ultimate 版本,新建项目时可以直接选择 Spring Boot。社区版也支持,但需要手动从 start.spring.io 导入。
3. 创建第一个 Spring Boot 项目
我们有三种方式创建 Spring Boot 项目。推荐前两种。
方式一:在 IDEA 中直接创建(最推荐)
- 打开 IntelliJ IDEA,点击 New Project。
- 在左侧选择 Spring Boot (或 Spring Initializr)。
- 填写项目信息:
- Name :项目名称,比如
demo-springboot - Group :比如
com.example - Artifact :比如
demo-springboot - JDK:选择 JDK 21
- Name :项目名称,比如
- 点击 Next ,在依赖列表中选择 Spring Web。
- 点击 Create,IDEA 会自动生成项目并下载所有依赖。
方式二:通过 Spring Initializr 网站生成
- 填写 Group、Artifact、Dependencies(勾选 Spring Web)。
- 点击 Generate 下载 ZIP 包。
- 解压后,在 IDEA 中选择 File → New → Project from Existing Sources 导入。
方式三:手动创建 Maven 项目 + 添加依赖
如果你更习惯手动操作,可以创建一个普通的 Maven 项目,然后在 pom.xml 中添加 Spring Boot 的父依赖和起步依赖。
4. 项目结构 ------ 长什么样?
Spring Boot 项目生成后,你会看到这样的目录结构:
demo-springboot/
├── pom.xml ← Maven 配置文件
├── src/
│ ├── main/
│ │ ├── java/
│ │ │ └── com/example/demo/
│ │ │ └── DemoApplication.java ← 启动类(最重要的文件!)
│ │ └── resources/
│ │ ├── application.properties ← 配置文件(可选)
│ │ └── static/ ← 静态资源(CSS、JS、图片)
│ └── test/
│ └── java/
│ └── com/example/demo/
│ └── DemoApplicationTests.java ← 测试类
其中最核心的是 DemoApplication.java,它是整个应用的"入口"。
5. 编写第一个 REST API ------ Hello World
让我们打开 DemoApplication.java,看看里面的内容:
java
package com.example.demo;
import org.springframework.boot.SpringApplication;
import org.springframework.boot.autoconfigure.SpringBootApplication;
import org.springframework.web.bind.annotation.GetMapping;
import org.springframework.web.bind.annotation.RequestParam;
import org.springframework.web.bind.annotation.RestController;
@SpringBootApplication // ① 标记这是一个 Spring Boot 应用
@RestController // ② 标记这是一个 REST 控制器
public class DemoApplication {
public static void main(String[] args) {
SpringApplication.run(DemoApplication.class, args); // ③ 启动应用!
}
@GetMapping("/hello") // ④ 处理 GET 请求,路径为 /hello
public String hello(@RequestParam(value = "name", defaultValue = "World") String name) {
return String.format("Hello %s!", name); // ⑤ 返回响应
}
}
逐行解读:
- ①
@SpringBootApplication:这是一个组合注解,它包含了@Configuration、@EnableAutoConfiguration和@ComponentScan。简单说,它告诉 Spring Boot:"这是一个 Spring Boot 应用,请自动配置一切"。 - ②
@RestController:标记这个类是一个 REST 风格的 Web 控制器,它的每个方法返回值会直接作为 HTTP 响应体返回(而不是跳转到一个页面)。 - ③
SpringApplication.run(...):启动 Spring Boot 应用。它会启动内嵌的 Tomcat 服务器,扫描所有 Bean,完成自动配置。 - ④
@GetMapping("/hello"):将hello()方法映射到/hello路径的 GET 请求。 - ⑤
@RequestParam:从 HTTP 请求参数中获取name的值。如果没传,默认是"World"。
就这么几行代码,我们就有了一个完整的 Web 服务!没有配置 web.xml,没有配置 Spring 容器,没有部署 WAR 文件------全部"开箱即用"。
6. 运行与测试
在 IDEA 中,点击 DemoApplication 类中的绿色三角形 ▶,或者右键 → Run 'DemoApplication'。
你会看到类似这样的启动日志:
. ____ _ __ _ _
/\\ / ___'_ __ _ _(_)_ __ __ _ \ \ \ \
( ( )\___ | '_ | '_| | '_ \/ _` | \ \ \ \
\\/ ___)| |_)| | | | | || (_| | ) ) ) )
' |____| .__|_| |_|_| |_\__, | / / / /
=========|_|==============|___/=/_/_/_/
:: Spring Boot :: (v3.4.0)
2026-07-01T14:30:45.123Z INFO 12345 --- [main] com.example.demo.DemoApplication
...
Tomcat started on port 8080 (http) with context path '/'
Started DemoApplication in 2.5 seconds
最后一行提示 Tomcat started on port 8080------Spring Boot 内嵌的 Tomcat 服务器已经启动,正在监听 8080 端口。
打开浏览器,访问 http://localhost:8080/hello,你会看到:
Hello World!
再试试 http://localhost:8080/hello?name=张三:
Hello 张三!
恭喜你!你已经用 Spring Boot 成功构建了一个 Web 服务。
7. 自动配置 ------ Spring Boot 的"魔法"是什么?
你可能会好奇:我们明明没有配置 Tomcat,为什么它能启动?我们没有配置 Spring MVC,为什么 @GetMapping 能工作?
这就是 Spring Boot 的自动配置(Auto-configuration) 在起作用。
自动配置的核心思想是 "开箱即用" 。Spring Boot 会根据你项目中的依赖来"猜"你需要什么配置:
- 当 Spring Boot 检测到
spring-web依赖,它会自动配置 Spring MVC 和 内嵌 Tomcat。 - 当它检测到
spring-data-jpa依赖,它会自动配置 数据源 和 JPA。 - 当它检测到
spring-security依赖,它会自动配置 安全过滤器链。
自动配置的背后是 条件注解(Condition Annotations) 。Spring Boot 中大量的 @ConditionalOnClass、@ConditionalOnMissingBean 等注解,会在启动时判断"某个类是否存在"、"某个 Bean 是否已经定义",然后决定是否应用某个自动配置。
你可以在 application.properties 或 application.yml 中覆盖这些默认配置。比如,如果你想修改服务器端口:
properties
# application.properties
server.port=9090
或者用 YAML 格式:
yaml
# application.yml
server:
port: 9090
重启应用,访问 http://localhost:9090/hello 就能看到效果。
8. Spring Boot 的"起步依赖"
在 pom.xml 中,你会看到这样的依赖:
xml
<parent>
<groupId>org.springframework.boot</groupId>
<artifactId>spring-boot-starter-parent</artifactId>
<version>3.4.0</version>
</parent>
<dependencies>
<dependency>
<groupId>org.springframework.boot</groupId>
<artifactId>spring-boot-starter-web</artifactId>
</dependency>
</dependencies>
spring-boot-starter-web 就是一个"起步依赖"(Starter)。它不是一个单一的 JAR,而是一个依赖集合------它包含了:
spring-web和spring-webmvc(Spring MVC 框架)spring-boot-starter-tomcat(内嵌 Tomcat)jackson-databind(JSON 序列化/反序列化)- 以及其他一些辅助库
你只需要引入这一个依赖,所有构建 Web 应用所需的核心库就全部到位了。
Spring Boot 提供了几十个起步依赖,覆盖了绝大多数常见场景:
| Starter | 用途 |
|---|---|
spring-boot-starter-web |
构建 Web 应用(REST API) |
spring-boot-starter-data-jpa |
使用 JPA 访问数据库 |
spring-boot-starter-security |
集成 Spring Security |
spring-boot-starter-test |
测试(JUnit、Mockito 等) |
spring-boot-starter-actuator |
生产监控(健康检查、指标) |
9. 一个更"真实"的 REST API 示例
让我们写一个更贴近实际的项目:一个简单的"用户管理"REST API。
java
package com.example.demo;
import jakarta.annotation.PostConstruct;
import org.springframework.boot.SpringApplication;
import org.springframework.boot.autoconfigure.SpringBootApplication;
import org.springframework.web.bind.annotation.*;
import java.util.ArrayList;
import java.util.List;
import java.util.concurrent.ConcurrentHashMap;
import java.util.concurrent.atomic.AtomicLong;
@SpringBootApplication
@RestController
@RequestMapping("/api/users") // ① 所有方法的路由前缀
public class DemoApplication {
// 模拟数据库:用 Map 存储用户
private final ConcurrentHashMap<Long, User> userStore = new ConcurrentHashMap<>();
private final AtomicLong idGenerator = new AtomicLong(1);
public static void main(String[] args) {
SpringApplication.run(DemoApplication.class, args);
}
/** 应用启动后自动插入默认数据 */
@PostConstruct
public void initDefaultUsers() {
addUser("Alice", "alice@example.com", 28);
addUser("Bob", "bob@example.com", 34);
addUser("Charlie", "charlie@example.com", 22);
System.out.println(">>> 默认用户已加载,当前共 " + userStore.size() + " 条");
}
/** 辅助方法:创建用户并返回 ID */
private long addUser(String name, String email, int age) {
long id = idGenerator.getAndIncrement();
User user = new User();
user.setId(id);
user.setName(name);
user.setEmail(email);
user.setAge(age);
userStore.put(id, user);
return id;
}
// ② GET /api/users ------ 获取所有用户
@GetMapping
public List<User> listUsers() {
return new ArrayList<>(userStore.values());
}
// ③ GET /api/users/{id} ------ 根据 ID 获取用户
@GetMapping("/{id}")
public User getUser(@PathVariable Long id) {
User user = userStore.get(id);
if (user == null) {
throw new RuntimeException("用户不存在: " + id); // 实际项目应使用自定义异常
}
return user;
}
// ④ POST /api/users ------ 创建用户
@PostMapping
public User createUser(@RequestBody User user) {
long id = idGenerator.getAndIncrement();
user.setId(id);
userStore.put(id, user);
return user;
}
// ⑤ PUT /api/users/{id} ------ 更新用户
@PutMapping("/{id}")
public User updateUser(@PathVariable Long id, @RequestBody User user) {
if (!userStore.containsKey(id)) {
throw new RuntimeException("用户不存在: " + id);
}
user.setId(id);
userStore.put(id, user);
return user;
}
// ⑥ DELETE /api/users/{id} ------ 删除用户
@DeleteMapping("/{id}")
public String deleteUser(@PathVariable Long id) {
if (userStore.remove(id) == null) {
throw new RuntimeException("用户不存在: " + id);
}
return "用户 " + id + " 已删除";
}
// ---- 内部数据类 ----
public static class User {
private Long id;
private String name;
private String email;
private Integer age;
// getter / setter(省略,实际用 Lombok 简化)
public Long getId() { return id; }
public void setId(Long id) { this.id = id; }
public String getName() { return name; }
public void setName(String name) { this.name = name; }
public String getEmail() { return email; }
public void setEmail(String email) { this.email = email; }
public Integer getAge() { return age; }
public void setAge(Integer age) { this.age = age; }
}
}
代码中用到的注解:
| 注解 | 作用 |
|---|---|
@RequestMapping("/api/users") |
类级别的路由前缀 |
@GetMapping |
处理 GET 请求 |
@PostMapping |
处理 POST 请求 |
@PutMapping |
处理 PUT 请求 |
@DeleteMapping |
处理 DELETE 请求 |
@PathVariable |
从 URL 路径中提取参数 |
@RequestBody |
把 HTTP 请求体(JSON)自动绑定到 Java 对象 |
你可以用 curl 或 Postman 测试这些接口:
bash
# 创建用户
curl -X POST http://localhost:8080/api/users \
-H "Content-Type: application/json" \
-d '{"name":"张三","email":"zhangsan@example.com","age":25}'
# 获取所有用户
curl http://localhost:8080/api/users
# 获取 ID=1 的用户
curl http://localhost:8080/api/users/1
# 更新用户
curl -X PUT http://localhost:8080/api/users/1 \
-H "Content-Type: application/json" \
-d '{"name":"张三丰","email":"zhangsanfeng@example.com","age":30}'
# 删除用户
curl -X DELETE http://localhost:8080/api/users/1
Spring Boot 自动集成了 Jackson,会自动把 JSON 请求体转换成 Java 对象,也会把 Java 对象自动序列化成 JSON 响应。你完全不需要手动处理 JSON 的序列化和反序列化。
10. 关于 JDK 21 与 Spring Boot
Spring Boot 3.x 对 JDK 21 有完整的支持。在 Spring Boot 3.2+ 中,你还可以开启虚拟线程支持,让 Web 应用处理高并发请求的能力大幅提升。
在 application.yml 中只需一行配置:
yaml
spring:
threads:
virtual:
enabled: true
开启后,Tomcat 处理每个请求的线程池会从"平台线程"切换为"虚拟线程"。在 I/O 密集型的 Web 应用中,这可以显著提升吞吐量。
11. 今天的总结
今天我们迈入了 Spring Boot 的大门:
- Spring Boot 是什么:基于 Spring 框架的"一键启动"版本,核心理念是"约定大于配置"。
- 核心特性:自动配置、起步依赖、内嵌服务器、生产就绪。
- 第一个应用:通过 Spring Initializr 创建项目,一个类 + 几行注解,就完成了一个 Web 服务。
- 自动配置原理:根据 classpath 中的依赖自动配置组件。
- 起步依赖 :
spring-boot-starter-*是一组预定义的依赖集合。 - REST API 开发 :
@RestController、@GetMapping、@PostMapping、@RequestBody、@PathVariable等注解。 - JDK 21 支持:Spring Boot 3.x 完全支持 JDK 21,且可以开启虚拟线程支持。
Spring Boot 让 Java Web 开发从一个"繁琐的配置过程"变成了一件"愉快的事情"。你不再需要花大量时间在配置文件上,而是可以专注于写业务逻辑。
动手试试
-
在 IDEA 中创建一个 Spring Boot 项目,运行
DemoApplication,在浏览器中访问http://localhost:8080/hello,确认服务正常启动。 -
在
application.properties或application.yml中把端口改成9090,重启应用,验证端口变化。 -
在上面的用户管理 API 示例中,添加一个
@GetMapping("/search")方法,接收name参数,返回名字包含该关键词的用户列表。 -
在 IDEA 中,打开
pom.xml,找到spring-boot-starter-web依赖,查看它传递引入了哪些其他的依赖(在 IDEA 的 Maven 面板中查看依赖树)。 -
(挑战)结合上一篇文章的 JDBC 知识,把用户管理 API 的数据存储从内存 Map 改为 MySQL 数据库(提示:在
pom.xml中添加spring-boot-starter-data-jpa和mysql-connector-j,配置数据源,创建一个UserRepository接口)。
下一篇文章,我们将从零到一构建一个完整的个人博客项目,把 Spring Boot、数据库、模板引擎等知识全部串联起来。
我们下一篇见。😃
📌 获取本系列示例代码请访问 GitCode。