学完 Spring Boot 再看 FastAPI,我破防了
撸了两年 Spring Boot,自认为后端功力还行。上周心血来潮打开 FastAPI 官方文档,15 分钟后我沉默了。
不是它太难,而是太简单了。简单到让我怀疑自己这些年到底在干什么。
这不是一篇踩一捧一的文章。Spring Boot 是我的启蒙框架,教会了我工程化思维。但有些话,不吐不快。
一、Hello World 对比——第一刀就破防
Spring Boot 的第一行代码:
@RestController
@RequestMapping("/api")
public class HelloController {
@GetMapping("/hello/{name}")
public String sayHello(@PathVariable String name) {
return "Hello, " + name + "!";
}
}
写这一行之前你要经历什么?建 Maven 项目、配 pom.xml、等依赖下载、写启动类、配 application.yml……等你跑起来,半小时过去了。
FastAPI 呢?
from fastapi import FastAPI
app = FastAPI()
@app.get("/api/hello/{name}")
def say_hello(name: str):
return f"Hello, {name}!"
pip install fastapi → 写 5 行代码 → uvicorn main:app --reload → 浏览器打开,搞定。
破防点:Spring Boot 的启动类还没写完,FastAPI 已经能调了。
而且 FastAPI 自带 /docs 页面,Swagger UI 直接生成,不用配任何东西。Spring Boot 接 Swagger 的经历,懂的都懂。
二、依赖注入——Spring 的重器 vs FastAPI 的轻拳
Spring 的依赖注入是它的灵魂,也是它的包袱。
@Service
public class UserService {
@Autowired
private UserRepository userRepository;
public List<User> getUsers() {
return userRepository.findAll();
}
}
@Service + @Autowired + @ComponentScan + 配置扫描路径……Spring 的 IoC 容器确实强大,但学 Spring 的人,一半时间在理解容器是怎么工作的。
FastAPI 的依赖注入完全不同:
from fastapi import Depends
def get_db():
db = Database()
try:
yield db
finally:
db.close()
@app.get("/users")
def get_users(db: Database = Depends(get_db)):
return db.query_all()
显式声明、一目了然、没有黑魔法。Depends() 直接把依赖链甩在参数里,谁依赖谁一眼看穿。
破防点:在 Spring 里学会的 DI,到了 FastAPI 发现原来可以这么简单。不是 Spring 不好,是 FastAPI 让你意识到 DI 本身不需要那么复杂。
三、数据校验——JPA 的痛 vs Pydantic 的爽
写过 Spring Boot 的都知道,一个 DTO 类有多酸爽:
public class UserDVO {
@NotNull(message = "名称不能为空")
@Size(min = 2, max = 20)
private String name;
@Email
private String email;
@Pattern(regexp = "^1[3-9]\\d{9}$")
private String phone;
// 构造方法
public UserDVO() {}
// getter/setter x 6
public String getName() { return name; }
public void setName(String name) { this.name = name; }
public String getEmail() { return email; }
public void setEmail(String email) { this.email = email; }
public String getPhone() { return phone; }
public void setPhone(String phone) { this.phone = phone; }
}
30 行起步,还只是最基本的 Bean Validation。加上 Swagger 注解?50 行起步。
FastAPI 的 Pydantic:
from pydantic import BaseModel, EmailStr, Field
class UserDTO(BaseModel):
name: str = Field(min_length=2, max_length=20)
email: EmailStr
phone: str = Field(pattern=r"^1[3-9]\\d{9}$")
10 行,搞定。校验、类型提示、序列化、文档生成,全自动。
最重要的是:不用写 getter/setter。不用写构造方法。不用配 toString。Python 的数据类天然就是 DTO。
破防点:Java 写 DTO 等于加班,Python 写 DTO 等于顺便。
四、异步编程——补丁 vs 原生
Java 的异步之路,一部打补丁的历史:
- 1.0:同步阻塞
- 1.5:
java.util.concurrent+Future - 1.8:
CompletableFuture - 21:虚拟线程(终于像个样子了)
写个异步接口:
@GetMapping("/users/{id}")
public CompletableFuture<User> getUser(@PathVariable Long id) {
return CompletableFuture.supplyAsync(() -> userService.findById(id));
}
CompletableFuture、线程池、ExecutorService、Future 链……光异常传播就能写一篇文章。
FastAPI 的异步:
@app.get("/users/{id}")
async def get_user(id: int):
user = await db.fetch_one("SELECT * FROM users WHERE id = ?", (id,))
return user
async def + await,语言原生的异步支持。不用学 Reactor、不用理解 Mono/Flux,写出来的代码跟同步几乎没有区别。
破防点:在 Java 里搞异步像在考试,在 FastAPI 里搞异步像在摸鱼。
五、中间件——仪式感 vs 实用主义
Spring Boot 的拦截器:
@Component
public class LogInterceptor implements HandlerInterceptor {
@Override
public boolean preHandle(HttpServletRequest request,
HttpServletResponse response,
Object handler) {
System.out.println("请求: " + request.getMethod() + " " + request.getRequestURI());
return true;
}
}
还要注册:
@Configuration
public class WebConfig implements WebMvcConfigurer {
@Override
public void addInterceptors(InterceptorRegistry registry) {
registry.addInterceptor(new LogInterceptor())
.addPathPatterns("/api/**");
}
}
接口、实现类、注册配置,三步一个不能少。
FastAPI:
@app.middleware("http")
async def log_requests(request: Request, call_next):
print(f"请求: {request.method} {request.url}")
return await call_next(request)
一个装饰器,搞定。
破防点:一个 @app.middleware 的事,Spring 要我写三个文件。
六、项目结构——约定 vs 自由
Spring Boot 推荐的项目结构:
src/main/java/com/example/demo/
├── controller/
├── service/
├── repository/
├── dto/
├── config/
├── exception/
├── entity/
└── DemoApplication.java
不是说这个结构不好,而是只能这样。社区规范、团队约定、框架要求,你没得选。
FastAPI:
myapp/
├── main.py
├── routers/
├── models.py
└── schemas.py
想拆就拆,想合就合。小项目一个 main.py 搞定,大项目慢慢拆模块。没人管你。
破防点:Spring Boot 的规范是好规范,但有时候我就想要"随便放"的自由。
七、这不是终点,是选择
写到最后,我想说点真心话。
Spring Boot 教会了我太多东西:
- 分层架构——Controller/Service/Repository 各司其职
- 依赖注入——理解什么是 IoC、什么是控制反转
- 面向接口编程——不仅仅是一种技术,更是一种思维方式
- 工程化思维——测试、部署、监控,一个完整的后端生态
这些经验是无价的。
FastAPI 则让我重新审视自己:
- 同样一个 CRUD API,代码量减少 70%
- 自动生成 API 文档,不用额外写一行配置
- 类型提示 + Pydantic = 编辑器补全直接起飞
- 原生异步,性能不输 Node.js
它们不是替代关系,是互补关系。
大型企业项目、复杂业务、团队协作,Spring Boot 依然是王者。快糙猛的原型、个人项目、AI 服务,FastAPI 让你爽到飞起。
最后送大家一句话:
"学完 Spring Boot 再看 FastAPI,我破防的不是技术,而是发现自己被 Java 惯坏了——习惯了复杂,忘记了简单也是一种能力。"
你觉得 Spring Boot 和 FastAPI 哪个更香?欢迎评论区聊聊 👇