Spring Boot入门教程:60分钟快速上手
上周五晚上十一点半,我正窝在沙发上远程调试一个订单超时关闭的定时任务——没错,又是线上告警。这破逻辑上线前测试说“没问题”,结果双11大促刚过,用户投诉就炸了锅。我当时一边啃着冷掉的外卖(对,就是我们美团自己的),一边盯着日志里那堆 NullPointerException,心里默念:要是当初用 Spring Boot 重构这个老项目就好了。
我是美团外卖干了快4年的 Java 开发,主攻高并发场景下的订单和配送系统。这几年从手动配 XML 到全栈注解化,踩过的坑比吃过的饭还多。最近组里来了几个实习生,一问连 Spring Boot 都没跑起来过,我心想:得,干脆写篇接地气的入门教程吧。不是那种“Hello World + 理论八股”的假大空,而是真能帮你60分钟内把服务跑起来、接前端、连数据库、还能扛点流量的实战路线。
为啥是 Spring Boot?别被“脚手架”骗了
很多人以为 Spring Boot 就是个“快速生成项目”的工具,其实大错特错。它真正的价值在于自动装配(Auto Configuration)+ 生产就绪(Production Ready)。你想想,在我们这种天天面对百万级 QPS 的外卖平台,谁还有时间手动配 DataSource、TransactionManager、RedisTemplate?
去年搞春节红包活动,产品凌晨三点甩过来一句:“明早十点上线,支持十万并发抢券”。我差点把咖啡喷屏幕上。但靠着 Spring Boot 的 spring-boot-starter-* 体系,半小时搭好骨架,集成 Redis 做库存扣减、RabbitMQ 做异步解耦,再加个 Sentinel 限流——核心代码不到200行。要搁以前手写 Spring XML,估计现在还在改配置文件。
所以别小看这玩意儿,它不是玩具,是高并发战场上的 AK47。
60分钟实操:从零到可交付
Step 1:初始化项目(5分钟)
打开 start.spring.io,别用国内某些魔改镜像(容易拉不到依赖)。我一般这么选:
- Project: Maven
- Language: Java
- Spring Boot: 3.2.x(别贪新,3.x 起要求 JDK17+,我们生产环境刚升)
- Dependencies:
- Spring Web
- Spring Data JPA
- MySQL Driver
- Lombok(省去 getter/setter,程序员之光)
- Validation(参数校验,前端传参不靠谱是常态)
📌 血泪教训:千万别勾 Thymeleaf!我们是后端,不是写页面的。前端兄弟用 React/Vue,咱只管提供 REST API。
下载解压,IDEA 打开(记得装 Lombok 插件),mvn clean install 跑通——搞定!
Step 2:写个接口给前端(15分钟)
假设前端要查用户订单列表。先定义 DTO:
@Data
public class OrderResponse {
private Long id;
private String merchantName;
private BigDecimal amount;
private LocalDateTime createTime;
}
Controller 层直接怼:
@RestController
@RequestMapping("/api/v1/orders")
@RequiredArgsConstructor // Lombok 自动生成构造器注入
public class OrderController {
private final OrderService orderService;
@GetMapping("/user/{userId}")
public List<OrderResponse> getUserOrders(@PathVariable Long userId) {
// 实际项目这里会加权限校验、分页、防刷...
return orderService.findOrdersByUser(userId);
}
}
前端看到这个 /api/v1/orders/user/123 接口,直接拿 Postman 测试(或者让前端兄弟联调)。注意路径规范,我们团队强制要求 /api/v{版本号},避免后期接口兼容爆炸。
Step 3:连数据库,别裸奔(20分钟)
建表语句(简化版):
CREATE TABLE `orders` (
`id` bigint NOT NULL AUTO_INCREMENT,
`user_id` bigint NOT NULL,
`merchant_name` varchar(100) NOT NULL,
`amount` decimal(10,2) NOT NULL,
`create_time` datetime NOT NULL,
PRIMARY KEY (`id`),
KEY `idx_user_id` (`user_id`)
) ENGINE=InnoDB;
Entity 写法:
@Entity
@Table(name = "orders")
@Data
public class Order {
@Id
@GeneratedValue(strategy = GenerationType.IDENTITY)
private Long id;
private Long userId;
private String merchantName;
private BigDecimal amount;
@Column(name = "create_time")
private LocalDateTime createTime;
}
Repository 直接继承:
public interface OrderRepository extends JpaRepository<Order, Long> {
List<Order> findByUserId(Long userId);
}
配置 application.yml:
spring:
datasource:
url: jdbc:mysql://localhost:3306/food_delivery?useSSL=false&serverTimezone=Asia/Shanghai
username: root
password: your_password
hikari:
maximum-pool-size: 20 # 别设太大!我们生产默认20,太多反而锁竞争
jpa:
show-sql: false # 上线必须关!否则日志爆炸
hibernate:
ddl-auto: validate # 别用 create!血的教训
⚠️ 安全意识提醒:
- 密码别硬编码!用配置中心或环境变量
ddl-auto在生产只能是validate或none- 敏感字段(如用户手机号)记得脱敏,别直接返回
Step 4:启动 & 验证(5分钟)
运行 main 方法,看到:
Tomcat started on port(s): 8080 (http)
Postman 访问 GET http://localhost:8080/api/v1/orders/user/1,返回 JSON:
[
{
"id": 1001,
"merchantName": "黄焖鸡米饭",
"amount": 28.50,
"createTime": "2024-04-01T12:30:00"
}
]
前端拿到数据,页面渲染完成——前后端联调成功!
实战经验:那些文档不会告诉你的坑
坑1:事务失效
实习生曾在一个 @Service 方法里用 this.saveOrder() 调自己,结果事务没生效。因为 Spring AOP 是基于代理的,内部调用绕过了代理对象。解决办法:注入自己,或者用 ApplicationContext 获取代理 bean。
坑2:连接池打满
有一次大促,DB 连接池爆了。查了半天发现是某个查询没加索引,慢 SQL 卡住连接。务必监控 HikariCP 的 active/total 连接数,配合 Arthas 看线程堆栈。
坑3:前端传参乱七八糟
前端传个 "userId": "abc",后端直接报 400。所以 Controller 参数加上 @Valid:
@GetMapping("/user/{userId}")
public List<OrderResponse> getUserOrders(@PathVariable @Min(1) Long userId) {
配合全局异常处理,返回友好错误:
@RestControllerAdvice
public class GlobalExceptionHandler {
@ResponseStatus(HttpStatus.BAD_REQUEST)
@ExceptionHandler(MethodArgumentTypeMismatchException.class)
public String handleTypeMismatch() {
return "参数类型错误,请检查 userId 是否为数字";
}
}
性能与运维:上线前必做三件事
| 检查项 | 开发环境 | 生产环境 |
|---|---|---|
| Actuator 健康检查 | ✅ | ✅(但需鉴权) |
| 日志级别 | DEBUG | WARN |
| 数据库连接池 | 10 | 20~50(根据 DB 规格) |
| JVM 参数 | 默认 | -Xms4g -Xmx4g -XX:+UseG1GC |
我们美团内部有标准化的 Spring Boot Starter,集成了链路追踪(SkyWalking)、配置中心(Apollo)、熔断降级(Sentinel)。但即使没有这些,至少要暴露 /actuator/health 和 /actuator/metrics,让运维能监控服务状态。
最后说两句
Spring Boot 真的不难,难的是在复杂业务中用对、用稳。我见过太多人把所有逻辑塞进 Controller,结果后期改不动;也见过盲目追求微服务,最后连本地调试都要起五个服务。
记住:框架是工具,不是银弹。60分钟上手只是起点,真正值钱的是你如何设计接口、规避并发问题、保障数据一致性——这些才是我们 Java 老兵吃饭的家伙。
哦对了,刚才那个订单超时 Bug,最后发现是 RabbitMQ 消息积压导致监听器没触发……不过那是另一个故事了。先去改代码,产品又在群里@我了 😅
本文代码已上传 GitHub(模拟),实际项目请遵守公司安全规范。
—— 一个在家撸代码、被线上告警追着跑的美团外卖 Java 开发

评论 0