Spring Boot 实战入门:从零构建 CRUD Web 应用与 RESTful API
Spring Boot 应该怎么学如果你觉得它概念多、配置杂、上手慢那这篇文章就是为你准备的。我们不谈空泛的理论直接聚焦于“能不能用”和“怎么用”。Spring Boot 的核心价值在于它能让你用最少的配置快速构建出独立运行、生产就绪的 Spring 应用。对于 Java 开发者尤其是刚接触企业级开发或想从传统 Spring MVC 项目转型的同学来说掌握 Spring Boot 意味着开发效率的质变。这篇文章将采用一种直击要害的方式带你快速上手 Spring Boot。我们会重点关注几个实际开发中最关心的问题环境门槛高不高启动一个项目到底需要几步如何集成 MyBatis、MySQL 这些必备组件怎么处理 Web 请求和前后端交互以及最终如何打包部署。整个过程会围绕一个具体的实战项目展开你将看到从零到一构建一个具备基础 CRUD 和 API 接口的 Web 应用的全过程。无论你是想快速完成课程设计、毕业设计还是为面试积累实战经验这篇内容都能提供一条清晰的路径。1. 核心能力速览在深入细节之前我们先快速了解 Spring Boot 能为你做什么以及它的核心特点。能力项说明与价值项目类型用于快速构建独立、生产级的 Spring 应用框架。核心主张“约定大于配置”极大简化了传统 Spring 繁琐的 XML 和 Java 配置。内嵌服务器默认集成 Tomcat、Jetty 或 Undertow应用可打包为可直接运行的 JAR 文件无需单独部署 WAR 到外部服务器。自动配置根据项目依赖如 spring-boot-starter-web, spring-boot-starter-data-jpa自动配置 Spring 应用上下文和第三方库。起步依赖提供一系列spring-boot-starter-*依赖一站式引入某技术栈所需的所有库及其兼容版本。生产就绪特性内置健康检查、指标监控、外部化配置等功能开箱即用。环境门槛仅需 JDK 8 和 Maven/Gradle 构建工具对硬件无特殊要求普通开发机即可运行。启动方式通过main方法直接运行或使用java -jar命令启动打包后的 JAR 文件。适合场景微服务、RESTful API、全栈 Web 应用、批处理作业、集成测试等。特别适合需要快速原型开发和迭代的项目。2. 适用场景与使用边界Spring Boot 并非万能明确其适用边界能帮助你更好地决策。它非常适合以下场景快速原型与验证当你有一个新想法需要快速验证时Spring Boot 能让你在几分钟内搭建起一个可运行的后端服务。微服务架构每个微服务都是独立的、轻量级的 JARSpring Boot 是构建微服务的理想选择。传统企业应用现代化将老旧的、配置复杂的 Spring 项目迁移到 Spring Boot能显著简化部署和运维。学生与初学者对于学习 Java Web 开发的同学Spring Boot 绕开了大量环境配置和整合的坑让你更专注于业务逻辑和核心概念。需要内嵌容器的应用开发需要独立交付、不依赖外部应用服务器的工具或应用。它可能不是最佳选择或需要额外考虑的场景极度轻量级的任务如果只是写一个简单的脚本或工具引入完整的 Spring Boot 框架可能显得臃肿。已有复杂 XML 配置的大型遗留项目直接迁移到 Spring Boot 的改造成本可能很高需要评估。对启动速度有极端要求的应用虽然 Spring Boot 2.x 以后启动速度已大幅优化但与原生编译如 Spring Native或更轻量的框架相比仍有差距。需要深度定制 Servlet 容器虽然可以定制但 Spring Boot 的强项在于“开箱即用”过度定制可能违背其设计初衷。安全与合规边界依赖安全定期检查并升级spring-boot-starter-parent或依赖版本以获取安全补丁。配置安全切勿将数据库密码、API密钥等敏感信息硬编码在代码或application.properties中。应使用环境变量、配置服务器或加密方式管理。API 暴露生产环境务必关闭不必要的 Actuator 端点如/env,/heapdump或为其配置严格的访问控制。3. 环境准备与前置条件开始之前确保你的开发环境已经就绪。这个过程非常简单。Java 开发工具包Spring Boot 3.x 需要JDK 17或更高版本Spring Boot 2.x 需要JDK 8或更高版本。建议使用 JDK 17 或 21 以获得更好的性能和长期支持。在终端输入java -version验证。构建工具Maven或Gradle。本文以 Maven 为例因为它与 Spring Boot 的集成更广泛。在终端输入mvn -v验证。集成开发环境IntelliJ IDEA社区版或旗舰版或Eclipse。IDEA 对 Spring Boot 的支持更为出色能提供强大的代码提示、运行和调试功能。数据库按需准备。例如学习常用MySQL可下载安装 MySQL Community Server或使用 Docker 运行。也可以使用内存数据库如H2进行快速测试无需安装。其他工具Git版本控制、Postman或curlAPI 测试、浏览器。验证环境打开命令行依次执行以下命令确认输出正常。java -version # 应输出类似openjdk version 17.0.10 2024-01-16 mvn -v # 应输出 Apache Maven 版本信息如 3.9.64. 创建第一个 Spring Boot 项目我们将使用 Spring Initializr这是官方推荐的、最快捷的项目生成方式。4.1 通过 IDEA 创建推荐打开 IntelliJ IDEA选择New Project。在左侧选择Spring Initializr。Project SDK选择你安装的 JDK 17 或更高版本。在Spring Initializr服务 URL 处使用默认地址即可。填写项目元数据Group:com.example(通常为公司域名倒写)Artifact:demo(项目名称)Name:demoPackage name:com.example.demoPackaging:Jar(默认)Java Version:17(与你安装的 JDK 版本对应)点击Next进入依赖选择页面。这是关键步骤我们为第一个项目添加Spring Web: 用于构建 Web 应用包含 RESTful API 支持。Spring Boot DevTools: 开发工具支持热加载提升开发效率。Lombok: 通过注解简化 Java Bean 的编写如 getter/setter。可选MySQL Driver: 如果你打算连接 MySQL。可选Spring Data JPA: 用于数据库操作。点击Next选择项目存储位置然后点击Finish。IDEA 会自动下载项目模板并构建完成后你会看到一个标准的 Spring Boot 项目结构。4.2 通过网站创建访问 start.spring.io 在网页上填写与上述类似的项目信息、选择依赖然后点击Generate下载一个 ZIP 压缩包解压后用 IDEA 打开即可。4.3 项目结构解析生成的项目结构如下demo ├── src │ ├── main │ │ ├── java │ │ │ └── com │ │ │ └── example │ │ │ └── demo │ │ │ └── DemoApplication.java // 主启动类 │ │ └── resources │ │ ├── application.properties // 配置文件 │ │ └── static // 静态资源 (HTML, CSS, JS) │ │ └── templates // 模板文件 (Thymeleaf, Freemarker) │ └── test // 测试代码 └── pom.xml // Maven 依赖管理文件核心文件说明DemoApplication.java: 包含main方法的启动类。SpringBootApplication注解是关键。application.properties: 应用配置文件可以配置服务器端口、数据库连接等。pom.xml: 管理项目依赖。Spring Boot 父项目 (spring-boot-starter-parent) 统一管理了大量依赖的版本。5. 编写第一个 RESTful API现在让我们创建一个简单的接口验证项目是否能跑通。创建 Controller在com.example.demo包下新建一个类HelloController.java。package com.example.demo; import org.springframework.web.bind.annotation.GetMapping; import org.springframework.web.bind.annotation.RequestParam; import org.springframework.web.bind.annotation.RestController; RestController // 声明这是一个 REST 控制器返回值直接写入 HTTP 响应体 public class HelloController { GetMapping(/hello) // 处理 GET 请求路径为 /hello public String sayHello(RequestParam(value name, defaultValue World) String name) { return String.format(Hello, %s! This is Spring Boot., name); } }启动应用找到DemoApplication.java右键点击选择Run ‘DemoApplication’。IDEA 会启动内嵌的 Tomcat 服务器。测试接口观察控制台日志看到类似Tomcat started on port(s): 8080的信息后打开浏览器或使用 Postman。访问:http://localhost:8080/hello返回:Hello, World! This is Spring Boot.带参数访问:http://localhost:8080/hello?nameSpring返回:Hello, Spring! This is Spring Boot.恭喜你的第一个 Spring Boot 应用已经成功运行并对外提供了 API 服务。整个过程没有配置任何 XML没有部署 WAR 包仅仅写了几行代码。6. 连接数据库与数据操作一个完整的应用离不开数据持久化。我们以 MySQL 和 Spring Data JPA 为例演示如何集成数据库。6.1 添加依赖与配置修改pom.xml如果你创建项目时未选择 MySQL 和 JPA 依赖需要手动添加。!-- 在 dependencies 节点内添加 -- dependency groupIdorg.springframework.boot/groupId artifactIdspring-boot-starter-data-jpa/artifactId /dependency dependency groupIdcom.mysql/groupId artifactIdmysql-connector-j/artifactId scoperuntime/scope !-- 运行时才需要 -- /dependency配置数据库连接打开src/main/resources/application.properties文件添加配置。# 服务器端口 server.port8080 # 数据库连接配置 spring.datasource.urljdbc:mysql://localhost:3306/springboot_demo?useUnicodetruecharacterEncodingutf8serverTimezoneAsia/Shanghai spring.datasource.usernameroot spring.datasource.passwordyour_password # 替换为你的数据库密码 spring.datasource.driver-class-namecom.mysql.cj.jdbc.Driver # JPA 配置 spring.jpa.database-platformorg.hibernate.dialect.MySQL8Dialect spring.jpa.hibernate.ddl-autoupdate # 启动时根据实体类自动更新表结构仅用于开发 spring.jpa.show-sqltrue # 在控制台显示执行的 SQL 语句方便调试注意请先在 MySQL 中创建名为springboot_demo的数据库。6.2 创建实体类与 Repository创建实体类对应数据库中的表。新建entity包和User.java类。package com.example.demo.entity; import jakarta.persistence.*; import lombok.Data; Data // Lombok 注解自动生成 getter, setter, toString 等方法 Entity // 标明这是一个 JPA 实体类 Table(name user) // 指定对应的表名默认为类名小写 public class User { Id // 主键 GeneratedValue(strategy GenerationType.IDENTITY) // 主键自增 private Long id; Column(nullable false, unique true) // 对应列非空且唯一 private String username; Column(nullable false) private String password; private String email; }创建 Repository 接口用于数据访问。新建repository包和UserRepository.java接口。package com.example.demo.repository; import com.example.demo.entity.User; import org.springframework.data.jpa.repository.JpaRepository; import org.springframework.stereotype.Repository; Repository // 可省略Spring 会自动识别 public interface UserRepository extends JpaRepositoryUser, Long { // 无需实现任何方法JpaRepository 已提供了基础的 CRUD 方法 // 可以根据方法名自动推导查询例如 User findByUsername(String username); }JpaRepositoryUser, Long提供了save(),findById(),findAll(),deleteById()等常用方法。6.3 创建 Service 与 Controller创建 Service 层处理业务逻辑。新建service包和UserService.java。package com.example.demo.service; import com.example.demo.entity.User; import com.example.demo.repository.UserRepository; import org.springframework.beans.factory.annotation.Autowired; import org.springframework.stereotype.Service; import java.util.List; import java.util.Optional; Service public class UserService { Autowired private UserRepository userRepository; public User saveUser(User user) { // 简单的保存逻辑实际项目需增加校验、加密等 return userRepository.save(user); } public ListUser getAllUsers() { return userRepository.findAll(); } public OptionalUser getUserById(Long id) { return userRepository.findById(id); } public void deleteUser(Long id) { userRepository.deleteById(id); } }完善 Controller新建或修改UserController.java来暴露 REST API。package com.example.demo.controller; import com.example.demo.entity.User; import com.example.demo.service.UserService; import org.springframework.beans.factory.annotation.Autowired; import org.springframework.web.bind.annotation.*; import java.util.List; import java.util.Optional; RestController RequestMapping(/api/users) // 所有接口前缀为 /api/users public class UserController { Autowired private UserService userService; PostMapping // POST /api/users public User createUser(RequestBody User user) { return userService.saveUser(user); } GetMapping // GET /api/users public ListUser getAllUsers() { return userService.getAllUsers(); } GetMapping(/{id}) // GET /api/users/1 public OptionalUser getUserById(PathVariable Long id) { return userService.getUserById(id); } DeleteMapping(/{id}) // DELETE /api/users/1 public String deleteUser(PathVariable Long id) { userService.deleteUser(id); return User deleted successfully.; } }6.4 测试数据库操作重启应用由于修改了配置和代码需要重启DemoApplication。观察日志启动时Hibernate 会根据ddl-autoupdate自动在springboot_demo数据库中创建user表。你可以在控制台看到create table user ...的 SQL 语句。使用 Postman 测试 APIPOSThttp://localhost:8080/api/usersBody (raw JSON):{username: testUser, password: 123456, email: testexample.com}应返回创建成功的用户信息包含生成的 id。GEThttp://localhost:8080/api/users应返回包含刚才创建用户的列表。GEThttp://localhost:8080/api/users/1应返回 id 为 1 的用户信息。DELETEhttp://localhost:8080/api/users/1应返回删除成功的消息再次 GET 列表应为空。至此一个具备完整 CRUD 功能的 Spring Boot 后端服务已经搭建完成。7. 集成 Thymeleaf 实现简单页面虽然前后端分离是主流但了解如何渲染页面也有其价值。我们使用 Thymeleaf 模板引擎快速实现一个页面。添加依赖在pom.xml中添加 Thymeleaf 起步依赖。dependency groupIdorg.springframework.boot/groupId artifactIdspring-boot-starter-thymeleaf/artifactId /dependency创建页面控制器新建PageController.java。package com.example.demo.controller; import org.springframework.stereotype.Controller; import org.springframework.ui.Model; import org.springframework.web.bind.annotation.GetMapping; Controller // 注意这里是 Controller不是 RestController public class PageController { GetMapping(/) public String index(Model model) { model.addAttribute(message, Welcome to Spring Boot with Thymeleaf!); model.addAttribute(users, List.of(Alice, Bob, Charlie)); // 模拟数据 return index; // 对应 src/main/resources/templates/index.html } }创建 HTML 模板在src/main/resources/templates/目录下新建index.html。!DOCTYPE html html xmlns:thhttp://www.thymeleaf.org head meta charsetUTF-8 titleSpring Boot Demo/title /head body h1 th:text${message}Default Message/h1 ul li th:eachuser : ${users} th:text${user}User Name/li /ul pCurrent Time: span th:text${#temporals.format(#temporals.createNow(), yyyy-MM-dd HH:mm:ss)}2024-01-01 00:00:00/span/p /body /html访问页面重启应用访问http://localhost:8080/你将看到一个渲染了动态数据的 HTML 页面。8. 配置文件与多环境Spring Boot 支持灵活的配置管理这是生产就绪的重要特性。配置文件优先级Spring Boot 会按以下顺序加载配置后加载的覆盖先加载的。项目根目录/config子目录下的application.properties项目根目录下的application.propertiesclasspath:/config/下的application.propertiesclasspath:/下的application.properties(即resources目录下)多环境配置可以创建application-{profile}.properties文件来区分环境。application-dev.properties: 开发环境配置如连接本地数据库。application-prod.properties: 生产环境配置如连接线上数据库。在application.properties中通过spring.profiles.activedev来激活指定环境的配置。YAML 格式除了.properties还可以使用更清晰的.yml或.yaml格式。# application.yml 示例 server: port: 8080 spring: datasource: url: jdbc:mysql://localhost:3306/demo username: root password: secret jpa: hibernate: ddl-auto: update show-sql: true custom: api: key: my-secret-key # 自定义配置读取自定义配置使用Value注解或ConfigurationProperties。Component public class MyConfig { Value(${custom.api.key}) private String apiKey; // 或者使用类型安全的绑定 ConfigurationProperties(prefix custom.api) Data public static class ApiProperties { private String key; } }9. 打包与部署开发完成后我们需要将应用打包并部署到服务器或容器中。9.1 打包为可执行 JARSpring Boot 的 Maven 插件使得打包极其简单。执行打包命令在项目根目录pom.xml所在目录打开终端执行mvn clean package找到 JAR 包命令执行成功后在target/目录下会生成一个demo-0.0.1-SNAPSHOT.jar文件名称取决于你的pom.xml中的artifactId和version。这个 JAR 包是可执行的因为它内嵌了 Tomcat 服务器和所有依赖。运行 JAR 包java -jar target/demo-0.0.1-SNAPSHOT.jar应用会以与在 IDEA 中相同的方式启动。你可以通过--server.port8081参数来覆盖配置文件中的端口。9.2 使用 Docker 部署可选Docker 能提供一致的环境。首先在项目根目录创建Dockerfile。# 使用官方 Eclipse Temurin 17 JDK 镜像作为基础镜像 FROM eclipse-temurin:17-jre-alpine # 维护者信息 LABEL maintaineryour-emailexample.com # 在容器内创建一个应用目录 WORKDIR /app # 将构建好的 JAR 文件复制到容器内 COPY target/demo-0.0.1-SNAPSHOT.jar app.jar # 暴露应用运行的端口 EXPOSE 8080 # 指定容器启动时执行的命令 ENTRYPOINT [java, -jar, app.jar]然后构建镜像并运行容器# 1. 确保已打包好 JAR 文件 (mvn clean package) # 2. 构建 Docker 镜像 docker build -t springboot-demo . # 3. 运行容器将宿主机的 8080 端口映射到容器的 8080 端口 docker run -d -p 8080:8080 --name demo-app springboot-demo访问http://localhost:8080即可访问容器中运行的应用。10. 常见问题与排查方法在学习和使用 Spring Boot 的过程中你可能会遇到以下常见问题。问题现象可能原因排查方式解决方案启动失败端口被占用默认端口 8080 被其他程序占用。查看日志Port 8080 was already in use.1. 在application.properties中修改server.port。2. 关闭占用端口的进程。无法连接到数据库数据库配置错误、服务未启动、网络不通。查看启动日志中的数据库连接错误信息。1. 检查spring.datasource.url,username,password。2. 确认 MySQL 服务已启动。3. 检查防火墙和网络。JPA 实体类扫描不到主启动类SpringBootApplication所在的包层级不对。实体类或 Repository 不在主类子包下。1. 将实体类、Repository 等放在主类所在包或其子包下。2. 使用EntityScan和EnableJpaRepositories注解手动指定扫描路径。依赖下载失败或冲突Maven 仓库网络问题或依赖版本冲突。查看 IDEA 的 Maven 面板或执行mvn dependency:tree。1. 检查网络更换 Maven 镜像源。2. 使用mvn dependency:tree分析依赖树排除冲突依赖。热部署不生效未正确配置或 IDEA 未开启自动编译。检查是否添加了spring-boot-devtools依赖。1. 确认依赖已添加。2. IDEA 中Settings - Build - Compiler勾选Build project automatically。3.CtrlShiftAlt/选择Registry勾选compiler.automake.allow.when.app.running。打包后运行找不到主类打包插件配置问题或主类路径错误。检查pom.xml中spring-boot-maven-plugin配置。确保pom.xml中使用了正确的打包插件xml build plugins plugin groupIdorg.springframework.boot/groupId artifactIdspring-boot-maven-plugin/artifactId /plugin /plugins /buildAutowired 注入失败被注入的类未被 Spring 管理缺少注解或存在多个同类型 Bean。查看启动日志中的 Bean 创建和依赖注入错误。1. 确保被注入的类上有Component,Service,Repository等注解。2. 使用Qualifier指定 Bean 名称。跨域请求被阻止前端应用如 Vue 运行在localhost:3000访问后端 API 时触发浏览器同源策略。浏览器控制台出现 CORS 错误。在后端配置全局 CORS 规则java Configuration public class WebConfig implements WebMvcConfigurer { Override public void addCorsMappings(CorsRegistry registry) { registry.addMapping(/**) .allowedOrigins(http://localhost:3000) .allowedMethods(*); } }11. 最佳实践与进阶方向掌握了基础之后遵循一些最佳实践能让你的项目更健壮、更易维护。分层架构严格遵守 Controller - Service - Repository 的分层每层职责单一。Controller 只负责参数校验和响应封装Service 处理业务逻辑Repository 负责数据访问。统一响应封装设计一个通用的响应类如ResultT包含状态码、消息和数据让所有 API 返回格式统一。全局异常处理使用ControllerAdvice和ExceptionHandler捕获并处理各类异常返回友好的错误信息而不是暴露堆栈跟踪。参数校验在接收参数的 DTO 类字段上使用NotNull,Size,Email等注解并在 Controller 方法参数前加Valid注解进行自动校验。使用日志框架使用 SLF4J 配合 Logback 或 Log4j2 记录日志合理使用不同级别DEBUG, INFO, WARN, ERROR便于问题排查。配置文件分离将敏感信息密码、密钥从application.properties中移出使用环境变量或配置中心管理。编写单元测试为 Service 层和 Controller 层编写单元测试使用 JUnit 和 Mockito和集成测试保证代码质量。下一步可以探索的进阶主题Spring Security: 为你的应用添加认证和授权功能。Spring Cloud: 如果你开始构建微服务Spring Cloud 提供了服务发现、配置中心、网关等全套解决方案。Redis 缓存: 集成 Redis 提升应用性能。消息队列: 集成 RabbitMQ 或 Kafka 进行异步处理和解耦。定时任务: 使用Scheduled注解执行定时任务。API 文档: 集成 Swagger/OpenAPI 自动生成 API 文档。监控与度量: 使用 Spring Boot Actuator 暴露应用健康指标并集成 Prometheus 和 Grafana。Spring Boot 的学习曲线前期非常平缓能让你快速获得成就感。它的价值在于通过“约定大于配置”的理念将开发者从繁琐的配置中解放出来更专注于业务创新。从创建一个能响应的“Hello World”接口到构建一个包含数据库操作、页面渲染、并最终能打包部署的完整应用整个过程在几个小时内就能走通。关键在于动手实践遇到问题多查阅官方文档和社区。当你熟悉了这套范式开发效率的提升将是实实在在的。