From 46ed4163a240951f8be7046dc3fefa872c8ac186 Mon Sep 17 00:00:00 2001
From: "vito.he" <hxmhlt@163.com>
Date: Thu, 4 Apr 2019 17:16:14 +0800
Subject: [PATCH] code refactor for abstracting service config's interface

---
 client/client_transport.go                    |  10 +-
 client/invoker/invoker.go                     |   6 +-
 client/invoker/service_array.go               |  10 +-
 client/selector/random.go                     |   2 +-
 client/selector/round_robin.go                |   2 +-
 client/selector/selector.go                   |   2 +-
 client/service_array.go                       |   2 +-
 dubbo/client.go                               |   8 +-
 examples/client_config.go                     |  21 ++-
 examples/dubbo/go-client/app/client.go        |   4 +-
 examples/dubbo/go-client/app/test.go          |  12 +-
 examples/jsonrpc/go-client/app/client.go      |   4 +-
 examples/jsonrpc/go-client/app/test.go        |  19 +--
 .../jsonrpc/go-client/profiles/dev/client.yml |   1 +
 examples/jsonrpc/go-server/app/config.go      |  28 +++-
 .../jsonrpc/go-server/profiles/dev/server.yml |   2 +-
 jsonrpc/http.go                               |  28 ++--
 jsonrpc/server.go                             |  32 ++--
 plugins/plugins.go                            |  41 +++++
 registry/event.go                             |   2 +-
 registry/registry.go                          |   2 +-
 registry/service.go                           | 148 ++++++++++++++----
 registry/zookeeper/consumer.go                |  29 ++--
 registry/zookeeper/listener.go                |  30 ++--
 registry/zookeeper/registry.go                |  84 ++++------
 25 files changed, 331 insertions(+), 198 deletions(-)

diff --git a/client/client_transport.go b/client/client_transport.go
index 0400511ae..c8f894a47 100644
--- a/client/client_transport.go
+++ b/client/client_transport.go
@@ -1,6 +1,5 @@
 package client
 
-
 import (
 	"context"
 )
@@ -10,15 +9,14 @@ import (
 )
 
 type Transport interface {
-	Call(ctx context.Context, url *registry.ServiceURL, request Request, resp interface{}) error
-	NewRequest(conf registry.DefaultServiceConfig, method string, args interface{}) Request
+	Call(ctx context.Context, url *registry.DefaultServiceURL, request Request, resp interface{}) error
+	NewRequest(conf registry.ServiceConfig, method string, args interface{}) (Request,error)
 }
 
 //////////////////////////////////////////////
 // Request
 //////////////////////////////////////////////
 
-type Request interface  {
-	ServiceConfig() registry.DefaultServiceConfig
+type Request interface {
+	ServiceConfig() registry.ServiceConfig
 }
-
diff --git a/client/invoker/invoker.go b/client/invoker/invoker.go
index 3d38ff3db..8ea43117a 100644
--- a/client/invoker/invoker.go
+++ b/client/invoker/invoker.go
@@ -133,7 +133,7 @@ func (ivk *Invoker) update(res *registry.ServiceEvent) {
 		if ok {
 			svcArr.add(res.Service, ivk.ServiceTTL)
 		} else {
-			ivk.cacheServiceMap[registryKey] = newServiceArray([]*registry.ServiceURL{res.Service})
+			ivk.cacheServiceMap[registryKey] = newServiceArray([]*registry.DefaultServiceURL{res.Service})
 		}
 	case registry.ServiceDel:
 		if ok {
@@ -147,7 +147,7 @@ func (ivk *Invoker) update(res *registry.ServiceEvent) {
 	}
 }
 
-func (ivk *Invoker) getService(registryConf registry.DefaultServiceConfig) (*ServiceArray, error) {
+func (ivk *Invoker) getService(registryConf registry.ServiceConfig) (*ServiceArray, error) {
 	defer ivk.listenerLock.Unlock()
 
 	registryKey := registryConf.Key()
@@ -197,7 +197,7 @@ func (ivk *Invoker) HttpCall(ctx context.Context, reqId int64, req client.Reques
 	return nil
 }
 
-func (ivk *Invoker) DubboCall(reqId int64, registryConf registry.DefaultServiceConfig, method string, args, reply interface{}, opts ...dubbo.CallOption) error {
+func (ivk *Invoker) DubboCall(reqId int64, registryConf registry.ServiceConfig, method string, args, reply interface{}, opts ...dubbo.CallOption) error {
 
 	registryArray, err := ivk.getService(registryConf)
 	if err != nil {
diff --git a/client/invoker/service_array.go b/client/invoker/service_array.go
index 4516360f4..6ad19b864 100644
--- a/client/invoker/service_array.go
+++ b/client/invoker/service_array.go
@@ -25,12 +25,12 @@ var (
 )
 
 type ServiceArray struct {
-	arr   []*registry.ServiceURL
+	arr   []*registry.DefaultServiceURL
 	birth time.Time
 	idx   int64
 }
 
-func newServiceArray(arr []*registry.ServiceURL) *ServiceArray {
+func newServiceArray(arr []*registry.DefaultServiceURL) *ServiceArray {
 	return &ServiceArray{
 		arr:   arr,
 		birth: time.Now(),
@@ -45,7 +45,7 @@ func (s *ServiceArray) GetSize() int64 {
 	return int64(len(s.arr))
 }
 
-func (s *ServiceArray) GetService(i int64) *registry.ServiceURL {
+func (s *ServiceArray) GetService(i int64) *registry.DefaultServiceURL {
 	return s.arr[i]
 }
 
@@ -60,12 +60,12 @@ func (s *ServiceArray) String() string {
 	return builder.String()
 }
 
-func (s *ServiceArray) add(registry *registry.ServiceURL, ttl time.Duration) {
+func (s *ServiceArray) add(registry *registry.DefaultServiceURL, ttl time.Duration) {
 	s.arr = append(s.arr, registry)
 	s.birth = time.Now().Add(ttl)
 }
 
-func (s *ServiceArray) del(registry *registry.ServiceURL, ttl time.Duration) {
+func (s *ServiceArray) del(registry *registry.DefaultServiceURL, ttl time.Duration) {
 	for i, svc := range s.arr {
 		if svc.PrimitiveURL == registry.PrimitiveURL {
 			s.arr = append(s.arr[:i], s.arr[i+1:]...)
diff --git a/client/selector/random.go b/client/selector/random.go
index 0161807c2..a4d1d7356 100644
--- a/client/selector/random.go
+++ b/client/selector/random.go
@@ -16,7 +16,7 @@ func NewRandomSelector() Selector {
 	return &RandomSelector{}
 }
 
-func (s *RandomSelector) Select(ID int64, array client.ServiceArrayIf) (*registry.ServiceURL, error) {
+func (s *RandomSelector) Select(ID int64, array client.ServiceArrayIf) (*registry.DefaultServiceURL, error) {
 	if array.GetSize() == 0 {
 		return nil, ServiceArrayEmpty
 	}
diff --git a/client/selector/round_robin.go b/client/selector/round_robin.go
index f9058974b..4d4585c53 100644
--- a/client/selector/round_robin.go
+++ b/client/selector/round_robin.go
@@ -15,7 +15,7 @@ func NewRoundRobinSelector() Selector {
 	return &RoundRobinSelector{}
 }
 
-func (s *RoundRobinSelector) Select(ID int64, array client.ServiceArrayIf) (*registry.ServiceURL, error) {
+func (s *RoundRobinSelector) Select(ID int64, array client.ServiceArrayIf) (*registry.DefaultServiceURL, error) {
 	if array.GetSize() == 0 {
 		return nil, ServiceArrayEmpty
 	}
diff --git a/client/selector/selector.go b/client/selector/selector.go
index 56eb82a02..8ec13561c 100644
--- a/client/selector/selector.go
+++ b/client/selector/selector.go
@@ -14,5 +14,5 @@ var (
 )
 
 type Selector interface {
-	Select(ID int64, array client.ServiceArrayIf) (*registry.ServiceURL, error)
+	Select(ID int64, array client.ServiceArrayIf) (*registry.DefaultServiceURL, error)
 }
diff --git a/client/service_array.go b/client/service_array.go
index e24e4593b..267275a30 100644
--- a/client/service_array.go
+++ b/client/service_array.go
@@ -7,5 +7,5 @@ import (
 type ServiceArrayIf interface {
 	GetIdx() *int64
 	GetSize() int64
-	GetService(i int64) *registry.ServiceURL
+	GetService(i int64) *registry.DefaultServiceURL
 }
diff --git a/dubbo/client.go b/dubbo/client.go
index 286bac1e8..76f2ad756 100644
--- a/dubbo/client.go
+++ b/dubbo/client.go
@@ -104,7 +104,7 @@ func NewClient(conf *ClientConfig) (*Client, error) {
 }
 
 // call one way
-func (c *Client) CallOneway(addr string, svcUrl registry.ServiceURL, method string, args interface{}, opts ...CallOption) error {
+func (c *Client) CallOneway(addr string, svcUrl registry.DefaultServiceURL, method string, args interface{}, opts ...CallOption) error {
 	var copts CallOptions
 
 	for _, o := range opts {
@@ -115,7 +115,7 @@ func (c *Client) CallOneway(addr string, svcUrl registry.ServiceURL, method stri
 }
 
 // if @reply is nil, the transport layer will get the response without notify the invoker.
-func (c *Client) Call(addr string, svcUrl registry.ServiceURL, method string, args, reply interface{}, opts ...CallOption) error {
+func (c *Client) Call(addr string, svcUrl registry.DefaultServiceURL, method string, args, reply interface{}, opts ...CallOption) error {
 	var copts CallOptions
 
 	for _, o := range opts {
@@ -130,7 +130,7 @@ func (c *Client) Call(addr string, svcUrl registry.ServiceURL, method string, ar
 	return jerrors.Trace(c.call(ct, addr, svcUrl, method, args, reply, nil, copts))
 }
 
-func (c *Client) AsyncCall(addr string, svcUrl registry.ServiceURL, method string, args interface{},
+func (c *Client) AsyncCall(addr string, svcUrl registry.DefaultServiceURL, method string, args interface{},
 	callback AsyncCallback, reply interface{}, opts ...CallOption) error {
 
 	var copts CallOptions
@@ -141,7 +141,7 @@ func (c *Client) AsyncCall(addr string, svcUrl registry.ServiceURL, method strin
 	return jerrors.Trace(c.call(CT_TwoWay, addr, svcUrl, method, args, reply, callback, copts))
 }
 
-func (c *Client) call(ct CallType, addr string, svcUrl registry.ServiceURL, method string,
+func (c *Client) call(ct CallType, addr string, svcUrl registry.DefaultServiceURL, method string,
 	args, reply interface{}, callback AsyncCallback, opts CallOptions) error {
 
 	if opts.RequestTimeout == 0 {
diff --git a/examples/client_config.go b/examples/client_config.go
index fb8c1d645..37a7f34ae 100644
--- a/examples/client_config.go
+++ b/examples/client_config.go
@@ -2,7 +2,7 @@ package examples
 
 import (
 	"fmt"
-
+	"github.com/dubbo/dubbo-go/plugins"
 	"io/ioutil"
 	"os"
 	"path"
@@ -13,7 +13,7 @@ import (
 	"github.com/AlexStocks/goext/log"
 	log "github.com/AlexStocks/log4go"
 	jerrors "github.com/juju/errors"
-	yaml "gopkg.in/yaml.v2"
+	"gopkg.in/yaml.v2"
 )
 
 import (
@@ -50,7 +50,9 @@ type (
 		Application_Config registry.ApplicationConfig `yaml:"application_config" json:"application_config,omitempty"`
 		ZkRegistryConfig   zookeeper.ZkRegistryConfig `yaml:"zk_registry_config" json:"zk_registry_config,omitempty"`
 		// 涓€涓鎴风鍙厑璁镐娇鐢ㄤ竴涓猻ervice鐨勫叾涓竴涓猤roup鍜屽叾涓竴涓獀ersion
-		Service_List []registry.DefaultServiceConfig `yaml:"service_list" json:"service_list,omitempty"`
+		ServiceConfigType string                   `default:"default" yaml:"service_config_type" json:"service_config_type,omitempty"`
+		Service_List      []registry.ServiceConfig `yaml:"-"`
+		ServiceList       []map[string]string      `yaml:"service_list" json:"service_list,omitempty"`
 	}
 )
 
@@ -83,6 +85,19 @@ func InitClientConfig() *ClientConfig {
 		panic(fmt.Sprintf("yaml.Unmarshal() = error:%s", jerrors.ErrorStack(err)))
 		return nil
 	}
+
+	//鍔ㄦ€佸姞杞絪ervice config
+	//璁剧疆榛樿ProviderServiceConfig绫�
+	plugins.SetDefaultServiceConfig(clientConfig.ServiceConfigType)
+
+	for _, service := range clientConfig.ServiceList {
+		svc := plugins.DefaultServiceConfig()()
+		svc.SetProtocol(service["protocol"])
+		svc.SetService(service["service"])
+		clientConfig.Service_List = append(clientConfig.Service_List, svc)
+	}
+	//鍔ㄦ€佸姞杞絪ervice config  end
+
 	if clientConfig.ZkRegistryConfig.Timeout, err = time.ParseDuration(clientConfig.ZkRegistryConfig.TimeoutStr); err != nil {
 		panic(fmt.Sprintf("time.ParseDuration(Registry_Config.Timeout:%#v) = error:%s", clientConfig.ZkRegistryConfig.TimeoutStr, err))
 		return nil
diff --git a/examples/dubbo/go-client/app/client.go b/examples/dubbo/go-client/app/client.go
index e13004e2e..19a1b3b23 100644
--- a/examples/dubbo/go-client/app/client.go
+++ b/examples/dubbo/go-client/app/client.go
@@ -86,9 +86,9 @@ func initClient(clientConfig *examples.ClientConfig) {
 	}
 
 	for idx := range clientConfig.Service_List {
-		codecType = public.GetCodecType(clientConfig.Service_List[idx].Protocol)
+		codecType = public.GetCodecType(clientConfig.Service_List[idx].Protocol())
 		if codecType == public.CODECTYPE_UNKNOWN {
-			panic(fmt.Sprintf("unknown protocol %s", clientConfig.Service_List[idx].Protocol))
+			panic(fmt.Sprintf("unknown protocol %s", clientConfig.Service_List[idx].Protocol()))
 		}
 	}
 
diff --git a/examples/dubbo/go-client/app/test.go b/examples/dubbo/go-client/app/test.go
index aafd05db5..095d87636 100644
--- a/examples/dubbo/go-client/app/test.go
+++ b/examples/dubbo/go-client/app/test.go
@@ -16,7 +16,6 @@ import (
 	"github.com/dubbo/dubbo-go/dubbo"
 	"github.com/dubbo/dubbo-go/examples"
 	"github.com/dubbo/dubbo-go/public"
-	"github.com/dubbo/dubbo-go/registry"
 )
 
 func testDubborpc(clientConfig *examples.ClientConfig, userKey string) {
@@ -26,12 +25,11 @@ func testDubborpc(clientConfig *examples.ClientConfig, userKey string) {
 		method     string
 		serviceIdx int
 		user       *DubboUser
-		conf       registry.DefaultServiceConfig
 	)
 	serviceIdx = -1
 	svc = "com.ikurento.user.UserProvider"
 	for i := range clientConfig.Service_List {
-		if clientConfig.Service_List[i].Service == svc && clientConfig.Service_List[i].Protocol == public.CODECTYPE_DUBBO.String() {
+		if clientConfig.Service_List[i].Service() == svc && clientConfig.Service_List[i].Protocol() == public.CODECTYPE_DUBBO.String() {
 			serviceIdx = i
 			break
 		}
@@ -42,12 +40,6 @@ func testDubborpc(clientConfig *examples.ClientConfig, userKey string) {
 
 	// Create request
 	method = string("GetUser")
-	conf = registry.DefaultServiceConfig{
-		Group:    clientConfig.Service_List[serviceIdx].Group,
-		Protocol: public.CodecType(public.CODECTYPE_DUBBO).String(),
-		Version:  clientConfig.Service_List[serviceIdx].Version,
-		Service:  clientConfig.Service_List[serviceIdx].Service,
-	}
 
 	// registry pojo
 	hessian.RegisterJavaEnum(Gender(MAN))
@@ -57,7 +49,7 @@ func testDubborpc(clientConfig *examples.ClientConfig, userKey string) {
 
 	user = new(DubboUser)
 	defer clientInvoker.DubboClient.Close()
-	err = clientInvoker.DubboCall(1, conf, method, []interface{}{userKey}, user, dubbo.WithCallRequestTimeout(10e9), dubbo.WithCallResponseTimeout(10e9), dubbo.WithCallSerialID(dubbo.S_Dubbo))
+	err = clientInvoker.DubboCall(1, clientConfig.Service_List[serviceIdx], method, []interface{}{userKey}, user, dubbo.WithCallRequestTimeout(10e9), dubbo.WithCallResponseTimeout(10e9), dubbo.WithCallSerialID(dubbo.S_Dubbo))
 	// Call service
 	if err != nil {
 		log.Error("client.Call() return error:%+v", jerrors.ErrorStack(err))
diff --git a/examples/jsonrpc/go-client/app/client.go b/examples/jsonrpc/go-client/app/client.go
index d46aaf111..c543702d3 100644
--- a/examples/jsonrpc/go-client/app/client.go
+++ b/examples/jsonrpc/go-client/app/client.go
@@ -89,9 +89,9 @@ func initClient(clientConfig *examples.ClientConfig) {
 	}
 
 	for idx := range clientConfig.Service_List {
-		codecType = public.GetCodecType(clientConfig.Service_List[idx].Protocol)
+		codecType = public.GetCodecType(clientConfig.Service_List[idx].Protocol())
 		if codecType == public.CODECTYPE_UNKNOWN {
-			panic(fmt.Sprintf("unknown protocol %s", clientConfig.Service_List[idx].Protocol))
+			panic(fmt.Sprintf("unknown protocol %s", clientConfig.Service_List[idx].Protocol()))
 		}
 	}
 
diff --git a/examples/jsonrpc/go-client/app/test.go b/examples/jsonrpc/go-client/app/test.go
index cb9ea0220..15db3efa8 100644
--- a/examples/jsonrpc/go-client/app/test.go
+++ b/examples/jsonrpc/go-client/app/test.go
@@ -11,10 +11,9 @@ import (
 )
 
 import (
+	"github.com/dubbo/dubbo-go/client"
 	"github.com/dubbo/dubbo-go/examples"
 	"github.com/dubbo/dubbo-go/public"
-	"github.com/dubbo/dubbo-go/client"
-	"github.com/dubbo/dubbo-go/registry"
 )
 
 func testJsonrpc(clientConfig *examples.ClientConfig, userKey string, method string) {
@@ -24,14 +23,13 @@ func testJsonrpc(clientConfig *examples.ClientConfig, userKey string, method str
 		serviceIdx int
 		user       *JsonRPCUser
 		ctx        context.Context
-		conf       registry.DefaultServiceConfig
 		req        client.Request
 	)
 
 	serviceIdx = -1
 	svc = "com.ikurento.user.UserProvider"
 	for i := range clientConfig.Service_List {
-		if clientConfig.Service_List[i].Service == svc && clientConfig.Service_List[i].Protocol == public.CODECTYPE_JSONRPC.String() {
+		if clientConfig.Service_List[i].Service() == svc && clientConfig.Service_List[i].Protocol() == public.CODECTYPE_JSONRPC.String() {
 			serviceIdx = i
 			break
 		}
@@ -42,14 +40,13 @@ func testJsonrpc(clientConfig *examples.ClientConfig, userKey string, method str
 
 	// Create request
 	// gxlog.CInfo("jsonrpc selected service %#v", clientConfig.Service_List[serviceIdx])
-	conf = registry.DefaultServiceConfig{
-		Group:    clientConfig.Service_List[serviceIdx].Group,
-		Protocol: public.CodecType(public.CODECTYPE_JSONRPC).String(),
-		Version:  clientConfig.Service_List[serviceIdx].Version,
-		Service:  clientConfig.Service_List[serviceIdx].Service,
-	}
+
 	// Attention the last parameter : []UserKey{userKey}
-	req = clientInvoker.HttpClient.NewRequest(conf, method, []string{userKey})
+	req, err = clientInvoker.HttpClient.NewRequest(clientConfig.Service_List[serviceIdx], method, []string{userKey})
+
+	if err != nil {
+		panic(err)
+	}
 
 	ctx = context.WithValue(context.Background(), public.DUBBOGO_CTX_KEY, map[string]string{
 		"X-Proxy-Id": "dubbogo",
diff --git a/examples/jsonrpc/go-client/profiles/dev/client.yml b/examples/jsonrpc/go-client/profiles/dev/client.yml
index 576fda613..47a364f90 100644
--- a/examples/jsonrpc/go-client/profiles/dev/client.yml
+++ b/examples/jsonrpc/go-client/profiles/dev/client.yml
@@ -29,6 +29,7 @@ zk_registry_config:
     address:
         - "127.0.0.1:2181"
 
+service_config_type: "default"
 service_list:
     -
         protocol : "jsonrpc"
diff --git a/examples/jsonrpc/go-server/app/config.go b/examples/jsonrpc/go-server/app/config.go
index ff69320cb..eb3a4e1ee 100644
--- a/examples/jsonrpc/go-server/app/config.go
+++ b/examples/jsonrpc/go-server/app/config.go
@@ -2,6 +2,7 @@ package main
 
 import (
 	"fmt"
+	"github.com/dubbo/dubbo-go/plugins"
 	"io/ioutil"
 	"os"
 	"path"
@@ -43,10 +44,13 @@ type (
 		// application
 		Application_Config registry.ApplicationConfig `yaml:"application_config" json:"application_config,omitempty"`
 		// Registry_Address  string `default:"192.168.35.3:2181"`
-		Registry         string                          `default:"zookeeper"  yaml:"registry" json:"registry,omitempty"`
-		ZkRegistryConfig zookeeper.ZkRegistryConfig      `yaml:"zk_registry_config" json:"zk_registry_config,omitempty"`
-		Service_List     []registry.DefaultServiceConfig `yaml:"service_list" json:"service_list,omitempty"`
-		Server_List      []server.ServerConfig           `yaml:"server_list" json:"server_list,omitempty"`
+		Registry         string                           `default:"zookeeper"  yaml:"registry" json:"registry,omitempty"`
+		ZkRegistryConfig zookeeper.ZkRegistryConfig       `yaml:"zk_registry_config" json:"zk_registry_config,omitempty"`
+		Service_List     []registry.ProviderServiceConfig `yaml:"-"`
+
+		ServiceConfigType string                `default:"default" yaml:"service_config_type" json:"service_config_type,omitempty"`
+		ServiceList       []map[string]string   `yaml:"service_list" json:"service_list,omitempty"`
+		Server_List       []server.ServerConfig `yaml:"server_list" json:"server_list,omitempty"`
 	}
 )
 
@@ -73,6 +77,22 @@ func initServerConf() *ServerConfig {
 		return nil
 	}
 	err = yaml.Unmarshal(confFileStream, conf)
+
+	//鍔ㄦ€佸姞杞絪ervice config
+	//璁剧疆榛樿ProviderServiceConfig绫�
+	plugins.SetDefaultProviderServiceConfig(conf.ServiceConfigType)
+	fmt.Println(1111)
+	for _, service := range conf.ServiceList {
+
+		svc := plugins.DefaultProviderServiceConfig()()
+		svc.SetProtocol(service["protocol"])
+		fmt.Println(service["protocol"])
+		fmt.Println(svc.Protocol())
+		svc.SetService(service["service"])
+		fmt.Println(svc)
+		conf.Service_List = append(conf.Service_List, svc)
+	}
+	//鍔ㄦ€佸姞杞絪ervice config  end
 	if err != nil {
 		panic(fmt.Sprintf("yaml.Unmarshal() = error:%s", jerrors.ErrorStack(err)))
 		return nil
diff --git a/examples/jsonrpc/go-server/profiles/dev/server.yml b/examples/jsonrpc/go-server/profiles/dev/server.yml
index 3af5ae4b8..2e0abd515 100644
--- a/examples/jsonrpc/go-server/profiles/dev/server.yml
+++ b/examples/jsonrpc/go-server/profiles/dev/server.yml
@@ -23,7 +23,7 @@ zk_registry_config:
     timeout	: "3s"
     address:
         - "127.0.0.1:2181"
-
+service_config_type: "default"
 service_list:
     -
         protocol : "jsonrpc"
diff --git a/jsonrpc/http.go b/jsonrpc/http.go
index 346be011f..e962a9bd0 100644
--- a/jsonrpc/http.go
+++ b/jsonrpc/http.go
@@ -20,9 +20,9 @@ import (
 )
 
 import (
+	"github.com/dubbo/dubbo-go/client"
 	"github.com/dubbo/dubbo-go/public"
 	"github.com/dubbo/dubbo-go/registry"
-	"github.com/dubbo/dubbo-go/client"
 )
 
 //////////////////////////////////////////////
@@ -38,15 +38,11 @@ type Request struct {
 	method      string
 	args        interface{}
 	contentType string
+	conf        registry.ServiceConfig
 }
 
-func (r *Request) ServiceConfig() registry.DefaultServiceConfig {
-	return registry.DefaultServiceConfig{
-		Protocol: r.protocol,
-		Service:  r.service,
-		Group:    r.group,
-		Version:  r.version,
-	}
+func (r *Request) ServiceConfig() registry.ServiceConfig {
+	return r.conf
 }
 
 //////////////////////////////////////////////
@@ -87,19 +83,21 @@ func NewHTTPClient(opt *HTTPOptions) *HTTPClient {
 	}
 }
 
-func (c *HTTPClient) NewRequest(conf registry.DefaultServiceConfig, method string, args interface{}) client.Request {
+func (c *HTTPClient) NewRequest(conf registry.ServiceConfig, method string, args interface{}) (client.Request, error) {
+
 	return &Request{
 		ID:       atomic.AddInt64(&c.ID, 1),
-		group:    conf.Group,
-		protocol: conf.Protocol,
-		version:  conf.Version,
-		service:  conf.Service,
+		group:    conf.Group(),
+		protocol: conf.Protocol(),
+		version:  conf.Version(),
+		service:  conf.Service(),
 		method:   method,
 		args:     args,
-	}
+		conf:	  conf,
+	}, nil
 }
 
-func (c *HTTPClient) Call(ctx context.Context, service *registry.ServiceURL, request client.Request, rsp interface{}) error {
+func (c *HTTPClient) Call(ctx context.Context, service *registry.DefaultServiceURL, request client.Request, rsp interface{}) error {
 	// header
 	req := request.(*Request)
 	httpHeader := http.Header{}
diff --git a/jsonrpc/server.go b/jsonrpc/server.go
index 1ae3bde05..d8604d4b1 100644
--- a/jsonrpc/server.go
+++ b/jsonrpc/server.go
@@ -4,6 +4,7 @@ import (
 	"bufio"
 	"bytes"
 	"context"
+	"github.com/dubbo/dubbo-go/plugins"
 	"io/ioutil"
 	"net"
 	"net/http"
@@ -60,7 +61,7 @@ type Option func(*Options)
 type Options struct {
 	Registry        registry.Registry
 	ConfList        []server.ServerConfig
-	ServiceConfList []registry.DefaultServiceConfig
+	ServiceConfList []registry.ProviderServiceConfig
 	Timeout         time.Duration
 }
 
@@ -95,7 +96,7 @@ func ConfList(confList []server.ServerConfig) Option {
 	}
 }
 
-func ServiceConfList(confList []registry.DefaultServiceConfig) Option {
+func ServiceConfList(confList []registry.ProviderServiceConfig) Option {
 	return func(o *Options) {
 		o.ServiceConfList = confList
 	}
@@ -236,35 +237,38 @@ func (s *Server) Options() Options {
 
 func (s *Server) Handle(h Handler) error {
 	var (
-		err         error
-		serviceConf registry.ProviderServiceConfig
+		err error
 	)
 
 	opts := s.Options()
+	serviceConf := plugins.DefaultProviderServiceConfig()()
 
-	serviceConf.Service = h.Service()
-	serviceConf.Version = h.Version()
+	serviceConf.SetService(h.Service())
+	serviceConf.SetVersion(h.Version())
 
 	flag := 0
 	serviceNum := len(opts.ServiceConfList)
 	ServerNum := len(opts.ConfList)
 	for i := 0; i < serviceNum; i++ {
-		if opts.ServiceConfList[i].Service == serviceConf.Service &&
-			opts.ServiceConfList[i].Version == serviceConf.Version {
+		if opts.ServiceConfList[i].Service() == serviceConf.Service() &&
+			opts.ServiceConfList[i].Version() == serviceConf.Version() {
 
-			serviceConf.Protocol = opts.ServiceConfList[i].Protocol
-			serviceConf.Group = opts.ServiceConfList[i].Group
+			serviceConf.SetProtocol(opts.ServiceConfList[i].Protocol())
+			serviceConf.SetGroup(opts.ServiceConfList[i].Group())
 			// serviceConf.Version = opts.ServiceConfList[i].Version
+			var methods, path string
 			for j := 0; j < ServerNum; j++ {
-				if opts.ConfList[j].Protocol == serviceConf.Protocol {
+				if opts.ConfList[j].Protocol == serviceConf.Protocol() {
 					s.Lock()
-					serviceConf.Methods, err = s.rpc[j].register(h)
+					methods, err = s.rpc[j].register(h)
 					s.Unlock()
 					if err != nil {
 						return err
 					}
+					serviceConf.SetMethods(methods)
 
-					serviceConf.Path = opts.ConfList[j].Address()
+					path = opts.ConfList[j].Address()
+					serviceConf.SetPath(path)
 					err = opts.Registry.Register(serviceConf)
 					if err != nil {
 						return err
@@ -277,7 +281,7 @@ func (s *Server) Handle(h Handler) error {
 
 	if flag == 0 {
 		return jerrors.Errorf("fail to register Handler{service:%s, version:%s}",
-			serviceConf.Service, serviceConf.Version)
+			serviceConf.Service(), serviceConf.Version())
 	}
 
 	s.Lock()
diff --git a/plugins/plugins.go b/plugins/plugins.go
index 3496b0f43..9cbe723ba 100644
--- a/plugins/plugins.go
+++ b/plugins/plugins.go
@@ -14,3 +14,44 @@ var PluggableLoadbalance = map[string]func() selector.Selector{
 	"round_robin": selector.NewRoundRobinSelector,
 	"random":      selector.NewRandomSelector,
 }
+
+// service configuration plugins , related to SeviceConfig for consumer paramters / ProviderSeviceConfig for provider parameters /
+
+// TODO:ServiceEven & ServiceURL subscribed by consumer from provider's listener shoud abstract to interface
+var PluggableServiceConfig = map[string]func() registry.ServiceConfig{
+	"default": registry.NewDefaultServiceConfig,
+}
+var PluggableProviderServiceConfig = map[string]func() registry.ProviderServiceConfig{
+	"default": registry.NewDefaultProviderServiceConfig,
+}
+
+//var PluggableServiceURL = map[string]func(string) (registry.ServiceURL, error){
+//	"default": registry.NewDefaultServiceURL,
+//}
+
+var defaultServiceConfig = registry.NewDefaultServiceConfig
+var defaultProviderServiceConfig = registry.NewDefaultProviderServiceConfig
+
+//var defaultServiceURL = registry.NewDefaultServiceURL
+
+func SetDefaultServiceConfig(s string) {
+	defaultServiceConfig = PluggableServiceConfig[s]
+}
+func DefaultServiceConfig() func() registry.ServiceConfig {
+	return defaultServiceConfig
+}
+
+func SetDefaultProviderServiceConfig(s string) {
+	defaultProviderServiceConfig = PluggableProviderServiceConfig[s]
+}
+func DefaultProviderServiceConfig() func() registry.ProviderServiceConfig {
+	return defaultProviderServiceConfig
+}
+
+//
+//func SetDefaultServiceURL(s string) {
+//	defaultProviderServiceConfig = PluggableProviderServiceConfig[s]
+//}
+//func DefaultServiceURL() func() registry.ProviderServiceConfig {
+//	return defaultProviderServiceConfig
+//}
diff --git a/registry/event.go b/registry/event.go
index 97f9a15c2..a6cb1991c 100644
--- a/registry/event.go
+++ b/registry/event.go
@@ -36,7 +36,7 @@ func (t ServiceEventType) String() string {
 
 type ServiceEvent struct {
 	Action  ServiceEventType
-	Service *ServiceURL
+	Service *DefaultServiceURL
 }
 
 func (e ServiceEvent) String() string {
diff --git a/registry/registry.go b/registry/registry.go
index acc5965eb..0efb368e6 100644
--- a/registry/registry.go
+++ b/registry/registry.go
@@ -15,7 +15,7 @@ type Registry interface {
 	Subscribe() (Listener, error)
 
 	//input the serviceConfig , registry should return serviceUrlArray with multi location(provider nodes) available
-	GetService(DefaultServiceConfig) ([]*ServiceURL, error)
+	GetService(ServiceConfig) ([]*DefaultServiceURL, error)
 	//close the registry for Elegant closing
 	Close()
 	//return if the registry is closed for consumer subscribing
diff --git a/registry/service.go b/registry/service.go
index 083b46d56..60ddc4716 100644
--- a/registry/service.go
+++ b/registry/service.go
@@ -20,55 +20,143 @@ import (
 type ServiceConfig interface {
 	Key() string
 	String() string
-	ServiceEqual(url *ServiceURL) bool
+	ServiceEqual(url *DefaultServiceURL) bool
+	//your service config implements must contain properties below
+	Service() string
+	Protocol() string
+	Version() string
+	Group() string
+	SetProtocol(string)
+	SetService(string)
+}
+
+type ProviderServiceConfig interface {
+	Key() string
+	String() string
+	ServiceEqual(url *DefaultServiceURL) bool
+	//your service config implements must contain properties below
+	Service() string
+	Protocol() string
+	Version() string
+	Group() string
+	Methods() string
+	Path() string
+	SetService(string)
+	SetVersion(string)
+	SetMethods(string)
+	SetPath(string)
+	SetProtocol(string)
+	SetGroup(string)
 }
 
 type DefaultServiceConfig struct {
-	Protocol string `required:"true",default:"dubbo"  yaml:"protocol"  json:"protocol,omitempty"`
-	Service  string `required:"true"  yaml:"service"  json:"service,omitempty"`
-	Group    string `yaml:"group" json:"group,omitempty"`
-	Version  string `yaml:"version" json:"version,omitempty"`
+	DProtocol string `required:"true",default:"dubbo"  yaml:"protocol"  json:"protocol,omitempty"`
+	DService  string `required:"true"  yaml:"service"  json:"service,omitempty"`
+	DGroup    string `yaml:"group" json:"group,omitempty"`
+	DVersion  string `yaml:"version" json:"version,omitempty"`
 }
 
-func (c DefaultServiceConfig) Key() string {
-	return fmt.Sprintf("%s@%s", c.Service, c.Protocol)
+func NewDefaultServiceConfig() ServiceConfig {
+	return &DefaultServiceConfig{}
 }
 
-func (c DefaultServiceConfig) String() string {
-	return fmt.Sprintf("%s@%s-%s-%s", c.Service, c.Protocol, c.Group, c.Version)
+func (c *DefaultServiceConfig) Key() string {
+	return fmt.Sprintf("%s@%s", c.DService, c.DProtocol)
 }
 
-func (c DefaultServiceConfig) ServiceEqual(url *ServiceURL) bool {
-	if c.Protocol != url.Protocol {
+func (c *DefaultServiceConfig) String() string {
+	return fmt.Sprintf("%s@%s-%s-%s", c.DService, c.DProtocol, c.DGroup, c.DVersion)
+}
+
+func (c *DefaultServiceConfig) ServiceEqual(url *DefaultServiceURL) bool {
+	if c.DProtocol != url.Protocol {
 		return false
 	}
 
-	if c.Service != url.Query.Get("interface") {
+	if c.DService != url.Query.Get("interface") {
 		return false
 	}
 
-	if c.Group != url.Group {
+	if c.DGroup != url.Group {
 		return false
 	}
 
-	if c.Version != url.Version {
+	if c.DVersion != url.Version {
 		return false
 	}
 
 	return true
 }
 
-type ProviderServiceConfig struct {
-	DefaultServiceConfig
-	Path    string `yaml:"path" json:"path,omitempty"`
-	Methods string `yaml:"methods" json:"methods,omitempty"`
+func (c *DefaultServiceConfig) Service() string {
+	return c.DService
+}
+
+func (c *DefaultServiceConfig) Protocol() string {
+	return c.DProtocol
+}
+
+func (c *DefaultServiceConfig) Version() string {
+	return c.DVersion
+}
+
+func (c *DefaultServiceConfig) Group() string {
+	return c.DGroup
+}
+func (c *DefaultServiceConfig) SetProtocol(s string) {
+	c.DProtocol = s
+}
+
+func (c *DefaultServiceConfig) SetService(s string) {
+	c.DService = s
+}
+
+type DefaultProviderServiceConfig struct {
+	*DefaultServiceConfig
+	DPath    string `yaml:"path" json:"path,omitempty"`
+	DMethods string `yaml:"methods" json:"methods,omitempty"`
+}
+
+func NewDefaultProviderServiceConfig() ProviderServiceConfig {
+	return &DefaultProviderServiceConfig{
+		DefaultServiceConfig: NewDefaultServiceConfig().(*DefaultServiceConfig),
+	}
+}
+
+func (c *DefaultProviderServiceConfig) Methods() string {
+	return c.DMethods
+}
+
+func (c *DefaultProviderServiceConfig) Path() string {
+	return c.DPath
+}
+
+func (c *DefaultProviderServiceConfig) SetVersion(s string) {
+	c.DVersion = s
+}
+
+func (c *DefaultProviderServiceConfig) SetMethods(s string) {
+	c.DMethods = s
+}
+
+func (c *DefaultProviderServiceConfig) SetPath(s string) {
+	c.DPath = s
+}
+
+func (c *DefaultProviderServiceConfig) SetGroup(s string) {
+	c.DGroup = s
 }
 
 //////////////////////////////////////////
 // service url
 //////////////////////////////////////////
 
-type ServiceURL struct {
+type ServiceURL interface {
+	ServiceConfig() ServiceConfig
+	CheckMethod(string) bool
+}
+
+type DefaultServiceURL struct {
 	Protocol     string
 	Location     string // ip+port
 	Path         string // like  /com.ikurento.dubbo.UserProvider3
@@ -82,12 +170,12 @@ type ServiceURL struct {
 	PrimitiveURL string
 }
 
-func NewServiceURL(urlString string) (*ServiceURL, error) {
+func NewDefaultServiceURL(urlString string) (*DefaultServiceURL, error) {
 	var (
 		err          error
 		rawUrlString string
 		serviceUrl   *url.URL
-		s            = &ServiceURL{}
+		s            = &DefaultServiceURL{}
 	)
 
 	rawUrlString, err = url.QueryUnescape(urlString)
@@ -131,25 +219,25 @@ func NewServiceURL(urlString string) (*ServiceURL, error) {
 	return s, nil
 }
 
-func (s ServiceURL) String() string {
+func (s DefaultServiceURL) String() string {
 	return fmt.Sprintf(
-		"ServiceURL{Protocol:%s, Location:%s, Path:%s, Ip:%s, Port:%s, "+
+		"DefaultServiceURL{Protocol:%s, Location:%s, Path:%s, Ip:%s, Port:%s, "+
 			"Timeout:%s, Version:%s, Group:%s, Weight:%d, Query:%+v}",
 		s.Protocol, s.Location, s.Path, s.Ip, s.Port,
 		s.Timeout, s.Version, s.Group, s.Weight, s.Query)
 }
 
-func (s *ServiceURL) ServiceConfig() DefaultServiceConfig {
+func (s *DefaultServiceURL) ServiceConfig() ServiceConfig {
 	interfaceName := s.Query.Get("interface")
-	return DefaultServiceConfig{
-		Protocol: s.Protocol,
-		Service:  interfaceName,
-		Group:    s.Group,
-		Version:  s.Version,
+	return &DefaultServiceConfig{
+		DProtocol: s.Protocol,
+		DService:  interfaceName,
+		DGroup:    s.Group,
+		DVersion:  s.Version,
 	}
 }
 
-func (s *ServiceURL) CheckMethod(method string) bool {
+func (s *DefaultServiceURL) CheckMethod(method string) bool {
 	var (
 		methodArray []string
 	)
diff --git a/registry/zookeeper/consumer.go b/registry/zookeeper/consumer.go
index b950a74d4..704e71206 100644
--- a/registry/zookeeper/consumer.go
+++ b/registry/zookeeper/consumer.go
@@ -14,16 +14,16 @@ import (
 )
 
 // name: service@protocol
-func (r *ZkRegistry) GetService(conf registry.DefaultServiceConfig) ([]*registry.ServiceURL, error) {
+func (r *ZkRegistry) GetService(conf registry.ServiceConfig) ([]*registry.DefaultServiceURL, error) {
+
 	var (
-		ok            bool
 		err           error
 		dubboPath     string
 		nodes         []string
 		listener      *zkEventListener
-		serviceURL    *registry.ServiceURL
-		serviceConfIf registry.ServiceConfig
-		serviceConf   registry.DefaultServiceConfig
+		serviceURL    *registry.DefaultServiceURL
+		serviceConf registry.ServiceConfig
+		ok            bool
 	)
 	r.listenerLock.Lock()
 	listener = r.listener
@@ -34,17 +34,16 @@ func (r *ZkRegistry) GetService(conf registry.DefaultServiceConfig) ([]*registry
 	}
 
 	r.cltLock.Lock()
-	serviceConfIf, ok = r.services[conf.Key()]
+	serviceConf, ok = r.services[conf.Key()]
 	r.cltLock.Unlock()
 	if !ok {
 		return nil, jerrors.Errorf("Service{%s} has not been registered", conf.Key())
 	}
-	serviceConf, ok = serviceConfIf.(registry.DefaultServiceConfig)
 	if !ok {
 		return nil, jerrors.Errorf("Service{%s}: failed to get serviceConfigIf type", conf.Key())
 	}
 
-	dubboPath = fmt.Sprintf("/dubbo/%s/providers", conf.Service)
+	dubboPath = fmt.Sprintf("/dubbo/%s/providers", conf.Service())
 	err = r.validateZookeeperClient()
 	if err != nil {
 		return nil, jerrors.Trace(err)
@@ -57,11 +56,11 @@ func (r *ZkRegistry) GetService(conf registry.DefaultServiceConfig) ([]*registry
 		return nil, jerrors.Trace(err)
 	}
 
-	var listenerServiceMap = make(map[string]*registry.ServiceURL)
+	var listenerServiceMap = make(map[string]*registry.DefaultServiceURL)
 	for _, n := range nodes {
-		serviceURL, err = registry.NewServiceURL(n)
+		serviceURL, err = registry.NewDefaultServiceURL(n)
 		if err != nil {
-			log.Error("NewServiceURL({%s}) = error{%v}", n, err)
+			log.Error("NewDefaultServiceURL({%s}) = error{%v}", n, err)
 			continue
 		}
 		if !serviceConf.ServiceEqual(serviceURL) {
@@ -76,7 +75,7 @@ func (r *ZkRegistry) GetService(conf registry.DefaultServiceConfig) ([]*registry
 		}
 	}
 
-	var services []*registry.ServiceURL
+	var services []*registry.DefaultServiceURL
 	for _, service := range listenerServiceMap {
 		services = append(services, service)
 	}
@@ -91,9 +90,7 @@ func (r *ZkRegistry) Subscribe() (registry.Listener, error) {
 
 func (r *ZkRegistry) getListener() (*zkEventListener, error) {
 	var (
-		ok          bool
 		zkListener  *zkEventListener
-		serviceConf registry.DefaultServiceConfig
 	)
 
 	r.listenerLock.Lock()
@@ -120,9 +117,7 @@ func (r *ZkRegistry) getListener() (*zkEventListener, error) {
 	// listen
 	r.cltLock.Lock()
 	for _, svs := range r.services {
-		if serviceConf, ok = svs.(registry.DefaultServiceConfig); ok {
-			go zkListener.listenServiceEvent(serviceConf)
-		}
+			go zkListener.listenServiceEvent(svs)
 	}
 	r.cltLock.Unlock()
 
diff --git a/registry/zookeeper/listener.go b/registry/zookeeper/listener.go
index f9f698cc9..2ec717a37 100644
--- a/registry/zookeeper/listener.go
+++ b/registry/zookeeper/listener.go
@@ -82,7 +82,7 @@ func (l *zkEventListener) listenServiceNodeEvent(zkPath string) bool {
 	return false
 }
 
-func (l *zkEventListener) handleZkNodeEvent(zkPath string, children []string, conf registry.DefaultServiceConfig) {
+func (l *zkEventListener) handleZkNodeEvent(zkPath string, children []string, conf registry.ServiceConfig) {
 	contains := func(s []string, e string) bool {
 		for _, a := range s {
 			if a == e {
@@ -102,7 +102,7 @@ func (l *zkEventListener) handleZkNodeEvent(zkPath string, children []string, co
 	// a node was added -- listen the new node
 	var (
 		newNode    string
-		serviceURL *registry.ServiceURL
+		serviceURL *registry.DefaultServiceURL
 	)
 	for _, n := range newChildren {
 		if contains(children, n) {
@@ -111,9 +111,9 @@ func (l *zkEventListener) handleZkNodeEvent(zkPath string, children []string, co
 
 		newNode = path.Join(zkPath, n)
 		log.Info("add zkNode{%s}", newNode)
-		serviceURL, err = registry.NewServiceURL(n)
+		serviceURL, err = registry.NewDefaultServiceURL(n)
 		if err != nil {
-			log.Error("NewServiceURL(%s) = error{%v}", n, jerrors.ErrorStack(err))
+			log.Error("NewDefaultServiceURL(%s) = error{%v}", n, jerrors.ErrorStack(err))
 			continue
 		}
 		if !conf.ServiceEqual(serviceURL) {
@@ -123,7 +123,7 @@ func (l *zkEventListener) handleZkNodeEvent(zkPath string, children []string, co
 		log.Info("add serviceURL{%s}", serviceURL)
 		l.events <- zkEvent{&registry.ServiceEvent{Action: registry.ServiceAdd, Service: serviceURL}, nil}
 		// listen l service node
-		go func(node string, serviceURL *registry.ServiceURL) {
+		go func(node string, serviceURL *registry.DefaultServiceURL) {
 			log.Info("delete zkNode{%s}", node)
 			if l.listenServiceNodeEvent(node) {
 				log.Info("delete serviceURL{%s}", serviceURL)
@@ -142,21 +142,21 @@ func (l *zkEventListener) handleZkNodeEvent(zkPath string, children []string, co
 
 		oldNode = path.Join(zkPath, n)
 		log.Warn("delete zkPath{%s}", oldNode)
-		serviceURL, err = registry.NewServiceURL(n)
+		serviceURL, err = registry.NewDefaultServiceURL(n)
 		if !conf.ServiceEqual(serviceURL) {
 			log.Warn("serviceURL{%s} has been deleted is not compatible with ServiceConfig{%#v}", serviceURL, conf)
 			continue
 		}
 		log.Warn("delete serviceURL{%s}", serviceURL)
 		if err != nil {
-			log.Error("NewServiceURL(i{%s}) = error{%v}", n, jerrors.ErrorStack(err))
+			log.Error("NewDefaultServiceURL(i{%s}) = error{%v}", n, jerrors.ErrorStack(err))
 			continue
 		}
 		l.events <- zkEvent{&registry.ServiceEvent{Action: registry.ServiceDel, Service: serviceURL}, nil}
 	}
 }
 
-func (l *zkEventListener) listenDirEvent(zkPath string, conf registry.DefaultServiceConfig) {
+func (l *zkEventListener) listenDirEvent(zkPath string, conf registry.ServiceConfig) {
 	l.wg.Add(1)
 	defer l.wg.Done()
 
@@ -222,16 +222,16 @@ func (l *zkEventListener) listenDirEvent(zkPath string, conf registry.DefaultSer
 // registry.go:Listen -> listenServiceEvent -> listenDirEvent -> listenServiceNodeEvent
 //                            |
 //                            --------> listenServiceNodeEvent
-func (l *zkEventListener) listenServiceEvent(conf registry.DefaultServiceConfig) {
+func (l *zkEventListener) listenServiceEvent(conf registry.ServiceConfig) {
 	var (
 		err        error
 		zkPath     string
 		dubboPath  string
 		children   []string
-		serviceURL *registry.ServiceURL
+		serviceURL *registry.DefaultServiceURL
 	)
 
-	zkPath = fmt.Sprintf("/dubbo/%s/providers", conf.Service)
+	zkPath = fmt.Sprintf("/dubbo/%s/providers", conf.Service())
 
 	l.serviceMapLock.Lock()
 	_, ok := l.serviceMap[zkPath]
@@ -254,9 +254,9 @@ func (l *zkEventListener) listenServiceEvent(conf registry.DefaultServiceConfig)
 
 	for _, c := range children {
 
-		serviceURL, err = registry.NewServiceURL(c)
+		serviceURL, err = registry.NewDefaultServiceURL(c)
 		if err != nil {
-			log.Error("NewServiceURL(r{%s}) = error{%v}", c, err)
+			log.Error("NewDefaultServiceURL(r{%s}) = error{%v}", c, err)
 			continue
 		}
 		if !conf.ServiceEqual(serviceURL) {
@@ -269,7 +269,7 @@ func (l *zkEventListener) listenServiceEvent(conf registry.DefaultServiceConfig)
 		// listen l service node
 		dubboPath = path.Join(zkPath, c)
 		log.Info("listen dubbo service key{%s}", dubboPath)
-		go func(zkPath string, serviceURL *registry.ServiceURL) {
+		go func(zkPath string, serviceURL *registry.DefaultServiceURL) {
 			if l.listenServiceNodeEvent(dubboPath) {
 				log.Debug("delete serviceUrl{%s}", serviceURL)
 				l.events <- zkEvent{&registry.ServiceEvent{Action: registry.ServiceDel, Service: serviceURL}, nil}
@@ -279,7 +279,7 @@ func (l *zkEventListener) listenServiceEvent(conf registry.DefaultServiceConfig)
 	}
 
 	log.Info("listen dubbo path{%s}", zkPath)
-	go func(zkPath string, conf registry.DefaultServiceConfig) {
+	go func(zkPath string, conf registry.ServiceConfig) {
 		l.listenDirEvent(zkPath, conf)
 		log.Warn("listenDirEvent(zkPath{%s}) goroutine exit now", zkPath)
 	}(zkPath, conf)
diff --git a/registry/zookeeper/registry.go b/registry/zookeeper/registry.go
index 62d64c3cb..6c414fa59 100644
--- a/registry/zookeeper/registry.go
+++ b/registry/zookeeper/registry.go
@@ -159,6 +159,7 @@ func (r *ZkRegistry) validateZookeeperClient() error {
 		if err != nil {
 			log.Warn("newZookeeperClient(name{%s}, zk addresss{%v}, timeout{%d}) = error{%v}",
 				RegistryZkClient, r.Address, r.Timeout.String(), err)
+			return jerrors.Annotatef(err, "newZookeeperClient(address:%+v)", r.Address)
 		}
 	}
 	if r.client.conn == nil {
@@ -239,8 +240,7 @@ LOOP:
 	}
 }
 
-
-func (r *ZkRegistry) Register(regConf registry.ServiceConfig) error {
+func (r *ZkRegistry) Register(conf registry.ServiceConfig) error {
 	var (
 		ok       bool
 		err      error
@@ -248,18 +248,12 @@ func (r *ZkRegistry) Register(regConf registry.ServiceConfig) error {
 	)
 	switch r.DubboType {
 	case registry.CONSUMER:
-
-		var conf registry.DefaultServiceConfig
-		if conf, ok = regConf.(registry.DefaultServiceConfig); !ok {
-			return jerrors.Errorf("the type of @regConf %T is not registry.ServiceConfig", regConf)
-		}
-
 		ok = false
 		r.cltLock.Lock()
 		_, ok = r.services[conf.Key()]
 		r.cltLock.Unlock()
 		if ok {
-			return jerrors.Errorf("Service{%s} has been registered", conf.Service)
+			return jerrors.Errorf("Service{%s} has been registered", conf.Service())
 		}
 
 		err = r.register(conf)
@@ -279,10 +273,6 @@ func (r *ZkRegistry) Register(regConf registry.ServiceConfig) error {
 			go listener.listenServiceEvent(conf)
 		}
 	case registry.PROVIDER:
-		var conf registry.ProviderServiceConfig
-		if conf, ok = regConf.(registry.ProviderServiceConfig); !ok {
-			return jerrors.Errorf("the tyep of @regConf{%v} is not ProviderServiceConfig", regConf)
-		}
 
 		// 妫€楠屾湇鍔℃槸鍚﹀凡缁忔敞鍐岃繃
 		ok = false
@@ -307,8 +297,6 @@ func (r *ZkRegistry) Register(regConf registry.ServiceConfig) error {
 		log.Debug("(ZkProviderRegistry)Register(conf{%#v})", conf)
 	}
 
-
-
 	return nil
 }
 
@@ -321,6 +309,8 @@ func (r *ZkRegistry) register(c registry.ServiceConfig) error {
 		rawURL     string
 		encodedURL string
 		dubboPath  string
+		conf       registry.ProviderServiceConfig
+		ok         bool
 	)
 
 	err = r.validateZookeeperClient()
@@ -347,16 +337,14 @@ func (r *ZkRegistry) register(c registry.ServiceConfig) error {
 	params.Add("revision", revision) // revision鏄痯ox.xml涓璦pplication鐨剉ersion灞炴€х殑鍊�
 
 	if r.DubboType == registry.PROVIDER {
-		conf, ok := c.(registry.ProviderServiceConfig)
-		if !ok {
-			return fmt.Errorf("the type of @c:%+v is not registry.ProviderServiceConfig", c)
+		if conf, ok = c.(registry.ProviderServiceConfig); !ok {
+			return jerrors.Errorf("conf is not ProviderServiceConfig")
 		}
-
-		if conf.Service == "" || conf.Methods == "" {
-			return jerrors.Errorf("conf{Service:%s, Methods:%s}", conf.Service, conf.Methods)
+		if conf.Service() == "" || conf.Methods() == "" {
+			return jerrors.Errorf("conf{Service:%s, Methods:%s}", conf.Service(), conf.Methods())
 		}
 		// 鍏堝垱寤烘湇鍔′笅闈㈢殑provider node
-		dubboPath = fmt.Sprintf("/dubbo/%s/%s", conf.Service, registry.DubboNodes[registry.PROVIDER])
+		dubboPath = fmt.Sprintf("/dubbo/%s/%s", conf.Service(), registry.DubboNodes[registry.PROVIDER])
 		r.cltLock.Lock()
 		err = r.client.Create(dubboPath)
 		r.cltLock.Unlock()
@@ -365,10 +353,10 @@ func (r *ZkRegistry) register(c registry.ServiceConfig) error {
 			return jerrors.Annotatef(err, "zkclient.Create(path:%s)", dubboPath)
 		}
 		params.Add("anyhost", "true")
-		params.Add("interface", conf.DefaultServiceConfig.Service)
+		params.Add("interface", conf.Service())
 
-		if conf.DefaultServiceConfig.Group != "" {
-			params.Add("group", conf.DefaultServiceConfig.Group)
+		if conf.Group() != "" {
+			params.Add("group", conf.Group())
 		}
 		// dubbo java consumer鏉ュ惎鍔ㄦ壘provider url鏃讹紝鍥犱负category涓嶅尮閰嶏紝浼氭壘涓嶅埌provider锛屽鑷碿onsumer鍚姩涓嶄簡,鎵€浠ヤ娇鐢╟onsumers&providers
 		// DubboRole               = [...]string{"consumer", "", "", "provider"}
@@ -378,36 +366,32 @@ func (r *ZkRegistry) register(c registry.ServiceConfig) error {
 
 		params.Add("side", (registry.DubboType(registry.PROVIDER)).Role())
 
-		if conf.DefaultServiceConfig.Version != "" {
-			params.Add("version", conf.DefaultServiceConfig.Version)
+		if conf.Version() != "" {
+			params.Add("version", conf.Version())
 		}
-		if conf.Methods != "" {
-			params.Add("methods", conf.Methods)
+		if conf.Methods() != "" {
+			params.Add("methods", conf.Methods())
 		}
 		log.Debug("provider zk url params:%#v", params)
-		if conf.Path == "" {
-			conf.Path = localIP
+		var path = conf.Path()
+		if path == "" {
+			path = localIP
 		}
 
-		urlPath = conf.Service
+		urlPath = conf.Service()
 		if r.zkPath[urlPath] != 0 {
 			urlPath += strconv.Itoa(r.zkPath[urlPath])
 		}
 		r.zkPath[urlPath]++
-		rawURL = fmt.Sprintf("%s://%s/%s?%s", conf.Protocol, conf.Path, urlPath, params.Encode())
+		rawURL = fmt.Sprintf("%s://%s/%s?%s", conf.Protocol(), path, urlPath, params.Encode())
 		encodedURL = url.QueryEscape(rawURL)
 
 		// 鎶婅嚜宸辨敞鍐宻ervice providers
-		dubboPath = fmt.Sprintf("/dubbo/%s/%s", conf.Service, (registry.DubboType(registry.PROVIDER)).String())
+		dubboPath = fmt.Sprintf("/dubbo/%s/%s", conf.Service(), (registry.DubboType(registry.PROVIDER)).String())
 		log.Debug("provider path:%s, url:%s", dubboPath, rawURL)
 
 	} else if r.DubboType == registry.CONSUMER {
-		conf, ok := c.(registry.DefaultServiceConfig)
-		if !ok {
-			return fmt.Errorf("the type of @c:%+v is not registry.ServiceConfig", c)
-		}
-
-		dubboPath = fmt.Sprintf("/dubbo/%s/%s", conf.Service, registry.DubboNodes[registry.CONSUMER])
+		dubboPath = fmt.Sprintf("/dubbo/%s/%s", c.Service(), registry.DubboNodes[registry.CONSUMER])
 		r.cltLock.Lock()
 		err = r.client.Create(dubboPath)
 		r.cltLock.Unlock()
@@ -415,7 +399,7 @@ func (r *ZkRegistry) register(c registry.ServiceConfig) error {
 			log.Error("zkClient.create(path{%s}) = error{%v}", dubboPath, jerrors.ErrorStack(err))
 			return jerrors.Trace(err)
 		}
-		dubboPath = fmt.Sprintf("/dubbo/%s/%s", conf.Service, registry.DubboNodes[registry.PROVIDER])
+		dubboPath = fmt.Sprintf("/dubbo/%s/%s", c.Service(), registry.DubboNodes[registry.PROVIDER])
 		r.cltLock.Lock()
 		err = r.client.Create(dubboPath)
 		r.cltLock.Unlock()
@@ -424,29 +408,29 @@ func (r *ZkRegistry) register(c registry.ServiceConfig) error {
 			return jerrors.Trace(err)
 		}
 
-		params.Add("protocol", conf.Protocol)
-		params.Add("interface", conf.Service)
+		params.Add("protocol", c.Protocol())
+		params.Add("interface", c.Service())
 		revision = r.ApplicationConfig.Version
 		if revision == "" {
 			revision = "0.1.0"
 		}
 		params.Add("revision", revision)
-		if conf.Group != "" {
-			params.Add("group", conf.Group)
+		if c.Group() != "" {
+			params.Add("group", c.Group())
 		}
 		params.Add("category", (registry.DubboType(registry.CONSUMER)).String())
 		params.Add("dubbo", "dubbogo-consumer-"+version.Version)
 
-		if conf.Version != "" {
-			params.Add("version", conf.Version)
+		if c.Version() != "" {
+			params.Add("version", c.Version())
 		}
-		rawURL = fmt.Sprintf("consumer://%s/%s?%s", localIP, conf.Service+conf.Version, params.Encode())
+		rawURL = fmt.Sprintf("consumer://%s/%s?%s", localIP, c.Service()+c.Version(), params.Encode())
 		encodedURL = url.QueryEscape(rawURL)
 
-		dubboPath = fmt.Sprintf("/dubbo/%s/%s", conf.Service, (registry.DubboType(registry.CONSUMER)).String())
+		dubboPath = fmt.Sprintf("/dubbo/%s/%s", c.Service(), (registry.DubboType(registry.CONSUMER)).String())
 		log.Debug("consumer path:%s, url:%s", dubboPath, rawURL)
 	} else {
-		return jerrors.Errorf("@c{%v} type is not DefaultServiceConfig or ProviderServiceConfig", c)
+		return jerrors.Errorf("@c{%v} type is not DefaultServiceConfig or DefaultProviderServiceConfig", c)
 	}
 
 	err = r.registerTempZookeeperNode(dubboPath, encodedURL)
-- 
GitLab