欢迎来到啾啾的博客🐱。
记录学习点滴。分享工作思考和实用技巧,偶尔也分享一些杂谈💬。
有很多很多不足的地方,欢迎评论交流,感谢您的阅读和评论😄。
引言
在之前的《FastAPI快速入门》中,我们对服务器搭建、依赖注入、接口定义与Pydantic模型有了基本了解。本篇继续深入FastAPI的核心机制,并与Java生态的SpringBoot进行对比,帮助Java开发者快速建立技术映射。
1 FastAPI事件管理
FastAPI 提供了 startup 和 shutdown 事件来处理应用启动和关闭时的逻辑,类似于 Spring Boot 的ApplicationRunner
和@PreDestroy
。
不过, on_event
在较新版本中已被弃用,推荐使用 lifespan
处理应用生命周期事件。
from contextlib import asynccontextmanager
from fastapi import FastAPI
# 现代 lifespan 处理方式
@asynccontextmanager
async def lifespan(app: FastAPI):
# 启动逻辑 - 类似 @PostConstruct
print("🚀 应用启动:数据库连接池初始化")
cache = {"hot_items": load_hot_data()}
yield cache # 将资源传递给路由,即赋值给app.state
# 关闭逻辑 - 类似 @PreDestroy
print("🛑 应用关闭:释放数据库连接池")
cache.clear()
app = FastAPI(lifespan=lifespan) # 注入 lifespan
@app.get("/items")
async def get_items():
return app.state["hot_items"] # 直接使用初始化资源
连接池示例
@asynccontextmanager
async def lifespan(app: FastAPI):
# 初始化 PostgreSQL 连接池
app.state.db_pool = await asyncpg.create_pool(
dsn=os.getenv("DB_DSN"),
min_size=5,
max_size=20
)
# 初始化 Redis 客户端
app.state.redis = await aioredis.from_url(
"redis://localhost",
encoding="utf-8",
decode_responses=True
)
yield
# 资源清理
await app.state.db_pool.close()
await app.state.redis.close()
对比SpringBoot
// Spring Boot 等效实现
@SpringBootApplication
public class DemoApp implements ApplicationRunner {
@Autowired
private DataSource dataSource;
@PreDestroy
public void onExit() {
System.out.println("🛑 释放资源");
}
@Override
public void run(ApplicationArguments args) {
System.out.println("🚀 初始化完成");
}
}
FastAPI采用显式事件注册,SpringBoot通过接口/注解实现,后者更符合Java的约定优于配置原则。
特性 | FastAPI (lifespan) | Spring Boot |
---|---|---|
事件类型 | 异步上下文管理器 | 接口实现 + 注解 |
资源传递 | yield 返回 → 直接注入路由 | 通过 ApplicationContext |
错误处理 | 自带 try/finally 语义 | 需手动实现销毁逻辑 |
依赖注入 | 通过 app.state 访问 | @Autowired 自动装配 |
多阶段初始化 | 单入口统一管理 | 多种初始化接口可选 |
2 类的使用
2.1 初始化方法对比
Python中有__new__
和__init__
方法可以用于在对象实例创建时执行一些操作。
class Service:
def __new__(cls):
print("1. 分配内存 → 类似Java的new关键字")
return super().__new__(cls)
def __init__(self):
print("2. 初始化属性 → 类似Java的构造函数")
self.cache = {}
__new__
方法比__init__
先调用。
Java等效实现如下:
public class Service {
private Map<String, Object> cache;
public Service() {
System.out.println("构造函数初始化");
this.cache = new HashMap<>();
}
}
- cls 与 self
cls代表类本身。在调用类方法时,Python会自动将类对象作为第一个参数传递给方法。通过 cls 能够访问和修改类的属性,还能创建类的实例。
self 代表类的实例对象。在调用实例方法时,Python 会自动将实例对象作为第一个参数传递给方法。借助 self 可以访问和修改实例的属性和方法。
2.2 Pydantic的构造
Pydantic模型是默认支持全参构造,等效于@NoArgsConstructor+@AllArgsConstructor的。
且可以通过关键字或字典解包,所以不会有Java的构造函数参数膨胀问题。
from pydantic import BaseModel
class User(BaseModel):
name: str
age: int
# 构造方式1:关键字参数
user = User(name="Alice", age=30) # 自动触发类型验证错误
# 构造方式2:字典解包
data = {"name": "Alice", "age": 30}
user = User(**data)
SpringBoot等效
// Lombok简化构造
@Data
@AllArgsConstructor
public class UserDTO {
private Long id;
private String name;
private String email;
}
3 依赖管理
使用Spring框架时,对象交由框架处理,默认单例,且可以做到复杂的依赖管理。
FastAPI的依赖系统轻量但强大,也支持函数/类级别注入:
from fastapi import Depends
def get_db_session():
print("创建DB会话 → 类似Spring的@Bean")
yield session # 通过yield实现资源清理
print("关闭DB会话")
@app.get("/users")
def get_users(db = Depends(get_db_session)):
return db.query(User).all()
类似于SpringBoot
@RestController
public class UserController {
private final UserRepository repo; // 构造器注入
public UserController(UserRepository repo) {
this.repo = repo;
}
@GetMapping("/users")
public List<User> getUsers() {
return repo.findAll();
}
}
@Repository // 自动装配
public interface UserRepository extends JpaRepository<User, Long> {}
核心差异:
特性 | FastAPI | Spring Boot |
---|---|---|
作用域 | 函数级控制 | 完整的Bean作用域 |
生命周期 | 显式yield管理 | 容器自动管理 |
配置复杂度 | 低(Python动态特性) | 高(需学习Spring生态) |
AOP支持 | 有限(通过中间件) | 完善(@Aspect等) |
4 类方法和静态方法
4.1 @classmethod
使用装饰器 @classmethod装饰的类和Java中的静态方法一样,可以直接通过类名调用。
不同的是@classmethod装饰的方法有默认入参cls。
class Validator:
@classmethod
def validate_email(cls, email: str) -> bool:
return "@" in email # cls可访问类属性
# 直接类调用 → 类似Java静态方法
Validator.validate_email("test@ex.com")
Java等效如下:
public class Validator {
public static boolean validateEmail(String email) {
return email.contains("@");
}
}
关键区别:Python的类方法自动获取cls
参数,可访问类状态,而Java静态方法无this/cls概念。