Spring Boot 入门实战:60 分钟上手我自己的 REST 接口服务
开篇:为什么我要写这篇教程?
去年刚换工作的那会儿,我接到了一个很典型的后端开发任务:用 Java 搭建一个 RESTful API 服务,提供给前端团队调用。公司是互联网初创公司,时间紧、人手少,项目要的是快速上线、尽早验证业务逻辑。
当时我虽然对 Java 还算熟悉,但真正独立负责完整的后端服务开发还是头一回。为了提高效率,技术栈选了 Spring Boot,毕竟它是目前 Java 后端框架中最主流、生态最完善的解决方案之一。
这篇文章就是基于那个项目经验写的,目的是帮你在一个小时内从零开始搭建一个 Spring Boot 项目,完成基础的接口功能。我会尽量用我当时的“初学者”视角,结合实际遇到的问题和踩过的坑来写,希望对你有帮助。
我们的目标
我们将在 60 分钟内实现一个简易的用户管理接口,包含以下功能:
- 新增用户
- 查询所有用户
- 根据 ID 查询用户
- 更新用户信息
- 删除用户
数据库采用 H2(轻量级内存数据库),方便本地快速测试。之后你可以根据需要替换成 MySQL、PostgreSQL 等生产环境支持更好的数据库。
项目背景 & 遇到的问题

在项目初期,我们原本打算使用传统 SSM 架构(Spring + Spring MVC + MyBatis)来做这个服务。但由于团队里没有资深的 Java 开发者做架构设计,大家都还处于学习阶段,导致前期花了不少时间搭环境、配置 XML、处理各种依赖冲突。
后来我在调研过程中发现了 Spring Boot——它的自动装配机制大大简化了项目的启动和配置流程。于是果断决定转向 Spring Boot 来重构整个项目。
遇到的主要挑战包括:
- 如何快速搭建一个可运行的 Spring Boot 工程?
- 接口怎么设计?Controller 跟 Service 的结构怎么安排?
- 数据库表怎么设计比较合理?
- H2 数据库怎么配置?数据能不能持久化?
- 前后端分离后,跨域问题怎么解决?
- 怎么打包部署到服务器?
这些问题,在下面我都会结合代码一一讲清楚。
第一步:快速创建 Spring Boot 项目

我们可以使用 Spring Initializr 来快速生成初始项目结构。
选择如下配置:
- Project: Maven
- Language: Java
- Spring Boot Version: 最新稳定版(如 3.1.x)
- Dependencies:
- Spring Web(构建 Web 接口)
- Spring Data JPA(ORM 框架,操作数据库)
- H2 Database(嵌入式数据库)
点击 Generate 下载 ZIP 文件后解压即可。
如果你用的是 IDE(比如 IntelliJ IDEA),也可以通过 File -> New Project -> Spring Initializr 直接创建。
下载完成后导入 IDE,你会看到如下结构:
├── src
│ ├── main
│ │ ├── java
│ │ │ └── com.example.demo
│ │ │ ├── DemoApplication.java
│ │ ├── resources
│ │ │ ├── application.properties
第二步:项目结构设计与编码实践

我按照经典的分层结构来组织代码,通常分为以下几层:
controller:接收 HTTP 请求,调用 Service 并返回结果service:业务逻辑处理层repository:数据库访问层model:实体类映射数据库表字段
先定义我们的 User 实体类:
// src/main/java/com/example/demo/model/User.java
package com.example.demo.model;
import jakarta.persistence.*;
@Entity
public class User {
@Id
@GeneratedValue(strategy = GenerationType.IDENTITY)
private Long id;
private String name;
private String email;
// getter/setter 略
}
接着写 Repository 层:
// src/main/java/com/example/demo/repository/UserRepository.java
package com.example.demo.repository;
import com.example.demo.model.User;
import org.springframework.data.jpa.repository.JpaRepository;
import org.springframework.stereotype.Repository;
@Repository
public interface UserRepository extends JpaRepository<User, Long> {
}
Service 层:
// src/main/java/com/example/demo/service/UserService.java
package com.example.demo.service;
import com.example.demo.model.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 List<User> getAllUsers() {
return userRepository.findAll();
}
public Optional<User> getUserById(Long id) {
return userRepository.findById(id);
}
public User createUser(User user) {
return userRepository.save(user);
}
public User updateUser(Long id, User userDetails) {
User user = userRepository.findById(id).orElseThrow();
user.setName(userDetails.getName());
user.setEmail(userDetails.getEmail());
return userRepository.save(user);
}
public void deleteUser(Long id) {
userRepository.deleteById(id);
}
}
最后写 Controller 层:
// src/main/java/com/example/demo/controller/UserController.java
package com.example.demo.controller;
import com.example.demo.model.User;
import com.example.demo.service.UserService;
import org.springframework.beans.factory.annotation.Autowired;
import org.springframework.http.ResponseEntity;
import org.springframework.web.bind.annotation.*;
import java.util.HashMap;
import java.util.List;
import java.util.Map;
import java.util.Optional;
@RestController
@RequestMapping("/api/users")
@CrossOrigin(origins = "http://localhost:3000") // 假设前端跑在 3000 端口
public class UserController {
@Autowired
private UserService userService;
@GetMapping
public List<User> getAllUsers() {
return userService.getAllUsers();
}
@GetMapping("/{id}")
public ResponseEntity<Optional<User>> getUserById(@PathVariable Long id) {
return ResponseEntity.ok(userService.getUserById(id));
}
@PostMapping
public User createUser(@RequestBody User user) {
return userService.createUser(user);
}
@PutMapping("/{id}")
public ResponseEntity<User> updateUser(@PathVariable Long id, @RequestBody User userDetails) {
User updatedUser = userService.updateUser(id, userDetails);
return ResponseEntity.ok(updatedUser);
}
@DeleteMapping("/{id}")
public Map<String, Boolean> deleteUser(@PathVariable Long id) {
userService.deleteUser(id);
Map<String, Boolean> response = new HashMap<>();
response.put("deleted", true);
return response;
}
}
到这里,核心业务逻辑就已经完成了!
第三步:配置 H2 数据库 & 查看界面

在 application.properties 中加入如下配置:
spring.datasource.url=jdbc:h2:mem:testdb
spring.datasource.driverClassName=org.h2.Driver
spring.datasource.username=sa
spring.datasource.password=
spring.h2.console.enabled=true
spring.jpa.hibernate.ddl-auto=update
启动应用后,打开浏览器访问:http://localhost:8080/h2-console/ 输入 JDBC URL、用户名和密码即可查看和操作数据库。
注意:H2 只适用于本地开发和测试环境,真实项目建议使用 MySQL、PostgreSQL 或 Oracle。
第四步:运行 & 测试
在 IDE 中运行 DemoApplication 类的 main 方法,或者执行命令行:
mvn spring-boot:run
启动成功后,可以使用 Postman 或 curl 测试接口:
curl http://localhost:8080/api/users
第一次访问会返回空数组,因为还没有插入数据。可以用 POST 请求添加几个用户试试看。
第五步:常见问题和踩坑经历
1. HTTP 403 / 401 错误?默认安全拦截开启?
Spring Boot 默认引入了 Security Starter,会导致未授权访问直接被拒绝。如果你不想用 Security 功能,可以通过排除依赖或关闭安全配置解决:
spring.security.enabled=false
或者在启动类加上:
@SpringBootApplication(exclude = {SecurityAutoConfiguration.class})
public class DemoApplication {
...
}
2. 跨域请求失败?
如果前后端不同源,默认会被浏览器拦截。除了加 @CrossOrigin 注解外,还可以统一配置 CORS:
@Configuration
@EnableWebMvc
public class CorsConfig implements WebMvcConfigurer {
@Override
public void addCorsMappings(CorsRegistry registry) {
registry.addMapping("/api/**").allowedOrigins("http://localhost:3000");
}
}
3. H2 数据库重启丢失数据?
H2 是内存型数据库,默认不持久化数据。如果你想测试持久化能力,可以把数据库路径改成文件存储:
spring.datasource.url=jdbc:h2:file:~/testdb
4. 实体类字段名和数据库不一致怎么办?
可以在字段上加注解指定列名:
@Column(name = "user_name")
private String name;
上线部署前的关键准备
我们当时把这个小项目打包成了 jar 包部署到一台 CentOS 服务器上:
mvn clean package
java -jar target/demo-0.0.1-SNAPSHOT.jar
为了方便运维,我们在生产环境中做了如下调整:
- 使用 Nginx 做反向代理,处理静态资源和服务转发;
- 将数据库切换为 MySQL,并启用连接池(HikariCP);
- 使用 Spring Profiles 实现多环境配置(dev/test/prod);
- 加了基本的日志输出(Logback);
- 添加了简单的健康检查
/actuator/health(依赖 Actuator 模块);
这些改动其实只需要修改一下配置文件就能搞定。
总结:这套方案带来了哪些收益?
从最初花了两三天才把 SSM 环境搭好,到最后用 Spring Boot 一个小时就实现了完整的基础 CRUD 功能,效率提升非常明显。
这套入门模板非常适合以下几种场景:
- 快速原型开发
- MVP 产品验证
- 教学实验项目
- 初学者练手项目
而且它具备良好的可扩展性,后续很容易接入更多高级功能,比如:
- 安全认证(Spring Security / OAuth2)
- 异常统一处理(@RestControllerAdvice)
- 接口文档(Swagger 或 SpringDoc)
- 日志收集(ELK Stack)
- 消息队列集成(RabbitMQ、Kafka)
给新手的几点建议
- 别一开始就追求高并发、分布式架构,先把单机服务搞明白再说;
- 多用官方 starter 模块,避免重复造轮子;
- 善用 Lombok 减少样板代码,提升编码效率;
- 多练习调试技巧:日志、断点、Postman、数据库查询都要会;
- 关注异常处理机制,不要让程序轻易崩溃;
- 养成良好的代码规范和注释习惯,方便后期维护;
- 持续学习 Spring Cloud 相关生态,为进阶打基础。
结语
说实话,刚开始用 Spring Boot 的时候我也很懵,特别是面对那么多的 Auto Configuration 和 Starter。但是当你亲手搭建第一个完整的项目之后,你会突然发现:“哦,原来它是在帮我们自动化那些繁琐的手工配置!”
现在的我已经能用 Spring Boot 搭建微服务、处理高并发场景,但每次回想起来,还是会感激当初那个坚持敲下第一行代码的自己。
所以如果你也正站在 Spring Boot 的门口犹豫要不要进来,我强烈推荐你跟着本文动手试一遍。相信我,只要肯动手,Java 后端开发也能变得轻松高效!
如果你觉得这篇文章对你有帮助,欢迎点赞、收藏、留言告诉我你在学习 Spring Boot 时遇到的最大困难是什么,我们一起交流进步 🚀

评论 0