关于dubbo:聊聊dubbogo的GenericFilter

51次阅读

共计 2897 个字符,预计需要花费 8 分钟才能阅读完成。

本文次要钻研一下 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

正文完
 0