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

以上是 聊聊dubbogo的GenericFilter 的全部内容, 来源链接: utcz.com/z/518398.html

回到顶部