Spring Boot 入门?我用一杯咖啡的时间跑通了第一个服务

Prometheus小骑士
2026-01-13 11:26
阅读 418

上周五晚上九点半,公司会议室的白板上还贴着“Q3数字化转型冲刺倒计时:14天”。产品经理小王端着瑞幸站在我工位旁边,笑得像刚抢到618优惠券:“老李,我们那个新后台系统能不能下周上线?就那个对接财务和供应链的……前端同事已经用 Vue 写完了页面,就差你这边的接口了。”

我看了眼 IDE 里还在飘红的 Maven 依赖冲突,默默咽下最后一口冷掉的美式——这已经是今天第三杯了。作为在传统制造企业干了六年 Java 的老码农,我太懂什么叫“前端都写完了,后端还没搭环境”。

其实说来惭愧,虽然杭州这边阿里网易遍地都是 Spring Cloud 微服务架构,但我们厂直到去年双11压测崩了三台 Oracle 数据库之后,才痛定思痛决定搞数字化转型。领导拍板:“上 Spring Boot!要快!”

于是乎,一个被 Oracle 存储过程折磨多年的 Java 老兵,被迫在 60 分钟内搞定 Spring Boot 初体验——不是为了卷,纯粹是为了活命。


为什么不用 Go?

有朋友可能会问:现在不是流行 Go 吗?简洁、并发强、部署轻量,连前端同学都在学。说实话,我也试过。上个月拿 Go 写了个简单的库存查询服务,代码确实清爽,但问题来了:

  • 公司历史系统全是 Java 生态(Hibernate + Oracle + WebLogic)
  • 运维团队只会看 JVM 日志,Go 的 pprof 对他们来说像天书
  • 更致命的是:没人敢在生产环境用没经过验证的新语言

所以,Spring Boot 成了最稳妥的选择——它既保留了 Java 的生态优势,又极大简化了配置。就像我们 CTO 在周会上说的:“别整那些花里胡哨的,能跑就行,先上线再优化。”


60 分钟实战:从零到可访问的 REST API

下面是我上周五实际操作的流程,全程记录,不含水分。

第一步:生成项目骨架(5分钟)

打开 https://start.spring.io,这是 Spring 官方脚手架,比手动建 Maven 项目快十倍。

我选了这些依赖:

  • Spring Web(必须的,不然怎么暴露接口)
  • Spring Data JPA(对接数据库,虽然我们用 Oracle,但先用 H2 内存库跑通再说)
  • Lombok(省去 getter/setter,打工人必备)
  • Validation(参数校验,防止前端乱传)

注:前端同事用的是 Vue3 + Axios,所以接口必须返回标准 JSON 格式,不能是 JSP 页面!

点击 Generate,下载 ZIP 解压,导入 IDEA。整个过程比我泡面还快。

第二步:写个 Controller(10分钟)

新建 ProductController.java

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

    @Autowired
    private ProductService productService;

    @GetMapping("/{id}")
    public ResponseEntity<Product> getProduct(@PathVariable Long id) {
        Product product = productService.findById(id);
        if (product == null) {
            return ResponseEntity.notFound().build();
        }
        return ResponseEntity.ok(product);
    }

    @PostMapping
    public ResponseEntity<Product> createProduct(@Valid @RequestBody ProductDTO dto) {
        Product saved = productService.save(dto);
        return ResponseEntity.status(HttpStatus.CREATED).body(saved);
    }
}

注意几个细节:

  • @RestController 自动把返回对象转成 JSON,前端直接 res.data 就能拿到数据
  • 用了 ResponseEntity 明确状态码,前端可以根据 404/201 做不同 UI 反馈
  • 参数加了 @Valid,配合 DTO 里的 @NotBlank,避免前端传空字符串炸库

这时候前端小张跑过来问:“接口文档呢?” 我指了指控制台日志:“等会儿,Swagger 马上给你。”

第三步:集成 Swagger(5分钟)

pom.xml 加:

<dependency>
    <groupId>org.springdoc</groupId>
    <artifactId>springdoc-openapi-starter-webmvc-ui</artifactId>
    <version>2.3.0</version>
</dependency>

启动后访问 http://localhost:8080/swagger-ui.html,自动生成交互式文档。前端同学当场点赞:“比上次那个 Word 文档强多了!”

第四步:连数据库(15分钟)

虽然公司用 Oracle,但本地开发我先用 H2 内存数据库跑通逻辑。

application.yml 配置:

spring:
  datasource:
    url: jdbc:h2:mem:testdb
    driver-class-name: org.h2.Driver
    username: sa
    password: 
  jpa:
    hibernate:
      ddl-auto: create-drop  # 启动建表,关闭删表,适合 demo
    show-sql: true

定义 Entity:

@Entity
@Table(name = "products")
@Data
@NoArgsConstructor
@AllArgsConstructor
public class Product {
    @Id
    @GeneratedValue(strategy = GenerationType.IDENTITY)
    private Long id;
    
    @NotBlank(message = "商品名称不能为空")
    private String name;
    
    private BigDecimal price;
}

Service 层就几行代码:

@Service
@Transactional
public class ProductService {
    @Autowired
    private ProductRepository repository;

    public Product findById(Long id) {
        return repository.findById(id).orElse(null);
    }

    public Product save(ProductDTO dto) {
        Product product = new Product();
        product.setName(dto.getName());
        product.setPrice(dto.getPrice());
        return repository.save(product);
    }
}

这时候 ProductRepository 只需要继承 JpaRepository,CRUD 方法全都有了——这就是 Spring Data 的魔法。

第五步:本地测试(10分钟)

用 Postman 或 curl 测试:

# 创建商品
curl -X POST http://localhost:8080/api/products \
  -H "Content-Type: application/json" \
  -d '{"name":"智能螺丝刀","price":89.9}'

# 查询
curl http://localhost:8080/api/products/1

返回:

{
  "id": 1,
  "name": "智能螺丝刀",
  "tprice": 89.90
}

前端小张立马在 Vue 里调通了接口,界面刷出来了。他竖起大拇指:“后端终于不拖后腿了!”

第六步:打包部署(15分钟)

执行:

./mvnw clean package

生成 target/demo-0.0.1-SNAPSHOT.jar,一个 fat jar,包含所有依赖。

运维老刘看到这个 jar 包直摇头:“又是 jar?能不能打成 war 放 Tomcat?”
我苦笑:“哥,Spring Boot 内嵌 Tomcat,直接 java -jar 就行,不用装中间件。”

他半信半疑地在测试服务器上跑起来:

nohup java -jar demo-0.0.1-SNAPSHOT.jar --server.port=8081 > app.log 2>&1 &

5 秒后,服务就起来了。老刘嘀咕:“还真行……那监控咋办?”

我说:“加个 Actuator 就行。” 于是又加了个依赖:

<dependency>
    <groupId>org.springframework.boot</groupId>
    <artifactId>spring-boot-starter-actuator</artifactId>
</dependency>

暴露 /actuator/health/actuator/metrics,Prometheus 一接,监控面板立马有了数据。


踩过的坑 & 血泪经验

当然,60 分钟只是理想情况。实际中我踩了几个大坑:

问题 现象 解决方案
时区不对 数据库存的时间比本地快8小时 application.ymlspring.jackson.time-zone=GMT+8
中文乱码 前端收到 ??? 配置 server.servlet.encoding.charset=UTF-8
打包后静态资源404 Vue 的 dist 文件放错位置 把前端 build 后的文件放到 src/main/resources/static

最搞笑的是,第一次部署到测试环境,因为没配数据库连接池,10个并发请求就把 H2 干挂了。还好是测试环境,不然又要背锅。


为什么前端总催后端?

说到底,Spring Boot 的核心价值不是技术多牛,而是让后端快速响应业务需求。在传统企业,前端用 Vue/React 已经非常成熟,但他们卡在等接口。而 Spring Boot 把 80% 的样板代码自动化了,让我们能把精力放在业务逻辑上。

至于 Go?等哪天运维团队愿意学新语言,或者公司敢拿核心系统试水,我第一个冲。但现在,稳定压倒一切——毕竟谁也不想在凌晨三点被 PagerDuty 叫醒修线上事故。


最后一点真心话

这篇文章写完,已经是第二天早上 8 点。窗外杭州的天刚蒙蒙亮,我又泡了杯咖啡。Spring Boot 确实香,但别忘了:工具再快,也快不过清晰的需求和良好的沟通

所以下次前端再催你,别急着写代码,先问清楚:“你到底要什么字段?分页还是不分页?要不要缓存?”

毕竟,在数字化转型的路上,我们不是一个人在战斗。

(完)

评论 0

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