feat: copy bare configurations from config to global (#2413)

diff --git a/client/client.go b/client/client.go
index ab93c37..13334b0 100644
--- a/client/client.go
+++ b/client/client.go
@@ -19,6 +19,9 @@
 
 import (
 	"context"
+	commonCfg "dubbo.apache.org/dubbo-go/v3/common/config"
+	"dubbo.apache.org/dubbo-go/v3/config"
+	"dubbo.apache.org/dubbo-go/v3/global"
 )
 
 import (
@@ -35,6 +38,8 @@
 	invoker protocol.Invoker
 	info    *ClientInfo
 	cfg     *ReferenceConfig
+
+	cliOpts *ClientOptions
 }
 
 type ClientInfo struct {
@@ -44,6 +49,57 @@
 	Meta             map[string]interface{}
 }
 
+func (cli *Client) init(opts ...global.ReferenceOption) error {
+	refCfg := global.DefaultReferenceConfig()
+	for _, opt := range opts {
+		opt(refCfg)
+	}
+
+	// init method
+	if length := len(refCfg.Methods); length > 0 {
+		cli.methodsCompat = make([]*config.MethodConfig, length)
+		for i, method := range refCfg.Methods {
+			cli.methodsCompat[i] = compatMethodConfig(method)
+			if err := cli.methodsCompat[i].Init(); err != nil {
+				return err
+			}
+		}
+
+	}
+	// init application
+	if refCfg.pplication != nil {
+		rc.applicationCompat = compatApplicationConfig(rc.application)
+		if err := rc.applicationCompat.Init(); err != nil {
+			return err
+		}
+		rc.metaDataType = rc.applicationCompat.MetadataType
+		if rc.Group == "" {
+			rc.Group = rc.applicationCompat.Group
+		}
+		if rc.Version == "" {
+			rc.Version = rc.applicationCompat.Version
+		}
+	}
+	// init cluster
+	if rc.Cluster == "" {
+		rc.Cluster = "failover"
+	}
+	// todo: move to registry package
+	// init registries
+	if rc.registries != nil {
+		rc.registriesCompat = make(map[string]*config.RegistryConfig)
+		for key, reg := range rc.registries {
+			rc.registriesCompat[key] = compatRegistryConfig(reg)
+			if err := rc.registriesCompat[key].Init(); err != nil {
+				return err
+			}
+		}
+	}
+	rc.RegistryIDs = commonCfg.TranslateIds(rc.RegistryIDs)
+
+	return commonCfg.Verify(rc)
+}
+
 func (cli *Client) call(ctx context.Context, paramsRawVals []interface{}, interfaceName, methodName, callType string, opts ...CallOption) (protocol.Result, error) {
 	// get a default CallOptions
 	// apply CallOption
diff --git a/client/compat.go b/client/compat.go
index f09ddb6..b1f8d38 100644
--- a/client/compat.go
+++ b/client/compat.go
@@ -20,7 +20,6 @@
 import (
 	"dubbo.apache.org/dubbo-go/v3/config"
 	"dubbo.apache.org/dubbo-go/v3/global"
-	"dubbo.apache.org/dubbo-go/v3/registry"
 )
 
 // these functions are used to resolve circular dependencies temporarily.
@@ -40,7 +39,7 @@
 	}
 }
 
-func compatRegistryConfig(c *registry.RegistryConfig) *config.RegistryConfig {
+func compatRegistryConfig(c *global.RegistryConfig) *config.RegistryConfig {
 	return &config.RegistryConfig{
 		Protocol:          c.Protocol,
 		Timeout:           c.Timeout,
@@ -60,3 +59,21 @@
 		UseAsConfigCenter: c.UseAsConfigCenter,
 	}
 }
+
+func compatMethodConfig(c *global.MethodConfig) *config.MethodConfig {
+	return &config.MethodConfig{
+		InterfaceId:                 c.InterfaceId,
+		InterfaceName:               c.InterfaceName,
+		Name:                        c.Name,
+		Retries:                     c.Retries,
+		LoadBalance:                 c.LoadBalance,
+		Weight:                      c.Weight,
+		TpsLimitInterval:            c.TpsLimitInterval,
+		TpsLimitRate:                c.TpsLimitRate,
+		TpsLimitStrategy:            c.TpsLimitStrategy,
+		ExecuteLimit:                c.ExecuteLimit,
+		ExecuteLimitRejectedHandler: c.ExecuteLimitRejectedHandler,
+		Sticky:                      c.Sticky,
+		RequestTimeout:              c.RequestTimeout,
+	}
+}
diff --git a/client/options.go b/client/options.go
index 19063e8..6e3cffd 100644
--- a/client/options.go
+++ b/client/options.go
@@ -18,13 +18,109 @@
 package client
 
 import (
+	"dubbo.apache.org/dubbo-go/v3/common"
+	commonCfg "dubbo.apache.org/dubbo-go/v3/common/config"
+	"dubbo.apache.org/dubbo-go/v3/config"
 	"dubbo.apache.org/dubbo-go/v3/global"
+	"dubbo.apache.org/dubbo-go/v3/protocol"
+	"dubbo.apache.org/dubbo-go/v3/proxy"
+	"github.com/creasty/defaults"
 	"strconv"
 )
 
-import (
-	"dubbo.apache.org/dubbo-go/v3/registry"
-)
+type ClientOptions struct {
+	Application *global.ApplicationConfig
+	Consumer    *global.ConsumerConfig
+	Reference   *global.ReferenceConfig
+	Registries  map[string]*global.RegistryConfig
+
+	pxy          *proxy.Proxy
+	id           string
+	invoker      protocol.Invoker
+	urls         []*common.URL
+	metaDataType string
+	info         *ClientInfo
+
+	methodsCompat []*config.MethodConfig
+}
+
+func (cliOpts *ClientOptions) init() error {
+	if err := defaults.Set(cliOpts); err != nil {
+		return err
+	}
+
+	// init method
+	methods := cliOpts.Reference.Methods
+	if length := len(methods); length > 0 {
+		cliOpts.methodsCompat = make([]*config.MethodConfig, length)
+		for i, method := range methods {
+			cliOpts.methodsCompat[i] = compatMethodConfig(method)
+			if err := cliOpts.methodsCompat[i].Init(); err != nil {
+				return err
+			}
+		}
+
+	}
+
+	// init application
+	if rc.application != nil {
+		rc.applicationCompat = compatApplicationConfig(rc.application)
+		if err := rc.applicationCompat.Init(); err != nil {
+			return err
+		}
+		rc.metaDataType = rc.applicationCompat.MetadataType
+		if rc.Group == "" {
+			rc.Group = rc.applicationCompat.Group
+		}
+		if rc.Version == "" {
+			rc.Version = rc.applicationCompat.Version
+		}
+	}
+	// init cluster
+	if rc.Cluster == "" {
+		rc.Cluster = "failover"
+	}
+	// todo: move to registry package
+	// init registries
+	if rc.registries != nil {
+		rc.registriesCompat = make(map[string]*config.RegistryConfig)
+		for key, reg := range rc.registries {
+			rc.registriesCompat[key] = compatRegistryConfig(reg)
+			if err := rc.registriesCompat[key].Init(); err != nil {
+				return err
+			}
+		}
+	}
+	rc.RegistryIDs = commonCfg.TranslateIds(rc.RegistryIDs)
+
+	return commonCfg.Verify(rc)
+}
+
+type ClientOption func(*ClientOptions)
+
+func WithApplication(application *global.ApplicationConfig) ClientOption {
+	return func(opts *ClientOptions) {
+		opts.Application = application
+	}
+}
+
+func WithConsumer(consumer *global.ConsumerConfig) ClientOption {
+	return func(opts *ClientOptions) {
+		opts.Consumer = consumer
+	}
+}
+
+func WithReference(reference *global.ReferenceConfig) ClientOption {
+	return func(opts *ClientOptions) {
+		opts.Reference = reference
+	}
+}
+
+func WithRegistries(registries map[string]*global.RegistryConfig) ClientOption {
+	return func(opts *ClientOptions) {
+		opts.Registries = registries
+	}
+}
 
 // todo: need to be consistent with MethodConfig
 type CallOptions struct {
@@ -218,7 +314,7 @@
 
 // ----------From RegistryConfig----------
 
-func WithRegistries(registries map[string]*registry.RegistryConfig) ReferenceOption {
+func WithRegistries(registries map[string]*global.RegistryConfig) ReferenceOption {
 	return func(cfg *ReferenceConfig) {
 		cfg.registries = registries
 	}
diff --git a/client/reference_config.go b/client/reference_config.go
index 2d53ff5..0d02466 100644
--- a/client/reference_config.go
+++ b/client/reference_config.go
@@ -45,7 +45,6 @@
 	"dubbo.apache.org/dubbo-go/v3/protocol"
 	"dubbo.apache.org/dubbo-go/v3/protocol/protocolwrapper"
 	"dubbo.apache.org/dubbo-go/v3/proxy"
-	"dubbo.apache.org/dubbo-go/v3/registry"
 )
 
 // ReferenceConfig is the configuration of service consumer
@@ -89,7 +88,7 @@
 	application       *global.ApplicationConfig
 	applicationCompat *config.ApplicationConfig
 
-	registries       map[string]*registry.RegistryConfig
+	registries       map[string]*global.RegistryConfig
 	registriesCompat map[string]*config.RegistryConfig
 }
 
diff --git a/compat.go b/compat.go
index 30bca71..65d68f5 100644
--- a/compat.go
+++ b/compat.go
@@ -19,12 +19,7 @@
 
 import (
 	"dubbo.apache.org/dubbo-go/v3/config"
-	"dubbo.apache.org/dubbo-go/v3/config_center"
 	"dubbo.apache.org/dubbo-go/v3/global"
-	"dubbo.apache.org/dubbo-go/v3/metadata/report"
-	"dubbo.apache.org/dubbo-go/v3/metrics"
-	"dubbo.apache.org/dubbo-go/v3/protocol"
-	"dubbo.apache.org/dubbo-go/v3/registry"
 	"go.uber.org/atomic"
 )
 
@@ -78,7 +73,7 @@
 	}
 }
 
-func compatProtocolConfig(c *protocol.ProtocolConfig) *config.ProtocolConfig {
+func compatProtocolConfig(c *global.ProtocolConfig) *config.ProtocolConfig {
 	return &config.ProtocolConfig{
 		Name:                 c.Name,
 		Ip:                   c.Ip,
@@ -89,7 +84,7 @@
 	}
 }
 
-func compatRegistryConfig(c *registry.RegistryConfig) *config.RegistryConfig {
+func compatRegistryConfig(c *global.RegistryConfig) *config.RegistryConfig {
 	return &config.RegistryConfig{
 		Protocol:          c.Protocol,
 		Timeout:           c.Timeout,
@@ -110,7 +105,7 @@
 	}
 }
 
-func compatCenterConfig(c *config_center.CenterConfig) *config.CenterConfig {
+func compatCenterConfig(c *global.CenterConfig) *config.CenterConfig {
 	return &config.CenterConfig{
 		Protocol:      c.Protocol,
 		Address:       c.Address,
@@ -127,7 +122,7 @@
 	}
 }
 
-func compatMetadataReportConfig(c *report.MetadataReportConfig) *config.MetadataReportConfig {
+func compatMetadataReportConfig(c *global.MetadataReportConfig) *config.MetadataReportConfig {
 	return &config.MetadataReportConfig{
 		Protocol:  c.Protocol,
 		Address:   c.Address,
@@ -156,13 +151,13 @@
 
 func compatConsumerConfig(c *global.ConsumerConfig) *config.ConsumerConfig {
 	return &config.ConsumerConfig{
-		Filter:          c.Filter,
-		RegistryIDs:     c.RegistryIDs,
-		Protocol:        c.Protocol,
-		RequestTimeout:  c.RequestTimeout,
-		ProxyFactory:    c.ProxyFactory,
-		Check:           c.Check,
-		AdaptiveService: c.AdaptiveService,
+		Filter:                         c.Filter,
+		RegistryIDs:                    c.RegistryIDs,
+		Protocol:                       c.Protocol,
+		RequestTimeout:                 c.RequestTimeout,
+		ProxyFactory:                   c.ProxyFactory,
+		Check:                          c.Check,
+		AdaptiveService:                c.AdaptiveService,
 		TracingKey:                     c.TracingKey,
 		FilterConf:                     c.FilterConf,
 		MaxWaitTimeForServiceDiscovery: c.MaxWaitTimeForServiceDiscovery,
@@ -170,7 +165,7 @@
 	}
 }
 
-func compatMetricConfig(c *metrics.MetricConfig) *config.MetricConfig {
+func compatMetricConfig(c *global.MetricConfig) *config.MetricConfig {
 	return &config.MetricConfig{
 		Mode:               c.Mode,
 		Namespace:          c.Namespace,
diff --git a/config_center/config_center_config.go b/global/config_center_config.go
similarity index 76%
rename from config_center/config_center_config.go
rename to global/config_center_config.go
index 8d5ee82..d219b69 100644
--- a/config_center/config_center_config.go
+++ b/global/config_center_config.go
@@ -1,4 +1,4 @@
-package config_center
+package global
 
 // CenterConfig is configuration for config center
 //
@@ -32,69 +32,67 @@
 
 type CenterOption func(*CenterConfig)
 
-func WithProtocol(protocol string) CenterOption {
+func WithCenter_Protocol(protocol string) CenterOption {
 	return func(cfg *CenterConfig) {
 		cfg.Protocol = protocol
 	}
 }
 
-func WithAddress(address string) CenterOption {
+func WithCenter_Address(address string) CenterOption {
 	return func(cfg *CenterConfig) {
 		cfg.Address = address
 	}
 }
 
-func WithDataID(id string) CenterOption {
+func WithCenter_DataID(id string) CenterOption {
 	return func(cfg *CenterConfig) {
 		cfg.DataId = id
 	}
 }
 
-func WithCluster(cluster string) CenterOption {
+func WithCenter_Cluster(cluster string) CenterOption {
 	return func(cfg *CenterConfig) {
 		cfg.Cluster = cluster
 	}
 }
 
-// todo: think about changing the name of another WithGroup in this package
-func WithGroup_(group string) CenterOption {
+func WithCenter_Group(group string) CenterOption {
 	return func(cfg *CenterConfig) {
 		cfg.Group = group
 	}
 }
 
-func WithUsername(name string) CenterOption {
+func WithCenter_Username(name string) CenterOption {
 	return func(cfg *CenterConfig) {
 		cfg.Username = name
 	}
 }
 
-func WithPassword(password string) CenterOption {
+func WithCenter_Password(password string) CenterOption {
 	return func(cfg *CenterConfig) {
 		cfg.Password = password
 	}
 }
 
-func WithNamespace(namespace string) CenterOption {
+func WithCenter_Namespace(namespace string) CenterOption {
 	return func(cfg *CenterConfig) {
 		cfg.Namespace = namespace
 	}
 }
 
-func WithAppID(id string) CenterOption {
+func WithCenter_AppID(id string) CenterOption {
 	return func(cfg *CenterConfig) {
 		cfg.AppID = id
 	}
 }
 
-// todo: think about changing the name of another WithTimeout in this package
-func WithTimeout_(timeout string) CenterOption {
+func WithCenter_Timeout(timeout string) CenterOption {
 	return func(cfg *CenterConfig) {
 		cfg.Timeout = timeout
 	}
 }
 
-func WithParams(params map[string]string) CenterOption {
+func WithCenter_Params(params map[string]string) CenterOption {
 	return func(cfg *CenterConfig) {
 		if cfg.Params == nil {
 			cfg.Params = make(map[string]string)
@@ -105,7 +103,7 @@
 	}
 }
 
-func WithFileExtension(extension string) CenterOption {
+func WithCenter_FileExtension(extension string) CenterOption {
 	return func(cfg *CenterConfig) {
 		cfg.FileExtension = extension
 	}
diff --git a/metadata/report/metadata_report_config.go b/global/metadata_report_config.go
similarity index 80%
rename from metadata/report/metadata_report_config.go
rename to global/metadata_report_config.go
index 1531605..65c97f6 100644
--- a/metadata/report/metadata_report_config.go
+++ b/global/metadata_report_config.go
@@ -15,7 +15,7 @@
  * limitations under the License.
  */
 
-package report
+package global
 
 // MetadataReportConfig is app level configuration
 type MetadataReportConfig struct {
@@ -37,43 +37,43 @@
 
 type MetadataReportOption func(*MetadataReportConfig)
 
-func WithProtocol(protocol string) MetadataReportOption {
+func WithMetadataReport_Protocol(protocol string) MetadataReportOption {
 	return func(cfg *MetadataReportConfig) {
 		cfg.Protocol = protocol
 	}
 }
 
-func WithAddress(address string) MetadataReportOption {
+func WithMetadataReport_Address(address string) MetadataReportOption {
 	return func(cfg *MetadataReportConfig) {
 		cfg.Address = address
 	}
 }
 
-func WithUsername(username string) MetadataReportOption {
+func WithMetadataReport_Username(username string) MetadataReportOption {
 	return func(cfg *MetadataReportConfig) {
 		cfg.Username = username
 	}
 }
 
-func WithPassword(password string) MetadataReportOption {
+func WithMetadataReport_Password(password string) MetadataReportOption {
 	return func(cfg *MetadataReportConfig) {
 		cfg.Password = password
 	}
 }
 
-func WithTimeout(timeout string) MetadataReportOption {
+func WithMetadataReport_Timeout(timeout string) MetadataReportOption {
 	return func(cfg *MetadataReportConfig) {
 		cfg.Timeout = timeout
 	}
 }
 
-func WithGroup(group string) MetadataReportOption {
+func WithMetadataReport_Group(group string) MetadataReportOption {
 	return func(cfg *MetadataReportConfig) {
 		cfg.Group = group
 	}
 }
 
-func WithNamespace(namespace string) MetadataReportOption {
+func WithMetadataReport_Namespace(namespace string) MetadataReportOption {
 	return func(cfg *MetadataReportConfig) {
 		cfg.Namespace = namespace
 	}
diff --git a/global/method_config.go b/global/method_config.go
new file mode 100644
index 0000000..2090a3e
--- /dev/null
+++ b/global/method_config.go
@@ -0,0 +1,18 @@
+package global
+
+// MethodConfig defines method config
+type MethodConfig struct {
+	InterfaceId                 string
+	InterfaceName               string
+	Name                        string `yaml:"name"  json:"name,omitempty" property:"name"`
+	Retries                     string `yaml:"retries"  json:"retries,omitempty" property:"retries"`
+	LoadBalance                 string `yaml:"loadbalance"  json:"loadbalance,omitempty" property:"loadbalance"`
+	Weight                      int64  `yaml:"weight"  json:"weight,omitempty" property:"weight"`
+	TpsLimitInterval            string `yaml:"tps.limit.interval" json:"tps.limit.interval,omitempty" property:"tps.limit.interval"`
+	TpsLimitRate                string `yaml:"tps.limit.rate" json:"tps.limit.rate,omitempty" property:"tps.limit.rate"`
+	TpsLimitStrategy            string `yaml:"tps.limit.strategy" json:"tps.limit.strategy,omitempty" property:"tps.limit.strategy"`
+	ExecuteLimit                string `yaml:"execute.limit" json:"execute.limit,omitempty" property:"execute.limit"`
+	ExecuteLimitRejectedHandler string `yaml:"execute.limit.rejected.handler" json:"execute.limit.rejected.handler,omitempty" property:"execute.limit.rejected.handler"`
+	Sticky                      bool   `yaml:"sticky"   json:"sticky,omitempty" property:"sticky"`
+	RequestTimeout              string `yaml:"timeout"  json:"timeout,omitempty" property:"timeout"`
+}
diff --git a/metrics/metric_config.go b/global/metric_config.go
similarity index 84%
rename from metrics/metric_config.go
rename to global/metric_config.go
index 03e7ff7..17df20a 100644
--- a/metrics/metric_config.go
+++ b/global/metric_config.go
@@ -15,7 +15,7 @@
  * limitations under the License.
  */
 
-package metrics
+package global
 
 // MetricConfig This is the config struct for all metrics implementation
 type MetricConfig struct {
@@ -36,49 +36,49 @@
 
 type MetricOption func(*MetricConfig)
 
-func WithMode(mode string) MetricOption {
+func WithMetric_Mode(mode string) MetricOption {
 	return func(cfg *MetricConfig) {
 		cfg.Mode = mode
 	}
 }
 
-func WithNamespace(namespace string) MetricOption {
+func WithMetric_Namespace(namespace string) MetricOption {
 	return func(cfg *MetricConfig) {
 		cfg.Namespace = namespace
 	}
 }
 
-func WithEnable(enable bool) MetricOption {
+func WithMetric_Enable(enable bool) MetricOption {
 	return func(cfg *MetricConfig) {
 		cfg.Enable = &enable
 	}
 }
 
-func WithPort(port string) MetricOption {
+func WithMetric_Port(port string) MetricOption {
 	return func(cfg *MetricConfig) {
 		cfg.Port = port
 	}
 }
 
-func WithPath(path string) MetricOption {
+func WithMetric_Path(path string) MetricOption {
 	return func(cfg *MetricConfig) {
 		cfg.Path = path
 	}
 }
 
-func WithPushGatewayAddress(address string) MetricOption {
+func WithMetric_PushGatewayAddress(address string) MetricOption {
 	return func(cfg *MetricConfig) {
 		cfg.PushGatewayAddress = address
 	}
 }
 
-func WithSummaryMaxAge(age int64) MetricOption {
+func WithMetric_SummaryMaxAge(age int64) MetricOption {
 	return func(cfg *MetricConfig) {
 		cfg.SummaryMaxAge = age
 	}
 }
 
-func WithProtocol(protocol string) MetricOption {
+func WithMetric_Protocol(protocol string) MetricOption {
 	return func(cfg *MetricConfig) {
 		cfg.Protocol = protocol
 	}
diff --git a/protocol/protocol_config.go b/global/protocol_config.go
similarity index 84%
rename from protocol/protocol_config.go
rename to global/protocol_config.go
index 6b39061..2872c5b 100644
--- a/protocol/protocol_config.go
+++ b/global/protocol_config.go
@@ -15,7 +15,7 @@
  * limitations under the License.
  */
 
-package protocol
+package global
 
 // ProtocolConfig is protocol configuration
 type ProtocolConfig struct {
@@ -33,37 +33,37 @@
 
 type ProtocolOption func(*ProtocolConfig)
 
-func WithName(name string) ProtocolOption {
+func WithProtocol_Name(name string) ProtocolOption {
 	return func(cfg *ProtocolConfig) {
 		cfg.Name = name
 	}
 }
 
-func WithIp(ip string) ProtocolOption {
+func WithProtocol_Ip(ip string) ProtocolOption {
 	return func(cfg *ProtocolConfig) {
 		cfg.Ip = ip
 	}
 }
 
-func WithPort(port string) ProtocolOption {
+func WithProtocol_Port(port string) ProtocolOption {
 	return func(cfg *ProtocolConfig) {
 		cfg.Port = port
 	}
 }
 
-func WithParam(param interface{}) ProtocolOption {
+func WithProtocol_Param(param interface{}) ProtocolOption {
 	return func(cfg *ProtocolConfig) {
 		cfg.Params = param
 	}
 }
 
-func WithMaxServerSendMsgSize(size string) ProtocolOption {
+func WithProtocol_MaxServerSendMsgSize(size string) ProtocolOption {
 	return func(cfg *ProtocolConfig) {
 		cfg.MaxServerSendMsgSize = size
 	}
 }
 
-func WithMaxServerRecvMsgSize(size string) ProtocolOption {
+func WithProtocol_MaxServerRecvMsgSize(size string) ProtocolOption {
 	return func(cfg *ProtocolConfig) {
 		cfg.MaxServerRecvMsgSize = size
 	}
diff --git a/global/reference_config.go b/global/reference_config.go
new file mode 100644
index 0000000..c1e2742
--- /dev/null
+++ b/global/reference_config.go
@@ -0,0 +1,36 @@
+package global
+
+// ReferenceConfig is the configuration of service consumer
+type ReferenceConfig struct {
+	InterfaceName    string            `yaml:"interface"  json:"interface,omitempty" property:"interface"`
+	Check            *bool             `yaml:"check"  json:"check,omitempty" property:"check"`
+	URL              string            `yaml:"url"  json:"url,omitempty" property:"url"`
+	Filter           string            `yaml:"filter" json:"filter,omitempty" property:"filter"`
+	Protocol         string            `yaml:"protocol"  json:"protocol,omitempty" property:"protocol"`
+	RegistryIDs      []string          `yaml:"registry-ids"  json:"registry-ids,omitempty"  property:"registry-ids"`
+	Cluster          string            `yaml:"cluster"  json:"cluster,omitempty" property:"cluster"`
+	Loadbalance      string            `yaml:"loadbalance"  json:"loadbalance,omitempty" property:"loadbalance"`
+	Retries          string            `yaml:"retries"  json:"retries,omitempty" property:"retries"`
+	Group            string            `yaml:"group"  json:"group,omitempty" property:"group"`
+	Version          string            `yaml:"version"  json:"version,omitempty" property:"version"`
+	Serialization    string            `yaml:"serialization" json:"serialization" property:"serialization"`
+	ProvidedBy       string            `yaml:"provided_by"  json:"provided_by,omitempty" property:"provided_by"`
+	Methods          []*MethodConfig   `yaml:"methods"  json:"methods,omitempty" property:"methods"`
+	Async            bool              `yaml:"async"  json:"async,omitempty" property:"async"`
+	Params           map[string]string `yaml:"params"  json:"params,omitempty" property:"params"`
+	Generic          string            `yaml:"generic"  json:"generic,omitempty" property:"generic"`
+	Sticky           bool              `yaml:"sticky"   json:"sticky,omitempty" property:"sticky"`
+	RequestTimeout   string            `yaml:"timeout"  json:"timeout,omitempty" property:"timeout"`
+	ForceTag         bool              `yaml:"force.tag"  json:"force.tag,omitempty" property:"force.tag"`
+	TracingKey       string            `yaml:"tracing-key" json:"tracing-key,omitempty" propertiy:"tracing-key"`
+	MeshProviderPort int               `yaml:"mesh-provider-port" json:"mesh-provider-port,omitempty" propertiy:"mesh-provider-port"`
+}
+
+type ReferenceOption func(*ReferenceConfig)
+
+func DefaultReferenceConfig() *ReferenceConfig {
+	return &ReferenceConfig{
+		Methods: make([]*MethodConfig, 0, 8),
+		Params:  make(map[string]string, 8),
+	}
+}
diff --git a/registry/registry_config.go b/global/registry_config.go
similarity index 81%
rename from registry/registry_config.go
rename to global/registry_config.go
index 468c1fe..7330ef2 100644
--- a/registry/registry_config.go
+++ b/global/registry_config.go
@@ -15,7 +15,7 @@
  * limitations under the License.
  */
 
-package registry
+package global
 
 // todo(DMwangnima): finish refactoring and move related logic from config package to this file.
 // This RegistryConfig is a copy of /config/RegistryConfig right now.
@@ -43,97 +43,97 @@
 
 type RegistryOption func(*RegistryConfig)
 
-func WithProtocol(protocol string) RegistryOption {
+func WithRegistry_Protocol(protocol string) RegistryOption {
 	return func(cfg *RegistryConfig) {
 		cfg.Protocol = protocol
 	}
 }
 
-func WithTimeout(timeout string) RegistryOption {
+func WithRegistry_Timeout(timeout string) RegistryOption {
 	return func(cfg *RegistryConfig) {
 		cfg.Timeout = timeout
 	}
 }
 
-func WithGroup(group string) RegistryOption {
+func WithRegistry_Group(group string) RegistryOption {
 	return func(cfg *RegistryConfig) {
 		cfg.Group = group
 	}
 }
 
-func WithNamespace(namespace string) RegistryOption {
+func WithRegistry_Namespace(namespace string) RegistryOption {
 	return func(cfg *RegistryConfig) {
 		cfg.Namespace = namespace
 	}
 }
 
-func WithTTL(ttl string) RegistryOption {
+func WithRegistry_TTL(ttl string) RegistryOption {
 	return func(cfg *RegistryConfig) {
 		cfg.TTL = ttl
 	}
 }
 
-func WithAddress(address string) RegistryOption {
+func WithRegistry_Address(address string) RegistryOption {
 	return func(cfg *RegistryConfig) {
 		cfg.Address = address
 	}
 }
 
-func WithUsername(name string) RegistryOption {
+func WithRegistry_Username(name string) RegistryOption {
 	return func(cfg *RegistryConfig) {
 		cfg.Username = name
 	}
 }
 
-func WithPassword(password string) RegistryOption {
+func WithRegistry_Password(password string) RegistryOption {
 	return func(cfg *RegistryConfig) {
 		cfg.Password = password
 	}
 }
 
-func WithSimplified(flag bool) RegistryOption {
+func WithRegistry_Simplified(flag bool) RegistryOption {
 	return func(cfg *RegistryConfig) {
 		cfg.Simplified = flag
 	}
 }
 
-func WithPreferred(flag bool) RegistryOption {
+func WithRegistry_Preferred(flag bool) RegistryOption {
 	return func(cfg *RegistryConfig) {
 		cfg.Preferred = flag
 	}
 }
 
-func WithZone(zone string) RegistryOption {
+func WithRegistry_Zone(zone string) RegistryOption {
 	return func(cfg *RegistryConfig) {
 		cfg.Zone = zone
 	}
 }
 
-func WithWeight(weight int64) RegistryOption {
+func WithRegistry_Weight(weight int64) RegistryOption {
 	return func(cfg *RegistryConfig) {
 		cfg.Weight = weight
 	}
 }
 
-func WithParams(params map[string]string) RegistryOption {
+func WithRegistry_Params(params map[string]string) RegistryOption {
 	return func(cfg *RegistryConfig) {
 		cfg.Params = params
 	}
 }
 
-func WithRegistryType(typ string) RegistryOption {
+func WithRegistry_RegistryType(typ string) RegistryOption {
 	return func(cfg *RegistryConfig) {
 		cfg.RegistryType = typ
 	}
 }
 
-func WithUseAsMetaReport(flag bool) RegistryOption {
+func WithRegistry_UseAsMetaReport(flag bool) RegistryOption {
 	return func(cfg *RegistryConfig) {
 		cfg.UseAsMetaReport = flag
 	}
 }
 
-func WithUseAsConfigCenter(flag bool) RegistryOption {
+func WithRegistry_UseAsConfigCenter(flag bool) RegistryOption {
 	return func(cfg *RegistryConfig) {
 		cfg.UseAsConfigCenter = flag
 	}
diff --git a/options.go b/options.go
index 550a7c0..c920d8e 100644
--- a/options.go
+++ b/options.go
@@ -18,44 +18,40 @@
 package dubbo
 
 import (
-	"dubbo.apache.org/dubbo-go/v3/config_center"
 	"dubbo.apache.org/dubbo-go/v3/global"
-	"dubbo.apache.org/dubbo-go/v3/metadata/report"
-	"dubbo.apache.org/dubbo-go/v3/metrics"
-	"dubbo.apache.org/dubbo-go/v3/protocol"
-	"dubbo.apache.org/dubbo-go/v3/registry"
 )
 
 type RootConfig struct {
-	Application         *global.ApplicationConfig           `validate:"required" yaml:"application" json:"application,omitempty" property:"application"`
-	Protocols           map[string]*protocol.ProtocolConfig `validate:"required" yaml:"protocols" json:"protocols" property:"protocols"`
-	Registries          map[string]*registry.RegistryConfig `yaml:"registries" json:"registries" property:"registries"`
-	ConfigCenter        *config_center.CenterConfig         `yaml:"config-center" json:"config-center,omitempty"`
-	MetadataReport      *report.MetadataReportConfig        `yaml:"metadata-report" json:"metadata-report,omitempty" property:"metadata-report"`
-	Provider            *global.ProviderConfig              `yaml:"provider" json:"provider" property:"provider"`
-	Consumer            *global.ConsumerConfig              `yaml:"consumer" json:"consumer" property:"consumer"`
-	Metric              *metrics.MetricConfig               `yaml:"metrics" json:"metrics,omitempty" property:"metrics"`
-	Tracing             map[string]*global.TracingConfig    `yaml:"tracing" json:"tracing,omitempty" property:"tracing"`
-	Logger              *global.LoggerConfig                `yaml:"logger" json:"logger,omitempty" property:"logger"`
-	Shutdown            *global.ShutdownConfig              `yaml:"shutdown" json:"shutdown,omitempty" property:"shutdown"`
-	Router              []*RouterConfig                     `yaml:"router" json:"router,omitempty" property:"router"`
-	EventDispatcherType string                              `default:"direct" yaml:"event-dispatcher-type" json:"event-dispatcher-type,omitempty"`
-	CacheFile           string                              `yaml:"cache_file" json:"cache_file,omitempty" property:"cache_file"`
-	Custom              *global.CustomConfig                `yaml:"custom" json:"custom,omitempty" property:"custom"`
-	Profiles            *global.ProfilesConfig              `yaml:"profiles" json:"profiles,omitempty" property:"profiles"`
-	TLSConfig           *global.TLSConfig                   `yaml:"tls_config" json:"tls_config,omitempty" property:"tls_config"`
+	Application    *global.ApplicationConfig         `validate:"required" yaml:"application" json:"application,omitempty" property:"application"`
+	Protocols      map[string]*global.ProtocolConfig `validate:"required" yaml:"protocols" json:"protocols" property:"protocols"`
+	Registries     map[string]*global.RegistryConfig `yaml:"registries" json:"registries" property:"registries"`
+	ConfigCenter   *global.CenterConfig              `yaml:"config-center" json:"config-center,omitempty"`
+	MetadataReport *global.MetadataReportConfig      `yaml:"metadata-report" json:"metadata-report,omitempty" property:"metadata-report"`
+	Provider       *global.ProviderConfig            `yaml:"provider" json:"provider" property:"provider"`
+	Consumer       *global.ConsumerConfig            `yaml:"consumer" json:"consumer" property:"consumer"`
+	Metric         *global.MetricConfig              `yaml:"metrics" json:"metrics,omitempty" property:"metrics"`
+	Tracing        map[string]*global.TracingConfig  `yaml:"tracing" json:"tracing,omitempty" property:"tracing"`
+	Logger         *global.LoggerConfig              `yaml:"logger" json:"logger,omitempty" property:"logger"`
+	Shutdown       *global.ShutdownConfig            `yaml:"shutdown" json:"shutdown,omitempty" property:"shutdown"`
+	// todo(DMwangnima): router feature would be supported in the future
+	//Router              []*RouterConfig                   `yaml:"router" json:"router,omitempty" property:"router"`
+	EventDispatcherType string                 `default:"direct" yaml:"event-dispatcher-type" json:"event-dispatcher-type,omitempty"`
+	CacheFile           string                 `yaml:"cache_file" json:"cache_file,omitempty" property:"cache_file"`
+	Custom              *global.CustomConfig   `yaml:"custom" json:"custom,omitempty" property:"custom"`
+	Profiles            *global.ProfilesConfig `yaml:"profiles" json:"profiles,omitempty" property:"profiles"`
+	TLSConfig           *global.TLSConfig      `yaml:"tls_config" json:"tls_config,omitempty" property:"tls_config"`
 }
 
 func defaultRootConfig() *RootConfig {
 	return &RootConfig{
 		Application:    global.DefaultApplicationConfig(),
-		Protocols:      make(map[string]*protocol.ProtocolConfig),
-		Registries:     make(map[string]*registry.RegistryConfig),
-		ConfigCenter:   config_center.DefaultCenterConfig(),
-		MetadataReport: report.DefaultMetadataReportConfig(),
+		Protocols:      make(map[string]*global.ProtocolConfig),
+		Registries:     make(map[string]*global.RegistryConfig),
+		ConfigCenter:   global.DefaultCenterConfig(),
+		MetadataReport: global.DefaultMetadataReportConfig(),
 		Provider:       global.DefaultProviderConfig(),
 		Consumer:       global.DefaultConsumerConfig(),
-		Metric:         metrics.DefaultMetricConfig(),
+		Metric:         global.DefaultMetricConfig(),
 		Tracing:        make(map[string]*global.TracingConfig),
 		Logger:         global.DefaultLoggerConfig(),
 		Shutdown:       global.DefaultShutdownConfig(),
@@ -91,36 +87,36 @@
 	}
 }
 
-func WithProtocol(key string, opts ...protocol.ProtocolOption) RootOption {
-	proCfg := new(protocol.ProtocolConfig)
+func WithProtocol(key string, opts ...global.ProtocolOption) RootOption {
+	proCfg := new(global.ProtocolConfig)
 	for _, opt := range opts {
 		opt(proCfg)
 	}
 
 	return func(cfg *RootConfig) {
 		if cfg.Protocols == nil {
-			cfg.Protocols = make(map[string]*protocol.ProtocolConfig)
+			cfg.Protocols = make(map[string]*global.ProtocolConfig)
 		}
 		cfg.Protocols[key] = proCfg
 	}
 }
 
-func WithRegistry(key string, opts ...registry.RegistryOption) RootOption {
-	regCfg := new(registry.RegistryConfig)
+func WithRegistry(key string, opts ...global.RegistryOption) RootOption {
+	regCfg := new(global.RegistryConfig)
 	for _, opt := range opts {
 		opt(regCfg)
 	}
 
 	return func(cfg *RootConfig) {
 		if cfg.Registries == nil {
-			cfg.Registries = make(map[string]*registry.RegistryConfig)
+			cfg.Registries = make(map[string]*global.RegistryConfig)
 		}
 		cfg.Registries[key] = regCfg
 	}
 }
 
-func WithConfigCenter(opts ...config_center.CenterOption) RootOption {
-	ccCfg := new(config_center.CenterConfig)
+func WithConfigCenter(opts ...global.CenterOption) RootOption {
+	ccCfg := new(global.CenterConfig)
 	for _, opt := range opts {
 		opt(ccCfg)
 	}
@@ -130,8 +126,8 @@
 	}
 }
 
-func WithMetadataReport(opts ...report.MetadataReportOption) RootOption {
-	mrCfg := new(report.MetadataReportConfig)
+func WithMetadataReport(opts ...global.MetadataReportOption) RootOption {
+	mrCfg := new(global.MetadataReportConfig)
 	for _, opt := range opts {
 		opt(mrCfg)
 	}
@@ -152,8 +148,8 @@
 	}
 }
 
-func WithMetric(opts ...metrics.MetricOption) RootOption {
-	meCfg := new(metrics.MetricConfig)
+func WithMetric(opts ...global.MetricOption) RootOption {
+	meCfg := new(global.MetricConfig)
 	for _, opt := range opts {
 		opt(meCfg)
 	}
diff --git a/protocol/triple/internal/client/cmd/main.go b/protocol/triple/internal/client/cmd/main.go
deleted file mode 100644
index 55ede08..0000000
--- a/protocol/triple/internal/client/cmd/main.go
+++ /dev/null
@@ -1,122 +0,0 @@
-package main
-
-import (
-	"context"
-)
-
-import (
-	"github.com/dubbogo/gost/log/logger"
-)
-
-import (
-	"dubbo.apache.org/dubbo-go/v3/client"
-	_ "dubbo.apache.org/dubbo-go/v3/imports"
-	greet "dubbo.apache.org/dubbo-go/v3/protocol/triple/internal/proto"
-	"dubbo.apache.org/dubbo-go/v3/protocol/triple/internal/proto/greettriple"
-)
-
-func main() {
-	//client initialization
-	cli, err := client.NewClient(
-		client.WithURL("127.0.0.1:8080"),
-	)
-	svc, err := greettriple.NewGreetService(cli)
-	if err != nil {
-		panic(err)
-	}
-
-	// classic config initialization
-	//svc := new(greettriple.GreetServiceImpl)
-	//greettriple.SetConsumerService(dubboCli)
-	//config.Load() // need dubbogo.yml
-
-	if err := testUnary(svc); err != nil {
-		logger.Error(err)
-		return
-	}
-
-	if err := testBidiStream(svc); err != nil {
-		logger.Error(err)
-		return
-	}
-
-	if err := testClientStream(svc); err != nil {
-		logger.Error(err)
-		return
-	}
-
-	if err := testServerStream(svc); err != nil {
-		logger.Error(err)
-		return
-	}
-}
-
-func testUnary(svc greettriple.GreetService) error {
-	logger.Info("start to test TRIPLE unary call")
-	resp, err := svc.Greet(context.Background(), &greet.GreetRequest{Name: "triple"})
-	if err != nil {
-		return err
-	}
-	logger.Infof("TRIPLE unary call resp: %s", resp.Greeting)
-	return nil
-}
-
-func testBidiStream(svc greettriple.GreetService) error {
-	logger.Info("start to test TRIPLE bidi stream")
-	stream, err := svc.GreetStream(context.Background())
-	if err != nil {
-		return err
-	}
-	if err := stream.Send(&greet.GreetStreamRequest{Name: "triple"}); err != nil {
-		return err
-	}
-	resp, err := stream.Recv()
-	if err != nil {
-		return err
-	}
-	logger.Infof("TRIPLE bidi stream resp: %s", resp.Greeting)
-	if err := stream.CloseRequest(); err != nil {
-		return err
-	}
-	if err := stream.CloseResponse(); err != nil {
-		return err
-	}
-	return nil
-}
-
-func testClientStream(svc greettriple.GreetService) error {
-	logger.Info("start to test TRIPLE dubboClint stream")
-	stream, err := svc.GreetClientStream(context.Background())
-	if err != nil {
-		return err
-	}
-	for i := 0; i < 5; i++ {
-		if err := stream.Send(&greet.GreetClientStreamRequest{Name: "triple"}); err != nil {
-			return err
-		}
-	}
-	resp, err := stream.CloseAndRecv()
-	if err != nil {
-		return err
-	}
-	logger.Infof("TRIPLE dubboClint stream resp: %s", resp.Greeting)
-	return nil
-}
-
-func testServerStream(svc greettriple.GreetService) error {
-	logger.Info("start to test TRIPLE server stream")
-	stream, err := svc.GreetServerStream(context.Background(), &greet.GreetServerStreamRequest{Name: "triple"})
-	if err != nil {
-		return err
-	}
-	for stream.Recv() {
-		logger.Infof("TRIPLE server stream resp: %s", stream.Msg().Greeting)
-	}
-	if stream.Err() != nil {
-		return err
-	}
-	if err := stream.Close(); err != nil {
-		return err
-	}
-	return nil
-}
diff --git a/protocol/triple/internal/client/cmd/dubbogo.yml b/protocol/triple/internal/client/cmd_classic/dubbogo.yml
similarity index 100%
rename from protocol/triple/internal/client/cmd/dubbogo.yml
rename to protocol/triple/internal/client/cmd_classic/dubbogo.yml
diff --git a/protocol/triple/internal/client/cmd_classic/main.go b/protocol/triple/internal/client/cmd_classic/main.go
new file mode 100644
index 0000000..a66b13c
--- /dev/null
+++ b/protocol/triple/internal/client/cmd_classic/main.go
@@ -0,0 +1,28 @@
+package main
+
+import (
+	"context"
+	"dubbo.apache.org/dubbo-go/v3/config"
+	"fmt"
+)
+
+import (
+	_ "dubbo.apache.org/dubbo-go/v3/imports"
+	greet "dubbo.apache.org/dubbo-go/v3/protocol/triple/internal/proto"
+	"dubbo.apache.org/dubbo-go/v3/protocol/triple/internal/proto/greettriple"
+)
+
+func main() {
+	svc := new(greettriple.GreetServiceImpl)
+	greettriple.SetConsumerService(svc)
+	if err := config.Load(); err != nil {
+		panic(err)
+	}
+
+	resp, err := svc.Greet(context.Background(), &greet.GreetRequest{Name: "dubbo"})
+	if err != nil {
+		panic(err)
+	}
+
+	fmt.Println(resp.Greeting)
+}
diff --git a/protocol/triple/internal/client/cmd_client/main.go b/protocol/triple/internal/client/cmd_client/main.go
new file mode 100644
index 0000000..2d2c4d9
--- /dev/null
+++ b/protocol/triple/internal/client/cmd_client/main.go
@@ -0,0 +1,30 @@
+package main
+
+import (
+	"context"
+	"dubbo.apache.org/dubbo-go/v3/client"
+	greet "dubbo.apache.org/dubbo-go/v3/protocol/triple/internal/proto"
+	"dubbo.apache.org/dubbo-go/v3/protocol/triple/internal/proto/greettriple"
+	"fmt"
+)
+
+func main() {
+	// for the most brief RPC case
+	cli, err := client.NewClient(
+		client.WithURL("127.0.0.1:20000"),
+	)
+	if err != nil {
+		panic(err)
+	}
+	svc, err := greettriple.NewGreetService(cli)
+	if err != nil {
+		panic(err)
+	}
+
+	resp, err := svc.Greet(context.Background(), &greet.GreetRequest{Name: "dubbo"})
+	if err != nil {
+		panic(err)
+	}
+
+	fmt.Println(resp.Greeting)
+}
diff --git a/protocol/triple/internal/client/cmd_instance/main.go b/protocol/triple/internal/client/cmd_instance/main.go
new file mode 100644
index 0000000..d0807c9
--- /dev/null
+++ b/protocol/triple/internal/client/cmd_instance/main.go
@@ -0,0 +1,49 @@
+package main
+
+import (
+	"context"
+	"dubbo.apache.org/dubbo-go/v3"
+	"dubbo.apache.org/dubbo-go/v3/client"
+	"dubbo.apache.org/dubbo-go/v3/global"
+	greet "dubbo.apache.org/dubbo-go/v3/protocol/triple/internal/proto"
+	"dubbo.apache.org/dubbo-go/v3/protocol/triple/internal/proto/greettriple"
+	"fmt"
+)
+
+func main() {
+	// global conception
+	// configure global configurations and common modules
+	ins, err := dubbo.NewInstance(
+		dubbo.WithApplication(
+			global.WithApplication_Name("dubbo_test"),
+		),
+		dubbo.WithRegistry("nacos",
+			global.WithRegistry_Address("127.0.0.1:8848"),
+		),
+		dubbo.WithMetric(
+			global.WithMetric_Enable(true),
+		),
+	)
+	if err != nil {
+		panic(err)
+	}
+	// configure the params that only client layer cares
+	cli, err := ins.NewClient(
+		client.WithRetries(3),
+	)
+	if err != nil {
+		panic(err)
+	}
+
+	svc, err := greettriple.NewGreetService(cli)
+	if err != nil {
+		panic(err)
+	}
+
+	resp, err := svc.Greet(context.Background(), &greet.GreetRequest{Name: "dubbo"})
+	if err != nil {
+		panic(err)
+	}
+
+	fmt.Println(resp.Greeting)
+}