Spring Boot上手实录:一个三线城市技术负责人的60分钟速成记
上周五晚上十点半,我还在公司盯着Jenkins的构建日志发呆。产品经理临时加了个需求,说要在下周一演示会上展示一个“内部效率工具”——其实就是个带用户登录和数据统计的小后台。时间紧、任务重,团队里两个应届生面面相觑,连Maven都没配明白。
这时候我突然想起自己刚入行那会儿,也是被Spring框架搞到怀疑人生。XML配置写得比小说还长,光是搭个Hello World就得折腾一整天。好在现在有Spring Boot,开箱即用,连我这种常年靠ChatGPT和Claude续命的技术负责人,也能在短时间内拉起一个能跑的项目。
坐标上海,租住在公司隔壁小区,平时喜欢折腾Rust、Zig这些新玩意儿,但真到了项目deadline前夜,我还是老老实实用最稳的方案。毕竟线上崩了,运维同事可不会管你用了多酷的语法糖。
为什么这次选Spring Boot?
说白了,就两个字:快和稳。
我们公司虽然是“互联网公司”,但在技术栈上其实相当保守。数据库还是MySQL 5.7,中间件能不用就不用,K8s?那是大厂的玩具。但Spring Boot不一样——它把那些繁琐的配置都默认好了,starter一引,自动装配,连Tomcat都给你内嵌了。对我们这种小团队来说,简直是救命稻草。
而且,面试题挑战里十道后端题,八道绕不开Spring Boot。新人来了问“Spring Boot和Spring有什么区别”,答不上来的直接pass。所以这次干脆借着做内部工具的机会,带着团队一起过一遍核心流程。
动手:60分钟从零到API上线
第一步:初始化项目(5分钟)
我习惯用 start.spring.io 快速生成骨架。这次选了:
- Java 17(公司统一版本)
- Spring Boot 3.2.x
- Dependencies: Spring Web, Spring Data JPA, H2 Database(先本地跑,省事)
生成完下载zip,解压导入IDEA。顺手让实习生跑了个./mvnw spring-boot:run,控制台刷出熟悉的Tomcat启动日志——成了!
💡 小技巧:其实我现在基本用 Aider 来初始化项目。只要在终端输入
aider --init spring-boot-web-app,它就能根据上下文自动生成完整结构,还能写README。配合Claude解释依赖关系,效率翻倍。
第二步:写个接口(10分钟)
目标很简单:提供一个 /api/users 接口,返回用户列表。
@RestController
@RequestMapping("/api")
public class UserController {
@GetMapping("/users")
public List<User> getUsers() {
return Arrays.asList(
new User(1L, "张三", "zhangsan@example.com"),
new User(2L, "李四", "lisi@example.com")
);
}
}
User类用record搞定(Java 14+真香):
public record User(Long id, String name, String email) {}
本地测试:curl http://localhost:8080/api/users,JSON哗哗输出。实习生眼睛都亮了:“原来这么简单?”
我笑了笑:“别急,等你连上真实数据库再说。”
第三步:接入数据库(20分钟)
虽然演示用H2就行,但为了贴近生产,我们还是模拟了MySQL场景。
- 把H2依赖换成MySQL驱动:
<dependency>
<groupId>mysql</groupId>
<artifactId>mysql-connector-java</artifactId>
<scope>runtime</scope>
</dependency>
- 配置
application.yml:
spring:
datasource:
url: jdbc:mysql://localhost:3306/internal_tool?useSSL=false&serverTimezone=UTC
username: root
password: 123456
jpa:
hibernate:
ddl-auto: update
show-sql: true
- 改User为JPA Entity:
@Entity
@Table(name = "users")
public class User {
@Id
@GeneratedValue(strategy = GenerationType.IDENTITY)
private Long id;
private String name;
private String email;
// getter/setter 略(其实我用Lombok,但公司禁用,只能手写😭)
}
- 写个Repository:
public interface UserRepository extends JpaRepository<User, Long> {}
- Controller注入并调用:
@Autowired
private UserRepository userRepository;
@GetMapping("/users")
public List<User> getUsers() {
return userRepository.findAll();
}
这时候问题来了:本地MySQL没开!实习生手忙脚乱装Docker,结果端口冲突,报错:
Communications link failure - The last packet sent successfully to the server was 0 milliseconds ago.
我淡定地敲了句:docker run --name mysql-demo -e MYSQL_ROOT_PASSWORD=123456 -p 3306:3306 -d mysql:8.0,世界清净了。
第四步:加点生产味(15分钟)
真实项目不能只返回假数据。我们快速补了几个关键点:
- 统一响应格式:封装
Result<T>,避免前端解析混乱 - 全局异常处理:用
@ControllerAdvice捕获Service层异常 - Swagger文档:加
springdoc-openapi-starter-webmvc-ui,访问/swagger-ui.html自动生成API文档 - 配置分离:
application-prod.yml和application-dev.yml分环境管理
特别吐槽一点:很多新人喜欢在Controller里直接写业务逻辑,结果后期改不动。我强制要求分三层:Controller → Service → Repository。虽然多写几个类,但排查Bug时感谢我。
第五步:打包部署(10分钟)
最后一步,打jar包扔测试服务器:
./mvnw clean package -DskipTests
java -jar target/internal-tool-0.0.1-SNAPSHOT.jar --spring.profiles.active=prod
为了省事,我还写了个简单的systemd服务文件,让运维同事帮忙挂后台。他说:“你们开发现在连部署都自动化了?” 我心想:要不是赶时间,我早用Dockerfile + Jenkins Pipeline了……
踩坑总结 & 面试题挑战
这次实战虽然顺利,但背后全是血泪教训:
| 坑点 | 解决方案 | 面试高频题 |
|---|---|---|
| JPA懒加载在Controller序列化时报错 | 用@JsonIgnore或DTO转换 |
“Spring Boot如何解决Hibernate懒加载问题?” |
| 多环境配置混乱 | 严格使用spring.profiles.active |
“如何管理不同环境的配置?” |
| 启动慢(尤其云服务器) | 关闭不必要的Starter,如Actuator未用就排除 | “如何优化Spring Boot启动速度?” |
另外,不要迷信自动配置!有一次线上OOM,查了半天发现是默认的HikariCP连接池配了50个连接,而我们的小数据库扛不住。后来手动调成10,稳如老狗。
最后几句心里话
说实话,Spring Boot入门真不难,难的是在复杂业务中保持架构清晰。我现在带团队,第一要求不是你会多少框架,而是代码能不能让三个月后的自己看懂。
这次60分钟速成,与其说是教技术,不如说是传递一种“最小可用”的工程思维:先跑起来,再迭代优化。毕竟在三线城市的互联网公司,资源有限、人力紧张,能快速交付比炫技重要得多。
对了,如果你也在准备跳槽,建议把Spring Boot的自动配置原理、启动流程、Starter机制搞清楚。我面人时最爱问:“@SpringBootApplication注解里三个元注解分别干嘛的?” 答不上来的,简历直接放一边。
工具永远只是工具。真正值钱的,是你解决问题的能力——哪怕你全程靠Aider和Claude辅助,只要结果靠谱,老板照样给你升职加薪(笑)。
搞定收工。回家路上点了杯瑞幸,看着手机里Jenkins的绿色构建状态,终于能睡个好觉了。

评论 0