理论看得再多,都不如亲手让一个接口跑起来。本小节将带你从零开始创建一个最小的 Spring Boot 应用,包含启动类、一个返回 JSON 的 REST 接口,并演示如何在 IDE 中和命令行下运行与调试。
2.4.1 创建项目
最快捷的方式是使用 Spring 官方提供的 Spring Initializr(https://start.spring.io)。你也可以在 IntelliJ IDEA 中直接新建 Spring Boot 项目,效果完全一致。
在 Initializr 页面上进行如下选择:
- 项目类型:Maven(或 Gradle,本文以 Maven 为例)
- 语言:Java
- Spring Boot 版本:选择当前最新的稳定版(如 3.2.x)
- 项目元数据:
- Group:
com.example - Artifact:
demo - Name:
demo - 包名:
com.example.demo - Java 版本:17 或 21(当前 Spring Boot 3.x 要求 Java 17+)
- 依赖:勾选
Spring Web(内嵌 Tomcat,提供 MVC 能力)
点击“生成”下载压缩包,解压后用 IDE 打开。你看到的项目结构中,最核心的是 pom.xml 和一个自动生成的启动类。
2.4.2 启动类:Spring Boot 的入口
生成的启动类位于 src/main/java/com/example/demo/DemoApplication.java,内容如下:
package com.example.demo;
import org.springframework.boot.SpringApplication;
import org.springframework.boot.autoconfigure.SpringBootApplication;
@SpringBootApplication
public class DemoApplication {
public static void main(String[] args) {
SpringApplication.run(DemoApplication.class, args);
}
}
三个关键点:
@SpringBootApplication:这是一个复合注解,等同于同时声明了三个注解:
@SpringBootConfiguration:标记当前类为配置类(相当于@Configuration)@EnableAutoConfiguration:开启 Spring Boot 的自动配置机制,根据类路径上的依赖、已定义的 Bean 以及各种属性配置,自动完成大量的默认配置(如内嵌 Web 容器、Jackson 序列化等)。@ComponentScan:默认扫描当前类所在包及其子包中的组件(@Component、@Service、@Controller等),自动将它们纳入 Spring 容器管理。
SpringApplication.run():这一行负责启动整个 Spring 应用上下文。它会创建合适的ApplicationContext(对于 Web 应用,默认是AnnotationConfigServletWebServerApplicationContext),触发自动配置,启动内嵌的 Web 服务器(默认 Tomcat),并注册所有 Bean。
main方法:一个标准的 Java 程序入口,让应用可以作为独立的 Java 进程运行,而无需部署到外部应用服务器。这种“打 fat jar 独立运行”的模式是现代微服务部署的标配。
实用建议:保持启动类位于最外层包,以覆盖所有子包。例如你的业务代码统一放在 com.example.demo 下的 controller、service、repository 等子包中,默认的 ComponentScan 就能扫描到它们。如果启动类层级过深,可能导致部分组件未被扫描到,此时可以手动添加 @ComponentScan("com.example") 扩大扫描范围。
2.4.3 编写第一个 REST 接口
在 com.example.demo 包下新建 controller 子包,然后创建 HelloController.java:
package com.example.demo.controller;
import org.springframework.web.bind.annotation.GetMapping;
import org.springframework.web.bind.annotation.RequestParam;
import org.springframework.web.bind.annotation.RestController;
@RestController
public class HelloController {
@GetMapping("/hello")
public String sayHello(@RequestParam(defaultValue = "World") String name) {
return "Hello, " + name + "!";
}
}
这个简单的 Controller 包含几个核心知识点:
@RestController:相当于@Controller+@ResponseBody。它告诉 Spring 该类中所有方法的返回值都将直接序列化为 HTTP 响应体(默认使用 Jackson 转换为 JSON 字符串)。如果你返回的是一个对象,会自动转为 JSON。@GetMapping("/hello"):将 HTTP GET 请求映射到/hello路径。对应的还有@PostMapping、@PutMapping、@DeleteMapping等。@RequestParam:绑定 URL 中的查询参数。defaultValue = "World"表示如果请求没有携带name参数,则使用默认值 "World"。
让我们再增加一个返回对象的接口,以验证 JSON 序列化能力。新建 controller 包下的 UserController.java:
package com.example.demo.controller;
import org.springframework.web.bind.annotation.GetMapping;
import org.springframework.web.bind.annotation.PathVariable;
import org.springframework.web.bind.annotation.RestController;
@RestController
public class UserController {
@GetMapping("/users/{id}")
public User getUser(@PathVariable Long id) {
// 模拟从数据库查询用户
return new User(id, "用户" + id, "user" + id + "@example.com");
}
// 内部静态类或定义独立的 Model 类
static class User {
private Long id;
private String name;
private String email;
public User(Long id, String name, String email) {
this.id = id;
this.name = name;
this.email = email;
}
// getter 和 setter 是 JSON 序列化所必需的
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; }
}
}
@PathVariable:将 URL 路径中的{id}部分绑定到方法参数上。- 返回的
User对象会被 Jackson 自动序列化为 JSON,响应头Content-Type自动设为application/json。
2.4.4 运行应用
1. 在 IDE 中运行
直接右键 DemoApplication 类,选择“Run 'DemoApplication'”或者点击 main 方法旁边的绿色三角形。控制台会打印出 Spring 的 ASCII Art 启动标志,以及内嵌 Tomcat 的启动信息,最后显示类似以下日志:
Tomcat started on port(s): 8080 (http)
Started DemoApplication in 1.5 seconds
2. 命令行运行
- 确保已安装 Maven 并配置好环境变量。
- 在项目根目录(包含
pom.xml的目录)执行打包命令:
mvn clean package
这会生成 target/demo-0.0.1-SNAPSHOT.jar(名称可能因项目 metadata 不同而异)。
- 直接运行 jar 包:
java -jar target/demo-0.0.1-SNAPSHOT.jar
这种方式完全脱离 IDE,适合部署到测试或生产环境。生成的 fat jar 内嵌了所有依赖和 Web 容器,真正实现了一次打包,到处运行。
3. 修改端口
默认端口是 8080。如果端口冲突,可以在 src/main/resources/application.properties 中添加:
server.port=9090
重启应用,即可在 9090 端口访问。
运行成功后,打开浏览器或使用 curl 测试:
curl http://localhost:8080/hello
# 输出: Hello, World!
curl http://localhost:8080/hello?name=Spring
# 输出: Hello, Spring!
curl http://localhost:8080/users/1
# 输出: {"id":1,"name":"用户1","email":"user1@example.com"}
2.4.5 开发阶段的调试技巧
1. 热部署 DevTools
在开发中频繁重启服务器非常浪费时间。Spring Boot 提供了开发者工具 spring-boot-devtools,以热部署的方式提升效率:
在 pom.xml 中添加依赖:
<dependency>
<groupId>org.springframework.boot</groupId>
<artifactId>spring-boot-devtools</artifactId>
<optional>true</optional>
</dependency>
启动应用后,当你修改了类路径下的文件(如 Java 类、模板、配置文件)并保存,DevTools 会监听文件变化并自动重启应用上下文(通常比手动重启快很多)。如果仅修改静态资源或视图模板,甚至会触发无重启的自动刷新(LiveReload)。
注意:DevTools 的自动重启仅适用于开发环境,打包部署时会被自动禁用。
2. 查看自动配置报告
有时你想知道 Spring Boot 到底帮你配置了哪些类,以及为什么某个配置没有生效。可以在启动时开启调试模式:
- 方法一:在
main方法处右键 “Debug” 运行,以调试模式启动。 - 方法二:在
application.properties中添加debug=true,控制台会打印详细的自动配置报告,列出所有已生效和未生效的配置类及其原因。
这在排查“为什么我的 DataSource 没自动创建?”之类的问题时非常有用。
3. IDEA 内置的 HTTP Client
IntelliJ IDEA 自带一个简易 HTTP 客户端,可以直接在项目中创建 .http 文件,编写并发送请求,无需外部工具:
### 测试 hello 接口
GET http://localhost:8080/hello?name=Spring
### 测试用户接口
GET http://localhost:8080/users/1
点击请求左侧的绿色箭头即可执行,响应会直接显示在下方,非常适合接口调试和端到端测试。
4. 使用 Actuator 监控应用
在 pom.xml 中引入 spring-boot-starter-actuator,即可获得一系列生产级端点:
<dependency>
<groupId>org.springframework.boot</groupId>
<artifactId>spring-boot-starter-actuator</artifactId>
</dependency>
启动后访问 /actuator/health 查看健康状态,访问 /actuator/beans 查看容器中所有的 Bean 列表,访问 /actuator/env 查看环境属性,等等。在 application.properties 中可以细粒度控制这些端点的公开范围:
management.endpoints.web.exposure.include=health,info,beans,env
Actuator 本质上也是以 REST 接口(或 JMX)的形式暴露,既是调试利器,也是构建微服务可观测性的基础。
2.4.6 本节小结
通过启动类、两个简单的 REST 接口以及运行调试手段,你已经亲手构建了一个能够响应 HTTP 请求的 Spring Boot 应用。这一切的实现,依赖于自动配置、起步依赖、内嵌容器等 Spring Boot 的核心理念。下一步,我们将深入项目结构,探索分层架构的最佳实践,以及如何将应用组织得更清晰、更易于维护。