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

阅读源码和查看官方文档,是解决问题最高效的办法。

作为一个工作8年的老程序员告诉你:阅读源码和查看官方文档,是解决问题最高效的办法。不信你来看,这个困扰了读者半天的问题我查了源码和文档后瞬间解决。

前言

上周五有位读者私信我一个问题,说困扰了他半天,研究了一个上午也没搞明白。

是一位运维转Go的朋友,最近有不少运维、测试、甚至Java、PHP转Go的朋友加我。

这个问题并不是三言两语就能讲清楚的,我就整理了一篇文章给他。

快乐

正如上图所示,反馈特别的好,更文的快乐又找到了,我把这个问题和解答又好好整理了一下,分享给大家,希望对大家有帮助.

也分享一下我作为一个工作8年的老程,解决问题的心得:

阅读源码和查看官方文档,是解决问题最高效的办法。

提问

在gofame框架的demo案例中,如下图所示:

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

先说结论

  1. 关于ctx context.Context上下文,Server组件会自动从请求中获取并传递给接口方法,声明并初始化了context初始值为context.Background()
  2. 可以通过GetCtx、SetCtx、GetCtxVar、SetCtxVar这些方法轻松的为context赋值和取值
  3. 通过示例代码轻松可知:我们可以通过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

总结

通过上面的示例,我们能更好的理解这位星友提出的困惑:

  1. 关于ctx context.Context上下文,Server组件会自动从请求中获取并传递给接口方法,声明并初始化了context初始值为context.Background()
  2. 可以通过GetCtx、SetCtx、GetCtxVar、SetCtxVar这些方法轻松的为context赋值和取值
  3. 通过示例代码轻松可知:我们可以通过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)&#xff0…...

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 ~]…...

JavaSec-RCE

简介 RCE(Remote Code Execution),可以分为:命令注入(Command Injection)、代码注入(Code Injection) 代码注入 1.漏洞场景:Groovy代码注入 Groovy是一种基于JVM的动态语言,语法简洁,支持闭包、动态类型和Java互操作性&#xff0c…...

蓝桥杯3498 01串的熵

问题描述 对于一个长度为 23333333的 01 串, 如果其信息熵为 11625907.5798&#xff0c; 且 0 出现次数比 1 少, 那么这个 01 串中 0 出现了多少次? #include<iostream> #include<cmath> using namespace std;int n 23333333;int main() {//枚举 0 出现的次数//因…...

Python Ovito统计金刚石结构数量

大家好,我是小马老师。 本文介绍python ovito方法统计金刚石结构的方法。 Ovito Identify diamond structure命令可以识别和统计金刚石结构,但是无法直接输出结构的变化情况。 本文使用python调用ovito包的方法,可以持续统计各步的金刚石结构,具体代码如下: from ovito…...

【学习笔记】erase 删除顺序迭代器后迭代器失效的解决方案

目录 使用 erase 返回值继续迭代使用索引进行遍历 我们知道类似 vector 的顺序迭代器被删除后&#xff0c;迭代器会失效&#xff0c;因为顺序迭代器在内存中是连续存储的&#xff0c;元素删除后&#xff0c;后续元素会前移。 但一些场景中&#xff0c;我们又需要在执行删除操作…...

在 Spring Boot 项目里,MYSQL中json类型字段使用

前言&#xff1a; 因为程序特殊需求导致&#xff0c;需要mysql数据库存储json类型数据&#xff0c;因此记录一下使用流程 1.java实体中新增字段 private List<User> users 2.增加mybatis-plus注解 TableField(typeHandler FastjsonTypeHandler.class) private Lis…...

实战三:开发网页端界面完成黑白视频转为彩色视频

​一、需求描述 设计一个简单的视频上色应用&#xff0c;用户可以通过网页界面上传黑白视频&#xff0c;系统会自动将其转换为彩色视频。整个过程对用户来说非常简单直观&#xff0c;不需要了解技术细节。 效果图 ​二、实现思路 总体思路&#xff1a; 用户通过Gradio界面上…...

Oracle11g安装包

Oracle 11g安装包 适用于windows系统&#xff0c;64位 下载路径 oracle 11g 安装包...

yaml读取写入常见错误 (‘cannot represent an object‘, 117)

错误一&#xff1a;yaml.representer.RepresenterError: (‘cannot represent an object’, 117) 出现这个问题一直没找到原因&#xff0c;后面把yaml.safe_dump直接替换成yaml.dump&#xff0c;确实能保存&#xff0c;但出现乱码&#xff1a; 放弃yaml.dump&#xff0c;又切…...

boost::filesystem::path文件路径使用详解和示例

boost::filesystem::path 是 Boost 库中用于跨平台操作文件路径的类&#xff0c;封装了路径的拼接、分割、提取、判断等常用功能。下面是对它的使用详解&#xff0c;包括常用接口与完整示例。 1. 引入头文件与命名空间 #include <boost/filesystem.hpp> namespace fs b…...

若依项目部署--传统架构--未完待续

若依项目介绍 项目源码获取 #Git工具下载 dnf -y install git #若依项目获取 git clone https://gitee.com/y_project/RuoYi-Vue.git项目背景 随着企业信息化需求的增加&#xff0c;传统开发模式存在效率低&#xff0c;重复劳动多等问题。若依项目通过整合主流技术框架&…...