Spring Boot快速上手实战:从零到跑通一个后端服务
上周五晚上十点半,办公室只剩我和运维小哥还在对线上问题。那会儿我刚改完一个基础架构的配置中心推送逻辑,正准备收工,突然收到产品经理的钉钉:“兄弟,能不能帮忙搭个简单的管理后台?就几个接口,明天上线用。” 我看了一眼时间——离双11大促还有两周,我们组自己的中间件压测都还没跑完,结果还要帮业务方搭 CRUD 服务?
但转念一想:正好最近在刷 LeetCode 准备跳槽,顺手练练 Spring Boot 也好。毕竟在字节待了五年,虽然一直在搞自研 RPC 框架和注册中心,但对外招人面试时发现,很多候选人连 Spring Boot 的自动装配原理都说不清。于是我就决定:花一个小时,写个最简但能跑通生产级配置的服务,顺便记录下来,给那些和我一样“被迫营业”的后端兄弟们参考。
为什么是 Spring Boot?
别误会,我在字节内部主要用的是自研框架(基于 Netty + 自定义协议),性能高、监控全、链路追踪无缝集成。但对外输出或者临时支援业务时,Spring Boot 真的是“银弹”——生态成熟、文档齐全、社区活跃,连测试同学都能看懂 application.yml 里改个端口。
更重要的是,资源复用成本低。你随便拉一个 Java 后端,90% 都会 Spring Boot。不像我们内部框架,新来实习生光看 SPI 扩展机制就得懵三天。
所以,哪怕你是基础架构组的“高冷底层佬”,也得会 Spring Boot。不然哪天老板说“这个需求很简单,你搭个 demo 先跑起来”,你就只能硬着头皮上了。
环境准备:Java 别用太老的版本
先确认你的本地环境:
java -version
建议 Java 17 起步。我知道很多老项目还在用 Java 8,但在字节,新服务基本都 Java 17+ 了。Spring Boot 3.x 甚至要求最低 Java 17,如果你还卡在 Java 8,有些新特性比如虚拟线程(Project Loom)就玩不起来。
Maven 或 Gradle 随便选,我个人偏好 Maven(公司模板统一),但如果你喜欢 Kotlin 或更灵活的构建脚本,Gradle 也不错。
第一步:生成项目骨架
打开 https://start.spring.io,这是 Spring 官方的初始化器,比手动建模块快多了。
我这次选的配置如下:
- Project: Maven
- Language: Java
- Spring Boot: 3.2.5(最新稳定版)
- Group: com.example
- Artifact: quick-start-demo
- Dependencies:
- Spring Web
- Spring Data JPA
- H2 Database(开发用内存数据库,省事)
- Validation
- Lombok
💡 小技巧:别一上来就加 MyBatis、Redis、Kafka。先跑通最简流程,再按需引入。很多新人一建项目就堆 10 个 starter,结果连
@RestController返回 JSON 都配错。
点“Generate”下载 ZIP,解压后导入 IDEA。
第二步:写一个能跑的接口
新建一个 Controller:
@RestController
@RequestMapping("/api/v1")
public class DemoController {
@GetMapping("/hello")
public String hello() {
return "Hello, Spring Boot!";
}
}
启动类保持默认:
@SpringBootApplication
public class QuickStartDemoApplication {
public static void main(String[] args) {
SpringApplication.run(QuickStartDemoApplication.class, args);
}
}
运行 main 方法,看到控制台输出:
Tomcat started on port(s): 8080 (http)
浏览器访问 http://localhost:8080/api/v1/hello,返回 Hello, Spring Boot! —— 搞定!不到 5 分钟。
但别高兴太早,这离“能上线”还差十万八千里。
第三步:加个数据库,别只玩字符串
产品经理要的是管理后台,肯定有数据存储。我们用 JPA + H2 快速演示。
先定义一个实体:
@Entity
@Table(name = "users")
@Data
@NoArgsConstructor
@AllArgsConstructor
public class User {
@Id
@GeneratedValue(strategy = GenerationType.IDENTITY)
private Long id;
@NotBlank
private String name;
@Email
private String email;
}
Repository 接口:
public interface UserRepository extends JpaRepository<User, Long> {
}
Controller 补充:
@PostMapping("/users")
public ResponseEntity<User> createUser(@Valid @RequestBody User user) {
User saved = userRepository.save(user);
return ResponseEntity.ok(saved);
}
@GetMapping("/users/{id}")
public ResponseEntity<User> getUser(@PathVariable Long id) {
return userRepository.findById(id)
.map(ResponseEntity::ok)
.orElse(ResponseEntity.notFound().build());
}
配置文件 application.yml:
spring:
datasource:
url: jdbc:h2:mem:testdb
driver-class-name: org.h2.Driver
jpa:
hibernate:
ddl-auto: create-drop
show-sql: true
h2:
console:
enabled: true
现在你可以:
- POST
/api/v1/users创建用户 - GET
/api/v1/users/1获取用户 - 访问
http://localhost:8080/h2-console查看内存数据库(JDBC URL 填jdbc:h2:mem:testdb)
🚨 注意:
ddl-auto: create-drop只用于开发!生产环境必须用 Flyway 或 Liquibase 管理 schema,否则 DBA 会追杀你。
第四步:配置分离与生产就绪
在字节,所有服务都要求配置外置、日志结构化、健康检查完备。Spring Boot 天然支持这些。
1. 多环境配置
创建:
application-dev.yml(开发)application-prod.yml(生产)
主配置 application.yml 中指定:
spring:
profiles:
active: dev
生产配置示例(关键项):
server:
port: 8080
shutdown: graceful # 平滑关闭,避免请求中断
logging:
level:
com.example: INFO
pattern:
console: "%d{HH:mm:ss.SSS} [%thread] %-5level %logger{36} - %msg%n"
file:
name: logs/app.log
management:
endpoints:
web:
exposure:
include: health,info,metrics,prometheus
endpoint:
health:
show-details: always
这样,/actuator/health 就能被 K8s 的 liveness probe 调用,运维同学再也不用半夜 call 你说“服务挂了但进程还在”。
2. 资源路径与静态文件
Spring Boot 默认从 classpath:/static/ 提供静态资源。如果你要嵌入一个简单的前端页面(比如 Swagger UI 或管理面板),直接放进去就行。
但注意:不要把敏感配置或内部工具暴露在公网。我们曾经有个实习生把 Actuator 端点全开,结果被安全扫描扫出一堆 info 泄露,差点背 PIP。
第五步:打包与部署
执行:
./mvnw clean package
生成 target/quick-start-demo-0.0.1-SNAPSHOT.jar。
运行:
java -jar target/*.jar --spring.profiles.active=prod
在字节,我们会把这个 JAR 打包进 Docker 镜像,然后由 ArgoCD 自动部署到 K8s。但如果你只是本地测试或小团队,直接 nohup java -jar ... & 也能凑合。
💡 经验之谈:JAR 包默认包含 Tomcat,所以一个文件就能跑。但如果你追求极致性能(比如 QPS > 1w),可以考虑换成 Undertow 或 Netty,不过对大多数业务场景,Tomcat 足够了。
踩坑记录:那些让我想砸键盘的瞬间
Lombok 不生效
IDEA 没装 Lombok 插件,或者 Maven 没加 annotation processor。解决:装插件 + 在pom.xml加<annotationProcessorPaths>。H2 数据库连接失败
控制台提示Database may be already in use。原因:上次进程没关干净。解决:删掉*.mv.db文件,或改用jdbc:h2:mem:testdb;DB_CLOSE_DELAY=-1。跨域问题
前端调接口报 CORS 错误。别急着加@CrossOrigin,最好在网关层统一处理。临时方案:@Bean public CorsConfigurationSource corsConfigurationSource() { CorsConfiguration config = new CorsConfiguration(); config.setAllowedOrigins(List.of("*")); config.setAllowedMethods(List.of("*")); config.setAllowedHeaders(List.of("*")); UrlBasedCorsConfigurationSource source = new UrlBasedCorsConfigurationSource(); source.registerCorsConfiguration("/**", config); return source; }时区不对
数据库存的时间比本地早 8 小时。在application.yml加:spring: jpa: properties: hibernate.jdbc.time_zone: UTC datasource: url: jdbc:mysql://...?serverTimezone=Asia/Shanghai
性能与资源考量
虽然 Spring Boot 上手快,但它不是“轻量级”。一个空服务启动就要 1~2 秒,内存占用 200MB+。在字节的基础架构组,我们经常对比:
| 框架 | 启动时间 | 内存占用 | 冷启动延迟 | 适用场景 |
|---|---|---|---|---|
| Spring Boot | 1.5s | 250MB | 高 | 中后台、业务服务 |
| Quarkus | 0.3s | 80MB | 极低 | Serverless、边缘计算 |
| 自研 RPC 框架 | 0.8s | 150MB | 中 | 高并发核心链路 |
所以,别无脑上 Spring Boot。如果你要做高频交易系统或 IoT 设备代理,它可能不是最优解。但对于 90% 的企业应用,它的开发效率碾压一切。
最后:别只停留在“能跑”
我见过太多人学 Spring Boot 到“能返回 JSON”就停了。但真正的差距在于:
- 你会不会看
@ConditionalOnClass源码理解自动装配? - 你会不会用 Micrometer 接入 Prometheus 做指标监控?
- 你会不会通过
@Async+ 线程池优化耗时操作? - 你会不会用
@Transactional的传播行为避免脏读?
这些才是面试官想听的,也是你在字节、阿里、腾讯这类公司立足的根本。
结语
这篇文章花了我两个深夜(没错,又是凌晨一点),但值得。因为 Spring Boot 虽然简单,但简单不等于肤浅。掌握它,是你从“CRUD 工程师”迈向“系统设计者”的第一步。
现在,我的管理后台已经上线了,产品经理发了个红包。而我,继续回去刷我的算法题——毕竟,下一份 offer 还在等着我。
如果你觉得有用,欢迎转发给那个还在手写 Servlet 的兄弟。共勉。

评论 0