FastAPI 中 lifespan 的用法详解
摘要本文系统讲解 FastAPI 中lifespan的用法介绍其作为异步上下文管理器在应用启动和关闭时管理资源生命周期的机制并通过数据库连接池、机器学习模型加载、app.state共享资源等实战示例展示如何编写清晰的启动与清理逻辑最后对比已废弃的on_event说明lifespan是官方推荐的现代方案。1. 引言在 FastAPI 中lifespan是管理应用启动和关闭时资源生命周期的重要机制。它取代了早期版本中已废弃的on_event方式提供了更清晰、更可控的异步上下文管理方案。本文将从基本概念、实际用法到常见场景系统讲解 FastAPI 中lifespan的用法。2. 什么是 lifespanlifespan是 FastAPI 提供的一个异步上下文管理器用于在应用启动时执行初始化逻辑如建立数据库连接、加载模型并在应用关闭时执行清理逻辑如关闭连接、释放资源。它通过asynccontextmanager实现代码结构清晰异常处理也更可靠。3. 基本用法使用lifespan需要从contextlib导入asynccontextmanager然后定义一个异步生成器函数在yield之前是启动逻辑yield之后是关闭逻辑。最后将lifespan传给FastAPI实例。from contextlib import asynccontextmanager from fastapi import FastAPI asynccontextmanager async def lifespan(app: FastAPI): # 启动时执行 print(应用启动中...) yield # 关闭时执行 print(应用关闭中...) app FastAPI(lifespanlifespan)4. 在 lifespan 中管理数据库连接最常见的场景是在应用启动时建立数据库连接池并在关闭时释放。下面以 SQLAlchemy 异步引擎为例。from contextlib import asynccontextmanager from fastapi import FastAPI from sqlalchemy.ext.asyncio import create_async_engine, AsyncSession from sqlalchemy.orm import sessionmaker DATABASE_URL sqliteaiosqlite:///./test.db engine None SessionLocal None asynccontextmanager async def lifespan(app: FastAPI): global engine, SessionLocal engine create_async_engine(DATABASE_URL) SessionLocal sessionmaker(engine, class_AsyncSession, expire_on_commitFalse) print(数据库连接池已创建) yield await engine.dispose() print(数据库连接池已释放) app FastAPI(lifespanlifespan)5. 在 lifespan 中加载机器学习模型对于机器学习服务通常需要在启动时加载模型避免每次请求都重复加载。可以将模型实例存储在应用状态中供路由处理函数使用。from contextlib import asynccontextmanager from fastapi import FastAPI model None asynccontextmanager async def lifespan(app: FastAPI): global model # 模拟加载模型 model {name: my_model, version: 1.0} print(模型加载完成) yield model None print(模型已释放) app FastAPI(lifespanlifespan) app.get(/predict) async def predict(): if model is None: return {error: 模型未加载} return {model: model[name], version: model[version]}6. 使用 app.state 共享资源更推荐的做法是将资源挂载到app.state上这样在路由中可以通过request.app.state访问避免使用全局变量。from contextlib import asynccontextmanager from fastapi import FastAPI, Request asynccontextmanager async def lifespan(app: FastAPI): # 启动时初始化 app.state.db_pool {size: 10, status: ready} app.state.model {name: bert, version: 2.0} print(资源初始化完成) yield # 关闭时清理 app.state.db_pool None app.state.model None print(资源清理完成) app FastAPI(lifespanlifespan) app.get(/status) async def status(request: Request): return { db: request.app.state.db_pool, model: request.app.state.model }7. lifespan 与 on_event 的对比早期 FastAPI 使用on_event(startup)和on_event(shutdown)处理启动和关闭逻辑但这种方式存在一些问题事件处理函数之间没有明确的执行顺序保证且难以共享状态。而lifespan通过单个异步上下文管理器统一管理执行顺序明确代码更简洁也更符合 Python 的异步编程习惯。对比项on_eventlifespan执行顺序不保证明确yield 前后状态共享依赖全局变量可通过 app.state异常处理较繁琐上下文管理器自动处理推荐程度已废弃官方推荐8. 总结lifespan是 FastAPI 管理应用生命周期的推荐方式适用于数据库连接、模型加载、缓存初始化等场景。通过asynccontextmanager定义启动和关闭逻辑配合app.state共享资源可以让代码更清晰、更易维护。建议新项目直接使用lifespan避免使用已废弃的on_event。