diff --git a/common/constant/default.go b/common/constant/default.go
index 05461ca6e7360e08d716d6b78d20ad4411df99e8..7ab92249ad742152b385ac7f0aa6e96f37fdb00c 100644
--- a/common/constant/default.go
+++ b/common/constant/default.go
@@ -38,6 +38,8 @@ const (
 	PREFIX_DEFAULT_KEY        = "default."
 	DEFAULT_SERVICE_FILTERS   = "echo"
 	DEFAULT_REFERENCE_FILTERS = ""
+	GENERIC_REFERENCE_FILTERS = "generic"
+	GENERIC                   = "$invoke"
 	ECHO                      = "$echo"
 )
 
diff --git a/common/constant/key.go b/common/constant/key.go
index bca658b2623e3ca9241103b5f9c82c7e15fb4062..ba86c531c95e02583a0e7e8be9da10ff622136ca 100644
--- a/common/constant/key.go
+++ b/common/constant/key.go
@@ -30,6 +30,7 @@ const (
 	METHODS_KEY   = "methods"
 	TIMEOUT_KEY   = "timeout"
 	BEAN_NAME_KEY = "bean.name"
+	GENERIC_KEY   = "generic"
 )
 
 const (
diff --git a/config/config_loader.go b/config/config_loader.go
index 0dd0fb7f963e09a4402f4fd01c8a6b91959a7ca3..720f65f5de6b24b445b7ce07dd2daaba0a856681 100644
--- a/config/config_loader.go
+++ b/config/config_loader.go
@@ -66,6 +66,10 @@ func Load() {
 			logger.Errorf("[consumer config center refresh] %#v", err)
 		}
 		for key, ref := range consumerConfig.References {
+			if ref.Generic {
+				genericService := NewGenericService(key)
+				SetConsumerService(genericService)
+			}
 			rpcService := GetConsumerService(key)
 
 			if rpcService == nil {
diff --git a/config/generic_service.go b/config/generic_service.go
new file mode 100644
index 0000000000000000000000000000000000000000..8a4e88df9788554bc4a5ee33884166e4ccede37f
--- /dev/null
+++ b/config/generic_service.go
@@ -0,0 +1,30 @@
+/*
+ * Licensed to the Apache Software Foundation (ASF) under one or more
+ * contributor license agreements.  See the NOTICE file distributed with
+ * this work for additional information regarding copyright ownership.
+ * The ASF licenses this file to You under the Apache License, Version 2.0
+ * (the "License"); you may not use this file except in compliance with
+ * the License.  You may obtain a copy of the License at
+ *
+ *     http://www.apache.org/licenses/LICENSE-2.0
+ *
+ * Unless required by applicable law or agreed to in writing, software
+ * distributed under the License is distributed on an "AS IS" BASIS,
+ * WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied.
+ * See the License for the specific language governing permissions and
+ * limitations under the License.
+ */
+package config
+
+type GenericService struct {
+	Invoke       func(req []interface{}) (interface{}, error) `dubbo:"$invoke"`
+	referenceStr string
+}
+
+func NewGenericService(referenceStr string) *GenericService {
+	return &GenericService{referenceStr: referenceStr}
+}
+
+func (u *GenericService) Reference() string {
+	return u.referenceStr
+}
diff --git a/config/reference_config.go b/config/reference_config.go
index a5b7d50db51df02cd1871b3fb6d0bd2d6a545dd2..bbf3c66b062ca6b93a974faf07652d13f8630b10 100644
--- a/config/reference_config.go
+++ b/config/reference_config.go
@@ -55,6 +55,7 @@ type ReferenceConfig struct {
 	Params        map[string]string `yaml:"params"  json:"params,omitempty" property:"params"`
 	invoker       protocol.Invoker
 	urls          []*common.URL
+	Generic       bool `yaml:"generic"  json:"generic,omitempty" property:"generic"`
 }
 
 func (c *ReferenceConfig) Prefix() string {
@@ -110,7 +111,6 @@ func (refconfig *ReferenceConfig) Refer() {
 			regUrl.SubURL = url
 		}
 	}
-
 	if len(refconfig.urls) == 1 {
 		refconfig.invoker = extension.GetProtocol(refconfig.urls[0].Protocol).Refer(*refconfig.urls[0])
 	} else {
@@ -157,6 +157,7 @@ func (refconfig *ReferenceConfig) getUrlMap() url.Values {
 	urlMap.Set(constant.RETRIES_KEY, strconv.FormatInt(refconfig.Retries, 10))
 	urlMap.Set(constant.GROUP_KEY, refconfig.Group)
 	urlMap.Set(constant.VERSION_KEY, refconfig.Version)
+	urlMap.Set(constant.GENERIC_KEY, strconv.FormatBool(refconfig.Generic))
 	//getty invoke async or sync
 	urlMap.Set(constant.ASYNC_KEY, strconv.FormatBool(refconfig.async))
 
@@ -170,7 +171,11 @@ func (refconfig *ReferenceConfig) getUrlMap() url.Values {
 	urlMap.Set(constant.ENVIRONMENT_KEY, consumerConfig.ApplicationConfig.Environment)
 
 	//filter
-	urlMap.Set(constant.REFERENCE_FILTER_KEY, mergeValue(consumerConfig.Filter, refconfig.Filter, constant.DEFAULT_REFERENCE_FILTERS))
+	var defaultReferenceFilter = constant.DEFAULT_REFERENCE_FILTERS
+	if refconfig.Generic {
+		defaultReferenceFilter = constant.GENERIC_REFERENCE_FILTERS + defaultReferenceFilter
+	}
+	urlMap.Set(constant.REFERENCE_FILTER_KEY, mergeValue(consumerConfig.Filter, refconfig.Filter, defaultReferenceFilter))
 
 	for _, v := range refconfig.Methods {
 		urlMap.Set("methods."+v.Name+"."+constant.LOADBALANCE_KEY, v.Loadbalance)
@@ -180,3 +185,11 @@ func (refconfig *ReferenceConfig) getUrlMap() url.Values {
 	return urlMap
 
 }
+func (refconfig *ReferenceConfig) GenericLoad(id string) {
+	genericService := NewGenericService(refconfig.id)
+	SetConsumerService(genericService)
+	refconfig.id = id
+	refconfig.Refer()
+	refconfig.Implement(genericService)
+	return
+}
diff --git a/examples/general/dubbo/go-client/app/client.go b/examples/general/dubbo/go-client/app/client.go
index e6f1ae96fb387a1756c8a1c0b026746378377fff..b7ee0e662a26251a79af13d36215cc2cb44fd794 100644
--- a/examples/general/dubbo/go-client/app/client.go
+++ b/examples/general/dubbo/go-client/app/client.go
@@ -25,16 +25,15 @@ import (
 	"syscall"
 	"time"
 )
-
 import (
-	"github.com/apache/dubbo-go-hessian2"
+	hessian "github.com/apache/dubbo-go-hessian2"
 )
 
 import (
 	"github.com/apache/dubbo-go/common/logger"
 	_ "github.com/apache/dubbo-go/common/proxy/proxy_factory"
 	"github.com/apache/dubbo-go/config"
-	_ "github.com/apache/dubbo-go/protocol/dubbo"
+	"github.com/apache/dubbo-go/protocol/dubbo"
 	_ "github.com/apache/dubbo-go/registry/protocol"
 
 	_ "github.com/apache/dubbo-go/filter/impl"
@@ -65,7 +64,8 @@ func main() {
 	test1()
 	println("\n\ntest2")
 	test2()
-
+	println("\n\ntest3")
+	test3()
 	initSignal()
 }
 
@@ -288,3 +288,24 @@ func test2() {
 	}
 	println("error: %v", err)
 }
+func test3() {
+	var appName = "UserProviderGer"
+	var referenceConfig = config.ReferenceConfig{
+		InterfaceName: "com.ikurento.user.UserProvider",
+		Cluster:       "failover",
+		Registry:      "hangzhouzk",
+		Protocol:      dubbo.DUBBO,
+		Generic:       true,
+	}
+	referenceConfig.GenericLoad(appName) //appName is the unique identification of RPCService
+
+	time.Sleep(3 * time.Second)
+	println("\n\n\nstart to generic invoke")
+	resp, err := referenceConfig.GetRPCService().(*config.GenericService).Invoke([]interface{}{"GetUser", []string{"java.lang.String"}, []interface{}{"A003"}})
+	if err != nil {
+		panic(err)
+	}
+	println("res: %v\n", resp)
+	println("succ!")
+
+}
diff --git a/filter/impl/generic_filter.go b/filter/impl/generic_filter.go
new file mode 100644
index 0000000000000000000000000000000000000000..12cb4c7fa59ac4f1f7c1466f385ea9e9b59567b5
--- /dev/null
+++ b/filter/impl/generic_filter.go
@@ -0,0 +1,125 @@
+/*
+ * Licensed to the Apache Software Foundation (ASF) under one or more
+ * contributor license agreements.  See the NOTICE file distributed with
+ * this work for additional information regarding copyright ownership.
+ * The ASF licenses this file to You under the Apache License, Version 2.0
+ * (the "License"); you may not use this file except in compliance with
+ * the License.  You may obtain a copy of the License at
+ *
+ *     http://www.apache.org/licenses/LICENSE-2.0
+ *
+ * Unless required by applicable law or agreed to in writing, software
+ * distributed under the License is distributed on an "AS IS" BASIS,
+ * WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied.
+ * See the License for the specific language governing permissions and
+ * limitations under the License.
+ */
+
+package impl
+
+import (
+	"reflect"
+	"strings"
+)
+import (
+	hessian "github.com/apache/dubbo-go-hessian2"
+)
+import (
+	"github.com/apache/dubbo-go/common/constant"
+	"github.com/apache/dubbo-go/common/extension"
+	"github.com/apache/dubbo-go/filter"
+	"github.com/apache/dubbo-go/protocol"
+	invocation2 "github.com/apache/dubbo-go/protocol/invocation"
+)
+
+const (
+	GENERIC = "generic"
+)
+
+func init() {
+	extension.SetFilter(GENERIC, GetGenericFilter)
+}
+
+//  when do a generic invoke, struct need to be map
+
+type GenericFilter struct{}
+
+func (ef *GenericFilter) Invoke(invoker protocol.Invoker, invocation protocol.Invocation) protocol.Result {
+	if invocation.MethodName() == constant.GENERIC && len(invocation.Arguments()) == 3 {
+		oldArguments := invocation.Arguments()
+		var newParams []hessian.Object
+		if oldParams, ok := oldArguments[2].([]interface{}); ok {
+			for i := range oldParams {
+				newParams = append(newParams, hessian.Object(struct2MapAll(oldParams[i])))
+			}
+		} else {
+			return invoker.Invoke(invocation)
+		}
+		newArguments := []interface{}{
+			oldArguments[0],
+			oldArguments[1],
+			newParams,
+		}
+		newInvocation := invocation2.NewRPCInvocation(invocation.MethodName(), newArguments, invocation.Attachments())
+		newInvocation.SetReply(invocation.Reply())
+		return invoker.Invoke(newInvocation)
+	}
+	return invoker.Invoke(invocation)
+}
+
+func (ef *GenericFilter) OnResponse(result protocol.Result, invoker protocol.Invoker, invocation protocol.Invocation) protocol.Result {
+	return result
+}
+
+func GetGenericFilter() filter.Filter {
+	return &GenericFilter{}
+}
+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 {
+				if v.Field(i).CanInterface() {
+					setInMap(result, t.Field(i), struct2MapAll(v.Field(i).Interface()))
+				}
+			} else if v.Field(i).Kind() == reflect.Slice {
+				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 {
+		return obj
+	}
+}
+func setInMap(m map[string]interface{}, structField reflect.StructField, value interface{}) (result map[string]interface{}) {
+	result = m
+	if tagName := structField.Tag.Get("m"); tagName == "" {
+		result[headerAtoa(structField.Name)] = value
+	} else {
+		result[tagName] = value
+	}
+	return
+}
+func headerAtoa(a string) (b string) {
+	b = strings.ToLower(a[:1]) + a[1:]
+	return
+}
diff --git a/filter/impl/generic_filter_test.go b/filter/impl/generic_filter_test.go
new file mode 100644
index 0000000000000000000000000000000000000000..a71a9db95759a143186fe9a1a4fb0c861c8949e8
--- /dev/null
+++ b/filter/impl/generic_filter_test.go
@@ -0,0 +1,89 @@
+/*
+ * Licensed to the Apache Software Foundation (ASF) under one or more
+ * contributor license agreements.  See the NOTICE file distributed with
+ * this work for additional information regarding copyright ownership.
+ * The ASF licenses this file to You under the Apache License, Version 2.0
+ * (the "License"); you may not use this file except in compliance with
+ * the License.  You may obtain a copy of the License at
+ *
+ *     http://www.apache.org/licenses/LICENSE-2.0
+ *
+ * Unless required by applicable law or agreed to in writing, software
+ * distributed under the License is distributed on an "AS IS" BASIS,
+ * WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied.
+ * See the License for the specific language governing permissions and
+ * limitations under the License.
+ */
+
+package impl
+
+import (
+	"reflect"
+	"testing"
+)
+import (
+	"github.com/stretchr/testify/assert"
+)
+
+func Test_struct2MapAll(t *testing.T) {
+	var testData struct {
+		AaAa string `m:"aaAa"`
+		BaBa string
+		CaCa struct {
+			AaAa string
+			BaBa string `m:"baBa"`
+			XxYy struct {
+				xxXx string `m:"xxXx"`
+				Xx   string `m:"xx"`
+			} `m:"xxYy"`
+		} `m:"caCa"`
+	}
+	testData.AaAa = "1"
+	testData.BaBa = "1"
+	testData.CaCa.BaBa = "2"
+	testData.CaCa.AaAa = "2"
+	testData.CaCa.XxYy.xxXx = "3"
+	testData.CaCa.XxYy.Xx = "3"
+	m := struct2MapAll(testData).(map[string]interface{})
+	assert.Equal(t, "1", m["aaAa"].(string))
+	assert.Equal(t, "1", m["baBa"].(string))
+	assert.Equal(t, "2", m["caCa"].(map[string]interface{})["aaAa"].(string))
+	assert.Equal(t, "3", m["caCa"].(map[string]interface{})["xxYy"].(map[string]interface{})["xx"].(string))
+
+	assert.Equal(t, reflect.Map, reflect.TypeOf(m["caCa"]).Kind())
+	assert.Equal(t, reflect.Map, reflect.TypeOf(m["caCa"].(map[string]interface{})["xxYy"]).Kind())
+}
+
+type testStruct struct {
+	AaAa string
+	BaBa string `m:"baBa"`
+	XxYy struct {
+		xxXx string `m:"xxXx"`
+		Xx   string `m:"xx"`
+	} `m:"xxYy"`
+}
+
+func Test_struct2MapAll_Slice(t *testing.T) {
+	var testData struct {
+		AaAa string `m:"aaAa"`
+		BaBa string
+		CaCa []testStruct `m:"caCa"`
+	}
+	testData.AaAa = "1"
+	testData.BaBa = "1"
+	var tmp testStruct
+	tmp.BaBa = "2"
+	tmp.AaAa = "2"
+	tmp.XxYy.xxXx = "3"
+	tmp.XxYy.Xx = "3"
+	testData.CaCa = append(testData.CaCa, tmp)
+	m := struct2MapAll(testData).(map[string]interface{})
+
+	assert.Equal(t, "1", m["aaAa"].(string))
+	assert.Equal(t, "1", m["baBa"].(string))
+	assert.Equal(t, "2", m["caCa"].([]interface{})[0].(map[string]interface{})["aaAa"].(string))
+	assert.Equal(t, "3", m["caCa"].([]interface{})[0].(map[string]interface{})["xxYy"].(map[string]interface{})["xx"].(string))
+
+	assert.Equal(t, reflect.Slice, reflect.TypeOf(m["caCa"]).Kind())
+	assert.Equal(t, reflect.Map, reflect.TypeOf(m["caCa"].([]interface{})[0].(map[string]interface{})["xxYy"]).Kind())
+}