Spring Boot 教程:从入门到实践
欢迎来到 Spring Boot 的世界!如果你是一名 Java 开发者,无论是初学者还是有一定经验,Spring Boot 都将极大地提升你的开发效率和体验。它以“约定大于配置”的理念,简化了 Spring 应用的搭建和开发过程,让你能够更专注于业务逻辑的实现。
本文将带你从零开始,一步步掌握 Spring Boot 的核心概念和常用实践,最终能够独立构建一个简单的 Spring Boot 应用。
第一部分:入门篇 – 踏出第一步
1. 为什么选择 Spring Boot?
在深入学习之前,我们先来了解一下 Spring Boot 带来的主要优势:
- 简化配置: Spring Boot 大量使用了自动配置,根据你项目中引入的依赖,自动配置好常用的 Bean 和功能,极大地减少了繁琐的 XML 或 Java Config 配置。
- 内嵌服务器: 内置 Tomcat, Jetty 或 Undertow 等服务器,可以直接打包成可执行的 JAR 包运行,无需额外安装和配置 Web 服务器。
- 简化依赖管理: 提供了各种 Starter POMs(启动器),只需引入一个 Starter,就能获得相关场景下所有常用的依赖,并解决了版本兼容问题。
- 开箱即用: 提供了很多生产级别的功能,如健康检查、指标监控、外部化配置等,通过 Actuator 组件即可轻松获得。
- 强大的生态: 无缝集成 Spring 生态系统中的其他项目,如 Spring Data, Spring Security, Spring Cloud 等。
- 提高开发效率: 综合以上优点,Spring Boot 能够让开发者更快速地搭建项目、开发功能并进行部署。
总之,Spring Boot 的目标是让你“Just Run”,让开发 Spring 应用变得前所未有的简单。
2. 环境准备
在开始 Spring Boot 开发之前,你需要准备以下环境:
- Java Development Kit (JDK): Spring Boot 2.x/3.x 需要 Java 8 或更高版本。推荐使用 JDK 11 或 JDK 17(LTS 版本)。
- 集成开发环境 (IDE): 推荐使用支持 Spring Boot 的 IDE,例如:
- IntelliJ IDEA (Community 或 Ultimate 版)
- Eclipse with Spring Tool Suite (STS) 插件
- VS Code with relevant Java extensions
- 构建工具: Maven 或 Gradle。本文主要以 Maven 为例。
- 网络连接: 需要下载依赖。
请确保你的环境中已经正确安装并配置了 JDK 和构建工具。
3. 创建你的第一个 Spring Boot 项目
最快、最方便创建 Spring Boot 项目的方式是使用 Spring Initializr。
方法一:使用网页版 Spring Initializr
- 打开网页浏览器,访问 https://start.spring.io/。
- Project: 选择构建工具,例如
Maven Project
。 - Language: 选择
Java
。 - Spring Boot: 选择一个稳定版本,推荐最新的非 SNAPSHOT/M 版本。
- Project Metadata:
Group
: 填写组织/公司域名倒序,例如com.example
。Artifact
: 填写项目名称,例如demo
。Name
: 填写项目友好名称,例如demo
(默认与 Artifact 相同)。Description
: 填写项目描述。Package name
: 填写根包名,例如com.example.demo
(默认根据 Group 和 Artifact 生成)。Packaging
: 选择打包方式,通常选择Jar
(内嵌服务器)。Java
: 选择你安装的 JDK 版本。
- Dependencies: 点击 “Add Dependencies…” 按钮,搜索并添加你需要的依赖。对于第一个 Web 应用,至少需要添加
Spring Web
。如果你想使用 Actuator,可以添加Spring Boot Actuator
。 - 点击 “Generate” 按钮,会下载一个 Zip 压缩包。
- 解压压缩包,使用你选择的 IDE 导入该项目(作为 Maven 或 Gradle 项目)。IDE 会自动下载所需的依赖。
方法二:使用 IDE 内置的 Initializr
大多数现代 Java IDE 都内置了 Spring Initializr 功能,可以在创建新项目时直接选择。例如,在 IntelliJ IDEA 中,选择 “File” -> “New” -> “Project…”,然后在左侧选择 “Spring Initializr”。
无论使用哪种方式,你都会得到一个基本的 Spring Boot 项目骨架。
4. 项目结构解析
导入项目后,你会看到类似以下的目录结构 (以 Maven 为例):
demo
├── .mvn
│ └── wrapper
│ ├── maven-wrapper.jar
│ └── maven-wrapper.properties
├── mvnw
├── mvnw.cmd
├── pom.xml
└── src
├── main
│ ├── java
│ │ └── com
│ │ └── example
│ │ └── demo
│ │ └── DemoApplication.java
│ └── resources
│ ├── application.properties (或 application.yml)
│ ├── static (存放静态资源,如HTML, CSS, JS)
│ └── templates (存放模板文件,如Thymeleaf, FreeMarker)
└── test
└── java
└── com
└── example
└── demo
└── DemoApplicationTests.java
.mvn
,mvnw
,mvnw.cmd
: Maven Wrapper 文件,允许你在没有安装 Maven 的情况下构建项目。pom.xml
: Maven 项目对象模型文件,定义了项目的依赖、构建配置等。这是 Spring Boot 项目的核心配置文件之一。src/main/java
: 存放 Java 源代码。com.example.demo.DemoApplication.java
: Spring Boot 应用的启动类。
src/main/resources
: 存放资源文件。application.properties
(或application.yml
): ** Spring Boot 的全局配置文件**,用于配置各种属性,如服务器端口、数据库连接等。static
: 存放静态资源文件,如 HTML, CSS, JavaScript, 图片等。这些文件可以直接通过浏览器访问。templates
: 存放动态模板文件,如 Thymeleaf, FreeMarker, Velocity 等。通常与 Spring MVC 结合使用来渲染动态页面。
src/test/java
: 存放测试源代码。-
DemoApplication.java
:
“`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); }
}
``
main
这是 Spring Boot 应用的入口。方法调用
SpringApplication.run()来启动整个应用。
@SpringBootApplication是一个复合注解,它包含了
@EnableAutoConfiguration,
@ComponentScan, 和
@Configuration。
@EnableAutoConfiguration
*: **开启 Spring Boot 的自动配置功能**。Spring Boot 会根据你添加的依赖自动配置相应的 Bean。
@ComponentScan
*: **扫描当前包及其子包下的组件**(如
@Component,
@Service,
@Repository,
@Controller等),并将它们注册为 Spring Bean。
@Configuration`: 表明这是一个配置类。
*
5. 运行你的第一个 Spring Boot 应用
你可以通过多种方式运行 Spring Boot 应用:
- 在 IDE 中运行: 找到
DemoApplication
类,右键点击,选择 “Run ‘DemoApplication.main()'” (或类似选项)。 - 使用 Maven 或 Gradle 命令行:
- 打开命令行终端,进入项目根目录。
- 对于 Maven: 运行
./mvnw spring-boot:run
(或mvn spring-boot:run
)。 - 对于 Gradle: 运行
./gradlew bootRun
。
- 打包成 JAR 后运行:
- 在项目根目录运行 Maven 构建命令:
./mvnw clean package
(或mvn clean package
)。这会在target
目录下生成一个可执行的 JAR 文件 (例如demo-0.0.1-SNAPSHOT.jar
)。 - 运行 JAR 文件:
java -jar target/demo-0.0.1-SNAPSHOT.jar
。
- 在项目根目录运行 Maven 构建命令:
无论哪种方式,你都会在控制台看到 Spring Boot 的 Logo 和启动日志。如果日志显示启动成功,说明你的第一个 Spring Boot 应用已经在默认端口 8080 上运行了。
6. 创建一个简单的 Web 接口 (Hello World)
现在,我们来创建一个最简单的 RESTful 接口。
在 com.example.demo
包下创建一个新的 Java 类,例如 HelloController.java
:
“`java
package com.example.demo;
import org.springframework.web.bind.annotation.GetMapping;
import org.springframework.web.bind.annotation.RestController;
@RestController // 结合了 @Controller 和 @ResponseBody
public class HelloController {
@GetMapping("/hello") // 将 HTTP GET 请求映射到 /hello 路径
public String sayHello() {
return "Hello, Spring Boot!";
}
}
“`
@RestController
: 这是一个特殊的 Controller,它的方法返回值会直接作为响应体发送给客户端,而不是作为视图名称。它等同于@Controller
+@ResponseBody
。@GetMapping("/hello")
: 这是一个处理 GET 请求的注解,将/hello
路径的 GET 请求映射到sayHello()
方法。
重新运行你的 Spring Boot 应用。
打开浏览器或使用工具(如 curl, Postman)访问 http://localhost:8080/hello
。
你应该会看到页面上显示 Hello, Spring Boot!
。
恭喜你!你已经成功创建并运行了你的第一个 Spring Boot Web 应用,并实现了一个简单的接口。
第二部分:核心概念与常用功能
掌握了基本的项目创建和运行,接下来我们将深入了解 Spring Boot 的一些核心概念和常用功能。
1. 自动配置 (Auto-configuration)
自动配置是 Spring Boot 最核心的特性之一。它的原理是根据项目中存在的类、配置和依赖,自动推断出用户可能需要的功能,并自动配置相应的 Bean。
例如,如果你引入了 spring-boot-starter-web
依赖,Spring Boot 会自动配置 Tomcat 或 Jetty 等 Web 服务器、Spring MVC 的 DispatcherServlet、Web相关的 Bean 等。如果你引入了 H2 数据库依赖,Spring Boot 会自动配置一个内存数据库的 DataSource。
- 它是如何工作的? 主要是通过
@EnableAutoConfiguration
注解(包含在@SpringBootApplication
中)和大量的*-spring-boot-autoconfigure
模块来实现的。这些模块中包含了很多@Configuration
类,这些配置类使用@ConditionalOnClass
,@ConditionalOnMissingBean
,@ConditionalOnProperty
等条件注解,根据条件来决定是否启用某些配置。 - 查看自动配置报告: Spring Boot Actuator 提供了一个
/actuator/conditions
端点,可以查看所有自动配置类哪些被应用了(Positive Matches),哪些没有被应用(Negative Matches),以及未应用的原因。这对于调试自动配置问题非常有用。
2. Starter Dependencies (启动器依赖)
Starter 是 Spring Boot 提供的一组便利的依赖描述符,可以一站式地获取特定场景下的所有常用库。它们的名字遵循 spring-boot-starter-*
的命名模式。
例如:
spring-boot-starter-web
: 用于构建 Web 应用,包含 Tomcat, Spring MVC 等。spring-boot-starter-data-jpa
: 用于使用 Spring Data JPA 和 Hibernate。spring-boot-starter-security
: 用于 Spring Security 安全认证和授权。spring-boot-starter-test
: 用于单元测试和集成测试,包含 JUnit, Spring Test, Mockito 等。spring-boot-starter-actuator
: 用于添加生产级别的监控和管理功能。
使用 Starter 的好处是简化了 pom.xml
(或 build.gradle
) 文件,避免了手动管理大量依赖及其版本号的麻烦。Spring Boot 的父项目 spring-boot-starter-parent
已经管理了大部分常用库的版本。
在 pom.xml
中引入 Starter 非常简单:
xml
<dependency>
<groupId>org.springframework.boot</groupId>
<artifactId>spring-boot-starter-web</artifactId>
</dependency>
3. 外部化配置 (Externalized Configuration)
Spring Boot 允许你将配置(如端口号、数据库连接信息、自定义属性等)外部化,与代码分离。这样,你可以在不修改代码的情况下,轻松地在不同环境(开发、测试、生产)中运行相同的应用。
主要的外部化配置方式包括:
- 属性文件:
application.properties
(默认) 或application.yml
。 - YAML 文件:
application.yml
是一种更结构化的配置方式,层级清晰,推荐使用。 - 命令行参数: 启动应用时使用
--key=value
格式。 - 环境变量: 使用约定好的命名规则将环境变量映射到配置属性。
- JNDI: 从 JNDI 树中查找属性。
- 随机值: 使用
${random.value}
等表达式生成随机值。
优先级: 这些配置方式有优先级顺序,高优先级的会覆盖低优先级的。命令行参数 > 环境变量 > JAR包外部的 application.properties/yml > JAR包内部的 application.properties/yml 等。
示例: 修改默认端口
在 src/main/resources/application.properties
中添加:
properties
server.port=8081
或在 application.yml
中添加:
yaml
server:
port: 8081
重新运行应用,它就会在 8081 端口启动了。
注入配置属性:
你可以使用 @Value
注解或 @ConfigurationProperties
注解将外部配置的值注入到你的 Bean 中。
-
@Value
: 适用于注入单个属性。
“`java
import org.springframework.beans.factory.annotation.Value;
import org.springframework.stereotype.Component;@Component
public class MyBean {@Value("${my.app.greeting:Hello}") // 注入属性,指定默认值 private String greeting; public void sayGreeting() { System.out.println(greeting); }
}
``
application.properties
你可以在中设置
my.app.greeting=你好` 来覆盖默认值。 -
@ConfigurationProperties
: 适用于将一组相关的属性绑定到一个 POJO 类上,结构更清晰,且支持类型安全和校验。首先,创建一个 POJO 类:
“`java
import org.springframework.boot.context.properties.ConfigurationProperties;
import org.springframework.stereotype.Component;
import java.util.List;@Component
@ConfigurationProperties(prefix = “my.app”) // 绑定前缀为 my.app 的属性
public class MyAppProperties {
private String name;
private String description;
private Listservers; // 支持列表绑定 // Getters and Setters (必须提供!) public String getName() { return name; } public void setName(String name) { this.name = name; } public String getDescription() { return description; } public void setDescription(String description) { this.description = description; } public List<String> getServers() { return servers; } public void setServers(List<String> servers) { this.servers = servers; }
}
“`然后在
application.yml
(YAML 格式更适合层次结构) 中配置:
yaml
my:
app:
name: My Awesome App
description: A demo application
servers:
- server1.example.com
- server2.example.com你可以在其他 Bean 中注入
MyAppProperties
并使用它:
“`java
import org.springframework.beans.factory.annotation.Autowired;
import org.springframework.stereotype.Component;@Component
public class AnotherBean {private final MyAppProperties myAppProperties; @Autowired // 通过构造函数注入更推荐 public AnotherBean(MyAppProperties myAppProperties) { this.myAppProperties = myAppProperties; } public void printConfig() { System.out.println("App Name: " + myAppProperties.getName()); System.out.println("Description: " + myAppProperties.getDescription()); System.out.println("Servers: " + myAppProperties.getServers()); }
}
``
@ConfigurationProperties是 Spring Boot 推荐的属性注入方式,特别是当属性比较多或者需要结构化时。为了让
@ConfigurationProperties生效,你可能需要在你的
@SpringBootApplication类或
@Configuration类上添加
@EnableConfigurationProperties(MyAppProperties.class)注解,或者直接在属性类上添加
@Component` 注解。
4. Profiles (环境配置)
Profiles 允许你为不同的环境(如开发、测试、生产)定义不同的配置。
- 定义 Profile 相关的配置文件: 使用
application-{profile}.properties
或application-{profile}.yml
的命名规则。application-dev.properties
: 开发环境配置application-prod.yml
: 生产环境配置
- 激活 Profile: 有多种方式可以激活特定的 Profile:
- 在
application.properties
或application.yml
中设置spring.profiles.active={profile_name}
。 - 通过命令行参数:
java -jar myapp.jar --spring.profiles.active=prod
。 - 通过环境变量:设置
SPRING_PROFILES_ACTIVE={profile_name}
。 - 在 IDE 中配置运行参数。
- 在
示例:
application.properties
:
“`properties
server.port=8080
默认激活 dev profile
spring.profiles.active=dev
“`
application-dev.properties
:
properties
server.port=9090
my.app.greeting=Hello from Dev!
application-prod.properties
:
properties
server.port=80
my.app.greeting=Hello from Prod!
当你直接运行应用时,由于 spring.profiles.active=dev
,应用会在 9090 端口启动,并输出 “Hello from Dev!”。
当你使用命令 java -jar myapp.jar --spring.profiles.active=prod
运行时,应用会在 80 端口启动,并输出 “Hello from Prod!”。
Profile 机制是实现环境隔离和配置管理的关键。
5. Logging (日志)
Spring Boot 默认使用 Logback 作为日志框架,并集成了 JUL (java.util.logging), Log4j2 和 Logback,通过 Starter 依赖自动配置。
默认情况下,日志会输出到控制台,包含时间戳、日志级别、线程名、Logger 名称和消息。
- 配置日志级别: 在
application.properties
或application.yml
中可以配置不同 Logger 的日志级别。
properties
logging.level.root=INFO
logging.level.com.example.demo=DEBUG # 设置特定包的日志级别
logging.level.org.springframework=WARN # 设置 Spring 框架的日志级别 - 输出到文件: 可以配置将日志输出到文件。
properties
logging.file.name=myapp.log # 将日志输出到指定文件
# logging.file.path=/var/log/myapp # 将日志输出到指定目录下的 spring.log 文件 - 自定义配置: 如果需要更复杂的日志配置(如日志滚动、多种输出目标),可以创建 Logback (logback-spring.xml)、Log4j2 (log4j2-spring.xml) 或 JUL 的配置文件。Spring Boot 会自动加载这些文件(推荐带
-spring
后缀的,因为它们支持 Spring Profile)。
良好的日志记录是应用监控和故障排查的基础。
6. Spring Boot Actuator
Spring Boot Actuator 提供了许多生产级别的功能,让你可以监控和管理你的应用。通过添加 spring-boot-starter-actuator
依赖即可启用。
Actuator 默认提供了一系列端点 (Endpoints),可以通过 HTTP 或 JMX 访问:
/actuator/health
: 应用健康状态。/actuator/info
: 应用自定义信息。/actuator/metrics
: 应用指标,如内存、CPU、线程等。/actuator/env
: 查看 Spring Environment 属性。/actuator/beans
: 查看应用中的所有 Spring Bean。/actuator/conditions
: 查看自动配置的条件评估报告(Positive/Negative Matches)。/actuator/httptrace
: HTTP 请求跟踪。/actuator/threaddump
: 线程 Dump。
配置 Actuator:
默认情况下,为了安全,大部分端点(除了 health
和 info
)不会通过 HTTP 暴露。你需要进行配置来暴露更多端点:
“`properties
management.endpoints.web.exposure.include=health,info,beans,metrics # 暴露指定的端点
management.endpoints.web.exposure.include=* # 暴露所有端点 (生产环境慎用)
management.endpoint.health.show-details=always # 显示健康检查详情 (默认只有授权用户可见或关闭)
“`
默认访问路径是 /actuator
,你也可以通过 management.endpoints.web.base-path=/monitor
等属性修改。
Actuator 是构建可观测系统的重要组成部分。
第三部分:实践篇 – 构建一个简单的 Web 应用
前面我们学习了 Spring Boot 的基本概念和核心功能。现在,我们将这些知识结合起来,构建一个简单的用户管理 Web API。
需求:实现对用户的基本 CRUD (创建、读取、更新、删除) 操作接口。
我们将使用:
* Spring Web (处理 HTTP 请求)
* Spring Data JPA (访问数据库)
* H2 Database (内存数据库,方便演示,实际项目会用 MySQL, PostgreSQL 等)
* Lombok (简化 POJO 类,可选)
1. 添加依赖
首先,修改 pom.xml
,添加必要的依赖:
“`xml
<properties>
<java.version>17</java.version>
</properties>
<dependencies>
<!-- Web Starter -->
<dependency>
<groupId>org.springframework.boot</groupId>
<artifactId>spring-boot-starter-web</artifactId>
</dependency>
<!-- Spring Data JPA Starter -->
<dependency>
<groupId>org.springframework.boot</groupId>
<artifactId>spring-boot-starter-data-jpa</artifactId>
</dependency>
<!-- H2 Database (内存数据库,用于开发和测试) -->
<dependency>
<groupId>com.h2database</groupId>
<artifactId>h2</artifactId>
<scope>runtime</scope>
</dependency>
<!-- Lombok (可选,简化POJO) -->
<dependency>
<groupId>org.projectlombok</groupId>
<artifactId>lombok</artifactId>
<optional>true</optional>
</dependency>
<!-- Test Starter -->
<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>
<configuration>
<excludes>
<exclude>
<groupId>org.projectlombok</groupId>
<artifactId>lombok</artifactId>
</exclude>
</excludes>
</configuration>
</plugin>
</plugins>
</build>
``
spring-boot-maven-plugin
**注意:** 如果使用了 Lombok,并且打包时遇到问题,可能需要在中添加
2. 配置数据源 (H2 Database)
在 src/main/resources/application.properties
或 application.yml
中配置 H2 数据库。H2 内存数据库通常不需要复杂的配置。我们可以配置开启 H2 的 Web 控制台,方便查看数据。
application.properties
:
“`properties
H2 Database Configuration
spring.datasource.url=jdbc:h2:mem:userdb # 内存数据库名称
spring.datasource.driverClassName=org.h2.Driver
spring.datasource.username=sa
spring.datasource.password=password
spring.jpa.database-platform=org.hibernate.dialect.H2Dialect # 告诉JPA使用H2方言
spring.h2.console.enabled=true # 开启H2控制台
spring.h2.console.path=/h2-console # H2控制台访问路径
JPA/Hibernate Configuration
spring.jpa.hibernate.ddl-auto=update # 启动时自动更新数据库表结构 (开发环境推荐,生产环境慎用)
spring.jpa.show-sql=true # 打印执行的SQL语句
“`
application.yml
:
yaml
spring:
datasource:
url: jdbc:h2:mem:userdb
driverClassName: org.h2.Driver
username: sa
password: password
jpa:
database-platform: org.hibernate.dialect.H2Dialect
hibernate:
ddl-auto: update
show-sql: true
h2:
console:
enabled: true
path: /h2-console
spring.jpa.hibernate.ddl-auto=update
会在应用启动时根据你的 JPA 实体类自动创建或更新数据库表结构。这在开发阶段非常方便,但生产环境通常使用 none
,通过 Flyway 或 Liquibase 等工具管理数据库Schema版本。
3. 创建实体类 (Entity)
创建一个表示用户的 JPA 实体类。
“`java
package com.example.userdemo.model;
import jakarta.persistence.*;
import lombok.Data; // 使用 Lombok 的 @Data 注解自动生成 getter, setter, toString, equals, hashCode
@Entity // 标记这是一个JPA实体类
@Table(name = “users”) // 指定数据库表名
@Data // Lombok 注解
public class User {
@Id // 标记为主键
@GeneratedValue(strategy = GenerationType.IDENTITY) // 配置主键生成策略,IDENTITY 表示数据库自增
private Long id;
@Column(nullable = false, unique = true) // 配置字段属性,非空且唯一
private String username;
@Column(nullable = false)
private String email;
// @Data 会自动生成 getter 和 setter
}
``
javax.persistence
**注意:** 在 Spring Boot 3.x+ 中,JPA 相关的注解包从变为
jakarta.persistence`。请根据你的 Spring Boot 版本选择正确的包。
4. 创建数据访问层 (Repository)
使用 Spring Data JPA 创建一个 Repository 接口,它将自动为你实现基本的 CRUD 方法。
“`java
package com.example.userdemo.repository;
import com.example.userdemo.model.User;
import org.springframework.data.jpa.repository.JpaRepository;
import org.springframework.stereotype.Repository;
@Repository // 标记这是一个Repository组件
// 继承 JpaRepository,指定实体类型和主键类型
public interface UserRepository extends JpaRepository
// Spring Data JPA 允许你通过方法名定义查询,例如:
User findByUsername(String username);
// 你也可以定义更复杂的查询...
}
``
JpaRepository` 接口以及你定义的方法名生成实现类。
Spring Data JPA 会在运行时自动根据
5. 创建业务逻辑层 (Service)
创建一个 Service 类来处理业务逻辑,协调 Controller 和 Repository。
“`java
package com.example.userdemo.service;
import com.example.userdemo.model.User;
import com.example.userdemo.repository.UserRepository;
import org.springframework.beans.factory.annotation.Autowired;
import org.springframework.stereotype.Service;
import java.util.List;
import java.util.Optional;
@Service // 标记这是一个Service组件
public class UserService {
private final UserRepository userRepository;
@Autowired // 构造函数注入 UserRepository
public UserService(UserRepository userRepository) {
this.userRepository = userRepository;
}
public List<User> getAllUsers() {
return userRepository.findAll(); // 使用 JpaRepository 提供的方法
}
public Optional<User> getUserById(Long id) {
return userRepository.findById(id); // 使用 JpaRepository 提供的方法
}
public User createUser(User user) {
// 可以添加业务校验,例如检查用户名是否已存在
return userRepository.save(user); // 使用 JpaRepository 提供的方法
}
public User updateUser(Long id, User userDetails) {
Optional<User> userOptional = userRepository.findById(id);
if (userOptional.isPresent()) {
User existingUser = userOptional.get();
existingUser.setUsername(userDetails.getUsername());
existingUser.setEmail(userDetails.getEmail());
// 可以添加更多更新逻辑
return userRepository.save(existingUser); // 保存更新后的用户
}
return null; // 或者抛出异常表示用户不存在
}
public void deleteUser(Long id) {
userRepository.deleteById(id); // 使用 JpaRepository 提供的方法
}
public User getUserByUsername(String username) {
return userRepository.findByUsername(username); // 使用我们在 Repository 中定义的方法
}
}
“`
6. 创建控制器层 (Controller)
创建 REST Controller 来处理 HTTP 请求,调用 Service 层的方法,并返回响应。
“`java
package com.example.userdemo.controller;
import com.example.userdemo.model.User;
import com.example.userdemo.service.UserService;
import org.springframework.beans.factory.annotation.Autowired;
import org.springframework.http.HttpStatus;
import org.springframework.http.ResponseEntity;
import org.springframework.web.bind.annotation.*;
import java.util.List;
@RestController // 标记这是一个REST Controller
@RequestMapping(“/api/users”) // 所有接口的根路径
public class UserController {
private final UserService userService;
@Autowired // 构造函数注入 UserService
public UserController(UserService userService) {
this.userService = userService;
}
@GetMapping // GET /api/users
public List<User> getAllUsers() {
return userService.getAllUsers();
}
@GetMapping("/{id}") // GET /api/users/{id}
public ResponseEntity<User> getUserById(@PathVariable Long id) {
return userService.getUserById(id)
.map(ResponseEntity::ok) // 如果找到用户,返回 200 OK 和用户数据
.orElse(ResponseEntity.notFound().build()); // 如果没找到,返回 404 Not Found
}
@PostMapping // POST /api/users
@ResponseStatus(HttpStatus.CREATED) // 返回 201 Created 状态码
public User createUser(@RequestBody User user) { // 从请求体中解析User对象
return userService.createUser(user);
}
@PutMapping("/{id}") // PUT /api/users/{id}
public ResponseEntity<User> updateUser(@PathVariable Long id, @RequestBody User userDetails) {
User updatedUser = userService.updateUser(id, userDetails);
if (updatedUser != null) {
return ResponseEntity.ok(updatedUser); // 更新成功,返回 200 OK 和更新后的数据
}
return ResponseEntity.notFound().build(); // 用户不存在,返回 404 Not Found
}
@DeleteMapping("/{id}") // DELETE /api/users/{id}
public ResponseEntity<Void> deleteUser(@PathVariable Long id) {
userService.deleteUser(id);
// 返回 204 No Content 表示删除成功但没有响应体
return ResponseEntity.noContent().build();
}
// 示例:通过用户名查找用户
@GetMapping("/username/{username}") // GET /api/users/username/{username}
public ResponseEntity<User> getUserByUsername(@PathVariable String username) {
User user = userService.getUserByUsername(username);
if (user != null) {
return ResponseEntity.ok(user);
}
return ResponseEntity.notFound().build();
}
}
“`
7. 运行和测试应用
- 启动应用: 运行
UserDemoApplication
的 main 方法,或使用 Maven 命令./mvnw spring-boot:run
。 - 访问 H2 控制台: 应用启动后,访问
http://localhost:8080/h2-console
(如果修改了端口,用对应的端口)。输入你在application.properties
中配置的 JDBC URL (jdbc:h2:mem:userdb
)、用户名 (sa
) 和密码 (password
),点击 Connect。你应该能看到USERS
表。 - 测试 API: 使用 Postman, curl 或其他 REST 客户端测试你的接口:
POST http://localhost:8080/api/users
带 JSON 请求体{ "username": "john_doe", "email": "[email protected]" }
GET http://localhost:8080/api/users
GET http://localhost:8080/api/users/1
(假设 POST 返回的 id 是 1)PUT http://localhost:8080/api/users/1
带更新的 JSON 请求体{ "username": "john_doe_updated", "email": "[email protected]" }
GET http://localhost:8080/api/users/username/john_doe_updated
DELETE http://localhost:8080/api/users/1
通过以上步骤,你就完成了一个基于 Spring Boot 的简单用户管理 Web API 的开发。
第四部分:进阶之路
掌握了基础和实践,你可以继续深入学习 Spring Boot 的更多高级特性和相关技术:
- 参数校验: 使用 Spring Validation (
@Valid
,@Validated
) 对请求体或请求参数进行校验。 - 全局异常处理: 使用
@ControllerAdvice
和@ExceptionHandler
实现统一的异常处理。 - Spring Security: 集成 Spring Security 实现用户认证和授权。
- 缓存: 集成 Spring Cache,配合 Redis 或 Ehcache 等缓存提供者提升性能。
- 消息队列: 集成 RabbitMQ, Kafka 等消息队列。
- 异步编程: 使用
@Async
实现异步方法调用。 - 调度任务: 使用
@Scheduled
实现定时任务。 - 单元测试与集成测试: 学习如何使用
@SpringBootTest
和 MockMvc 等进行测试。 - 部署: 学习如何将 Spring Boot 应用打包成 JAR 或 WAR,并部署到不同的环境(如传统的 Tomcat 容器、Docker 容器、云平台等)。
- 微服务: 了解 Spring Cloud 生态系统,用于构建分布式微服务架构。
- 响应式编程: 学习 Spring WebFlux 构建响应式 Web 应用。
Spring Boot 的生态系统非常庞大且活跃,总有新的知识和技术等待你去探索。
总结
通过本文的学习,你已经:
- 了解了 Spring Boot 的优势以及为什么它成为 Java 后端开发的流行框架。
- 掌握了使用 Spring Initializr 快速创建 Spring Boot 项目的方法。
- 熟悉了 Spring Boot 项目的基本结构和启动过程。
- 理解了自动配置、Starter 依赖、外部化配置和 Profiles 等核心概念。
- 学会了配置和使用日志以及 Actuator 监控。
- 通过构建一个简单的用户管理 API,实践了 Spring Boot Web, Spring Data JPA 和内存数据库的集成。
从入门到实践是一个持续学习的过程。Spring Boot 极大地降低了 Spring 开发的门槛,但要成为一名优秀的 Spring Boot 开发者,还需要不断地学习和实践更复杂的场景和高级特性。
希望这篇教程能为你开启愉快的 Spring Boot 学习之旅!现在,就开始你的实践吧!