🎬 HoRain云小助手个人主页

 🔥 个人专栏: 《Linux 系列教程》《c语言教程

⛺️生活的理想,就是为了理想的生活!


⛳️ 推荐

前些天发现了一个超棒的服务器购买网站,性价比超高,大内存超划算!忍不住分享一下给大家。点击跳转到网站。

专栏介绍

专栏名称

专栏介绍

《C语言》

本专栏主要撰写C干货内容和编程技巧,让大家从底层了解C,把更多的知识由抽象到简单通俗易懂。

《网络协议》

本专栏主要是注重从底层来给大家一步步剖析网络协议的奥秘,一起解密网络协议在运行中协议的基本运行机制!

《docker容器精解篇》

全面深入解析 docker 容器,从基础到进阶,涵盖原理、操作、实践案例,助您精通 docker。

《linux系列》

本专栏主要撰写Linux干货内容,从基础到进阶,知识由抽象到简单通俗易懂,帮你从新手小白到扫地僧。

《python 系列》

本专栏着重撰写Python相关的干货内容与编程技巧,助力大家从底层去认识Python,将更多复杂的知识由抽象转化为简单易懂的内容。

《试题库》

本专栏主要是发布一些考试和练习题库(涵盖软考、HCIE、HRCE、CCNA等)

目录

⛳️ 推荐

专栏介绍

一、核心概念与作用

1. 依赖注入的本质

2. 核心优势

二、基本用法

1. 函数依赖(最常用)

场景:通用逻辑复用(如分页参数、认证校验)

2. 类依赖(面向对象)

场景:需维护状态或配置参数(如带角色校验的认证器)

三、依赖作用域与生命周期

1. 请求级作用域(默认)

2. 应用级作用域(单例)

3. 作用域选择原则

四、典型应用场景

1. 认证与权限控制

2. 数据库会话管理

3. 缓存与性能优化

五、依赖注入 vs 中间件

六、最佳实践


img

FastAPI 的依赖注入系统通过 Depends() 声明所需资源,由框架自动执行依赖逻辑并将结果注入路由函数,核心价值在于 实现代码复用、逻辑解耦与测试友好性。它允许开发者将横切关注点(如认证、数据库连接)抽象为可复用组件,避免重复代码,同时保持业务逻辑的清晰聚焦。


一、核心概念与作用

1. 依赖注入的本质

  • 声明式编程:开发者只需声明“需要什么”(如 user: User = Depends(get_current_user)),框架自动处理“如何获取”。
  • 解耦关键:业务逻辑 不关心依赖的创建过程,仅关注使用结果,符合“我需要什么,你给我什么,我不关心怎么创建的”原则。

2. 核心优势

  • 代码复用:避免在多个路由中重复编写相同逻辑(如分页参数、认证校验)。
  • 逻辑解耦:业务代码与基础设施(数据库、认证)分离,单一职责更明确
  • 测试友好:可轻松替换依赖为模拟对象(Mock),无需修改业务逻辑即可完成单元测试。

二、基本用法

1. 函数依赖(最常用)

场景:通用逻辑复用(如分页参数、认证校验)
from fastapi import Depends, Query

# 1. 定义依赖函数
async def common_params(
    skip: int = Query(0, ge=0),
    limit: int = Query(10, le=100)
):
    return {"skip": skip, "limit": limit}

# 2. 在路由中注入
@app.get("/items")
async def read_items(params: dict = Depends(common_params)):
    return {"data": "示例数据", **params}  # 直接使用依赖返回值
  • 关键点:依赖函数的参数(如 skiplimit)会 自动从请求中解析(Query/Path/Header 等)。

2. 类依赖(面向对象)

场景:需维护状态或配置参数(如带角色校验的认证器)
class RoleChecker:
    def __init__(self, allowed_roles: list):
        self.allowed_roles = allowed_roles  # 可配置参数
    
    def __call__(self, user: User = Depends(get_current_user)):
        if user.role not in self.allowed_roles:
            raise HTTPException(403, "权限不足")
        return user

# 使用:注入时传入配置
admin_required = RoleChecker(["admin"])
@app.get("/admin", dependencies=[Depends(admin_required)])
async def admin_dashboard():
    return {"message": "管理员页面"}
  • 关键点:通过 __call__ 使类实例可调用,支持初始化参数,适合复杂逻辑。

三、依赖作用域与生命周期

1. 请求级作用域(默认)

  • 每个请求创建新实例,请求结束自动清理(如数据库会话)。
  • 推荐用 yield 管理资源
    async def get_db():
        db = DatabaseSession()
        try:
            yield db  # 注入到路由函数
        finally:
            db.close()  # 请求结束自动执行
    

2. 应用级作用域(单例)

  • 整个应用生命周期内仅初始化一次,适合昂贵资源(如缓存客户端)。
  • 通过 lifespan 或模块级变量实现
    from contextlib import asynccontextmanager
    
    @asynccontextmanager
    async def lifespan(app: FastAPI):
        app.state.redis = await create_redis_pool()  # 启动时初始化
        yield
        await app.state.redis.close()  # 关闭时清理
    
    app = FastAPI(lifespan=lifespan)
    

3. 作用域选择原则

  • 无状态服务(如配置读取):应用级作用域。
  • 需清理的资源(如数据库连接):请求级作用域 + yield
  • 避免全局变量:依赖注入 天然线程安全,比全局变量更可靠。

四、典型应用场景

1. 认证与权限控制

  • 将用户身份验证抽象为依赖,全局或按路由组注入
    # 全局启用认证
    app = FastAPI(dependencies=[Depends(verify_token)])
    
    # 路由组级认证
    admin_router = APIRouter(dependencies=[Depends(require_admin)])
    

2. 数据库会话管理

  • 统一管理连接生命周期,避免手动开闭:
    @app.get("/users")
    async def get_users(db: Session = Depends(get_db)):
        return db.query(User).all()  # 无需关心连接创建/关闭
    

3. 缓存与性能优化

  • 结合 lru_cache 避免重复计算
    from functools import lru_cache
    
    @lru_cache(maxsize=1)
    def get_settings():
        return Settings()  # 仅加载一次配置
    

五、依赖注入 vs 中间件

特性 依赖注入 中间件
作用范围 精细化控制(单路由/路由组/全局) 全局生效(所有请求)
灵活性 高(可按需声明) 低(统一处理)
适用场景 局部通用逻辑(如特定路由的认证) 全局逻辑(如日志、CORS)
参数传递 可向路由函数注入数据 仅能修改请求/响应对象

简单总结

  • 所有接口都需要的逻辑用中间件(如统一日志)。
  • 部分接口需要的逻辑用依赖注入(如仅管理员路由需角色校验)。

六、最佳实践

  1. 单一职责:每个依赖 只做一件事(如仅处理认证,不混入日志)。
  2. 清晰命名:用 get_current_userrequire_admin 等见名知意的名称。
  3. 避免副作用:依赖尽量是“纯”的,不修改全局状态
  4. 测试覆盖:为关键依赖编写单元测试,确保其行为独立可靠

依赖注入不仅是传参工具,更是 架构设计的基石。通过合理抽象依赖,可显著提升代码的可维护性、可测试性与团队协作效率。

❤️❤️❤️本人水平有限,如有纰漏,欢迎各位大佬评论批评指正!😄😄😄

💘💘💘如果觉得这篇文对你有帮助的话,也请给个点赞、收藏下吧,非常感谢!👍 👍 👍

🔥🔥🔥Stay Hungry Stay Foolish 道阻且长,行则将至,让我们一起加油吧!🌙🌙🌙

Logo

AtomGit 是由开放原子开源基金会联合 CSDN 等生态伙伴共同推出的新一代开源与人工智能协作平台。平台坚持“开放、中立、公益”的理念,把代码托管、模型共享、数据集托管、智能体开发体验和算力服务整合在一起,为开发者提供从开发、训练到部署的一站式体验。

更多推荐