当前位置: 首页 > news >正文

FastAPI 的依赖注入与生命周期管理深度解析

FastAPI 的依赖注入与生命周期管理深度解析

目录

  1. 🔧 依赖注入与 FastAPI 高级特性

    • 1.1 依赖注入的基础与核心概念
    • 1.2 FastAPI 的依赖注入机制与设计理念
    • 1.3 FastAPI 依赖注入的异步特性
  2. 🕹 生命周期与依赖的异步管理

    • 2.1 依赖的生命周期管理:数据库连接与缓存
    • 2.2 利用 FastAPI 的异步特性优化依赖注入性能
  3. 🌐 FastAPI 中的高效依赖管理与性能优化

    • 3.1 如何使用背景任务进行依赖管理
    • 3.2 依赖注入与多线程、多进程应用场景
  4. 🏗 实际项目中的依赖注入应用场景

    • 4.1 在微服务架构中使用 FastAPI 的依赖注入
    • 4.2 集成外部服务与第三方库的依赖管理

2. 🕹 生命周期与依赖的异步管理

2.1 依赖的生命周期管理:数据库连接与缓存

在 FastAPI 中,依赖注入(Dependency Injection)是一个强大的特性,允许开发者在 API 端点中自动管理和注入复杂的依赖。依赖注入不仅限于基本的功能,还可以帮助开发者更高效地管理资源的生命周期,尤其是在涉及数据库连接、缓存、外部服务等情况下。通过合理的生命周期管理,开发者能够确保系统资源的高效使用,避免重复创建和销毁资源的性能问题。

依赖注入的生命周期

FastAPI 提供了一种灵活的依赖管理方式,支持两种主要的生命周期管理方式:

  1. 请求级别依赖:每次请求创建新的依赖对象,适用于如数据库连接、用户认证等在每个请求中都有不同状态的依赖。
  2. 应用级别依赖:整个应用生命周期内共享的依赖,适用于如缓存实例、连接池等跨多个请求复用的资源。

在 FastAPI 中,开发者可以通过 Depends 来定义依赖。以下是一个数据库连接生命周期的例子,演示了如何管理数据库连接:

from fastapi import FastAPI, Depends
from sqlalchemy import create_engine
from sqlalchemy.orm import sessionmaker
from contextlib import contextmanager# 创建数据库引擎和会话
SQLALCHEMY_DATABASE_URL = "sqlite:///./test.db"
engine = create_engine(SQLALCHEMY_DATABASE_URL)
SessionLocal = sessionmaker(autocommit=False, autoflush=False, bind=engine)# 使用 contextmanager 管理会话的生命周期
@contextmanager
def get_db():db = SessionLocal()try:yield dbfinally:db.close()# 创建 FastAPI 应用
app = FastAPI()# 定义数据库依赖
def get_database(db: Session = Depends(get_db)):return db@app.get("/users/")
def read_users(db: Session = Depends(get_database)):# 使用 db 进行数据库操作return {"msg": "Fetching user data..."}

在上述代码中,get_db 函数利用 contextmanager 来管理数据库会话的生命周期。每次请求时,FastAPI 会自动调用 get_db 来创建一个新的数据库会话,并在请求结束后自动关闭该会话。这种方式确保了每个请求都能使用独立的数据库连接,并且避免了连接泄漏或过度占用数据库资源。

数据库连接池

对于高并发应用来说,创建和销毁数据库连接可能会成为性能瓶颈,因此数据库连接池通常会被用来重用现有的连接,从而提高应用的性能。FastAPI 与 SQLAlchemy 等库紧密集成,支持使用连接池。通过 SQLAlchemy 的连接池,开发者可以管理连接的复用和生命周期。

from sqlalchemy import create_engine
from sqlalchemy.orm import sessionmaker# 创建数据库引擎,使用连接池
SQLALCHEMY_DATABASE_URL = "postgresql://user:password@localhost/testdb"
engine = create_engine(SQLALCHEMY_DATABASE_URL, pool_size=10, max_overflow=20)
SessionLocal = sessionmaker(autocommit=False, autoflush=False, bind=engine)

在这个示例中,engine 配置了数据库连接池。pool_size 定义了池中保持的连接数,max_overflow 控制了池的最大溢出连接数。当请求到来时,FastAPI 会自动从连接池中获取一个连接,并在请求处理完成后将连接归还池中。

缓存管理

缓存是提升应用性能的另一个关键部分。在 FastAPI 中,依赖注入可以用于管理缓存生命周期。例如,可以使用 Redis 来缓存某些频繁访问的数据。以下代码展示了如何通过依赖注入管理 Redis 缓存的生命周期:

import redis
from fastapi import FastAPI, Dependsapp = FastAPI()# 创建 Redis 客户端
def get_cache():cache = redis.StrictRedis(host='localhost', port=6379, db=0)try:yield cachefinally:pass  # Redis 客户端通常无需显式关闭# 依赖注入 Redis 客户端
def get_cached_data(cache: redis.StrictRedis = Depends(get_cache)):return cache.get('some_key')@app.get("/cache/")
def read_cache(cached_data: bytes = Depends(get_cached_data)):return {"cached_data": cached_data.decode() if cached_data else "No data found"}

在此示例中,get_cache 函数通过依赖注入提供了 Redis 客户端。每次请求到来时,FastAPI 会自动提供一个新的 Redis 客户端实例。虽然在此简单示例中没有显式关闭 Redis 客户端,但在实际应用中,可以根据需要添加更多的资源清理逻辑。

2.2 利用 FastAPI 的异步特性优化依赖注入性能

FastAPI 具有对异步编程的良好支持,可以帮助开发者在 I/O 密集型应用中优化性能。通过异步的方式管理依赖的生命周期,可以显著提高应用的响应速度和吞吐量。尤其是在数据库访问、缓存操作或网络请求等场景中,异步能够最大化利用系统资源,提高并发处理能力。

异步数据库操作

FastAPI 的异步特性与数据库连接的异步操作相结合,可以帮助开发者优化数据库访问的性能。例如,使用 asyncpgdatabases 等库,FastAPI 可以在数据库查询时异步执行,避免阻塞主线程。

import databases
from fastapi import FastAPI, Depends# 创建数据库连接
DATABASE_URL = "postgresql://user:password@localhost/testdb"
database = databases.Database(DATABASE_URL)# 创建 FastAPI 应用
app = FastAPI()# 异步获取数据
async def get_data_from_db():query = "SELECT * FROM users"result = await database.fetch_all(query)return result@app.get("/users/")
async def read_users(data: list = Depends(get_data_from_db)):return {"users": data}

在这个例子中,get_data_from_db 函数通过异步方式访问数据库,避免了传统阻塞的 I/O 操作。database.fetch_all(query) 是异步执行的,这样在处理数据库查询时,FastAPI 可以处理更多的请求,提高系统的并发能力。

异步缓存操作

类似于数据库操作,FastAPI 也能够与异步缓存(如 Redis)结合,进行高效的缓存管理。例如,使用 aioredis 来管理 Redis 的异步操作,可以确保在高并发情况下依赖注入的性能得到最大化提升。

import aioredis
from fastapi import FastAPI, Dependsapp = FastAPI()# 异步创建 Redis 客户端
async def get_cache():cache = await aioredis.create_redis_pool('redis://localhost')return cache# 依赖注入 Redis 客户端
async def get_cached_data(cache: aioredis.Redis = Depends(get_cache)):cached_data = await cache.get('some_key')return cached_data@app.get("/cache/")
async def read_cache(cached_data: bytes = Depends(get_cached_data)):return {"cached_data": cached_data.decode() if cached_data else "No data found"}

在这个示例中,get_cacheget_cached_data 都是异步函数,它们能够高效地与 Redis 进行交互。通过使用异步缓存,系统可以处理更多的请求,避免了阻塞操作。

异步任务和背景任务

FastAPI 还支持背景任务,通过 BackgroundTasks 进行异步处理。对于需要长时间执行的任务(如数据处理、发送电子邮件等),可以将这些操作放入后台执行,避免阻塞主请求流程,提高用户体验。

from fastapi import FastAPI,BackgroundTasksapp = FastAPI()# 异步背景任务
def send_email(email: str):print(f"Sending email to {email}...")@app.post("/send-email/")
async def send_email_task(background_tasks: BackgroundTasks, email: str):background_tasks.add_task(send_email, email)return {"message": "Email sent in the background"}

在这个示例中,send_email 函数被添加到后台任务队列中执行,这样请求本身就不需要等待邮件发送完成,用户可以快速得到响应。

相关文章:

FastAPI 的依赖注入与生命周期管理深度解析

FastAPI 的依赖注入与生命周期管理深度解析 目录 🔧 依赖注入与 FastAPI 高级特性 1.1 依赖注入的基础与核心概念1.2 FastAPI 的依赖注入机制与设计理念1.3 FastAPI 依赖注入的异步特性 🕹 生命周期与依赖的异步管理 2.1 依赖的生命周期管理&#xff1…...

【express-generator】05-路由中间件和错误处理(第一阶段收尾)

一、前言 上篇文章我们介绍了express-generator的请求体解析,重点讲了常用的请求体数据格式(JSON/URL 编码的表单数据)以及一个FILE文件上传,同时搭配代码示范进行辅助理解。 二、本篇重点 我们继续第一阶段的知识,…...

Linux环境下确认并操作 Git 仓库

在软件开发和版本控制中,Git 已成为不可或缺的工具。有时,我们需要确认某个目录是否是一个 Git 仓库,并在该目录中运行脚本。本文将详细介绍如何确认 /usr/local/src/zcxt/backend/policy-system-backend 目录是否是一个 Git 仓库&#xff0c…...

UDP -- 简易聊天室

目录 gitee(内有详细代码) 图解 MessageRoute.hpp UdpClient.hpp UdpServer.hpp Main.hpp 运行结果(本地通信) 如何分开对话显示? gitee(内有详细代码) chat_room zihuixie/Linux_Lear…...

NVIDIA在CES 2025上的三大亮点:AI芯片、机器人与自动驾驶、全新游戏显卡

每周跟踪AI热点新闻动向和震撼发展 想要探索生成式人工智能的前沿进展吗?订阅我们的简报,深入解析最新的技术突破、实际应用案例和未来的趋势。与全球数同行一同,从行业内部的深度分析和实用指南中受益。不要错过这个机会,成为AI领…...

【通俗理解】AI的两次寒冬:从感知机困局到深度学习前夜

AI的两次寒冬:从感知机困局到深度学习前夜 引用(中英双语) 中文: “第一次AI寒冬,是因为感知机局限性被揭示,让人们失去了对算法可行性的信心。” “第二次AI寒冬,则是因为专家系统的局限性和硬…...

transformer深度学习实战CCTSDB中国交通标志识别

本文采用RT-DETR作为核心算法框架,结合PyQt5构建用户界面,使用Python3进行开发。RT-DETR以其高效的实时检测能力,在多个目标检测任务中展现出卓越性能。本研究针对CCTSDB交通标志数据集进行训练和优化,该数据集包含丰富的CCTSDB交…...

JavaWeb开发(六)XML介绍

1. XML介绍 1.1. 什么是XML (1)XML 指可扩展标记语言(EXtensible Markup Language)XML 是一种很像HTML的标记语言。   (2)XML 的设计宗旨是传输数据(目前主要是作为配置文件),而不是显示数据。   (3&a…...

使用pbootcms开发一个企业官网

V:llike620 pbootcms开源PHP建站系统 https://www.pbootcms.com/ 配置网站 域名解析后,网站绑定到程序根目录即可 例如:本地域名是dobot.test ,那么也要同步本地的hosts是 127.0.0.1 dobot.test 需要配置下伪静态规则 location / {if (!-e $r…...

Linux C编程——文件IO基础

文件IO基础 一、简单的文件 IO 示例二、文件描述符三、open 打开文件1. 函数原型2. 文件权限3. 宏定义文件权限4. 函数使用实例 四、write 写文件五、read 读文件六、close 关闭文件七、Iseek 绍 Linux 应用编程中最基础的知识,即文件 I/O(Input、Outout…...

【信息系统项目管理师】高分论文:论信息系统项目的风险管理(人民医院的信息系统)

更多内容请见: 备考信息系统项目管理师-专栏介绍和目录 文章目录 论文1、规划风险管理2、项目风险识别3、风险定性分析4、风险定量分析5、制定风险应对6、实施风险应对计划7、监督风险论文 2022年6月,我作为项目经理承担了XX县人民医院的信息系统建设,该项目总投资300万,其…...

UE播放声音

蓝图中有两个播放声音的函数 Play Sound 2D 和 Play Sound at Location Play Sound 2D没有声音距离衰减,一般用于界面ui Play Sound at Location 有声音距离衰减,一般用于枪声,场景声等,比较常用...

Docker Compose 启动 Harbor 并指定网络

1. 介绍 Harbor 是一个开源的企业级 Docker 镜像仓库,提供镜像存储、访问控制、安全扫描等功能。使用 Docker Compose 启动 Harbor 时,您可以指定一个自定义网络,以便管理容器之间的网络通信。在本示例中,我们将创建一个名为 har…...

WebSocket 实战案例:从设计到部署

在前六篇文章中,我们深入探讨了 WebSocket 的基础原理、服务端开发、客户端实现、安全实践、性能优化和测试调试。今天,让我们通过一个实战案例,看看如何将这些知识应用到实际项目中。我曾在一个大型在线教育平台中,通过 WebSocket 实现了实时互动课堂,支持了数万名师生的同时在…...

selenium合集

环境搭建步骤 安装selenium pip install selenium 安装浏览器 安装浏览器驱动 谷歌浏览器:chromdriver.exe ie浏览器:ieserverdriver.exe FireFox浏览器:geckodriver.exe 特别注意⚠️:下载驱动版本必须与浏览器版本一致 下载地址 淘宝镜像&#xff1…...

JVM生产环境常用参数配置及调优建议

一、生产常用参数配置 JAVA_OPTS"-server -Xms3000m -Xmx3000m -Xmn1500m -XX:UseG1GC -XX:ConcGCThreads8 -XX:PrintGCDetails -XX:PrintGCTimeStamps -Xloggc:./g1-gc.log -XX:MaxMetaspaceSize256m -XX:-UseGCOverheadLimit -XX:UseCompressedOops -XX:HeapDumpOnOu…...

Spring Boot 3 实现 MySQL 主从数据库之间的数据同步

✅ Spring Boot 3 实现 MySQL 主从数据库之间的数据同步 在实际项目中,为了提高 系统的读性能 和 数据的可用性,通常会使用 主从数据库架构。Spring Boot 提供了对 多数据源 的良好支持,可以轻松配置 主从数据库 的数据同步,实现…...

【小程序开发】- 小程序版本迭代指南(版本发布教程)

一,版本号 版本号是小程序版本的标识,通常由一系列数字组成,如 1.0.0、1.1.0 等。版本号的格式通常是 主版本号.次版本号.修订号 主版本号:当小程序有重大更新或不兼容的更改时,主版本号会增加。 次版本号&#xff1a…...

MySQL 间隙锁避免“可重复读”出现“幻读”

在数据库事务处理中,可重复读(Repeatable Read)是一个常用的隔离级别,但其默认行为可能导致幻读现象。然而,在 MySQL 的实现中,通过 **间隙锁(Gap Lock)**机制,能够避免幻…...

揭秘区块链隐私黑科技:零知识证明如何改变未来

文章目录 1. 引言:什么是零知识证明?2. 零知识证明的核心概念与三大属性2.1 完备性(Completeness)2.2 可靠性(Soundness)2.3 零知识性(Zero-Knowledge) 3. 零知识证明的工作原理4. 零…...

使用docker在3台服务器上搭建基于redis 6.x的一主两从三台均是哨兵模式

一、环境及版本说明 如果服务器已经安装了docker,则忽略此步骤,如果没有安装,则可以按照一下方式安装: 1. 在线安装(有互联网环境): 请看我这篇文章 传送阵>> 点我查看 2. 离线安装(内网环境):请看我这篇文章 传送阵>> 点我查看 说明:假设每台服务器已…...

MMaDA: Multimodal Large Diffusion Language Models

CODE : https://github.com/Gen-Verse/MMaDA Abstract 我们介绍了一种新型的多模态扩散基础模型MMaDA,它被设计用于在文本推理、多模态理解和文本到图像生成等不同领域实现卓越的性能。该方法的特点是三个关键创新:(i) MMaDA采用统一的扩散架构&#xf…...

PL0语法,分析器实现!

简介 PL/0 是一种简单的编程语言,通常用于教学编译原理。它的语法结构清晰,功能包括常量定义、变量声明、过程(子程序)定义以及基本的控制结构(如条件语句和循环语句)。 PL/0 语法规范 PL/0 是一种教学用的小型编程语言,由 Niklaus Wirth 设计,用于展示编译原理的核…...

安宝特方案丨船舶智造的“AR+AI+作业标准化管理解决方案”(装配)

船舶制造装配管理现状:装配工作依赖人工经验,装配工人凭借长期实践积累的操作技巧完成零部件组装。企业通常制定了装配作业指导书,但在实际执行中,工人对指导书的理解和遵循程度参差不齐。 船舶装配过程中的挑战与需求 挑战 (1…...

计算机基础知识解析:从应用到架构的全面拆解

目录 前言 1、 计算机的应用领域:无处不在的数字助手 2、 计算机的进化史:从算盘到量子计算 3、计算机的分类:不止 “台式机和笔记本” 4、计算机的组件:硬件与软件的协同 4.1 硬件:五大核心部件 4.2 软件&#…...

MinIO Docker 部署:仅开放一个端口

MinIO Docker 部署:仅开放一个端口 在实际的服务器部署中,出于安全和管理的考虑,我们可能只能开放一个端口。MinIO 是一个高性能的对象存储服务,支持 Docker 部署,但默认情况下它需要两个端口:一个是 API 端口(用于存储和访问数据),另一个是控制台端口(用于管理界面…...

BLEU评分:机器翻译质量评估的黄金标准

BLEU评分:机器翻译质量评估的黄金标准 1. 引言 在自然语言处理(NLP)领域,衡量一个机器翻译模型的性能至关重要。BLEU (Bilingual Evaluation Understudy) 作为一种自动化评估指标,自2002年由IBM的Kishore Papineni等人提出以来,…...

适应性Java用于现代 API:REST、GraphQL 和事件驱动

在快速发展的软件开发领域,REST、GraphQL 和事件驱动架构等新的 API 标准对于构建可扩展、高效的系统至关重要。Java 在现代 API 方面以其在企业应用中的稳定性而闻名,不断适应这些现代范式的需求。随着不断发展的生态系统,Java 在现代 API 方…...

LangFlow技术架构分析

🔧 LangFlow 的可视化技术栈 前端节点编辑器 底层框架:基于 (一个现代化的 React 节点绘图库) 功能: 拖拽式构建 LangGraph 状态机 实时连线定义节点依赖关系 可视化调试循环和分支逻辑 与 LangGraph 的深…...

DeepSeek源码深度解析 × 华为仓颉语言编程精粹——从MoE架构到全场景开发生态

前言 在人工智能技术飞速发展的今天,深度学习与大模型技术已成为推动行业变革的核心驱动力,而高效、灵活的开发工具与编程语言则为技术创新提供了重要支撑。本书以两大前沿技术领域为核心,系统性地呈现了两部深度技术著作的精华:…...