成人免费xxxxx在线视频软件_久久精品久久久_亚洲国产精品久久久_天天色天天色_亚洲人成一区_欧美一级欧美三级在线观看

GoFrame 如何優雅的共享變量?Context的使用

開發 后端
今天就為大家介紹一下Context的使用:告訴大家Context是什么?怎么用?為什么要用Context以及使用中的小技巧和注意問題。

前言

昨天merge代碼,發現了好多沖突,原因是同事在review項目,做鏈路追蹤,發現老項目有不少方法傳參不規范,沒有傳入Context,不方便做鏈路追蹤。

所以把這些方法和調用進行了修改,導致了大量沖突,修復沖突又花了好長時間

所以:傳參規范還是要在項目啟動時就確定好呀,一定要搞清楚Context怎么用呀!

今天就為大家介紹一下Context的使用:

告訴大家Context是什么?怎么用?為什么要用Context以及使用中的小技巧和注意問題。

Context是什么?

Context?指的是標準庫的context.Context?,是一個接口對象,常用于異步IO控制以及上下文流程變量的傳遞。

本文將要介紹的是Context如何優雅的在業務流程中進行變量的傳遞,以及為什么需要要進行變量的傳遞。

為什么需要Context?

在Go?的執行流程中,特別是HTTP/RPC?執行流程中,沒有通過”全局變量”獲取請求參數的方式,只能通過上下文Context變量,傳遞到后續執行流程的方法中。

如何使用?

Context上下文變量,包含了所有需要傳遞的共享變量。

并且Context中的共享變量是需要事先約定的,并且往往存儲為對象指針形式。

通過Context上下文,共享變量非常簡單,下面通過示例帶大家了解一下如何傳遞和使用通用的共享變量。

一、結構定義

上下文對象中往往存儲一些需要共享的變量,這些變量通常使用結構化的對象來存儲,以方便維護。

例如,我們在model定義一個上下文中的共享變量:

const (
// 上下文變量存儲鍵名,前后端系統共享
ContextKey = "ContextKey"
)

// 請求上下文結構
type Context struct {
Session *ghttp.Session // 當前Session管理對象
User *ContextUser // 上下文用戶信息
Data g.Map // 自定KV變量,業務模塊根據需要設置,不固定
}

// 請求上下文中的用戶信息
type ContextUser struct {
Id uint // 用戶ID
Passport string // 用戶賬號
Nickname string // 用戶名稱
Avatar string // 用戶頭像
}

介紹

  • model.ContextKey?常量表示存儲在context.Context?上下文變量中的鍵名,該鍵名用于從傳遞的context.Context變量中存儲/獲取業務自定義的共享變量。
  • model.Context?結構體中的Session?表示當前請求的Session?對象,在GoFrame?框架中每個HTTP?請求對象中都會有一個空的Session對象,該對象采用了懶初始化設計,只有在真正執行讀寫操作時才會初始化。
  • model.Context?結構體中的User?表示當前登錄的用戶基本信息,只有在用戶登錄后才有數據,否則是nil。
  • model.Context?結構體中的Data?,用于存儲自定義的KV?變量,因此一般來說開發者無需再往context.Context?上下文變量中增加自定義的鍵值對,而是直接使用model.Context?對象的這個Data屬性即可。

二、邏輯封裝

由于該上下文對象也是和業務邏輯相關的,因此我們需要通過service對象將上下文變量封裝起來以方便其他模塊使用。

// 上下文管理服務
var Context = new(contextService)

type contextService struct{}

// 初始化上下文對象指針到上下文對象中,以便后續的請求流程中可以修改。
func (s *contextService) Init(r *ghttp.Request, customCtx *model.Context) {
r.SetCtxVar(model.ContextKey, customCtx)
}

// 獲得上下文變量,如果沒有設置,那么返回nil
func (s *contextService) Get(ctx context.Context) *model.Context {
value := ctx.Value(model.ContextKey)
if value == nil {
return nil
}
if localCtx, ok := value.(*model.Context); ok {
return localCtx
}
return nil
}

// 將上下文信息設置到上下文請求中,注意是完整覆蓋
func (s *contextService) SetUser(ctx context.Context, ctxUser *model.ContextUser) {
s.Get(ctx).User = ctxUser
}

Tips

在架構設計中,在哪個場景下設置Context是非常關鍵的。

上下文的變量必須在請求一開始便注入到請求流程中,以便于其他方法調用,所以在中間件中來實現是非常優雅的選擇。

我們來看下面的介紹:

三、上下文變量注入

在HTTP?請求中我們可以使用GoFrame的中間件來實現。

在GRPC請求中我們也可以使用攔截器來實現。

在service?層的middleware管理對象中,我們可以這樣來定義:

// 自定義上下文對象
func (s *middlewareService) Ctx(r *ghttp.Request) {
// 初始化,務必最開始執行
customCtx := &model.Context{
Session: r.Session,
Data: make(g.Map),
}
service.Context.Init(r, customCtx)
if userEntity := Session.GetUser(r.Context()); userEntity != nil {
customCtx.User = &model.ContextUser{
Id: userEntity.Id,
Passport: userEntity.Passport,
Nickname: userEntity.Nickname,
Avatar: userEntity.Avatar,
}
}
// 將自定義的上下文對象傳遞到模板變量中使用
r.Assigns(g.Map{
"Context": customCtx,
})
// 執行下一步請求邏輯
r.Middleware.Next()
}

這個中間件,初始化了用戶執行流程 共享的對象,并且存儲到context.Context?變量中的對象是指針類型*model.Context。

這樣做的好處是:任何一個地方獲取到這個指針,不僅可以獲取到里面的數據,而且能夠直接修改里面的數據。

TIPS

如果Session?中存在用戶登錄后的存儲信息,那么也會將需要共享的用戶基本信息寫入到*model.Context中。

四、上下文變量使用

方法定義

方法定義的第一個輸入參數往往預留給context.Context?類型參數使用,以便接受上下文變量,特別是service層的方法。

例如:

// 執行用戶登錄
func (s *userService) Login(ctx context.Context, loginReq *define.UserServiceLoginReq) error {
...
}

// 查詢內容列表
func (s *contentService) GetList(ctx context.Context, r *define.ContentServiceGetListReq) (*define.ContentServiceGetListRes, error) {
...
}

// 創建回復內容
func (s *replyService) Create(ctx context.Context, r *define.ReplyServiceCreateReq) error {
...
}

TIPS

另外一個好習慣是:方法的最后一個返回參數往往是error?類型。如果確定方法內部永不會產生error,那么可以忽略。

?Context??對象獲取

通過service?中封裝的以下方法,將context.Context上下文變量傳遞進去即可。

context.Context?上下文變量在GoFrame?框架的HTTP?請求中可以通過r.Context()方法獲取。

在GRPC?請求中,編譯生成的pb?文件中執行方法的第一個參數即固定是context.Context。

service.Context.Get(ctx)

自定義?Key-Value?

我們可以通過以下方式設置/獲取自定義的key-value鍵值對。

// 設置自定義鍵值對
service.Context.Get(ctx).Data[key] = value

// 獲取自定義鍵值對
service.Context.Get(ctx).Data[key]

五、注意問題

上下文變量只傳遞必須的鏈路參數數據,不要什么參數都往里面塞。特別是一些方法參數、傳參的數據,千萬不能往上下文里面塞,而應當用顯示的方式傳遞方法參數。

上下文變量僅用作運行時臨時使用,不可做持久化存儲長期使用。

總結

這篇文章詳細的為大家介紹了GoFrame上下文對象Context的知識點:

Context的作用:在業務流程中進行變量的共享。

Context的結構定義、邏輯封裝、如何在中間件中注入、如何通過Context設置值和取值、Context如何自定義key-value、以及在項目開發中使用的注意問題。

歡迎Star GoFrame:https://github.com/gogf/gf

本文轉載自微信公眾號「 程序員升級打怪之旅」,作者「王中陽Go」,可以通過以下二維碼關注。

轉載本文請聯系「 程序員升級打怪之旅」公眾號。

責任編輯:武曉燕 來源: 程序員升級打怪之旅
相關推薦

2023-06-16 09:08:39

ReactContextRFC

2021-08-10 07:41:24

ContextWaitGroupGoroutine

2017-07-26 11:32:50

NETRabbitMQ系統集成

2015-11-26 10:53:45

LinuxWindowsMac OS

2022-11-29 10:42:46

GoFrame技巧腳手架

2021-03-28 09:17:18

JVM場景鉤子函數

2022-09-14 08:16:48

裝飾器模式對象

2022-06-02 10:02:47

Kubectl更新應用Linux

2019-11-15 09:58:04

LinuxAsciinemapython

2022-02-28 09:19:12

MDK芯片軟件

2020-05-08 14:45:00

JS代碼變量

2022-01-21 09:45:42

Mozilla SOKubernetesLinux

2021-01-19 10:35:49

JVM場景函數

2022-11-15 07:50:47

ORM鏈式操作刪除

2022-11-11 07:48:56

ORM鏈式輪播圖

2020-10-16 11:48:06

服務器系統運維

2022-12-28 12:11:57

PHPGo框架

2020-05-14 09:15:52

設計模式SOLID 原則JS

2017-09-25 16:39:51

移動端

2021-04-28 09:02:48

Golang語言Context
點贊
收藏

51CTO技術棧公眾號

主站蜘蛛池模板: 国产精品久久久乱弄 | 九九伊人sl水蜜桃色推荐 | 成人自拍视频 | 在线一区二区三区 | 黄色免费在线观看网址 | 婷婷中文在线 | 99久久精品国产毛片 | 日本一区二区不卡视频 | 国产视频一区二区在线观看 | 夜夜摸夜夜操 | 羞羞视频免费观看 | 美国黄色毛片 | 久久高清精品 | 国产成人黄色 | v亚洲 | 在线免费激情视频 | 中文字幕亚洲国产 | 超碰综合 | 久久99精品久久久久蜜桃tv | 国内自拍真实伦在线观看 | 亚洲一区二区在线视频 | 中文字幕一区二区三区乱码图片 | 久久成人国产 | 羞羞的视频免费看 | 国产精品午夜电影 | 日本又色又爽又黄又高潮 | 永久免费av| 亚洲不卡av在线 | 成人网在线 | 欧美日韩精品综合 | 九色视频网 | 国产午夜在线观看 | 一区二区三区四区在线视频 | 精品亚洲一区二区三区 | 欧美日韩亚 | 国产精品123区 | 女同久久 | 欧美日韩福利视频 | 在线国产一区二区三区 | 久久久久成人精品 | 奇米在线|