聊聊dubbo-go的GenericFilter
时间:2022-07-22
本文章向大家介绍聊聊dubbo-go的GenericFilter,主要内容包括其使用实例、应用技巧、基本知识点总结和需要注意事项,具有一定的参考价值,需要的朋友可以参考一下。
序
本文主要研究一下dubbo-go的GenericFilter
GenericFilter
dubbo-go-v1.4.2/filter/filter_impl/generic_filter.go
const (
// GENERIC
//generic module name
GENERIC = "generic"
)
func init() {
extension.SetFilter(GENERIC, GetGenericFilter)
}
// when do a generic invoke, struct need to be map
// GenericFilter ...
type GenericFilter struct{}
- GenericFilter的init方法设置了GetGenericFilter
GetGenericFilter
dubbo-go-v1.4.2/filter/filter_impl/generic_filter.go
// GetGenericFilter ...
func GetGenericFilter() filter.Filter {
return &GenericFilter{}
}
- GetGenericFilter方法创建了GenericFilter
Invoke
dubbo-go-v1.4.2/filter/filter_impl/generic_filter.go
// Invoke ...
func (ef *GenericFilter) Invoke(ctx context.Context, invoker protocol.Invoker, invocation protocol.Invocation) protocol.Result {
if invocation.MethodName() == constant.GENERIC && len(invocation.Arguments()) == 3 {
oldArguments := invocation.Arguments()
if oldParams, ok := oldArguments[2].([]interface{}); ok {
newParams := make([]hessian.Object, 0, len(oldParams))
for i := range oldParams {
newParams = append(newParams, hessian.Object(struct2MapAll(oldParams[i])))
}
newArguments := []interface{}{
oldArguments[0],
oldArguments[1],
newParams,
}
newInvocation := invocation2.NewRPCInvocation(invocation.MethodName(), newArguments, invocation.Attachments())
newInvocation.SetReply(invocation.Reply())
return invoker.Invoke(ctx, newInvocation)
}
}
return invoker.Invoke(ctx, invocation)
}
- Invoke方法在methodName为generic,且参数长度为3时,通过struct2MapAll方法将oldParams转换为newParams,发起newInvocation
struct2MapAll
dubbo-go-v1.4.2/filter/filter_impl/generic_filter.go
func struct2MapAll(obj interface{}) interface{} {
if obj == nil {
return obj
}
t := reflect.TypeOf(obj)
v := reflect.ValueOf(obj)
if t.Kind() == reflect.Struct {
result := make(map[string]interface{}, t.NumField())
for i := 0; i < t.NumField(); i++ {
if v.Field(i).Kind() == reflect.Struct || v.Field(i).Kind() == reflect.Slice || v.Field(i).Kind() == reflect.Map {
if v.Field(i).CanInterface() {
setInMap(result, t.Field(i), struct2MapAll(v.Field(i).Interface()))
}
} else {
if v.Field(i).CanInterface() {
setInMap(result, t.Field(i), v.Field(i).Interface())
}
}
}
return result
} else if t.Kind() == reflect.Slice {
value := reflect.ValueOf(obj)
var newTemps = make([]interface{}, 0, value.Len())
for i := 0; i < value.Len(); i++ {
newTemp := struct2MapAll(value.Index(i).Interface())
newTemps = append(newTemps, newTemp)
}
return newTemps
} else if t.Kind() == reflect.Map {
var newTempMap = make(map[string]interface{}, v.Len())
iter := v.MapRange()
for iter.Next() {
mapK := iter.Key().String()
if !iter.Value().CanInterface() {
continue
}
mapV := iter.Value().Interface()
newTempMap[mapK] = struct2MapAll(mapV)
}
return newTempMap
} else {
return obj
}
}
- struct2MapAll方法针对reflect.Struct、reflect.Slice、reflect.Map做了不同的转换
OnResponse
dubbo-go-v1.4.2/filter/filter_impl/generic_filter.go
// OnResponse ...
func (ef *GenericFilter) OnResponse(_ context.Context, result protocol.Result, _ protocol.Invoker,
_ protocol.Invocation) protocol.Result {
return result
}
- OnResponse方法直接返回result
小结
GenericFilter的Invoke方法在methodName为generic,且参数长度为3时,通过struct2MapAll方法将oldParams转换为newParams,发起newInvocation
doc
- Java学习之深拷贝浅拷贝及对象拷贝的两种方式
- [周末课程]什么是“页面业务流程”分析思维导图?如何编写页面假JSON数据? &下一个前端组件“日历”
- Java并发学习之玩转线程池
- Java & PhantomJs 实现html输出图片
- 干货 | React Native实践之携程Moles框架
- Java并发学习之ThreadLocal使用及原理介绍
- ibeacon蓝牙技术简介
- Java并发学习之定时任务的几种玩法
- [视频直播]本周日先行者视频“React多级菜单
- Java并发学习之线程状态及Thread常用方法详解
- Java并发学习之四种线程创建方式的实现与对比
- Google protocol buffer简介
- Java反射的使用姿势一览
- [一对一讲什么] 之 测完了接口、搞好了目录,然后做啥?
- JavaScript 教程
- JavaScript 编辑工具
- JavaScript 与HTML
- JavaScript 与Java
- JavaScript 数据结构
- JavaScript 基本数据类型
- JavaScript 特殊数据类型
- JavaScript 运算符
- JavaScript typeof 运算符
- JavaScript 表达式
- JavaScript 类型转换
- JavaScript 基本语法
- JavaScript 注释
- Javascript 基本处理流程
- Javascript 选择结构
- Javascript if 语句
- Javascript if 语句的嵌套
- Javascript switch 语句
- Javascript 循环结构
- Javascript 循环结构实例
- Javascript 跳转语句
- Javascript 控制语句总结
- Javascript 函数介绍
- Javascript 函数的定义
- Javascript 函数调用
- Javascript 几种特殊的函数
- JavaScript 内置函数简介
- Javascript eval() 函数
- Javascript isFinite() 函数
- Javascript isNaN() 函数
- parseInt() 与 parseFloat()
- escape() 与 unescape()
- Javascript 字符串介绍
- Javascript length属性
- javascript 字符串函数
- Javascript 日期对象简介
- Javascript 日期对象用途
- Date 对象属性和方法
- Javascript 数组是什么
- Javascript 创建数组
- Javascript 数组赋值与取值
- Javascript 数组属性和方法
- 蓝桥杯vip测试题-找零钱(解题思路以及解题代码)
- 剑指Office-二进制中1的个数
- 剑指Office-旋转数组的最小数
- Mysql调优你不知道这几点,就太可惜了
- Mysql快速导入数百万条数据,亲测有效
- [面试题06]从未到头打印链表(LeetCode-剑指Offer)
- SpringBoot集成RabbitMQ-三种模式的实现
- Centos7-Docker卸载旧的更新到新版本
- vue vuecli3 前端解决跨域问题
- 求求你,不要再纠结指针了(1) ——万能转化公式
- 求求你,不要再纠结指针了(2)——函数指针
- 用Python解决100个问题 | 倒计时
- 【转载】【ionic+angularjs】angularjs ui-router路由简介
- 实时性迷思(1) —— “快是优点么?”
- Java中Thread的join方法为什么能让线程插队?