diff --git a/common/proxy/proxy.go b/common/proxy/proxy.go
index 6c42dab8fd7173f3ba1919ca8721201d690002df..2304b1ebcea1e95fcd07b1b0927b6c4980710e19 100644
--- a/common/proxy/proxy.go
+++ b/common/proxy/proxy.go
@@ -54,28 +54,59 @@ func (p *Proxy) Implement(v common.RPCService) {
 	makeDubboCallProxy := func(methodName string, outs []reflect.Type) func(in []reflect.Value) []reflect.Value {
 		return func(in []reflect.Value) []reflect.Value {
 			var (
-				err error
-				inv *invocation_impl.RPCInvocation
+				err   error
+				inv   *invocation_impl.RPCInvocation
+				inArr []interface{}
+				reply reflect.Value
 			)
 			if methodName == "Echo" {
 				methodName = "$echo"
 			}
-			if len(in) == 2 {
-				inv = invocation_impl.NewRPCInvocationForConsumer(methodName, nil, in[0].Interface().([]interface{}), in[1].Interface(), p.callBack, common.URL{}, nil)
+
+			start := 0
+			end := len(in)
+			if in[0].Type().String() == "context.Context" {
+				start += 1
+			}
+			if len(outs) == 1 {
+				end -= 1
+				reply = in[len(in)-1]
+			} else {
+				if outs[0].Kind() == reflect.Ptr {
+					reply = reflect.New(outs[0].Elem())
+				} else {
+					reply = reflect.New(outs[0])
+				}
 			}
-			if len(in) == 3 {
-				inv = invocation_impl.NewRPCInvocationForConsumer(methodName, nil, in[1].Interface().([]interface{}), in[2].Interface(), p.callBack, common.URL{}, nil)
+
+			if v, ok := in[start].Interface().([]interface{}); ok && end-start == 1 {
+				inArr = v
+			} else {
+				inArr = make([]interface{}, end-start)
+				index := 0
+				for i := start; i < end; i++ {
+					inArr[index] = in[i].Interface()
+					index++
+				}
 			}
 
-			for k, v := range p.attachments {
-				inv.SetAttachments(k, v)
+			inv = invocation_impl.NewRPCInvocationForConsumer(methodName, nil, inArr, reply.Interface(), p.callBack, common.URL{}, nil)
+
+			for k, value := range p.attachments {
+				inv.SetAttachments(k, value)
 			}
 
 			result := p.invoke.Invoke(inv)
 
 			err = result.Error()
-			log.Info("[makeDubboCallProxy] err: %v", err)
-			return []reflect.Value{reflect.ValueOf(&err).Elem()}
+			log.Info("[makeDubboCallProxy] result: %v, err: %v", result.Result(), err)
+			if len(outs) == 1 {
+				return []reflect.Value{reflect.ValueOf(&err).Elem()}
+			}
+			if len(outs) == 2 && outs[0].Kind() != reflect.Ptr {
+				return []reflect.Value{reply.Elem(), reflect.ValueOf(&err).Elem()}
+			}
+			return []reflect.Value{reply, reflect.ValueOf(&err).Elem()}
 		}
 	}
 
@@ -88,35 +119,31 @@ func (p *Proxy) Implement(v common.RPCService) {
 		}
 		f := valueOfElem.Field(i)
 		if f.Kind() == reflect.Func && f.IsValid() && f.CanSet() {
-			if t.Type.NumIn() != 2 && t.Type.NumIn() != 3 {
-				log.Warn("method %s of mtype %v has wrong number of in parameters %d; needs exactly 3/4",
-					t.Name, t.Type.String(), t.Type.NumIn())
-				continue
-			}
+			inNum := t.Type.NumIn()
+			outNum := t.Type.NumOut()
 
-			if t.Type.NumIn() == 2 && t.Type.In(1).Kind() != reflect.Ptr {
-				log.Warn("reply type of method %q is not a pointer %v", t.Name, t.Type.In(1))
+			if outNum != 1 && outNum != 2 {
+				log.Warn("method %s of mtype %v has wrong number of in out parameters %d; needs exactly 1/2",
+					t.Name, t.Type.String(), outNum)
 				continue
 			}
 
-			if t.Type.NumIn() == 3 && t.Type.In(2).Kind() != reflect.Ptr {
-				log.Warn("reply type of method %q is not a pointer %v", t.Name, t.Type.In(2))
+			// The latest return type of the method must be error.
+			if returnType := t.Type.Out(outNum - 1); returnType != typError {
+				log.Warn("the latest return type %s of method %q is not error", returnType, t.Name)
 				continue
 			}
 
-			// Method needs one out.
-			if t.Type.NumOut() != 1 {
-				log.Warn("method %q has %d out parameters; needs exactly 1", t.Name, t.Type.NumOut())
-				continue
-			}
-			// The return type of the method must be error.
-			if returnType := t.Type.Out(0); returnType != typError {
-				log.Warn("return type %s of method %q is not error", returnType, t.Name)
+			// reply must be Ptr when outNum == 1
+			if outNum == 1 && t.Type.In(inNum-1).Kind() != reflect.Ptr {
+				log.Warn("reply type of method %q is not a pointer or interface", t.Name)
 				continue
 			}
 
-			var funcOuts = make([]reflect.Type, t.Type.NumOut())
-			funcOuts[0] = t.Type.Out(0)
+			var funcOuts = make([]reflect.Type, outNum)
+			for i := 0; i < outNum; i++ {
+				funcOuts[i] = t.Type.Out(i)
+			}
 
 			// do method proxy here:
 			f.Set(reflect.MakeFunc(f.Type(), makeDubboCallProxy(methodName, funcOuts)))
diff --git a/common/proxy/proxy_test.go b/common/proxy/proxy_test.go
index 8720298aa6372108f8b6ebbb6dbef707db38fecc..617502ee657d307067586e7f83e7099fca7bafcd 100644
--- a/common/proxy/proxy_test.go
+++ b/common/proxy/proxy_test.go
@@ -3,6 +3,7 @@ package proxy
 import (
 	"context"
 	"errors"
+	"reflect"
 	"testing"
 )
 
@@ -17,10 +18,11 @@ import (
 )
 
 type TestService struct {
-	MethodOne   func(context.Context, []interface{}, *struct{}) error
-	MethodTwo   func([]interface{}, *struct{}) error
-	MethodThree func([]interface{}, *struct{}) error `dubbo:"methodThree"`
-	Echo        func([]interface{}, *struct{}) error
+	MethodOne   func(context.Context, int, bool, *interface{}) error
+	MethodTwo   func([]interface{}, *interface{}) error
+	MethodThree func(int, bool) (interface{}, error)
+	MethodFour  func(int, bool) (*interface{}, error) `dubbo:"methodFour"`
+	Echo        func(interface{}, *interface{}) error
 }
 
 func (s *TestService) Service() string {
@@ -45,12 +47,16 @@ func TestProxy_Implement(t *testing.T) {
 	p := NewProxy(invoker, nil, map[string]string{constant.ASYNC_KEY: "false"})
 	s := &TestService{}
 	p.Implement(s)
-	err := p.Get().(*TestService).MethodOne(nil, nil, nil)
+	err := p.Get().(*TestService).MethodOne(nil, 0, false, nil)
 	assert.NoError(t, err)
 	err = p.Get().(*TestService).MethodTwo(nil, nil)
 	assert.NoError(t, err)
-	err = p.Get().(*TestService).MethodThree(nil, nil)
+	ret, err := p.Get().(*TestService).MethodThree(0, false)
 	assert.NoError(t, err)
+	assert.Nil(t, ret) // ret is nil, because it doesn't be injection yet
+	ret2, err := p.Get().(*TestService).MethodFour(0, false)
+	assert.NoError(t, err)
+	assert.Equal(t, "*interface {}", reflect.TypeOf(ret2).String())
 	err = p.Get().(*TestService).Echo(nil, nil)
 	assert.NoError(t, err)
 
@@ -58,13 +64,13 @@ func TestProxy_Implement(t *testing.T) {
 	p.rpc = nil
 	type S1 struct {
 		TestService
-		methodOne func(context.Context, []interface{}, *struct{}) error
+		methodOne func(context.Context, interface{}, *struct{}) error
 	}
-	s1 := &S1{TestService: *s, methodOne: func(i context.Context, i2 []interface{}, i3 *struct{}) error {
+	s1 := &S1{TestService: *s, methodOne: func(i context.Context, i2 interface{}, i3 *struct{}) error {
 		return errors.New("errors")
 	}}
 	p.Implement(s1)
-	err = s1.MethodOne(nil, nil, nil)
+	err = s1.MethodOne(nil, 0, false, nil)
 	assert.NoError(t, err)
 	err = s1.methodOne(nil, nil, nil)
 	assert.EqualError(t, err, "errors")
@@ -75,21 +81,21 @@ func TestProxy_Implement(t *testing.T) {
 	p.Implement(&it)
 	assert.Nil(t, p.rpc)
 
-	// args number
+	// return number
 	p.rpc = nil
 	type S2 struct {
 		TestService
-		MethodOne func([]interface{}) error
+		MethodOne func([]interface{}) (*struct{}, int, error)
 	}
 	s2 := &S2{TestService: *s}
 	p.Implement(s2)
 	assert.Nil(t, s2.MethodOne)
 
-	// returns number
+	// reply type
 	p.rpc = nil
 	type S3 struct {
 		TestService
-		MethodOne func(context.Context, []interface{}, *struct{}) (interface{}, error)
+		MethodOne func(context.Context, []interface{}, struct{}) error
 	}
 	s3 := &S3{TestService: *s}
 	p.Implement(s3)
@@ -105,23 +111,4 @@ func TestProxy_Implement(t *testing.T) {
 	p.Implement(s4)
 	assert.Nil(t, s4.MethodOne)
 
-	// reply type for number 3
-	p.rpc = nil
-	type S5 struct {
-		TestService
-		MethodOne func(context.Context, []interface{}, interface{}) error
-	}
-	s5 := &S5{TestService: *s}
-	p.Implement(s5)
-	assert.Nil(t, s5.MethodOne)
-
-	// reply type for number 2
-	p.rpc = nil
-	type S6 struct {
-		TestService
-		MethodOne func([]interface{}, interface{}) error
-	}
-	s6 := &S6{TestService: *s}
-	p.Implement(s6)
-	assert.Nil(t, s5.MethodOne)
 }
diff --git a/examples/dubbo/go-client/app/client.go b/examples/dubbo/go-client/app/client.go
index 3632a0e723a5bf2eb2912f604f4ed6893c37a889..35f25ae9b625986b4134c4cea797c0a02640dff2 100644
--- a/examples/dubbo/go-client/app/client.go
+++ b/examples/dubbo/go-client/app/client.go
@@ -52,8 +52,7 @@ func main() {
 	initProfiling()
 
 	gxlog.CInfo("\n\n\necho")
-	res := ""
-	err := conMap["com.ikurento.user.UserProvider"].GetRPCService().(*UserProvider).Echo(context.TODO(), []interface{}{"OK"}, &res)
+	res, err := conMap["com.ikurento.user.UserProvider"].GetRPCService().(*UserProvider).Echo(context.TODO(), "OK")
 	if err != nil {
 		panic(err)
 	}
@@ -69,13 +68,21 @@ func main() {
 	}
 	gxlog.CInfo("response result: %v", user)
 
+	gxlog.CInfo("\n\n\nstart to test dubbo - GetUser0")
+	ret, err := conMap["com.ikurento.user.UserProvider"].GetRPCService().(*UserProvider).GetUser0(context.TODO(), "A003")
+	if err != nil {
+		panic(err)
+	}
+	gxlog.CInfo("response result: %v", ret)
+
 	gxlog.CInfo("\n\n\nstart to test dubbo - getUser")
 	user = &User{}
 	err = conMap["com.ikurento.user.UserProvider"].GetRPCService().(*UserProvider).GetUser2(context.TODO(), []interface{}{1}, user)
 	if err != nil {
 		fmt.Println("getUser - error: ", err)
+	} else {
+		gxlog.CInfo("response result: %v", user)
 	}
-	gxlog.CInfo("response result: %v", user)
 
 	gxlog.CInfo("\n\n\nstart to test dubbo illegal method")
 	err = conMap["com.ikurento.user.UserProvider"].GetRPCService().(*UserProvider).GetUser1(context.TODO(), []interface{}{"A003"}, user)
diff --git a/examples/dubbo/go-client/app/user.go b/examples/dubbo/go-client/app/user.go
index 1dd100ce436becc03e55abf6981b5b92136b354b..be5dde2829e2722c6bf34ca567c7e7918084a625 100644
--- a/examples/dubbo/go-client/app/user.go
+++ b/examples/dubbo/go-client/app/user.go
@@ -77,9 +77,10 @@ func (User) JavaClassName() string {
 
 type UserProvider struct {
 	GetUser  func(ctx context.Context, req []interface{}, rsp *User) error
+	GetUser0 func(ctx context.Context, req interface{}) (User, error) `dubbo:"GetUser"`
 	GetUser1 func(ctx context.Context, req []interface{}, rsp *User) error
 	GetUser2 func(ctx context.Context, req []interface{}, rsp *User) error   `dubbo:"getUser"`
-	Echo     func(ctx context.Context, req []interface{}, rsp *string) error // Echo represent EchoFilter will be used
+	Echo     func(ctx context.Context, req interface{}) (interface{}, error) // Echo represent EchoFilter will be used
 }
 
 func (u *UserProvider) Service() string {
diff --git a/examples/jsonrpc/go-client/app/client.go b/examples/jsonrpc/go-client/app/client.go
index 5eb6babb2dd276e1bd8dc3b476a49dbf9aa3fdfc..c87fb5e79a626d2108054e9cb342ae11398f91b9 100644
--- a/examples/jsonrpc/go-client/app/client.go
+++ b/examples/jsonrpc/go-client/app/client.go
@@ -47,12 +47,12 @@ func main() {
 	initProfiling()
 
 	gxlog.CInfo("\n\n\necho")
-	res := ""
-	err := conMap["com.ikurento.user.UserProvider"].GetRPCService().(*UserProvider).Echo(context.TODO(), []interface{}{"OK"}, &res)
+	res, err := conMap["com.ikurento.user.UserProvider"].GetRPCService().(*UserProvider).Echo(context.TODO(), "OK")
 	if err != nil {
 		fmt.Println("echo - error: ", err)
+	} else {
+		gxlog.CInfo("res: %s", res)
 	}
-	gxlog.CInfo("res: %s", res)
 
 	time.Sleep(3e9)
 
@@ -64,13 +64,21 @@ func main() {
 	}
 	gxlog.CInfo("response result: %v", user)
 
+	gxlog.CInfo("\n\n\nstart to test dubbo - GetUser0")
+	ret, err := conMap["com.ikurento.user.UserProvider"].GetRPCService().(*UserProvider).GetUser0(context.TODO(), "A003")
+	if err != nil {
+		panic(err)
+	}
+	gxlog.CInfo("response result: %v", ret)
+
 	gxlog.CInfo("\n\n\nstart to test jsonrpc - getUser")
 	user = &JsonRPCUser{}
 	err = conMap["com.ikurento.user.UserProvider"].GetRPCService().(*UserProvider).GetUser2(context.TODO(), []interface{}{1}, user)
 	if err != nil {
 		fmt.Println("getUser - error: ", err)
+	} else {
+		gxlog.CInfo("response result: %v", user)
 	}
-	gxlog.CInfo("response result: %v", user)
 
 	gxlog.CInfo("\n\n\nstart to test jsonrpc illegal method")
 	err = conMap["com.ikurento.user.UserProvider"].GetRPCService().(*UserProvider).GetUser1(context.TODO(), []interface{}{"A003"}, user)
diff --git a/examples/jsonrpc/go-client/app/user.go b/examples/jsonrpc/go-client/app/user.go
index 20a62a010638c5813157a09a9d8186c0d81c0281..a453a06d2f76b3f54fc1139c6f3921039f5cad4f 100644
--- a/examples/jsonrpc/go-client/app/user.go
+++ b/examples/jsonrpc/go-client/app/user.go
@@ -31,9 +31,10 @@ func (u JsonRPCUser) String() string {
 
 type UserProvider struct {
 	GetUser  func(ctx context.Context, req []interface{}, rsp *JsonRPCUser) error
+	GetUser0 func(ctx context.Context, req interface{}) (*JsonRPCUser, error) `dubbo:"GetUser"`
 	GetUser1 func(ctx context.Context, req []interface{}, rsp *JsonRPCUser) error
 	GetUser2 func(ctx context.Context, req []interface{}, rsp *JsonRPCUser) error `dubbo:"getUser"`
-	Echo     func(ctx context.Context, req []interface{}, rsp *string) error      // Echo represent EchoFilter will be used
+	Echo     func(ctx context.Context, req interface{}) (interface{}, error)      // Echo represent EchoFilter will be used
 }
 
 func (u *UserProvider) Service() string {
diff --git a/examples/jsonrpc/java-client/src/main/java/com/ikurento/user/Consumer.java b/examples/jsonrpc/java-client/src/main/java/com/ikurento/user/Consumer.java
index a9e5aaa51fe0a4bb5a3ee31b36cfb46cac5a6122..fec1597240ee351e6b53a3cb6a43a18ca33eef6e 100644
--- a/examples/jsonrpc/java-client/src/main/java/com/ikurento/user/Consumer.java
+++ b/examples/jsonrpc/java-client/src/main/java/com/ikurento/user/Consumer.java
@@ -47,9 +47,6 @@ public class Consumer {
             e.printStackTrace();
         }
         try {
-            EchoService echoService = (EchoService)userProvider;
-            Object status = echoService.$echo("OK");
-            System.out.println("echo: "+status);
             User user1 = userProvider.GetUser("A003");
             System.out.println("[" + new SimpleDateFormat("HH:mm:ss").format(new Date()) + "] " +
                     " UserInfo, Id:" + user1.getId() + ", name:" + user1.getName() + ", sex:" + user1.getSex().toString()
diff --git a/filter/impl/echo_filter.go b/filter/impl/echo_filter.go
index 3608cefd23a9c4412292ee8aadaedbbaa3a0026f..82d48701383c5c3b91b69aec780d2bc5e071d640 100644
--- a/filter/impl/echo_filter.go
+++ b/filter/impl/echo_filter.go
@@ -19,7 +19,7 @@ func init() {
 
 // RPCService need a Echo method in consumer, if you want to use EchoFilter
 // eg:
-//		Echo func(ctx context.Context, args []interface{}, rsp *Xxx) error
+//		Echo func(ctx context.Context, arg interface{}, rsp *Xxx) error
 type EchoFilter struct {
 }
 
diff --git a/protocol/dubbo/listener.go b/protocol/dubbo/listener.go
index f180ca63196ce707d4ce7f864621acf1d07511aa..21b19c0742c5a52196af40d01aa1f2cde55d66a2 100644
--- a/protocol/dubbo/listener.go
+++ b/protocol/dubbo/listener.go
@@ -279,30 +279,18 @@ func (h *RpcServerHandler) callService(req *DubboPackage, ctx context.Context) {
 	}
 
 	// prepare argv
-	var argv reflect.Value
-	argIsValue := false // if true, need to indirect before calling.
-	if method.ArgType().Kind() == reflect.Ptr {
-		argv = reflect.New(method.ArgType().Elem())
-	} else {
-		argv = reflect.New(method.ArgType())
-		argIsValue = true
-	}
-	argvTmp := argv.Interface()
-	argvTmp = req.Body.(map[string]interface{})["args"] // type is []interface
-	if argIsValue {
-		argv = argv.Elem()
-	}
+	argv := req.Body.(map[string]interface{})["args"] // type is []interface
 
 	// prepare replyv
 	replyv := reflect.New(method.ReplyType().Elem())
 	var returnValues []reflect.Value
 	if method.CtxType() == nil {
-		returnValues = method.Method().Func.Call([]reflect.Value{svc.Rcvr(), reflect.ValueOf(argvTmp), reflect.ValueOf(replyv.Interface())})
+		returnValues = method.Method().Func.Call([]reflect.Value{svc.Rcvr(), reflect.ValueOf(argv), reflect.ValueOf(replyv.Interface())})
 	} else {
 		if contextv := reflect.ValueOf(ctx); contextv.IsValid() {
-			returnValues = method.Method().Func.Call([]reflect.Value{svc.Rcvr(), contextv, reflect.ValueOf(argvTmp), reflect.ValueOf(replyv.Interface())})
+			returnValues = method.Method().Func.Call([]reflect.Value{svc.Rcvr(), contextv, reflect.ValueOf(argv), reflect.ValueOf(replyv.Interface())})
 		} else {
-			returnValues = method.Method().Func.Call([]reflect.Value{svc.Rcvr(), reflect.Zero(method.CtxType()), reflect.ValueOf(argvTmp), reflect.ValueOf(replyv.Interface())})
+			returnValues = method.Method().Func.Call([]reflect.Value{svc.Rcvr(), reflect.Zero(method.CtxType()), reflect.ValueOf(argv), reflect.ValueOf(replyv.Interface())})
 		}
 	}
 
diff --git a/protocol/jsonrpc/server.go b/protocol/jsonrpc/server.go
index 78c1b791e2b462fc58a9b519901b936f6f564a9d..0d625b347d076cdb514a067e68b2d78d6149f35f 100644
--- a/protocol/jsonrpc/server.go
+++ b/protocol/jsonrpc/server.go
@@ -345,25 +345,6 @@ func serveRequest(ctx context.Context,
 		return jerrors.New("cannot find method " + methodName + " of svc " + serviceName)
 	}
 
-	// get args
-	var argv reflect.Value
-	argIsValue := false
-	if mtype.ArgType().Kind() == reflect.Ptr {
-		argv = reflect.New(mtype.ArgType().Elem())
-	} else {
-		argv = reflect.New(mtype.ArgType())
-		argIsValue = true
-	}
-	// argv guaranteed to be a pointer now.
-	argvTmp := argv.Interface()
-	argvTmp = args
-	//if err = codec.ReadBody(argv.Interface()); err != nil {
-	//	return jerrors.Trace(err)
-	//}
-	if argIsValue {
-		argv = argv.Elem()
-	}
-
 	replyv := reflect.New(mtype.ReplyType().Elem())
 
 	//  call service.method(args)
@@ -374,14 +355,14 @@ func serveRequest(ctx context.Context,
 	if mtype.CtxType() == nil {
 		returnValues = mtype.Method().Func.Call([]reflect.Value{
 			svc.Rcvr(),
-			reflect.ValueOf(argvTmp),
+			reflect.ValueOf(args),
 			reflect.ValueOf(replyv.Interface()),
 		})
 	} else {
 		returnValues = mtype.Method().Func.Call([]reflect.Value{
 			svc.Rcvr(),
 			mtype.SuiteContext(ctx),
-			reflect.ValueOf(argvTmp),
+			reflect.ValueOf(args),
 			reflect.ValueOf(replyv.Interface()),
 		})
 	}