diff --git a/cluster/cluster_impl/failover_cluster_test.go b/cluster/cluster_impl/failover_cluster_test.go
index cc533ea098ee76488d2f76cbbe601b275274db83..dc039db8de41ab6722b20f99c5a0c5536a42a7e6 100644
--- a/cluster/cluster_impl/failover_cluster_test.go
+++ b/cluster/cluster_impl/failover_cluster_test.go
@@ -143,8 +143,7 @@ func Test_FailoverInvoke2(t *testing.T) {
 	urlParams.Set(constant.RETRIES_KEY, "2")
 	urlParams.Set("methods.test."+constant.RETRIES_KEY, "3")
 
-	ivc := &invocation.RPCInvocation{}
-	ivc.SetMethod("test")
+	ivc := invocation.NewRPCInvocationWithOptions(invocation.WithMethodName("test"))
 	result := normalInvoke(t, 3, urlParams, ivc)
 	assert.NoError(t, result.Error())
 	count = 0
diff --git a/cluster/loadbalance/least_active_test.go b/cluster/loadbalance/least_active_test.go
index c29a2092a19161d0dd75ee4098ee786b620880b0..7663ea3ce6252dcb7ddeaea92fb6bef8d95478d5 100644
--- a/cluster/loadbalance/least_active_test.go
+++ b/cluster/loadbalance/least_active_test.go
@@ -43,8 +43,7 @@ func TestLeastActiveByWeight(t *testing.T) {
 		invokers = append(invokers, protocol.NewBaseInvoker(url))
 	}
 
-	inv := new(invocation.RPCInvocation)
-	inv.SetMethod("test")
+	inv := invocation.NewRPCInvocationWithOptions(invocation.WithMethodName("test"))
 	protocol.BeginCount(invokers[2].GetUrl(), inv.MethodName())
 
 	loop = 10000
diff --git a/cluster/loadbalance/random_test.go b/cluster/loadbalance/random_test.go
index 09d3d259a903693e9c0550965fc12d2089228662..ffe65d78ac61e5210d23e44c7f802597fed78f96 100644
--- a/cluster/loadbalance/random_test.go
+++ b/cluster/loadbalance/random_test.go
@@ -67,8 +67,7 @@ func Test_RandomlbSelectWeight(t *testing.T) {
 	urlParams.Set("methods.test."+constant.WEIGHT_KEY, "10000000000000")
 	urll, _ := common.NewURL(context.TODO(), fmt.Sprintf("dubbo://192.168.1.100:20000/com.ikurento.user.UserProvider"), common.WithParams(urlParams))
 	invokers = append(invokers, protocol.NewBaseInvoker(urll))
-	ivc := &invocation.RPCInvocation{}
-	ivc.SetMethod("test")
+	ivc := invocation.NewRPCInvocationWithOptions(invocation.WithMethodName("test"))
 
 	var selectedInvoker []protocol.Invoker
 	var selected float64
@@ -99,8 +98,7 @@ func Test_RandomlbSelectWarmup(t *testing.T) {
 	urlParams.Set(constant.REMOTE_TIMESTAMP_KEY, strconv.FormatInt(time.Now().Add(time.Minute*(-9)).Unix(), 10))
 	urll, _ := common.NewURL(context.TODO(), fmt.Sprintf("dubbo://192.168.1.100:20000/com.ikurento.user.UserProvider"), common.WithParams(urlParams))
 	invokers = append(invokers, protocol.NewBaseInvoker(urll))
-	ivc := &invocation.RPCInvocation{}
-	ivc.SetMethod("test")
+	ivc := invocation.NewRPCInvocationWithOptions(invocation.WithMethodName("test"))
 
 	var selectedInvoker []protocol.Invoker
 	var selected float64
diff --git a/common/proxy/proxy.go b/common/proxy/proxy.go
index 96d42eb21152e64d170f50276bbce88e1bf8db69..1c079f6bca52bf8f6e8c5ebb168da82ab8ccb5f2 100644
--- a/common/proxy/proxy.go
+++ b/common/proxy/proxy.go
@@ -116,7 +116,9 @@ func (p *Proxy) Implement(v common.RPCService) {
 				}
 			}
 
-			inv = invocation_impl.NewRPCInvocationForConsumer(methodName, nil, inArr, reply.Interface(), p.callBack, common.URL{}, nil)
+			inv = invocation_impl.NewRPCInvocationWithOptions(invocation_impl.WithMethodName(methodName),
+				invocation_impl.WithArguments(inArr), invocation_impl.WithReply(reply.Interface()),
+				invocation_impl.WithCallBack(p.callBack))
 
 			for k, value := range p.attachments {
 				inv.SetAttachments(k, value)
diff --git a/filter/impl/echo_filter_test.go b/filter/impl/echo_filter_test.go
index e2752c85b24b5dbc8175cbd125ed771b412d1818..e2e592974701ad18c5b01e884485c022ee2320b8 100644
--- a/filter/impl/echo_filter_test.go
+++ b/filter/impl/echo_filter_test.go
@@ -34,11 +34,11 @@ import (
 func TestEchoFilter_Invoke(t *testing.T) {
 	filter := GetFilter()
 	result := filter.Invoke(protocol.NewBaseInvoker(common.URL{}),
-		invocation.NewRPCInvocationForProvider("$echo", []interface{}{"OK"}, nil))
+		invocation.NewRPCInvocation("$echo", []interface{}{"OK"}, nil))
 	assert.Equal(t, "OK", result.Result())
 
 	result = filter.Invoke(protocol.NewBaseInvoker(common.URL{}),
-		invocation.NewRPCInvocationForProvider("MethodName", []interface{}{"OK"}, nil))
+		invocation.NewRPCInvocation("MethodName", []interface{}{"OK"}, nil))
 	assert.Nil(t, result.Error())
 	assert.Nil(t, result.Result())
 }
diff --git a/protocol/dubbo/dubbo_invoker_test.go b/protocol/dubbo/dubbo_invoker_test.go
index 182d6d8e0b11cfcb231789cebf9c4cefdecfa258..e88e782730e14387169a5201d94fe898cfbba0a7 100644
--- a/protocol/dubbo/dubbo_invoker_test.go
+++ b/protocol/dubbo/dubbo_invoker_test.go
@@ -44,7 +44,8 @@ func TestDubboInvoker_Invoke(t *testing.T) {
 	invoker := NewDubboInvoker(url, c)
 	user := &User{}
 
-	inv := invocation.NewRPCInvocationForConsumer("GetUser", nil, []interface{}{"1", "username"}, user, nil, url, nil)
+	inv := invocation.NewRPCInvocationWithOptions(invocation.WithMethodName("GetUser"), invocation.WithArguments([]interface{}{"1", "username"}),
+		invocation.WithReply(user))
 
 	// Call
 	res := invoker.Invoke(inv)
diff --git a/protocol/dubbo/listener.go b/protocol/dubbo/listener.go
index 120ecf9a4df2416698d5750c860fddc1a11b34c1..1333fd3dc6f5baef51b3aae5ea8255397008dd2c 100644
--- a/protocol/dubbo/listener.go
+++ b/protocol/dubbo/listener.go
@@ -223,7 +223,7 @@ func (h *RpcServerHandler) OnMessage(session getty.Session, pkg interface{}) {
 	}
 	invoker := exporter.(protocol.Exporter).GetInvoker()
 	if invoker != nil {
-		result := invoker.Invoke(invocation.NewRPCInvocationForProvider(p.Service.Method, p.Body.(map[string]interface{})["args"].([]interface{}), map[string]string{
+		result := invoker.Invoke(invocation.NewRPCInvocation(p.Service.Method, p.Body.(map[string]interface{})["args"].([]interface{}), map[string]string{
 			constant.PATH_KEY:      p.Service.Path,
 			constant.GROUP_KEY:     p.Service.Group,
 			constant.INTERFACE_KEY: p.Service.Interface,
diff --git a/protocol/invocation/rpcinvocation.go b/protocol/invocation/rpcinvocation.go
index d515cc4c8ad4bcdcc88eccd4b1e8ddb545a17315..2124a22f1611b24d7f4370de64b117c58c4f7e7b 100644
--- a/protocol/invocation/rpcinvocation.go
+++ b/protocol/invocation/rpcinvocation.go
@@ -22,8 +22,6 @@ import (
 )
 
 import (
-	"github.com/apache/dubbo-go/common"
-	"github.com/apache/dubbo-go/common/constant"
 	"github.com/apache/dubbo-go/protocol"
 )
 
@@ -41,27 +39,7 @@ type RPCInvocation struct {
 	invoker        protocol.Invoker
 }
 
-func NewRPCInvocationForConsumer(methodName string, parameterTypes []reflect.Type, arguments []interface{},
-	reply interface{}, callBack interface{}, url common.URL, invoker protocol.Invoker) *RPCInvocation {
-
-	attachments := map[string]string{}
-	attachments[constant.PATH_KEY] = url.Path
-	attachments[constant.GROUP_KEY] = url.GetParam(constant.GROUP_KEY, "")
-	attachments[constant.INTERFACE_KEY] = url.GetParam(constant.INTERFACE_KEY, "")
-	attachments[constant.VERSION_KEY] = url.GetParam(constant.VERSION_KEY, "")
-
-	return &RPCInvocation{
-		methodName:     methodName,
-		parameterTypes: parameterTypes,
-		arguments:      arguments,
-		reply:          reply,
-		callBack:       callBack,
-		attachments:    attachments,
-		invoker:        invoker,
-	}
-}
-
-func NewRPCInvocationForProvider(methodName string, arguments []interface{}, attachments map[string]string) *RPCInvocation {
+func NewRPCInvocation(methodName string, arguments []interface{}, attachments map[string]string) *RPCInvocation {
 	return &RPCInvocation{
 		methodName:  methodName,
 		arguments:   arguments,
@@ -69,26 +47,6 @@ func NewRPCInvocationForProvider(methodName string, arguments []interface{}, att
 	}
 }
 
-type option func(invo *RPCInvocation)
-
-func WithMethodName(methodName string) option {
-	return func(invo *RPCInvocation) {
-		invo.methodName = methodName
-	}
-}
-
-func WithParameterTypes(parameterTypes []reflect.Type) option {
-	return func(invo *RPCInvocation) {
-		invo.parameterTypes = parameterTypes
-	}
-}
-
-func WithArguments(arguments []interface{}) option {
-	return func(invo *RPCInvocation) {
-		invo.arguments = arguments
-	}
-}
-
 func NewRPCInvocationWithOptions(opts ...option) *RPCInvocation {
 	invo := &RPCInvocation{}
 	for _, opt := range opts {
@@ -147,14 +105,58 @@ func (r *RPCInvocation) SetInvoker() protocol.Invoker {
 	return r.invoker
 }
 
+func (r *RPCInvocation) CallBack() interface{} {
+	return r.callBack
+}
+
 func (r *RPCInvocation) SetCallBack(c interface{}) {
 	r.callBack = c
 }
 
-func (r *RPCInvocation) CallBack() interface{} {
-	return r.callBack
+///////////////////////////
+// option
+///////////////////////////
+
+type option func(invo *RPCInvocation)
+
+func WithMethodName(methodName string) option {
+	return func(invo *RPCInvocation) {
+		invo.methodName = methodName
+	}
+}
+
+func WithParameterTypes(parameterTypes []reflect.Type) option {
+	return func(invo *RPCInvocation) {
+		invo.parameterTypes = parameterTypes
+	}
+}
+
+func WithArguments(arguments []interface{}) option {
+	return func(invo *RPCInvocation) {
+		invo.arguments = arguments
+	}
+}
+
+func WithReply(reply interface{}) option {
+	return func(invo *RPCInvocation) {
+		invo.reply = reply
+	}
+}
+
+func WithCallBack(callBack interface{}) option {
+	return func(invo *RPCInvocation) {
+		invo.callBack = callBack
+	}
+}
+
+func WithAttachments(attachments map[string]string) option {
+	return func(invo *RPCInvocation) {
+		invo.attachments = attachments
+	}
 }
 
-func (r *RPCInvocation) SetMethod(method string) {
-	r.methodName = method
+func WithInvoker(invoker protocol.Invoker) option {
+	return func(invo *RPCInvocation) {
+		invo.invoker = invoker
+	}
 }
diff --git a/protocol/jsonrpc/jsonrpc_invoker_test.go b/protocol/jsonrpc/jsonrpc_invoker_test.go
index 1a7f61b64e5530c6f7debc90daebc683c1e0274f..bc88759bf522a35a30e8585429f1db614c3a15ce 100644
--- a/protocol/jsonrpc/jsonrpc_invoker_test.go
+++ b/protocol/jsonrpc/jsonrpc_invoker_test.go
@@ -57,7 +57,9 @@ func TestJsonrpcInvoker_Invoke(t *testing.T) {
 
 	jsonInvoker := NewJsonrpcInvoker(url, client)
 	user := &User{}
-	res := jsonInvoker.Invoke(invocation.NewRPCInvocationForConsumer("GetUser", nil, []interface{}{"1", "username"}, user, nil, url, nil))
+	res := jsonInvoker.Invoke(invocation.NewRPCInvocationWithOptions(invocation.WithMethodName("GetUser"), invocation.WithArguments([]interface{}{"1", "username"}),
+		invocation.WithReply(user)))
+
 	assert.NoError(t, res.Error())
 	assert.Equal(t, User{Id: "1", Name: "username"}, *res.Result().(*User))
 
diff --git a/protocol/jsonrpc/server.go b/protocol/jsonrpc/server.go
index a88896ae98ce73ca505988bb32df57fa9308ef7b..6b3a39c68b4fdb417e8d2efaec4a43806acb2219 100644
--- a/protocol/jsonrpc/server.go
+++ b/protocol/jsonrpc/server.go
@@ -325,7 +325,7 @@ func serveRequest(ctx context.Context,
 	exporter, _ := jsonrpcProtocol.ExporterMap().Load(path)
 	invoker := exporter.(*JsonrpcExporter).GetInvoker()
 	if invoker != nil {
-		result := invoker.Invoke(invocation.NewRPCInvocationForProvider(methodName, args, map[string]string{
+		result := invoker.Invoke(invocation.NewRPCInvocation(methodName, args, map[string]string{
 			constant.PATH_KEY:    path,
 			constant.VERSION_KEY: codec.req.Version,
 		}))