竹简文档
上下文

概述

上下文管理机制,基于标准 context.Context 实现框架解耦

上下文管理

Bamboo Base 提供了完整的上下文管理机制,基于标准 context.Context 实现框架解耦

相关包

别名说明
.../contextxCtx上下文键常量定义
.../utility/ctxutilxCtxUtil上下文工具函数
.../helperxHelper上下文中间件
.../register/nodexRegNode节点化注册系统

工作原理

上下文数据流

初始化流程
// 1. Register 创建节点管理器
xReg.Register(ctx, nodeList)

    ├── configInit()           // 私有:加载配置
    ├── loggerInit()           // 私有:初始化日志

    // 2. 内置节点注入雪花算法
    ├── SnowflakeNodeKey → *xSnowflake.Node

    // 3. 自定义节点注入业务资源
    ├── DatabaseKey      → *gorm.DB
    ├── RedisClientKey   → *redis.Client

    // 4. 引擎初始化,注入上下文到请求
    └── engineInit()
            └── injectContext(ctx)
请求流程
// 5. RequestContext 中间件注入请求级数据
xHelper.RequestContext()
    ├── RequestKey       → UUID 请求标识
    └── UserStartTimeKey → 请求开始时间

快速使用

import (
    xCtxUtil "github.com/bamboo-services/bamboo-base-go/common/utility/context"
)

func MyHandler(c *gin.Context) {
    // 获取标准上下文
    ctx := c.Request.Context()

    // 获取数据库连接(Panic 版本)
    db := xCtxUtil.MustGetDB(ctx)

    // 获取数据库连接(错误返回版本)
    db, err := xCtxUtil.GetDB(ctx)

    // 获取 Redis 客户端
    rdb := xCtxUtil.MustGetRDB(ctx)

    // 生成雪花 ID
    id := xCtxUtil.MustGenerateSnowflakeID(ctx)

    // 获取请求 ID
    requestID := xCtxUtil.GetRequestKey(ctx)
}

上下文节点

ContextNode 用于在初始化阶段保存上下文中的资源条目,配合 ContextNodeList 形成有序的键值链式列表。

import xCtx "github.com/bamboo-services/bamboo-base-go/defined/context"

ContextNode 结构

type ContextNode struct {
    Key   xCtx.ContextKey
    Value any
}
  • Key:上下文键,用于标识资源类型
  • Value:资源实例,支持任意类型

ContextNodeList 结构

type ContextNodeList []ContextNode

func NewCtxNodeList() ContextNodeList
func (c ContextNodeList) GetList() []ContextNode
func (c ContextNodeList) Get(key ContextKey) any
func (c *ContextNodeList) Append(key ContextKey, value any)

常用能力:

  • Get:按键读取已注入资源
  • Append:追加新的资源节点
  • GetList:按顺序获取完整节点列表

使用示例

register.go
nodeList := xCtx.NewCtxNodeList()
nodeList.Append(xCtx.DatabaseKey, initDatabase())
nodeList.Append(xCtx.RedisClientKey, initRedis())

reg := xReg.Register(ctx, []xRegNode.RegNodeList{
    {Key: xCtx.RegNodeKey, Node: func(ctx context.Context) (any, error) {
        return nodeList, nil
    }},
})

注入上下文

方式一:节点化注入(推荐)

Register 时通过自定义节点注入:

main.go
import (
    "context"
    xCtx "github.com/bamboo-services/bamboo-base-go/defined/context"
    xReg "github.com/bamboo-services/bamboo-base-go/major/register"
    xRegNode "github.com/bamboo-services/bamboo-base-go/major/register/node"
)

func main() {
    reg := xReg.Register(context.Background(), []xRegNode.RegNodeList{
        {Key: xCtx.DatabaseKey, Node: initDatabase},
        {Key: xCtx.RedisClientKey, Node: initRedis},
    })

    reg.Serve.Run(":8080")
}

// 数据库初始化节点
func initDatabase(ctx context.Context) (any, error) {
    db, err := gorm.Open(...)
    return db, err
}

// Redis 初始化节点
func initRedis(ctx context.Context) (any, error) {
    rdb := redis.NewClient(...)
    return rdb, nil
}

方式二:中间件注入

在业务中间件中注入(适用于请求级资源):

middleware.go
func InjectUserMiddleware() gin.HandlerFunc {
    return func(c *gin.Context) {
        // 获取用户信息...
        user := getUserFromToken(c)

        // 注入到 Gin 上下文
        c.Set("user", user)

        c.Next()
    }
}

框架解耦

新版本的核心改进是框架解耦

方面旧设计新设计
工具函数参数*gin.Contextcontext.Context
资源注入Gin 中间件节点化系统
上下文传递c.Set() / c.Get()context.WithValue()
业务代码依赖 Gin可独立测试

优势:

  • ✅ 业务逻辑不再依赖 Gin 框架
  • ✅ 更容易编写单元测试
  • ✅ 支持在非 HTTP 场景使用(如定时任务、消息队列)

下一步

On this page