60分钟,我用Spring Boot搭了个能跑的后端
上周五晚上十一点半,我正戴着耳机听着Lo-fi beats敲代码,突然产品经理在钉钉上@我:“新需求,下周三上线,后端接口明天给一版?” 我差点把咖啡喷在键盘上。作为一个创业公司的全栈开发(说白了就是“啥都干”),我已经习惯了这种节奏——前端改个UI、后端加个接口、运维查个日志、甚至偶尔还要帮测试写个自动化脚本。但这次真有点急。
不过还好,这次我决定用 Spring Boot 快速搭个原型。毕竟最近正在刷 LeetCode 准备跳槽,顺手复习下 Java 生态也挺好。更重要的是,我一直觉得:代码不仅要能跑,还得让人看得懂、改得动。今天这篇技术分享,就带你用不到一小时的时间,从零搞一个能跑、可扩展、带点 Fine-tuning 的 Spring Boot 应用。
起手式:别再手写 Maven 了!
首先,打开 start.spring.io(或者直接在 IDEA 里新建 Spring Initializr 项目)。我选了这些依赖:
- Spring Web(必须的)
- Spring Data JPA(懒人 ORM,比 MyBatis 上手快)
- H2 Database(内存数据库,开发阶段不用装 MySQL)
- Spring Boot DevTools(热部署,救命神器)
项目结构生成后,pom.xml 自动配好依赖,连版本都不用操心——这就是 Spring Boot 的魅力:约定优于配置。以前手写 XML 配置的日子,真的回不去了。
<!-- 别问我为啥不写具体版本号,Spring Boot parent 已经帮你管好了 -->
<parent>
<groupId>org.springframework.boot</groupId>
<artifactId>spring-boot-starter-parent</artifactId>
<version>3.2.0</version>
</parent>
写个实体类,顺便聊聊数据库设计
假设我们要做一个简单的用户管理 API。先定义 User 实体:
@Entity
@Table(name = "users")
public class User {
@Id
@GeneratedValue(strategy = GenerationType.IDENTITY)
private Long id;
@Column(nullable = false, unique = true)
private String email;
@Column(nullable = false)
private String name;
// getter/setter 省略(Lombok 大法好!)
}
这里有几个小细节:
- 用了
@Table(name = "users")明确表名,避免 Hibernate 自动生成复数形式踩坑。 email加了unique = true,防止重复注册——这种约束一定要在数据库层做,别只靠业务代码判断。- 主键用自增 ID,虽然分布式系统里可能不够用,但对 MVP(最小可行产品)完全够了。
Repository + Service + Controller,经典三层走起
Spring Data JPA 让 DAO 层几乎不用写代码:
public interface UserRepository extends JpaRepository<User, Long> {
Optional<User> findByEmail(String email);
}
Service 层简单封装逻辑(虽然现在只有 CRUD):
@Service
@Transactional
public class UserService {
@Autowired
private UserRepository userRepository;
public User createUser(User user) {
if (userRepository.findByEmail(user.getEmail()).isPresent()) {
throw new IllegalArgumentException("Email already exists");
}
return userRepository.save(user);
}
}
Controller 层暴露 REST 接口:
@RestController
@RequestMapping("/api/users")
public class UserController {
@Autowired
private UserService userService;
@PostMapping
public ResponseEntity<User> createUser(@RequestBody User user) {
try {
User saved = userService.createUser(user);
return ResponseEntity.status(HttpStatus.CREATED).body(saved);
} catch (IllegalArgumentException e) {
return ResponseEntity.badRequest().build();
}
}
}
看到没?异常处理很粗糙,但 MVP 阶段先跑起来再说。等后面有时间再统一用 @ControllerAdvice 做全局异常处理。
配置文件:别只用 application.properties
默认的 application.properties 没问题,但我习惯拆成多环境配置:
src/main/resources/
├── application.yml
├── application-dev.yml
└── application-prod.yml
application.yml 放通用配置:
spring:
profiles:
active: dev
application-dev.yml 开发环境:
spring:
datasource:
url: jdbc:h2:mem:testdb
driver-class-name: org.h2.Driver
jpa:
show-sql: true
hibernate:
ddl-auto: create-drop
而生产环境(application-prod.yml)会用真正的 MySQL,并关闭 show-sql,设置 ddl-auto: validate —— 线上绝对不能自动改表结构!
Fine-tuning:不只是调参,更是工程思维
很多人以为 Fine-tuning 就是改几个 JVM 参数,其实不止。在 Spring Boot 里,Fine-tuning 体现在:
- 连接池配置(HikariCP 默认集成)
- 线程池大小
- 日志级别
- 健康检查端点
比如,我在 application-prod.yml 里加了这些:
spring:
datasource:
hikari:
maximum-pool-size: 20
connection-timeout: 30000
management:
endpoints:
web:
exposure:
include: health,info,metrics
这样运维就能通过 /actuator/health 查服务状态,监控系统也能采集指标。别等到线上挂了才想起要可观测性。
踩过的坑:那些让我想砸电脑的瞬间
JPA LazyInitializationException
在 Controller 里直接返回 Entity,结果 Jackson 序列化时访问了未加载的关联字段。解决方案:要么用 DTO,要么加@JsonIgnore,或者开启spring.jpa.open-in-view=true(但后者有性能隐患,慎用)。H2 和 MySQL 语法差异
H2 支持AUTO_INCREMENT,但写法和 MySQL 不完全一样。后来我干脆本地也用 Docker 起个 MySQL 容器,保持环境一致。DevTools 热部署失效
原来是因为我改了pom.xml或静态资源,它只监听 classpath 下的 class 文件变化。后来学会用Ctrl+F9(Build Project)手动触发。
性能与可维护性:我的执念
作为被线上事故教育过的人,我特别在意两点:
- 接口幂等性:创建用户的 POST 接口其实应该用 PUT + 唯一 ID,或者加防重 Token。但现在 MVP 阶段先忍着。
- 日志上下文:每个请求加 traceId,方便排查。可以用
MDC+ Logback 实现,不过 Spring Cloud Sleuth 更省事(但引入了额外依赖)。
另外,代码格式统一很重要。我们团队强制用 Spotless 插件,每次 commit 自动格式化,避免 PR 里吵“空格还是 tab”。
最后跑起来,验证一下
启动应用,用 curl 测试:
curl -X POST http://localhost:8080/api/users \
-H "Content-Type: application/json" \
-d '{"name":"张三","email":"zhangsan@example.com"}'
返回 201 Created,搞定!
再访问 http://localhost:8080/h2-console(记得在配置里开启 spring.h2.console.enabled=true),还能直接查数据库——开发体验拉满。
写在最后
60 分钟,从零到一个可运行的 Spring Boot 应用,其实并不难。难点在于如何让它在生产环境中稳如老狗。Fine-tuning 不是一次性的工作,而是随着业务增长不断迭代的过程。
我现在每天边刷题边优化这个小项目,想着跳槽时能拿它当作品集。虽然创业公司节奏快、需求乱,但正是这种“什么都要自己搞”的环境,逼我学会了快速搭建可靠系统的能力。
如果你也在准备面试,或者刚接手一个后端项目,不妨试试 Spring Boot。它可能不是最炫酷的框架,但绝对是最能让你在 deadline 前睡个好觉的那个。
对了,刚才产品经理又发消息了:“那个接口,能不能加个导出 Excel 功能?” …… 我默默打开了 Apache POI 的文档。
附:常用配置速查表
| 配置项 | 开发环境 | 生产环境 |
|---|---|---|
ddl-auto |
create-drop |
validate |
show-sql |
true |
false |
| 数据库 | H2 / 本地 MySQL | 远程 MySQL + 连接池 |
| 日志级别 | DEBUG |
INFO |
| Actuator 端点 | 全开 | 只开 health, metrics |
技术分享不易,如果对你有帮助,欢迎点赞、转发。下次聊聊怎么用 Spring Boot + Redis 做缓存穿透防护——那可是我去年双11熬夜修的 Bug。

评论 0