阅读源码和查看官方文档,是解决问题最高效的办法。
作为一个工作8年的老程序员告诉你:阅读源码和查看官方文档,是解决问题最高效的办法。不信你来看,这个困扰了读者半天的问题我查了源码和文档后瞬间解决。
前言
上周五有位读者私信我一个问题,说困扰了他半天,研究了一个上午也没搞明白。
是一位运维转Go的朋友,最近有不少运维、测试、甚至Java、PHP转Go的朋友加我。
这个问题并不是三言两语就能讲清楚的,我就整理了一篇文章给他。
快乐

正如上图所示,反馈特别的好,更文的快乐又找到了,我把这个问题和解答又好好整理了一下,分享给大家,希望对大家有帮助.
也分享一下我作为一个工作8年的老程,解决问题的心得:
阅读源码和查看官方文档,是解决问题最高效的办法。
提问
在gofame框架的demo案例中,如下图所示:

- 为什么左侧路由绑定这里没有向controller中传入context的值,在controller中却能取到值?
- 如何赋值和接收context?
先说结论

- 关于
ctx context.Context上下文,Server组件会自动从请求中获取并传递给接口方法,声明并初始化了context初始值为context.Background() - 可以通过GetCtx、SetCtx、GetCtxVar、SetCtxVar这些方法轻松的为context赋值和取值
- 通过示例代码轻松可知:我们可以通过
ghttp.Request实例轻松的操作context。
解答
问题1. 为什么左侧路由绑定这里没有向controller中传入context的值,在controller中却能取到值?
先说结论:关于ctx context.Context上下文,Server组件会自动从请求中获取并传递给接口方法。
关键代码是上图中的s := g.Server():
追踪一下它的源码可以发现:声明并初始化了ctx的初始值:context.Background()

再带大家看一下context.Background()的源码和注释。
// Background returns a non-nil, empty Context. It is never canceled, has no
// values, and has no deadline. It is typically used by the main function,
// initialization, and tests, and as the top-level Context for incoming
// requests.
func Background() Context {return background
}
我们可以发现这里返回了一个non-nil, empty Context

问题2. 如何赋值和接收context?
在GoFrame框架中,官方推荐的正是使用Context上下文对象来处理流程共享的上下文变量,甚至将该对象进一步传递到依赖的各个模块方法中。
该Context对象类型实现了标准库的context.Context接口,该接口往往会作为模块间调用方法的第一个参数,该接口参数也是Golang官方推荐的在模块间传递上下文变量的推荐方式。
方法列表:
func (r *Request) GetCtx() context.Context
func (r *Request) SetCtx(ctx context.Context)
func (r *Request) GetCtxVar(key interface{}, def ...interface{}) *gvar.Var
func (r *Request) SetCtxVar(key interface{}, value interface{})
简要说明:
- GetCtx方法用于获取当前的context.Context对象,作用同Context方法。
- SetCtx方法用于设置自定义的context.Context上下文对象。
- GetCtxVar方法用于获取上下文变量,并可给定当该变量不存在时的默认值。
- SetCtxVar方法用于设置上下文变量。
使用示例
示例1,SetCtxVar/GetCtxVar
package mainimport ("github.com/gogf/gf/v2/frame/g""github.com/gogf/gf/v2/net/ghttp"
)const (TraceIdName = "trace-id"
)func main() {s := g.Server()s.Group("/", func(group *ghttp.RouterGroup) {group.Middleware(func(r *ghttp.Request) {//向context中赋值r.SetCtxVar(TraceIdName, "1234567890abcd")r.Middleware.Next()})group.ALL("/", func(r *ghttp.Request) {//从context中取值r.Response.Write(r.GetCtxVar(TraceIdName))})})s.SetPort(8199)s.Run()
}
可以看到:我们可以通过SetCtxVar和GetCtxVar来设置和获取自定义的变量,该变量生命周期仅限于当前请求流程。
执行后,访问 http://127.0.0.1:8199/ ,页面输出内容为:1234567890abcd
示例2,SetCtx
SetCtx方法常用于中间件中整合一些第三方的组件,例如第三方的链路跟踪组件等等。
为简化示例,这里我们将上面的例子通过SetCtx方法来改造一下来做演示。
package mainimport ("context""github.com/gogf/gf/v2/frame/g""github.com/gogf/gf/v2/net/ghttp"
)const (TraceIdName = "trace-id"
)func main() {s := g.Server()s.Group("/", func(group *ghttp.RouterGroup) {group.Middleware(func(r *ghttp.Request) {ctx := context.WithValue(r.Context(), TraceIdName, "1234567890abcd")r.SetCtx(ctx)r.Middleware.Next()})group.ALL("/", func(r *ghttp.Request) {//看到这里的示例代码,更能解答问题1,通过ghttp.Request可以轻松获得上下文对象r.Response.Write(r.Context().Value(TraceIdName))// 也可以使用// r.Response.Write(r.GetCtxVar(TraceIdName))})})s.SetPort(8199)s.Run()
}
执行后,访问 http://127.0.0.1:8199/ ,页面输出内容为:1234567890abcd
总结
通过上面的示例,我们能更好的理解这位星友提出的困惑:
- 关于
ctx context.Context上下文,Server组件会自动从请求中获取并传递给接口方法,声明并初始化了context初始值为context.Background() - 可以通过GetCtx、SetCtx、GetCtxVar、SetCtxVar这些方法轻松的为context赋值和取值
- 通过示例代码轻松可知:我们可以通过
ghttp.Request实例轻松的操作context。
参考链接
-
路由注册-规范路由
-
请求输入-Context
一起学习

欢迎关注下方公众号:程序员升职加薪之旅,也欢迎 加我好友 一起学习
相关文章:
阅读源码和查看官方文档,是解决问题最高效的办法。
作为一个工作8年的老程序员告诉你:阅读源码和查看官方文档,是解决问题最高效的办法。不信你来看,这个困扰了读者半天的问题我查了源码和文档后瞬间解决。 前言 上周五有位读者私信我一个问题,说困扰了他半天,研究了一…...
云原生流量管理系统中 Service , Ingress 和 Endpoint 的关系
摘要 Kubernetes(简称 K8s)是一个用于容器编排和管理的开源平台,其中流量管理是 K8s 的重要功能之一。K8s 提供了多种流量管理方式,以便对不同场景下的流量进行控制和管理。以下是 K8s 中常用的流量管理系统: Service:Service 是 K8s 中最基本的流量管理方式,用于提供…...
给你安利几款好用的谷歌浏览器插件
给你安利几款好用的谷歌浏览器插件前言一 Octotree 插件二 GitCodeTree 插件三 SourceGraph 插件四 GitZip 插件五 Enhanced GitHub 插件六 插件下载安装6.1 谷歌应用商店下载6.2 离线安装6.2.1 下载插件6.2.2 安装插件七 移除、启用、停用插件小结前言 GitHub是全球最大的代码…...
JDK定时器Timer原理
前言 前些时间想到利用redis实现延时队列,但是底层的定时器不止如何实现好些,故此研究了一下jdk的Timer。 Timer是一个用于执行定时任务的类,可以单次执行或按指定时间间隔循环执行(直到主动cancel或线程被杀掉)。Ti…...
vue3中使用swiper完整版教程
介绍 在 vue3 中使用 swiper, 实现轮播图的效果;如果组件样式等模块引入不当,很有可能导致,页面无效果;或者想要的箭头或者切换效果异常问题。具体使用方式如下所示: 使用方式 使用命令 npm install swiper 安装 sw…...
某个div的滚动条样式
.item-body,.chart2{/*滚动条整体样式*/&::-webkit-scrollbar {/*高宽分别对应横竖滚动条的尺寸*/width: 10px;height: 1px;}/*滚动条里面小方块*/&::-webkit-scrollbar-thumb {border-radius: 10px;-webkit-box-shadow: inset 0 0 5px rgba(0, 0, 0, 0.2);background:…...
Spring Boot框架基础介绍
Spring Boot 是一款基于 Spring 框架的开源应用程序开发工具,它旨在简化 Spring 应用程序的配置和开发过程。Spring Boot 提供了一种简单的方式来创建可独立运行的、生产级别的应用程序,并在需要时进行部署。Spring Boot 在微服务架构和云计算环境下得到…...
Git - 在主分支上创建分支并提交代码
拉取最新代码 因为当前在 master 分支下,你必须拉取最新代码,保证当前代码与线上同步(最新),执行以下命令: git pull origin master创建分支 目前我们在 master 主分支上,需要执行以下命令&…...
第三届无线通信AI大赛分享交流会暨颁奖典礼顺利举办,大赛圆满收官
2月16日,第三届无线通信AI大赛分享交流会暨颁奖典礼在北京顺利举行,宣告大赛圆满收官。 分享交流会暨颁奖典礼以线上线下结合的形式展开,邀请无线通信领域的多位专家、学者与「基于AI的信道估计与信道状态信息反馈联合设计」、「基于AI的高精…...
程序的本质与类的说明
摘自《深入浅出WPF完整版》P132程序的本质就是“数据算法”,,这一本质一直没有改变一一类的作用只是把散落在程序中的变量和函数进行归档封装并控制对它们的访问而已。被封装在类里的变量称为字段 (Fied)它表示的是类或实例的状态:被封装在类里的函数称为…...
单片机——显示方式
数码LED 一、静态显示方式 1、连接 所有LED的位选均共同连接到VCC或GND,每个LED的8根段选线分别连接一个8位并行I/O口,从该I/O口送出相应的字型码显示字型。 2、这种连接方式的缺点就是需要的数据线太多:我们可以计算一下:8*4133根…...
leetcode 1~10 学习经历
LeetCode 习题 1 - 101. 两数之和2. 两数相加3. 无重复字符的最长子串4. 寻找两个正序数组的中位数5. 最长回文子串6. N 字形变换7. 整数反转8. 字符串转换整数 (atoi)9. 回文数10. 正则表达式匹配1. 两数之和 给定一个整数数组 nums 和一个整数目标值 target,请你在…...
代码质量与安全 | 一文了解高级驾驶辅助系统(ADAS)及其开发中需要遵循的标准
高级驾驶辅助系统(ADAS)有助于提高车内每个人的安全性,帮助他们安全抵达目的地。这项技术功能非常重要,因为大多数的严重车祸都是人为错误造成的。 本篇文章将讨论什么是高级驾驶辅助系统(ADAS)࿰…...
2023年安徽省职业院校“磐云杯”网络安全竞赛任务书
2023年安徽省职业院校“磐云杯”网络安全竞赛 任务书 一、竞赛时间 总计:360分钟 三、竞赛任务书内容 (一)拓扑图 (二)A模块基础设施设置/安全加固(200分) 一、项目和任务描述:…...
九龙证券|豪掷超6000万,10转3派6元,今年第二只高送转股出炉!
新瀚新材高送转发布计划,股价年初以来大涨超50%。航运板块6股自2022年低点股价翻倍。 2月17日晚间,凯瑞德、新瀚新材2家公司发布了2022年年报;一起,新瀚新材高送转计划同步出炉。 报告显现,2022年度新瀚新材营业总收入…...
Java开发 - 数风流人物,还看“微服务”
目录 前言 服务器端的发展历程 早期的服务器 动态的页面 用户内容网站 微服务 企业级应用 互联网应用 微服务介绍 什么是微服务? 为什么使用微服务 怎么使用微服务 Spring Cloud 什么是Spring Cloud Nacos注册中心 什么是Nacos 创建微服务项目 创建…...
Springboot 整合 分布式定时任务 XXL-JOB
起因 恰逢周末, 最近公司接入了分布式定时任务,我是负责接入这块的,正好在网上想起了之前看过的分布式任务的文章,然后学习一下 各路框架发现看了很多框架比如 elasticjob 跟xxl-job不同的是,elasticjob是采用zookeepe…...
细谈JavaWeb中的Request和Response
文章目录1,Request和Response的概述2,Request对象2.1 Request继承体系2.2 Request获取请求数据2.2.1 获取请求行数据2.2.2 获取请求头数据2.2.3 获取请求体数据2.2.4 获取请求参数的通用方式2.4 请求参数中文乱码问题2.4.1 POST请求解决方案2.4.2 GET请求…...
lombok注解@Data使用在继承类上时出现警告解决方案
lombok为我们提供了Data注解,帮助我们省略了Setter,Getter,ToString等注解,一般对于普通的实体类使用该注解,不会出现什么问题,但是当我们把这个注解,使用在派生类上,就出现了一个警告1 情景再现父类:Data …...
linux环境搭建私有gitlab仓库以及启动gitlab后出现卡顿处理办法
搭建之前,需要安装相应的依赖包,并且要启动sshd服务(1).安装policycoreutils-python openssh-server openssh-clients [rootVM-0-2-centos ~]# sudo yum install -y curl policycoreutils-python openssh-server openssh-clients [rootVM-0-2-centos ~]…...
微信小程序之bind和catch
这两个呢,都是绑定事件用的,具体使用有些小区别。 官方文档: 事件冒泡处理不同 bind:绑定的事件会向上冒泡,即触发当前组件的事件后,还会继续触发父组件的相同事件。例如,有一个子视图绑定了b…...
通过Wrangler CLI在worker中创建数据库和表
官方使用文档:Getting started Cloudflare D1 docs 创建数据库 在命令行中执行完成之后,会在本地和远程创建数据库: npx wranglerlatest d1 create prod-d1-tutorial 在cf中就可以看到数据库: 现在,您的Cloudfla…...
Vue2 第一节_Vue2上手_插值表达式{{}}_访问数据和修改数据_Vue开发者工具
文章目录 1.Vue2上手-如何创建一个Vue实例,进行初始化渲染2. 插值表达式{{}}3. 访问数据和修改数据4. vue响应式5. Vue开发者工具--方便调试 1.Vue2上手-如何创建一个Vue实例,进行初始化渲染 准备容器引包创建Vue实例 new Vue()指定配置项 ->渲染数据 准备一个容器,例如: …...
React19源码系列之 事件插件系统
事件类别 事件类型 定义 文档 Event Event 接口表示在 EventTarget 上出现的事件。 Event - Web API | MDN UIEvent UIEvent 接口表示简单的用户界面事件。 UIEvent - Web API | MDN KeyboardEvent KeyboardEvent 对象描述了用户与键盘的交互。 KeyboardEvent - Web…...
3-11单元格区域边界定位(End属性)学习笔记
返回一个Range 对象,只读。该对象代表包含源区域的区域上端下端左端右端的最后一个单元格。等同于按键 End 向上键(End(xlUp))、End向下键(End(xlDown))、End向左键(End(xlToLeft)End向右键(End(xlToRight)) 注意:它移动的位置必须是相连的有内容的单元格…...
力扣-35.搜索插入位置
题目描述 给定一个排序数组和一个目标值,在数组中找到目标值,并返回其索引。如果目标值不存在于数组中,返回它将会被按顺序插入的位置。 请必须使用时间复杂度为 O(log n) 的算法。 class Solution {public int searchInsert(int[] nums, …...
【SSH疑难排查】轻松解决新版OpenSSH连接旧服务器的“no matching...“系列算法协商失败问题
【SSH疑难排查】轻松解决新版OpenSSH连接旧服务器的"no matching..."系列算法协商失败问题 摘要: 近期,在使用较新版本的OpenSSH客户端连接老旧SSH服务器时,会遇到 "no matching key exchange method found", "n…...
搭建DNS域名解析服务器(正向解析资源文件)
正向解析资源文件 1)准备工作 服务端及客户端都关闭安全软件 [rootlocalhost ~]# systemctl stop firewalld [rootlocalhost ~]# setenforce 0 2)服务端安装软件:bind 1.配置yum源 [rootlocalhost ~]# cat /etc/yum.repos.d/base.repo [Base…...
认识CMake并使用CMake构建自己的第一个项目
1.CMake的作用和优势 跨平台支持:CMake支持多种操作系统和编译器,使用同一份构建配置可以在不同的环境中使用 简化配置:通过CMakeLists.txt文件,用户可以定义项目结构、依赖项、编译选项等,无需手动编写复杂的构建脚本…...
DiscuzX3.5发帖json api
参考文章:PHP实现独立Discuz站外发帖(直连操作数据库)_discuz 发帖api-CSDN博客 简单改造了一下,适配我自己的需求 有一个站点存在多个采集站,我想通过主站拿标题,采集站拿内容 使用到的sql如下 CREATE TABLE pre_forum_post_…...
