Spring Boot入门教程:60分钟快速上手(附真实项目踩坑实录)
上周五晚上11点,我瘫在工位上盯着屏幕上疯狂滚动的 java.lang.OutOfMemoryError: GC overhead limit exceeded,一边啃着便利店冷掉的饭团,一边默默把“精通Spring Boot”从简历里删掉。作为去年刚从英国某Top 5高校硕士毕业、带着满脑子分布式系统理论回国找工作的海归,谁能想到入职三个月了还在被一个简单的REST API折磨?
说真的,国内互联网公司的节奏比我在伦敦熬夜赶论文还狠。老板一句“下周上线”,测试同事一句“这个接口压测QPS才80?”,运维大哥一句“你这jar包怎么占了2G内存?”,分分钟让我怀疑自己是不是读了个假硕士。不过吐槽归吐槽,该学的技术还得学——于是就有了这篇《Spring Boot 60分钟快速上手》,纯实战经验总结,没废话,全是血泪教训。
背景:为什么是Spring Boot?
我们团队正在做一个电商促销活动的后端服务,需求很简单:用户下单时调用优惠券服务,判断能否使用优惠券。但问题在于,这个服务要扛住双11级别的流量(老板原话:“至少1万QPS吧,不多”)。之前用纯Servlet写,代码又臭又长,加个新功能得改十处配置,运维部署更是噩梦。
技术老大拍板:“重构!用Spring Boot!”
我内心OS:行吧,反正简历上也得有Spring Boot实战经验不是?
环境准备:别再被Maven搞崩心态
首先,别信网上那些“一行命令创建Spring Boot项目”的鬼话。现实是:
- IDEA版本太旧?直接报错
- Maven镜像源在国外?下载依赖等到天荒地老
- JDK版本不对?
Unsupported major.minor version 55.0直接送你上西天
我的生产环境配置(上海租房党亲测有效):
# JDK 17(公司强制要求,别问为什么)
openjdk version "17.0.8" 2023-07-18
# Maven阿里云镜像(pom.xml里不用改,全局settings.xml加就行)
<mirrors>
<mirror>
<id>aliyunmaven</id>
<mirrorOf>*</mirrorOf>
<name>阿里云公共仓库</name>
<url>https://maven.aliyun.com/repository/public</url>
</mirror>
</mirrors>
然后用Spring Initializr(IDEA内置)勾选这几个核心依赖就够了:
- Spring Web(必选,不然你写个寂寞)
- Spring Data JPA(数据库操作简化神器)
- MySQL Driver(别用H2,线上没人用)
- Lombok(省去getter/setter,代码清爽一半)
项目结构:别一上来就搞微服务
很多教程一上来就给你整什么Nacos、Sentinel、Gateway,醒醒!你只是想跑个Hello World好吗?
我的建议:单体应用先跑通,再考虑拆。我们项目的目录结构长这样:
coupon-service/
├── src/main/java/com/example/coupon
│ ├── controller/ # 接口层
│ ├── service/ # 业务逻辑
│ ├── repository/ # 数据库操作
│ └── CouponApplication.java # 启动类
├── src/main/resources
│ ├── application.yml # 配置文件(别用properties!)
│ └── data.sql # 初始化脚本(开发用)
记住:controller只负责接收参数和返回结果,service写业务逻辑,repository只跟数据库打交道。别把SQL写在controller里,否则测试同事会拿你的工牌当飞镖靶子。
核心代码:一个能扛住压力的真实接口
下面是我写的优惠券校验接口,关键点都加了注释:
@RestController
@RequestMapping("/api/v1/coupons")
@RequiredArgsConstructor // Lombok自动生成构造函数注入
public class CouponController {
private final CouponService couponService;
/**
* 校验优惠券是否可用
* 注意:这里用了DTO做参数校验,别直接用Entity!
*/
@PostMapping("/validate")
public ResponseEntity<CouponValidationResponse> validateCoupon(
@Valid @RequestBody CouponValidationRequest request) {
try {
CouponValidationResponse response = couponService.validate(request);
return ResponseEntity.ok(response);
} catch (CouponExpiredException e) {
// 自定义异常处理,别让500暴露给前端
return ResponseEntity.badRequest()
.body(new CouponValidationResponse(false, "优惠券已过期"));
}
}
}
重点来了:别在service里直接写算法逻辑!比如判断优惠券是否满足满减条件,这种规则应该抽成独立的策略类:
// 满减优惠券校验策略
@Component
public class FullReductionValidator implements CouponValidator {
@Override
public boolean validate(Coupon coupon, Order order) {
// 这里才是真正的算法逻辑
if (order.getAmount().compareTo(coupon.getMinSpend()) < 0) {
return false; // 订单金额不足
}
// ...其他校验逻辑
return true;
}
}
为什么这么干?因为产品经理明天可能就说:“我们要支持叠加优惠券!” 如果逻辑散落在service各处,改起来就是一场灾难。
配置优化:别让默认配置害死你
Spring Boot的默认配置在开发环境很爽,但在生产环境就是定时炸弹。以下是我们线上必须改的几项:
| 配置项 | 开发环境 | 生产环境 | 说明 |
|---|---|---|---|
server.tomcat.max-threads |
200 | 500 | 默认200线程扛不住高并发 |
spring.datasource.hikari.maximum-pool-size |
10 | 50 | 连接池太小会阻塞 |
management.endpoints.web.exposure.include |
* | health,info | 别把所有监控端点暴露出去 |
logging.level.com.example |
DEBUG | WARN | 别让日志把磁盘写爆 |
特别提醒:别在application.yml里写数据库密码!我们用的是K8s的Secret挂载,本地开发用application-local.yml(记得加到.gitignore)。
坑点总结:这些雷我替你踩过了
JPA懒加载陷阱:
@OneToMany(fetch = FetchType.LAZY)在controller返回JSON时会触发N+1查询,直接导致接口慢如蜗牛。解决方法:用@EntityGraph或 DTO投影。时间时区问题:MySQL存的时间比Java快8小时?在连接字符串加
serverTimezone=Asia/Shanghai。内存泄漏:用了
@Async但没配线程池,结果默认线程池无界,OOM警告天天见。正确做法:@Configuration public class AsyncConfig { @Bean("taskExecutor") public Executor taskExecutor() { ThreadPoolTaskExecutor executor = new ThreadPoolTaskExecutor(); executor.setCorePoolSize(5); executor.setMaxPoolSize(10); executor.setQueueCapacity(100); // 关键!防止OOM executor.setThreadNamePrefix("async-pool-"); executor.initialize(); return executor; } }健康检查失效:Spring Boot Actuator默认不检查数据库连通性。必须手动加:
management: endpoint: health: show-details: always health: db: enabled: true
效果如何?
重构后,接口QPS从80提升到2200+(4核8G机器),内存占用稳定在500MB以内。上周五上线后,运维大哥终于没在群里@我了,测试同事甚至夸我“这次没写bug”(虽然我知道她是在阴阳怪气)。
更重要的是——我的简历终于可以光明正大地写“Spring Boot实战经验”了!毕竟在国内找工作,光有海外学历不够,得有能落地的技术栈。现在每天下班前还能准时溜去静安寺那家咖啡馆写博客,而不是在公司修祖传代码。
最后几句真心话
Spring Boot确实香,但别把它当银弹。它简化的是配置和集成,核心还是你的Java功底和系统设计能力。我在英国学的那些算法和系统原理,其实在调优时比框架本身更重要。
如果你也像我一样,刚回国找工作,被各种“精通Spring Cloud”、“三年高并发经验”的JD吓到——别慌。先把Spring Boot吃透,做出一个能跑的项目,面试时聊清楚你遇到的问题和解决方案,比背八股文有用多了。
对了,下期我打算写《Spring Boot + Redis缓存击穿实战》,因为昨天刚因为缓存雪崩被领导叫去喝茶…… 敬请期待(或者说,为我祈福)。
作者:坐标上海的海归码农,白天修BUG,晚上写博客。最近在面新工作,求内推(Java后端岗),简历可私~

评论 0