Spring Boot上手实录:从0到API上线只用了60分钟

Issue终结者
2026-01-05 09:30
阅读 423

上周五晚上十点半,我正一边喝着第三杯瑞幸,一边在工位上和一个线上Kafka消息堆积的Bug搏斗。突然企业微信弹出一条消息:“明早10点前,要把新产品的MVP接口跑起来,给产品演示用。”——典型的“产品经理式需求”:没文档、没PRD、只有口头一句话。

我当时真想把键盘砸了。但转念一想,这不正是用Spring Boot快速搭后端服务的最佳场景吗?毕竟在深圳腾讯系公司混,谁还没被“敏捷开发”和“快速验证”折磨过?而且我已经连续三周996了,实在没精力去搞什么重型架构。能60分钟搞定一个可用的REST API,就是最大的福报。


为什么是Spring Boot?而不是Flask或者Express?

别误会,我其实是个Python老粉。日常脚本、数据处理、甚至一些轻量级爬虫,首选都是Python + Flask。但这次不行——产品明确说后续要接入公司统一的微服务治理平台(基于Spring Cloud),数据库要用MySQL集群,还要对接内部鉴权系统。这些玩意儿,Spring生态原生支持,Python就得自己造轮子,或者硬套胶水代码。

至于JavaScript?Node.js确实快,但团队里没人敢在生产环境用它扛核心业务。上次隔壁组用Express写了个订单服务,结果因为异步回调地狱+内存泄漏,在双11压测时直接崩了。运维大哥当场黑脸,从此我们组对JS后端敬而远之。

所以,尽管我每天下班回家还在看《深入浅出Node.js》这本书(没错,技术人的通病:买书如山倒,读书如抽丝),但工作场景下,Spring Boot依然是那个“最稳妥的选择”。


环境准备:5分钟搞定一切

首先,你得有个JDK。别笑,我们组去年招了个实习生,上来就问:“Java不是被Oracle收费了吗?还能用吗?”——兄弟,OpenJDK香得很,而且公司内网有私有镜像,直接yum install openjdk-17就行。

然后是IDE。IntelliJ IDEA社区版够用,但如果你在腾讯系公司,大概率会用内部定制版(带一堆插件和模板)。不过为了通用性,我还是用标准版演示。

最关键的一步:别手动建项目!
直接上 start.spring.io —— 这个网站简直是996程序员的救命稻草。选好语言(Java)、Spring Boot版本(我选3.2.x)、打包方式(jar)、Java版本(17),再勾几个依赖:

  • Spring Web(必须)
  • Spring Data JPA(操作数据库)
  • MySQL Driver
  • Lombok(省掉getter/setter,打工人的时间很贵)

点击Generate,下载zip,解压导入IDEA。整个过程不超过3分钟。比我在淘宝下单一杯美式还快。


写第一个API:别整花活,先跑起来

新建一个 ProductController.java

@RestController
@RequestMapping("/api/v1")
public class ProductController {

    @GetMapping("/hello")
    public String hello() {
        return "Hello, Product Team!";
    }
}

然后启动类啥都不用改,直接点运行。控制台刷出一堆日志,最后看到:

Tomcat started on port(s): 8080 (http)
Started DemoApplication in 2.345 seconds

浏览器访问 http://localhost:8080/api/v1/hello,返回那句嘲讽产品的话——成了!

这时候我瞄了一眼手机,才过去8分钟。心里默默给自己点了个赞:这效率,要是让产品经理知道,怕是要连夜加需求。


接数据库:别被JPA吓退

接下来要存点真实数据。假设我们要建一个 Product 表,字段很简单:id、name、price、createdAt。

先在 application.properties 里配数据库:

spring.datasource.url=jdbc:mysql://localhost:3306/demo?useSSL=false&serverTimezone=UTC
spring.datasource.username=root
spring.datasource.password=your_password
spring.jpa.hibernate.ddl-auto=update
spring.jpa.show-sql=true

注意ddl-auto=update 只能在开发环境用!生产环境必须用 Flyway 或 Liquibase 做版本化迁移,否则DBA会拿刀追你三条街。

然后写Entity:

@Entity
@Table(name = "products")
@Data // Lombok注解,自动生成getter/setter/toString
public class Product {
    @Id
    @GeneratedValue(strategy = GenerationType.IDENTITY)
    private Long id;
    
    private String name;
    private BigDecimal price;
    
    @Column(name = "created_at")
    private LocalDateTime createdAt = LocalDateTime.now();
}

再写Repository:

public interface ProductRepository extends JpaRepository<Product, Long> {
}

最后在Controller里加个POST接口:

@PostMapping("/products")
public Product createProduct(@RequestBody Product product) {
    return productRepository.save(product);
}

用Postman一试,JSON传进去,数据库立马多了一条记录。全程没写一行SQL,JPA自动建表+插入。那一刻我突然理解了为什么那么多Java程序员说“Spring Boot是生产力工具”——它真的在替你干活。


踩坑实录:那些让我想辞职的瞬间

当然,事情不会总那么顺利。第二天早上产品来验收,说:“能不能加个分页查询?还有按价格排序?”

我心想:小case。结果一写就翻车。

坑1:LocalDateTime反序列化失败

前端传 { "name": "iPhone", "price": 5999, "createdAt": "2024-06-14T10:00:00" },结果后端报错:

Cannot deserialize value of type java.time.LocalDateTime from String ...

查了半天,发现Spring Boot 3.x 默认用Jackson,但没自动注册JavaTimeModule。解决办法:在启动类加个Bean:

@Bean
public Jackson2ObjectMapperBuilder jackson2ObjectMapperBuilder() {
    return new Jackson2ObjectMapperBuilder()
            .serializerByType(LocalDateTime.class, new LocalDateTimeSerializer(DateTimeFormatter.ISO_LOCAL_DATE_TIME))
            .deserializerByType(LocalDateTime.class, new LocalDateTimeDeserializer(DateTimeFormatter.ISO_LOCAL_DATE_TIME));
}

或者更简单的,在Entity字段上加注解:

@JsonFormat(pattern = "yyyy-MM-dd HH:mm:ss")
private LocalDateTime createdAt;

但这样每个字段都得加,累死。还是全局配置香。

坑2:分页查询性能爆炸

产品要“每页10条,按价格从高到低排”。我直接写了:

@GetMapping("/products")
public Page<Product> getProducts(Pageable pageable) {
    return productRepository.findAll(pageable);
}

结果测试数据一多(10万条),接口响应直接飙到3秒+。一看SQL,发现MySQL在做全表扫描+filesort。

解决方案:给 price 字段加索引!

ALTER TABLE products ADD INDEX idx_price (price DESC);

同时,确保Pageable的sort字段是安全的(防止SQL注入),最好白名单校验。


对比其他语言:Spring Boot到底值不值得学?

我知道很多Python/JS开发者觉得Java又重又啰嗦。但站在一个天天被线上事故追着跑的后端工程师角度,Spring Boot的“重”,其实是“稳”。

维度 Spring Boot Flask (Python) Express (JS)
启动速度 中等(1-3秒) 快(<1秒) 快(<1秒)
生产监控 Actuator + Prometheus 原生集成 需第三方库 需中间件
事务管理 @Transactional 一行搞定 需手动处理 回调地狱风险
类型安全 编译期检查 运行时才发现错 运行时才发现错
微服务支持 Spring Cloud全家桶 零碎方案拼凑 依赖第三方

尤其是在大厂,你写的代码可能三年后还有人维护。强类型 + 完善的错误堆栈 + 成熟的APM体系,能让你半夜不用被PagerDuty叫醒。


最后:60分钟真的够吗?

回到开头的问题。我实际花了多少时间?

  • 环境搭建:5分钟
  • Hello World:5分钟
  • 数据库集成:15分钟
  • CRUD接口:10分钟
  • 分页+排序:10分钟
  • 调试两个坑:15分钟

总计:60分钟整。刚好赶上第二天早会前部署到测试环境。

产品看了演示,满意地走了。而我,继续回去修那个Kafka Bug——毕竟996的福报,不能停。


给同样忙碌的你的建议

如果你和我一样,每天被需求追着跑,没时间系统学习,但又想快速产出:

  1. 别试图精通所有细节。先跑通流程,再回头补原理。就像我,现在也说不清Spring Boot自动配置的底层机制,但不影响我写出可用的服务。
  2. 善用AI工具。我写Repository方法名时,直接问Claude:“JPA怎么写按价格范围查询?” 它秒回 List<Product> findByPriceBetween(BigDecimal min, BigDecimal max); —— 效率翻倍。
  3. 读官方文档,别信二手教程。Spring Boot文档写得极好,而且更新快。那些三年前的CSDN博客,很可能用的是过时的注解。
  4. 买书不如动手。我书架上有《Spring实战》《Spring微服务实战》,但真正帮我解决问题的,永远是 spring-boot-starter-web 的源码和Stack Overflow。

最后送大家一句话:在互联网公司,完成比完美重要一万倍。先把东西跑起来,剩下的,交给明天的自己(或者下一个接盘侠)。

祝你今晚不用加班。

评论 0

最热最新
暂无评论
匿名用户Lv.1
0
影响力
0
文章
0
粉丝