专注于 JetBrains IDEA 全家桶,永久激活,教程
持续更新 PyCharm,IDEA,WebStorm,PhpStorm,DataGrip,RubyMine,CLion,AppCode 永久激活教程

聊聊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

  • generic_filter

文章永久链接:https://tech.souyunku.com/25966

未经允许不得转载:搜云库技术团队 » 聊聊dubbo-go的GenericFilter

JetBrains 全家桶,激活、破解、教程

提供 JetBrains 全家桶激活码、注册码、破解补丁下载及详细激活教程,支持 IntelliJ IDEA、PyCharm、WebStorm 等工具的永久激活。无论是破解教程,还是最新激活码,均可免费获得,帮助开发者解决常见激活问题,确保轻松破解并快速使用 JetBrains 软件。获取免费的破解补丁和激活码,快速解决激活难题,全面覆盖 2024/2025 版本!

联系我们联系我们