This is an automated email from the ASF dual-hosted git repository.

albumenj pushed a commit to branch 3.0-multi-instances
in repository https://gitbox.apache.org/repos/asf/dubbo.git

commit 7c059611a41f17f11ff3e0fd853be1a8c3a4735c
Merge: 6c65c31 3f59150
Author: Albumen Kevin <[email protected]>
AuthorDate: Tue Aug 31 17:47:12 2021 +0800

    Merge remote-tracking branch 'apache/3.0' into 3.0-multi-instances
    
    # Conflicts:
    #   
dubbo-common/src/main/java/org/apache/dubbo/common/constants/CommonConstants.java
    #   
dubbo-config/dubbo-config-api/src/main/java/org/apache/dubbo/config/ReferenceConfig.java
    #   
dubbo-config/dubbo-config-api/src/main/java/org/apache/dubbo/config/bootstrap/DubboBootstrap.java
    #   
dubbo-config/dubbo-config-api/src/test/java/org/apache/dubbo/config/ReferenceConfigTest.java
    #   
dubbo-config/dubbo-config-api/src/test/java/org/apache/dubbo/integration/multiple/servicediscoveryregistry/MultipleRegistryCenterServiceDiscoveryRegistryRegistryServiceListener.java
    #   
dubbo-config/dubbo-config-spring/src/test/java/org/apache/dubbo/config/spring/reference/javaconfig/JavaConfigReferenceBeanTest.java
    #   
dubbo-metadata/dubbo-metadata-api/src/main/java/org/apache/dubbo/metadata/report/MetadataReportInstance.java
    #   
dubbo-registry/dubbo-registry-api/src/main/java/org/apache/dubbo/registry/client/DefaultServiceInstance.java
    #   
dubbo-registry/dubbo-registry-api/src/main/java/org/apache/dubbo/registry/client/ServiceDiscoveryRegistryDirectory.java
    #   
dubbo-registry/dubbo-registry-api/src/main/java/org/apache/dubbo/registry/client/metadata/MetadataServiceNameMapping.java
    #   
dubbo-registry/dubbo-registry-api/src/main/java/org/apache/dubbo/registry/client/metadata/ServiceInstanceMetadataCustomizer.java
    #   
dubbo-registry/dubbo-registry-api/src/main/java/org/apache/dubbo/registry/client/metadata/ServiceInstanceMetadataUtils.java
    #   
dubbo-registry/dubbo-registry-api/src/main/java/org/apache/dubbo/registry/integration/RegistryProtocol.java
    #   
dubbo-registry/dubbo-registry-api/src/main/java/org/apache/dubbo/registry/support/CacheableFailbackRegistry.java
    #   
dubbo-registry/dubbo-registry-api/src/test/java/org/apache/dubbo/registry/client/DefaultServiceInstanceTest.java
    #   
dubbo-registry/dubbo-registry-api/src/test/java/org/apache/dubbo/registry/client/migration/MigrationRuleListenerTest.java
    #   
dubbo-registry/dubbo-registry-api/src/test/java/org/apache/dubbo/registry/client/migration/model/MigrationRuleTest.java
    #   
dubbo-registry/dubbo-registry-nacos/src/main/java/org/apache/dubbo/registry/nacos/NacosServiceDiscovery.java
    #   
dubbo-registry/dubbo-registry-zookeeper/src/main/java/org/apache/dubbo/registry/zookeeper/util/CuratorFrameworkUtils.java
    #   
dubbo-rpc/dubbo-rpc-dubbo/src/main/java/org/apache/dubbo/rpc/protocol/dubbo/DecodeableRpcResult.java

 compiler/pom.xml                                   |   2 +-
 .../main/resources/Dubbo3InterfaceStub.mustache    |  44 +-
 compiler/src/main/resources/Dubbo3Stub.mustache    |   5 +-
 compiler/src/main/resources/DubboGrpcStub.mustache |   3 -
 compiler/src/main/resources/DubboStub.mustache     |   3 -
 .../main/resources/ReactorDubboGrpcStub.mustache   |   3 -
 .../src/main/resources/RxDubboGrpcStub.mustache    |   3 -
 .../cluster/router/condition/ConditionRouter.java  |   3 -
 .../cluster/router/condition/config/AppRouter.java |   3 +-
 .../router/condition/config/ListenableRouter.java  |   4 +-
 .../cluster/router/mesh/route/MeshEnvListener.java |   3 -
 .../router/mesh/route/MeshEnvListenerFactory.java  |  10 +-
 .../cluster/router/mesh/route/MeshRuleManager.java |   5 +-
 .../cluster/support/BroadcastClusterInvoker.java   |   6 +-
 .../absent/AbsentConfiguratorTest.java             |  52 ++
 .../override/OverrideConfiguratorTest.java         |  49 ++
 .../filter/DefaultFilterChainBuilderTest.java      |  66 +++
 .../dubbo/rpc/cluster/filter/DemoServiceImpl.java  |  14 +-
 .../apache/dubbo/rpc/cluster/filter/LogFilter.java |  36 +-
 .../ShortestResponseLoadBalanceTest.java           |   7 +-
 .../router/mock/MockInvokersSelectorTest.java      |  71 +++
 .../support/BroadCastClusterInvokerTest.java       | 164 +++++++
 .../dubbo/internal/org.apache.dubbo.rpc.Filter     |   1 +
 .../dubbo/common/constants/CommonConstants.java    |  29 +-
 .../dubbo/common/extension/ExtensionLoader.java    |   1 +
 .../extension/support/WrapperComparator.java       |  31 +-
 .../url/component/DubboServiceAddressURL.java      |   6 -
 .../org/apache/dubbo/common/utils/ConfigUtils.java |   3 +-
 .../org/apache/dubbo/common/utils/NetUtils.java    |  55 ++-
 .../org/apache/dubbo/config/AbstractConfig.java    |   2 +-
 .../org/apache/dubbo/config/ApplicationConfig.java |  32 +-
 .../apache/dubbo/config/ConfigCenterConfig.java    |  74 +--
 .../apache/dubbo/config/MetadataReportConfig.java  |  37 +-
 .../java/org/apache/dubbo/config/ModuleConfig.java |   2 +
 .../apache/dubbo/rpc/model/MethodDescriptor.java   |  41 +-
 .../apache/dubbo/common/utils/NetUtilsTest.java    |  91 +++-
 .../dubbo/config/AbstractInterfaceConfigTest.java  |  70 +--
 .../java/org/apache/dubbo/config/Greeting.java     |  12 +-
 .../org/apache/dubbo/config/GreetingLocal1.java    |   9 +-
 .../org/apache/dubbo/config/GreetingLocal2.java    |  14 +-
 .../org/apache/dubbo/config/GreetingLocal3.java    |  17 +-
 .../apache/dubbo/descriptor/DescriptorService.java |   5 +
 .../dubbo/descriptor/MethodDescriptorTest.java     |  14 +
 dubbo-config/dubbo-config-api/pom.xml              |   7 +
 .../org/apache/dubbo/config/ReferenceConfig.java   |  12 +-
 .../org/apache/dubbo/config/ServiceConfig.java     |  11 +-
 .../dubbo/config/bootstrap/DubboBootstrap.java     | 116 +++--
 .../bootstrap/builders/MetadataReportBuilder.java  |  36 +-
 .../dubbo/config/utils/ConfigValidationUtils.java  |   2 +-
 .../apache/dubbo/config/ReferenceConfigTest.java   | 531 ++++++++++++++++++++-
 .../org/apache/dubbo/config/ServiceConfigTest.java |   6 +-
 .../dubbo/config/bootstrap/DubboBootstrapTest.java | 166 ++++++-
 .../org/apache/dubbo/config/url/UrlTestBase.java   |  61 +--
 .../config/utils/ConfigValidationUtilsTest.java    |  63 +++
 .../org/apache/dubbo/integration/Constants.java    |  10 +-
 ...gistryCenterExportProviderExporterListener.java |  23 +-
 ...MultipleRegistryCenterExportProviderFilter.java |  86 ++++
 ...gistryCenterExportProviderIntegrationTest.java} | 113 +++--
 ...terExportProviderRegistryProtocolListener.java} |   8 +-
 ...ltipleRegistryCenterExportProviderService.java} |  12 +-
 ...leRegistryCenterExportProviderServiceImpl.java} |  16 +-
 ...egistryCenterExportProviderServiceListener.java |  24 +-
 ...MultipleRegistryCenterInjvmIntegrationTest.java |  15 +-
 ...terServiceDiscoveryRegistryIntegrationTest.java |  55 ++-
 ...ceDiscoveryRegistryRegistryServiceListener.java |  28 +-
 ...RegistryCenterDubboProtocolIntegrationTest.java |  26 +-
 ...gistryCenterExportMetadataExporterListener.java |  24 +-
 ...gistryCenterExportMetadataIntegrationTest.java} | 131 ++---
 ...SingleRegistryCenterExportMetadataService.java} |  12 +-
 ...leRegistryCenterExportMetadataServiceImpl.java} |  17 +-
 ...egistryCenterExportMetadataServiceListener.java |  25 +-
 ...egistryCenterExportProviderIntegrationTest.java |  67 ++-
 ...nterExportProviderRegistryProtocolListener.java |   4 +-
 .../SingleRegistryCenterInjvmIntegrationTest.java  |  16 +-
 .../registrycenter/AbstractRegistryCenter.java     | 107 +++++
 .../DefaultMultipleRegistryCenter.java             | 121 -----
 .../DefaultSingleRegistryCenter.java               | 101 ----
 .../dubbo/registrycenter/RegistryCenter.java       |  33 ++
 ...r.java => ZookeeperMultipleRegistryCenter.java} |  26 +-
 .../registrycenter/ZookeeperRegistryCenter.java    | 142 ++++++
 ...ter.java => ZookeeperSingleRegistryCenter.java} |  27 +-
 .../org.apache.dubbo.common.status.StatusChecker   |  19 +-
 .../org.apache.dubbo.common.threadpool.ThreadPool  |  19 +-
 .../org.apache.dubbo.config.ServiceListener        |   2 +
 ...g.apache.dubbo.registry.RegistryServiceListener |  17 -
 ...o.registry.integration.RegistryProtocolListener |  18 +-
 .../services/org.apache.dubbo.remoting.Dispatcher  |  19 +-
 .../services/org.apache.dubbo.remoting.Transporter |  19 +-
 .../org.apache.dubbo.remoting.exchange.Exchanger   |  19 +-
 .../org.apache.dubbo.remoting.telnet.TelnetHandler |  16 -
 .../services/org.apache.dubbo.rpc.ExporterListener |  19 +-
 .../META-INF/services/org.apache.dubbo.rpc.Filter  |   1 +
 .../config/spring/util/DubboAnnotationUtils.java   |   3 +-
 .../src/main/resources/META-INF/dubbo.xsd          |   8 +-
 .../org/apache/dubbo/config/spring/ConfigTest.java |   9 +-
 .../dubbo/config/spring/JavaConfigBeanTest.java    |   8 +-
 .../annotation/MethodConfigCallbackTest.java       |   8 +-
 .../factory/annotation/ParameterConvertTest.java   |   5 +
 .../XmlReferenceBeanConditionalTest.java           |   8 +-
 ...nfigAnnotationReferenceBeanConditionalTest.java |   8 +-
 .../JavaConfigRawReferenceBeanConditionalTest.java |   8 +-
 .../JavaConfigReferenceBeanConditionalTest4.java   |   8 +-
 .../configprops/SpringBootConfigPropsTest.java     |  13 +-
 .../SpringBootMultipleConfigPropsTest.java         |  10 +-
 .../importxml/SpringBootImportDubboXmlTest.java    |   8 +-
 .../annotation/DubboConfigConfigurationTest.java   |   6 +-
 .../context/annotation/EnableDubboConfigTest.java  |  11 +-
 .../spring/issues/issue6000/Issue6000Test.java     |   8 +-
 .../spring/issues/issue6252/Issue6252Test.java     |  10 +-
 .../spring/issues/issue7003/Issue7003Test.java     |   8 +-
 .../consumer/PropertyConfigurerTest.java           |   8 +-
 .../consumer2/PropertySourcesConfigurerTest.java   |   8 +-
 .../consumer3/PropertySourcesInJavaConfigTest.java |  25 +-
 .../reference/DubboConfigBeanInitializerTest.java  |   8 +-
 .../config/spring/reference/ReferenceKeyTest.java  |   8 +-
 .../javaconfig/JavaConfigReferenceBeanTest.java    |  15 +-
 .../spring/reference/localcall/LocalCallTest.java  |   8 +-
 .../spring/reference/localcall/LocalCallTest2.java |   8 +-
 .../registrycenter/AbstractRegistryCenter.java     | 107 +++++
 .../DefaultSingleRegistryCenter.java               | 101 ----
 .../spring/registrycenter/RegistryCenter.java      |  33 ++
 ...r.java => ZookeeperMultipleRegistryCenter.java} |  42 +-
 .../registrycenter/ZookeeperRegistryCenter.java    | 142 ++++++
 ...ter.java => ZookeeperSingleRegistryCenter.java} |  27 +-
 .../config/spring/schema/GenericServiceTest.java   |  15 +-
 dubbo-dependencies-bom/pom.xml                     |   2 +-
 dubbo-distribution/dubbo-all/pom.xml               |  12 +
 .../org/apache/dubbo/metadata/MetadataInfo.java    |  63 ++-
 .../apache/dubbo/metadata/ServiceNameMapping.java  |   2 +-
 .../metadata/report/MetadataReportInstance.java    |   7 +-
 .../support/AbstractMetadataReportFactory.java     |  34 +-
 .../apache/dubbo/metadata/MetadataInfoTest.java    |  99 +++-
 .../CustomizedParamsFilter.java}                   |  19 +-
 .../metadata/filter/ExcludedParamsFilter.java      |  26 +-
 .../org.apache.dubbo.metadata.MetadataParamsFilter |   3 +-
 .../apache/dubbo/auth/AccessKeyAuthenticator.java  |   2 +-
 .../dubbo/auth/AccessKeyAuthenticatorTest.java     |   2 +-
 .../dubbo/registry/ListenerRegistryWrapper.java    |   8 +-
 .../dubbo/registry/ProviderFirstParams.java}       |  10 +-
 .../registry/client/DefaultServiceInstance.java    |   7 +-
 .../dubbo/registry/client/InstanceAddressURL.java  |  26 +-
 .../registry/client/ServiceDiscoveryRegistry.java  | 100 +---
 .../client/ServiceDiscoveryRegistryDirectory.java  |  22 +-
 .../dubbo/registry/client/ServiceInstance.java     |  11 -
 .../listener/ServiceInstancesChangedListener.java  |  42 +-
 .../metadata/MetadataServiceNameMapping.java       |  58 +--
 ...MetadataServiceURLParamsMetadataCustomizer.java |   3 +
 .../registry/client/metadata/MetadataUtils.java    |  33 +-
 .../ServiceInstanceMetadataCustomizer.java         |  42 +-
 .../metadata/ServiceInstanceMetadataUtils.java     |  42 +-
 .../store/InMemoryWritableMetadataService.java     |   2 +-
 .../metadata/store/RemoteMetadataServiceImpl.java  |   2 +-
 .../client/migration/MigrationRuleHandler.java     |  11 +-
 .../client/migration/MigrationRuleListener.java    |  33 +-
 .../client/migration/model/MigrationRule.java      |   3 +
 .../registry/integration/RegistryProtocol.java     |  31 +-
 .../registry/support/AbstractRegistryFactory.java  |  53 +-
 .../support/CacheableFailbackRegistry.java         |  15 +-
 .../support/DefaultProviderFirstParams.java        |  25 +-
 .../org.apache.dubbo.registry.ProviderFirstParams  |   1 +
 .../java/org/apache/dubbo/registry/MockLogger.java | 135 ++++++
 .../client/DefaultServiceInstanceTest.java         |  62 ++-
 .../registry/client/InstanceAddressURLTest.java    | 160 +++++++
 .../client/ServiceDiscoveryRegistryTest.java       | 248 ++++++++++
 .../MockServiceInstancesChangedListener.java       |  46 ++
 .../ServiceInstancesChangedListenerTest.java       |  61 ++-
 .../metadata/MetadataServiceNameMappingTest.java   | 134 ++++++
 .../ProtocolPortsMetadataCustomizerTest.java       | 101 ++++
 .../ServiceInstanceMetadataCustomizerTest.java     | 126 +++++
 .../metadata/store/CustomizedParamsFilter.java     |  22 +-
 .../metadata/store/ExcludedParamsFilter.java       |  16 +-
 .../store/InMemoryMetadataServiceTest.java         | 175 +++++++
 .../store/RemoteMetadataServiceImplTest.java}      |   7 +-
 .../client/migration/MigrationInvokerTest.java     |   8 +
 .../client/migration/MigrationRuleHandlerTest.java |  26 +
 .../migration/MigrationRuleListenerTest.java       | 174 ++++++-
 .../client/migration/model/MigrationRuleTest.java  | 106 ++--
 .../DemoService.java}                              |   9 +-
 .../DemoService2.java}                             |   9 +-
 .../support/ServiceOrientedRegistryTest.java       |  16 +-
 .../org.apache.dubbo.metadata.MetadataParamsFilter |   2 +
 .../KubernetesMeshEnvListenerFactory.java          |  51 +-
 ...uster.router.mesh.route.MeshEnvListenerFactory} |   2 +-
 .../dubbo/registry/multiple/MultipleRegistry.java  |   2 +-
 .../multiple/MultipleServiceDiscovery.java         |   2 +-
 .../registry/nacos/NacosNamingServiceWrapper.java  |   4 +
 .../apache/dubbo/registry/nacos/NacosRegistry.java |  16 +-
 .../registry/nacos/NacosServiceDiscovery.java      |  26 +-
 .../nacos/util/NacosNamingServiceUtils.java        |  15 -
 .../zookeeper/ZookeeperServiceDiscovery.java       |   9 +-
 .../zookeeper/util/CuratorFrameworkUtils.java      |  39 +-
 .../dubbo/remoting/transport/AbstractClient.java   |  13 +-
 .../java/org/apache/dubbo/rpc/HeaderFilter.java    |  11 +-
 .../apache/dubbo/rpc/filter/TokenHeaderFilter.java |  49 ++
 .../dubbo/rpc/listener/ListenerInvokerWrapper.java |   7 +
 .../dubbo/rpc/protocol/AbstractProtocol.java       |   8 +-
 .../apache/dubbo/rpc/support/AccessLogData.java    |   7 +-
 .../org/apache/dubbo/rpc/support/MockInvoker.java  |   7 +-
 .../internal/org.apache.dubbo.rpc.HeaderFilter     |   1 +
 .../dubbo/rpc/protocol/CountInvokerListener.java   |  28 +-
 .../rpc/protocol/ProtocolListenerWrapperTest.java  |  81 ++++
 .../org/apache/dubbo/rpc/support/DemoServiceA.java |   9 +-
 .../apache/dubbo/rpc/support/DemoServiceAMock.java |  12 +-
 .../org/apache/dubbo/rpc/support/DemoServiceB.java |   9 +-
 .../apache/dubbo/rpc/support/DemoServiceBMock.java |  11 +-
 .../apache/dubbo/rpc/support/MockInvokerTest.java  |  25 +
 .../internal/org.apache.dubbo.rpc.InvokerListener  |   1 +
 .../rpc/protocol/dubbo/DecodeableRpcResult.java    |  13 +-
 .../rpc/protocol/dubbo/DubboCodecSupport.java      |  18 +-
 .../dubbo/rpc/protocol/dubbo/DubboProtocol.java    |   6 +-
 .../dubbo/rpc/protocol/injvm/InjvmExporter.java    |   2 +-
 .../dubbo/rpc/protocol/injvm/InjvmInvoker.java     |   2 +-
 .../rpc/protocol/injvm/InjvmProtocolTest.java      |  19 +-
 .../rpc/protocol/tri/AbstractClientStream.java     |   6 +-
 .../rpc/protocol/tri/AbstractServerStream.java     |  23 +-
 .../dubbo/rpc/protocol/tri/AbstractStream.java     |  54 ++-
 .../dubbo/rpc/protocol/tri/ClientStream.java       |   8 +-
 .../rpc/protocol/tri/ClientTransportObserver.java  |   6 +-
 .../dubbo/rpc/protocol/tri/ServerStream.java       |  49 +-
 .../rpc/protocol/tri/ServerTransportObserver.java  |   8 +-
 ...Serialization.java => SingleProtobufUtils.java} |  64 ++-
 .../org/apache/dubbo/rpc/protocol/tri/Stream.java  |  46 +-
 .../dubbo/rpc/protocol/tri/TransportObserver.java  |  20 +-
 .../rpc/protocol/tri/TripleClientHandler.java      |  16 +-
 .../protocol/tri/TripleClientInboundHandler.java   |   2 +-
 .../tri/TripleHttp2ClientResponseHandler.java      |   6 +-
 .../tri/TripleHttp2FrameServerHandler.java         |   6 +-
 .../protocol/tri/TripleServerInboundHandler.java   |   2 +-
 .../apache/dubbo/rpc/protocol/tri/TripleUtil.java  |   6 +-
 .../dubbo/rpc/protocol/tri/UnaryClientStream.java  |  11 +-
 .../dubbo/rpc/protocol/tri/UnaryServerStream.java  |  18 +-
 .../rpc/protocol/tri/UnaryClientStreamTest.java    |   2 +-
 232 files changed, 5513 insertions(+), 2091 deletions(-)

diff --cc 
dubbo-cluster/src/main/java/org/apache/dubbo/rpc/cluster/router/mesh/route/MeshRuleManager.java
index 6e988f9,b07fede..c64d780
--- 
a/dubbo-cluster/src/main/java/org/apache/dubbo/rpc/cluster/router/mesh/route/MeshRuleManager.java
+++ 
b/dubbo-cluster/src/main/java/org/apache/dubbo/rpc/cluster/router/mesh/route/MeshRuleManager.java
@@@ -40,10 -42,11 +42,11 @@@ public final class MeshRuleManager 
  
          MeshAppRuleListener meshAppRuleListener = new 
MeshAppRuleListener(app);
          String appRuleDataId = app + MESH_RULE_DATA_ID_SUFFIX;
 -        DynamicConfiguration configuration = 
ApplicationModel.getEnvironment().getDynamicConfiguration()
 +        DynamicConfiguration configuration = 
ApplicationModel.defaultModel().getApplicationEnvironment().getDynamicConfiguration()
              .orElse(null);
  
-         Set<MeshEnvListener> envListeners = 
ExtensionLoader.getExtensionLoader(MeshEnvListener.class).getSupportedExtensionInstances();
+         Set<MeshEnvListenerFactory> envListenerFactories = 
ExtensionLoader.getExtensionLoader(MeshEnvListenerFactory.class).getSupportedExtensionInstances();
+         Set<MeshEnvListener> envListeners = 
envListenerFactories.stream().map(MeshEnvListenerFactory::getListener).filter(Objects::nonNull).collect(Collectors.toSet());
  
          if (configuration == null && 
envListeners.stream().noneMatch(MeshEnvListener::isEnable)) {
              logger.warn("Doesn't support Configuration!");
diff --cc 
dubbo-common/src/main/java/org/apache/dubbo/common/constants/CommonConstants.java
index 67de259,7c59e88..c1019ea
--- 
a/dubbo-common/src/main/java/org/apache/dubbo/common/constants/CommonConstants.java
+++ 
b/dubbo-common/src/main/java/org/apache/dubbo/common/constants/CommonConstants.java
@@@ -448,7 -464,12 +464,16 @@@ public interface CommonConstants 
  
      String SERVICE_NAME_MAPPING_KEY = "service-name-mapping";
  
 +    String SCOPE_MODEL = "scopeModel";
 +
 +    String SERVICE_MODEL = "serviceModel";
++
+     /**
+      * The property name for {@link NetworkInterface#getDisplayName() the 
name of network interface} that
+      * the Dubbo application will be ignored
+      *
+      * @since 2.7.6
+      */
+     String DUBBO_NETWORK_IGNORED_INTERFACE = 
"dubbo.network.interface.ignored";
+ 
  }
diff --cc 
dubbo-common/src/main/java/org/apache/dubbo/config/ConfigCenterConfig.java
index 4133f0e,412122e..59ff045
--- a/dubbo-common/src/main/java/org/apache/dubbo/config/ConfigCenterConfig.java
+++ b/dubbo-common/src/main/java/org/apache/dubbo/config/ConfigCenterConfig.java
@@@ -131,13 -149,11 +149,13 @@@ public class ConfigCenterConfig extend
          if (StringUtils.isEmpty(map.get(PROTOCOL_KEY))) {
              map.put(PROTOCOL_KEY, ZOOKEEPER_PROTOCOL);
          }
 -        return UrlUtils.parseURL(address, map);
 +        URL url = UrlUtils.parseURL(address, map);
 +        url.setScopeModel(getScopeModel());
 +        return url;
      }
  
-     public boolean checkOrUpdateInited() {
-         return inited.compareAndSet(false, true);
+     public boolean checkOrUpdateInitialized(boolean update) {
+         return initialized.compareAndSet(false, update);
      }
  
      public Map<String, String> getExternalConfiguration() {
diff --cc 
dubbo-config/dubbo-config-api/src/main/java/org/apache/dubbo/config/ReferenceConfig.java
index c66202f,04511e2..2f2e4cc
--- 
a/dubbo-config/dubbo-config-api/src/main/java/org/apache/dubbo/config/ReferenceConfig.java
+++ 
b/dubbo-config/dubbo-config-api/src/main/java/org/apache/dubbo/config/ReferenceConfig.java
@@@ -44,6 -45,6 +44,7 @@@ import org.apache.dubbo.rpc.model.Async
  import org.apache.dubbo.rpc.model.ConsumerModel;
  import org.apache.dubbo.rpc.model.ServiceDescriptor;
  import org.apache.dubbo.rpc.model.ServiceRepository;
++import org.apache.dubbo.rpc.model.ApplicationModel;
  import org.apache.dubbo.rpc.protocol.injvm.InjvmProtocol;
  import org.apache.dubbo.rpc.service.GenericService;
  import org.apache.dubbo.rpc.support.ProtocolUtils;
diff --cc 
dubbo-config/dubbo-config-api/src/main/java/org/apache/dubbo/config/ServiceConfig.java
index 7ce2e3f,4c07ecc..ec49581
--- 
a/dubbo-config/dubbo-config-api/src/main/java/org/apache/dubbo/config/ServiceConfig.java
+++ 
b/dubbo-config/dubbo-config-api/src/main/java/org/apache/dubbo/config/ServiceConfig.java
@@@ -208,10 -197,8 +208,8 @@@ public class ServiceConfig<T> extends S
              this.bootstrap.service(this);
  
              // load ServiceListeners from extension
 -            ExtensionLoader<ServiceListener> extensionLoader = 
ExtensionLoader.getExtensionLoader(ServiceListener.class);
 +            ExtensionLoader<ServiceListener> extensionLoader = 
this.getExtensionLoader(ServiceListener.class);
              
this.serviceListeners.addAll(extensionLoader.getSupportedExtensionInstances());
- 
-             this.checkAndUpdateSubConfigs();
          }
  
          initServiceMetadata(provider);
diff --cc 
dubbo-config/dubbo-config-api/src/main/java/org/apache/dubbo/config/bootstrap/DubboBootstrap.java
index 584544f,19d924d..ec51a07
--- 
a/dubbo-config/dubbo-config-api/src/main/java/org/apache/dubbo/config/bootstrap/DubboBootstrap.java
+++ 
b/dubbo-config/dubbo-config-api/src/main/java/org/apache/dubbo/config/bootstrap/DubboBootstrap.java
@@@ -113,7 -111,7 +113,8 @@@ import static org.apache.dubbo.common.u
  import static org.apache.dubbo.common.utils.StringUtils.isNotEmpty;
  import static 
org.apache.dubbo.metadata.MetadataConstants.DEFAULT_METADATA_PUBLISH_DELAY;
  import static 
org.apache.dubbo.metadata.MetadataConstants.METADATA_PUBLISH_DELAY_KEY;
 +import static 
org.apache.dubbo.registry.client.metadata.ServiceInstanceMetadataUtils.calInstanceRevision;
+ import static 
org.apache.dubbo.metadata.WritableMetadataService.getDefaultExtension;
  import static 
org.apache.dubbo.registry.client.metadata.ServiceInstanceMetadataUtils.setMetadataStorageType;
  import static 
org.apache.dubbo.registry.support.AbstractRegistryFactory.getServiceDiscoveries;
  import static org.apache.dubbo.remoting.Constants.CLIENT_KEY;
@@@ -160,47 -158,46 +161,50 @@@ public final class DubboBootstrap 
  
      private final ExecutorService executorService = newSingleThreadExecutor();
  
 -    private final ExecutorRepository executorRepository = 
getExtensionLoader(ExecutorRepository.class).getDefaultExtension();
 +    private ExecutorRepository executorRepository;
 +
 +    private final ApplicationModel applicationModel;
  
-     private final ConfigManager configManager;
+     protected ScheduledFuture<?> asyncMetadataFuture;
  
-     private final Environment environment;
+     protected final ConfigManager configManager;
  
-     private ReferenceConfigCache cache;
+     protected final Environment environment;
  
-     private AtomicBoolean initialized = new AtomicBoolean(false);
+     protected ReferenceConfigCache cache;
  
-     private AtomicBoolean started = new AtomicBoolean(false);
+     protected AtomicBoolean initialized = new AtomicBoolean(false);
  
-     private AtomicBoolean startup = new AtomicBoolean(true);
+     protected AtomicBoolean started = new AtomicBoolean(false);
  
-     private AtomicBoolean destroyed = new AtomicBoolean(false);
+     protected AtomicBoolean startup = new AtomicBoolean(true);
  
-     private AtomicBoolean shutdown = new AtomicBoolean(false);
+     protected AtomicBoolean destroyed = new AtomicBoolean(false);
  
-     private volatile boolean isCurrentlyInStart = false;
+     protected AtomicBoolean shutdown = new AtomicBoolean(false);
  
-     private volatile ServiceInstance serviceInstance;
+     protected volatile boolean isCurrentlyInStart = false;
  
-     private volatile MetadataService metadataService;
+     protected volatile ServiceInstance serviceInstance;
  
-     private volatile MetadataServiceExporter metadataServiceExporter;
+     protected volatile MetadataService metadataService;
  
-     private List<ServiceConfigBase<?>> exportedServices = new ArrayList<>();
+     protected volatile MetadataServiceExporter metadataServiceExporter;
  
-     private final List<CompletableFuture<?>> asyncExportingFutures = new 
ArrayList<>();
+     protected List<ServiceConfigBase<?>> exportedServices = new ArrayList<>();
  
-     private final List<CompletableFuture<?>> asyncReferringFutures = new 
ArrayList<>();
+     protected final List<CompletableFuture<?>> asyncExportingFutures = new 
ArrayList<>();
  
-     private boolean asyncExportFinish = true;
+     protected final List<CompletableFuture<?>> asyncReferringFutures = new 
ArrayList<>();
  
-     private boolean asyncReferFinish = true;
 -    protected volatile boolean asyncExportFinish = true;
++    protected boolean asyncExportFinish = true;
+ 
+     protected volatile boolean asyncReferFinish = true;
+ 
+     protected static boolean ignoreConfigState;
  
-     private static boolean ignoreConfigState;
 +    private Module currentModule;
 +
      /**
       * See {@link ApplicationModel} and {@link ExtensionLoader} for why 
DubboBootstrap is designed to be singleton.
       */
@@@ -1495,29 -1451,38 +1512,34 @@@
      }
  
      private void referServices() {
 -        if (cache == null) {
 -            cache = ReferenceConfigCache.getCache();
 -        }
 -
          configManager.getReferences().forEach(rc -> {
-             // TODO, compatible with  ReferenceConfig.refer()
-             ReferenceConfig<?> referenceConfig = (ReferenceConfig<?>) rc;
-             referenceConfig.setBootstrap(this);
-             if (!referenceConfig.isRefreshed()) {
-                 referenceConfig.refresh();
-             }
- 
-             if (rc.shouldInit()) {
-                 if (rc.shouldReferAsync()) {
-                     ExecutorService executor = 
executorRepository.getServiceReferExecutor();
-                     CompletableFuture<Void> future = 
CompletableFuture.runAsync(() -> {
-                         try {
-                             cache.get(rc);
-                         } catch (Throwable t) {
-                             logger.error("refer async catch error : " + 
t.getMessage(), t);
-                         }
-                     }, executor);
+             try {
+                 // TODO, compatible with  ReferenceConfig.refer()
+                 ReferenceConfig<?> referenceConfig = (ReferenceConfig<?>) rc;
+                 referenceConfig.setBootstrap(this);
+                 if (!referenceConfig.isRefreshed()) {
+                     referenceConfig.refresh();
+                 }
  
-                     asyncReferringFutures.add(future);
-                 } else {
-                     cache.get(rc);
+                 if (rc.shouldInit()) {
+                     if (rc.shouldReferAsync()) {
+                         ExecutorService executor = 
executorRepository.getServiceReferExecutor();
+                         CompletableFuture<Void> future = 
CompletableFuture.runAsync(() -> {
+                             try {
+                                 cache.get(rc);
+                             } catch (Throwable t) {
+                                 logger.error("refer async catch error : " + 
t.getMessage(), t);
+                             }
+                         }, executor);
+ 
+                         asyncReferringFutures.add(future);
+                     } else {
+                         cache.get(rc);
+                     }
                  }
+             } catch (Throwable t) {
+                 logger.error("refer catch error", t);
+                 cache.destroy(rc);
              }
          });
      }
@@@ -1550,10 -1519,10 +1572,10 @@@
              registered = false;
              logger.error("Register instance error", e);
          }
 -        if(registered){
 +        if (registered) {
              // scheduled task for updating Metadata and ServiceInstance
-             executorRepository.nextScheduledExecutor().scheduleAtFixedRate(() 
-> {
+             asyncMetadataFuture = 
executorRepository.nextScheduledExecutor().scheduleAtFixedRate(() -> {
 -                InMemoryWritableMetadataService localMetadataService = 
(InMemoryWritableMetadataService) WritableMetadataService.getDefaultExtension();
 +                InMemoryWritableMetadataService localMetadataService = 
(InMemoryWritableMetadataService) 
WritableMetadataService.getDefaultExtension(applicationModel);
                  localMetadataService.blockUntilUpdated();
                  try {
                      
ServiceInstanceMetadataUtils.refreshMetadataAndInstance(serviceInstance);
@@@ -1566,34 -1535,6 +1588,35 @@@
          }
      }
  
 +    private void doRegisterServiceInstance(ServiceInstance serviceInstance) {
 +        // register instance only when at least one service is exported.
 +        if (serviceInstance.getPort() > 0) {
 +            publishMetadataToRemote(serviceInstance);
 +            logger.info("Start registering instance address to registry.");
 +            getServiceDiscoveries().forEach(serviceDiscovery ->
 +            {
 +                ServiceInstance serviceInstanceForRegistry = new 
DefaultServiceInstance((DefaultServiceInstance) serviceInstance);
 +                calInstanceRevision(serviceDiscovery, 
serviceInstanceForRegistry);
 +                if (logger.isDebugEnabled()) {
 +                    logger.info("Start registering instance address to 
registry" + serviceDiscovery.getUrl() + ", instance " + 
serviceInstanceForRegistry);
 +                }
 +                // register metadata
 +                serviceDiscovery.register(serviceInstanceForRegistry);
 +            });
 +        }
 +    }
 +
 +    private void publishMetadataToRemote(ServiceInstance serviceInstance) {
 +//        InMemoryWritableMetadataService localMetadataService = 
(InMemoryWritableMetadataService)WritableMetadataService.getDefaultExtension();
 +//        localMetadataService.blockUntilUpdated();
 +        if (logger.isInfoEnabled()) {
 +            logger.info("Start publishing metadata to remote center, this 
only makes sense for applications enabled remote metadata center.");
 +        }
 +        RemoteMetadataServiceImpl remoteMetadataService = 
applicationModel.getBeanFactory().getBean(RemoteMetadataServiceImpl.class);
 +        
remoteMetadataService.publishMetadata(serviceInstance.getServiceName());
 +    }
 +
++
      private void unregisterServiceInstance() {
          if (serviceInstance != null) {
              getServiceDiscoveries().forEach(serviceDiscovery -> {
diff --cc 
dubbo-config/dubbo-config-api/src/test/java/org/apache/dubbo/config/ReferenceConfigTest.java
index ece4e47,45841ad..84a9807
--- 
a/dubbo-config/dubbo-config-api/src/test/java/org/apache/dubbo/config/ReferenceConfigTest.java
+++ 
b/dubbo-config/dubbo-config-api/src/test/java/org/apache/dubbo/config/ReferenceConfigTest.java
@@@ -22,10 -30,21 +30,22 @@@ import org.apache.dubbo.config.annotati
  import org.apache.dubbo.config.annotation.Reference;
  import org.apache.dubbo.config.api.DemoService;
  import org.apache.dubbo.config.bootstrap.DubboBootstrap;
+ import org.apache.dubbo.config.context.ConfigManager;
  import org.apache.dubbo.config.provider.impl.DemoServiceImpl;
+ 
+ import org.apache.dubbo.metadata.report.MetadataReport;
+ import org.apache.dubbo.metadata.report.MetadataReportInstance;
+ import org.apache.dubbo.rpc.Exporter;
+ import org.apache.dubbo.rpc.ProxyFactory;
+ import org.apache.dubbo.rpc.listener.ListenerInvokerWrapper;
  import org.apache.dubbo.rpc.model.ApplicationModel;
 +
  import org.apache.curator.test.TestingServer;
+ import org.apache.dubbo.rpc.model.ConsumerModel;
+ import org.apache.dubbo.rpc.model.ServiceMetadata;
+ import org.apache.dubbo.rpc.model.ServiceRepository;
+ import org.apache.dubbo.rpc.protocol.injvm.InjvmInvoker;
+ import org.apache.dubbo.rpc.protocol.injvm.InjvmProtocol;
  import org.junit.jupiter.api.AfterEach;
  import org.junit.jupiter.api.Assertions;
  import org.junit.jupiter.api.BeforeEach;
diff --cc 
dubbo-config/dubbo-config-spring/src/test/java/org/apache/dubbo/config/spring/JavaConfigBeanTest.java
index b3ccfdd,43be931..2f216c0
--- 
a/dubbo-config/dubbo-config-spring/src/test/java/org/apache/dubbo/config/spring/JavaConfigBeanTest.java
+++ 
b/dubbo-config/dubbo-config-spring/src/test/java/org/apache/dubbo/config/spring/JavaConfigBeanTest.java
@@@ -28,12 -28,10 +28,12 @@@ import org.apache.dubbo.config.context.
  import org.apache.dubbo.config.spring.api.DemoService;
  import org.apache.dubbo.config.spring.context.annotation.EnableDubbo;
  import org.apache.dubbo.config.spring.impl.DemoServiceImpl;
- import 
org.apache.dubbo.config.spring.registrycenter.DefaultSingleRegistryCenter;
- import org.apache.dubbo.config.spring.registrycenter.SingleRegistryCenter;
+ import org.apache.dubbo.config.spring.registrycenter.RegistryCenter;
+ import 
org.apache.dubbo.config.spring.registrycenter.ZookeeperSingleRegistryCenter;
  import org.apache.dubbo.rpc.Constants;
  import org.apache.dubbo.rpc.model.ApplicationModel;
 +
 +import org.junit.jupiter.api.AfterAll;
  import org.junit.jupiter.api.AfterEach;
  import org.junit.jupiter.api.Assertions;
  import org.junit.jupiter.api.BeforeAll;
diff --cc 
dubbo-config/dubbo-config-spring/src/test/java/org/apache/dubbo/config/spring/context/annotation/EnableDubboConfigTest.java
index d934565,666e0f1..4c309df
--- 
a/dubbo-config/dubbo-config-spring/src/test/java/org/apache/dubbo/config/spring/context/annotation/EnableDubboConfigTest.java
+++ 
b/dubbo-config/dubbo-config-spring/src/test/java/org/apache/dubbo/config/spring/context/annotation/EnableDubboConfigTest.java
@@@ -23,11 -23,12 +23,12 @@@ import org.apache.dubbo.config.MonitorC
  import org.apache.dubbo.config.ProtocolConfig;
  import org.apache.dubbo.config.ProviderConfig;
  import org.apache.dubbo.config.RegistryConfig;
 -
  import org.apache.dubbo.config.bootstrap.DubboBootstrap;
  import org.apache.dubbo.config.context.ConfigManager;
- import org.apache.dubbo.config.spring.registrycenter.ZooKeeperServer;
+ import org.apache.dubbo.config.spring.registrycenter.RegistryCenter;
+ import 
org.apache.dubbo.config.spring.registrycenter.ZookeeperMultipleRegistryCenter;
  import org.apache.dubbo.rpc.model.ApplicationModel;
 +
  import org.junit.jupiter.api.AfterEach;
  import org.junit.jupiter.api.Assertions;
  import org.junit.jupiter.api.BeforeEach;
diff --cc 
dubbo-config/dubbo-config-spring/src/test/java/org/apache/dubbo/config/spring/issues/issue7003/Issue7003Test.java
index 72bb370,869770b..e5714d4
--- 
a/dubbo-config/dubbo-config-spring/src/test/java/org/apache/dubbo/config/spring/issues/issue7003/Issue7003Test.java
+++ 
b/dubbo-config/dubbo-config-spring/src/test/java/org/apache/dubbo/config/spring/issues/issue7003/Issue7003Test.java
@@@ -22,10 -22,9 +22,10 @@@ import org.apache.dubbo.config.bootstra
  import org.apache.dubbo.config.spring.ReferenceBean;
  import org.apache.dubbo.config.spring.api.HelloService;
  import org.apache.dubbo.config.spring.context.annotation.EnableDubbo;
- import 
org.apache.dubbo.config.spring.registrycenter.DefaultSingleRegistryCenter;
- import org.apache.dubbo.config.spring.registrycenter.SingleRegistryCenter;
+ import 
org.apache.dubbo.config.spring.registrycenter.ZookeeperSingleRegistryCenter;
+ import org.apache.dubbo.config.spring.registrycenter.RegistryCenter;
  import org.apache.dubbo.rpc.model.ApplicationModel;
 +
  import org.junit.jupiter.api.AfterAll;
  import org.junit.jupiter.api.Assertions;
  import org.junit.jupiter.api.BeforeAll;
diff --cc 
dubbo-config/dubbo-config-spring/src/test/java/org/apache/dubbo/config/spring/reference/javaconfig/JavaConfigReferenceBeanTest.java
index 7fdb76d,f93bf06..73ca355
--- 
a/dubbo-config/dubbo-config-spring/src/test/java/org/apache/dubbo/config/spring/reference/javaconfig/JavaConfigReferenceBeanTest.java
+++ 
b/dubbo-config/dubbo-config-spring/src/test/java/org/apache/dubbo/config/spring/reference/javaconfig/JavaConfigReferenceBeanTest.java
@@@ -24,19 -24,17 +24,21 @@@ import org.apache.dubbo.config.spring.R
  import org.apache.dubbo.config.spring.api.DemoService;
  import org.apache.dubbo.config.spring.api.HelloService;
  import org.apache.dubbo.config.spring.context.annotation.EnableDubbo;
 -import org.apache.dubbo.config.spring.extension.SpringExtensionFactory;
 +import org.apache.dubbo.config.spring.extension.SpringExtensionInjector;
  import org.apache.dubbo.config.spring.impl.HelloServiceImpl;
  import org.apache.dubbo.config.spring.reference.ReferenceBeanBuilder;
 +import org.apache.dubbo.config.spring.registrycenter.ZooKeeperServer;
+ import org.apache.dubbo.config.spring.registrycenter.RegistryCenter;
+ import 
org.apache.dubbo.config.spring.registrycenter.ZookeeperMultipleRegistryCenter;
  import org.apache.dubbo.rpc.service.GenericException;
  import org.apache.dubbo.rpc.service.GenericService;
 +
 +import org.junit.jupiter.api.AfterAll;
 +import org.junit.jupiter.api.AfterEach;
  import org.junit.jupiter.api.Assertions;
 -import org.junit.jupiter.api.Test;
 +import org.junit.jupiter.api.BeforeAll;
  import org.junit.jupiter.api.BeforeEach;
 -import org.junit.jupiter.api.AfterEach;
 +import org.junit.jupiter.api.Test;
  import 
org.springframework.context.annotation.AnnotationConfigApplicationContext;
  import org.springframework.context.annotation.Bean;
  import org.springframework.context.annotation.Configuration;
@@@ -62,14 -52,15 +56,17 @@@ public class JavaConfigReferenceBeanTes
  
      @BeforeEach
      public void setUp() {
+         multipleRegistryCenter = new ZookeeperMultipleRegistryCenter();
+         multipleRegistryCenter.startup();
          DubboBootstrap.reset();
 +        SpringExtensionInjector.clearContexts();
      }
  
      @AfterEach
      public void tearDown() {
          DubboBootstrap.reset();
+         multipleRegistryCenter.shutdown();
 +        SpringExtensionInjector.clearContexts();
      }
  
      @Test
diff --cc 
dubbo-metadata/dubbo-metadata-api/src/main/java/org/apache/dubbo/metadata/report/MetadataReportInstance.java
index c63b09a1,08040ee..9484ebd
--- 
a/dubbo-metadata/dubbo-metadata-api/src/main/java/org/apache/dubbo/metadata/report/MetadataReportInstance.java
+++ 
b/dubbo-metadata/dubbo-metadata-api/src/main/java/org/apache/dubbo/metadata/report/MetadataReportInstance.java
@@@ -50,16 -49,18 +50,19 @@@ public class MetadataReportInstance 
          if (METADATA_REPORT_KEY.equals(url.getProtocol())) {
              String protocol = url.getParameter(METADATA_REPORT_KEY, 
DEFAULT_DIRECTORY);
              url = URLBuilder.from(url)
 -                .setProtocol(protocol)
 -                .removeParameter(METADATA_REPORT_KEY)
 -                .build();
 +                    .setProtocol(protocol)
 +                    .setScopeModel(config.getScopeModel())
 +                    .removeParameter(METADATA_REPORT_KEY)
 +                    .build();
          }
 -        url = url.addParameterIfAbsent(APPLICATION_KEY, 
ApplicationModel.getApplicationConfig().getName());
 +        url = url.addParameterIfAbsent(APPLICATION_KEY, 
applicationModel.getCurrentConfig().getName());
          String relatedRegistryId = config.getRegistry() == null ? DEFAULT_KEY 
: config.getRegistry();
 -//        RegistryConfig registryConfig = 
ApplicationModel.getConfigManager().getRegistry(relatedRegistryId)
 +//        RegistryConfig registryConfig = 
applicationModel.getConfigManager().getRegistry(relatedRegistryId)
  //                .orElseThrow(() -> new IllegalStateException("Registry id " 
+ relatedRegistryId + " does not exist."));
-         metadataReports.put(relatedRegistryId, 
metadataReportFactory.getMetadataReport(url));
+         MetadataReport metadataReport = 
metadataReportFactory.getMetadataReport(url);
+         if (metadataReport != null) {
+             metadataReports.put(relatedRegistryId, metadataReport);
+         }
          init.set(true);
      }
  
@@@ -80,9 -81,9 +83,9 @@@
      }
  
  
 -    private static void checkInit() {
 +    private void checkInit() {
          if (!init.get()) {
-             throw new IllegalStateException("the metadata report was not 
inited.");
+             throw new IllegalStateException("the metadata report was not 
initialized.");
          }
      }
  
diff --cc 
dubbo-registry/dubbo-registry-api/src/main/java/org/apache/dubbo/registry/client/DefaultServiceInstance.java
index e5fa427,e6b5923..bfdc191
--- 
a/dubbo-registry/dubbo-registry-api/src/main/java/org/apache/dubbo/registry/client/DefaultServiceInstance.java
+++ 
b/dubbo-registry/dubbo-registry-api/src/main/java/org/apache/dubbo/registry/client/DefaultServiceInstance.java
@@@ -29,9 -27,8 +29,10 @@@ import java.util.Objects
  import java.util.SortedMap;
  import java.util.TreeMap;
  
 +import static org.apache.dubbo.common.constants.CommonConstants.REVISION_KEY;
 +import static org.apache.dubbo.common.constants.CommonConstants.SCOPE_MODEL;
  import static 
org.apache.dubbo.registry.client.metadata.ServiceInstanceMetadataUtils.ENDPOINTS;
+ import static 
org.apache.dubbo.registry.client.metadata.ServiceInstanceMetadataUtils.EXPORTED_SERVICES_REVISION_PROPERTY_NAME;
  
  /**
   * The default implementation of {@link ServiceInstance}.
diff --cc 
dubbo-registry/dubbo-registry-api/src/main/java/org/apache/dubbo/registry/client/ServiceDiscoveryRegistry.java
index 44357c7,8aca204..1eaa2dd
--- 
a/dubbo-registry/dubbo-registry-api/src/main/java/org/apache/dubbo/registry/client/ServiceDiscoveryRegistry.java
+++ 
b/dubbo-registry/dubbo-registry-api/src/main/java/org/apache/dubbo/registry/client/ServiceDiscoveryRegistry.java
@@@ -102,9 -87,16 +87,16 @@@ public class ServiceDiscoveryRegistry i
      public ServiceDiscoveryRegistry(URL registryURL) {
          this.registryURL = registryURL;
          this.serviceDiscovery = createServiceDiscovery(registryURL);
 -        this.writableMetadataService = 
WritableMetadataService.getDefaultExtension();
 +        this.writableMetadataService = 
WritableMetadataService.getDefaultExtension(registryURL.getScopeModel());
      }
  
+     // Currently for test purpose
+     protected ServiceDiscoveryRegistry(URL registryURL, ServiceDiscovery 
serviceDiscovery, WritableMetadataService writableMetadataService) {
+         this.registryURL = registryURL;
+         this.serviceDiscovery = serviceDiscovery;
+         this.writableMetadataService = writableMetadataService;
+     }
+ 
      public ServiceDiscovery getServiceDiscovery() {
          return serviceDiscovery;
      }
diff --cc 
dubbo-registry/dubbo-registry-api/src/main/java/org/apache/dubbo/registry/client/ServiceDiscoveryRegistryDirectory.java
index ba4f958,bf982dc..108292a
--- 
a/dubbo-registry/dubbo-registry-api/src/main/java/org/apache/dubbo/registry/client/ServiceDiscoveryRegistryDirectory.java
+++ 
b/dubbo-registry/dubbo-registry-api/src/main/java/org/apache/dubbo/registry/client/ServiceDiscoveryRegistryDirectory.java
@@@ -60,12 -61,24 +62,29 @@@ public class ServiceDiscoveryRegistryDi
      private volatile boolean enableConfigurationListen = true;
      private volatile List<URL> originalUrls = null; // initial for null
      private volatile Map<String, String> overrideQueryMap;
+     private volatile Map<String, String> consumerFirstQueryMap;
 +    private final ApplicationModel applicationModel;
  
      public ServiceDiscoveryRegistryDirectory(Class<T> serviceType, URL url) {
          super(serviceType, url);
 +        applicationModel = getApplicationModel(url.getScopeModel());
 +        consumerConfigurationListener = new 
ConsumerConfigurationListener(applicationModel);
++
+         Set<ProviderFirstParams> providerFirstParams = 
ExtensionLoader.getExtensionLoader(ProviderFirstParams.class).getSupportedExtensionInstances();
+         if (CollectionUtils.isEmpty(providerFirstParams)) {
+             consumerFirstQueryMap = queryMap;
+         } else {
+             consumerFirstQueryMap = new HashMap<>(queryMap);
+             for (ProviderFirstParams paramsFilter : providerFirstParams) {
+                 if (paramsFilter.params() == null) {
+                     break;
+                 }
+                 for (String keyToRemove : paramsFilter.params()) {
+                     consumerFirstQueryMap.remove(keyToRemove);
+                 }
+             }
+         }
++
      }
  
      @Override
diff --cc 
dubbo-registry/dubbo-registry-api/src/main/java/org/apache/dubbo/registry/client/metadata/MetadataServiceNameMapping.java
index 4a63368,018d665..c963b72
--- 
a/dubbo-registry/dubbo-registry-api/src/main/java/org/apache/dubbo/registry/client/metadata/MetadataServiceNameMapping.java
+++ 
b/dubbo-registry/dubbo-registry-api/src/main/java/org/apache/dubbo/registry/client/metadata/MetadataServiceNameMapping.java
@@@ -29,10 -29,8 +29,9 @@@ import org.apache.dubbo.metadata.report
  import org.apache.dubbo.metadata.report.MetadataReportInstance;
  import org.apache.dubbo.registry.client.RegistryClusterIdentifier;
  import org.apache.dubbo.rpc.model.ApplicationModel;
 +import org.apache.dubbo.rpc.model.ScopeModelAware;
  
  import java.util.Collections;
- import java.util.LinkedHashSet;
  import java.util.List;
  import java.util.Set;
  
@@@ -46,77 -45,63 +45,70 @@@ public class MetadataServiceNameMappin
      private static final List<String> IGNORED_SERVICE_INTERFACES = 
Collections.singletonList(MetadataService.class.getName());
  
      private static final int CAS_RETRY_TIMES = 6;
 +    private MetadataReportInstance metadataReportInstance;
  
      @Override
-     public void map(URL url) {
-         execute(() -> {
+     public boolean map(URL url) {
 -        if 
(CollectionUtils.isEmpty(ApplicationModel.getConfigManager().getMetadataConfigs()))
 {
 -            return false;
 -        }
 -        String serviceInterface = url.getServiceInterface();
 -        if (IGNORED_SERVICE_INTERFACES.contains(serviceInterface)) {
 -            return false;
 -        }
 -        String registryCluster = getRegistryCluster(url);
 -        MetadataReport metadataReport = 
MetadataReportInstance.getMetadataReport(registryCluster);
 -
 -        if (metadataReport.registerServiceAppMapping(serviceInterface, 
getName(), url)) {
 -            // MetadataReport support directly register service-app mapping
 -            return true;
 -        }
 +            if 
(CollectionUtils.isEmpty(applicationModel.getApplicationConfigManager().getMetadataConfigs()))
 {
-                 return;
++                return false;
 +            }
 +            String serviceInterface = url.getServiceInterface();
 +            if (IGNORED_SERVICE_INTERFACES.contains(serviceInterface)) {
-                 return;
++                return false;
 +            }
 +            String registryCluster = getRegistryCluster(url);
 +            MetadataReport metadataReport = 
metadataReportInstance.getMetadataReport(registryCluster);
  
 -        int currentRetryTimes = 1;
 -        boolean succeeded = false;
 -        String newConfigContent = getName();
 -        do {
 -            ConfigItem configItem = 
metadataReport.getConfigItem(serviceInterface, DEFAULT_MAPPING_GROUP);
 -            String oldConfigContent = configItem.getContent();
 -            if (StringUtils.isNotEmpty(oldConfigContent)) {
 -                boolean contains = StringUtils.isContains(oldConfigContent, 
getName());
 -                if (contains) {
 -                    break;
 -                }
 -                newConfigContent = oldConfigContent + COMMA_SEPARATOR + 
getName();
 +            String appName = applicationModel.getApplicationName();
 +            if (metadataReport.registerServiceAppMapping(serviceInterface, 
appName, url)) {
 +                // MetadataReport support directly register service-app 
mapping
-                 return;
++                return true;
              }
 -            succeeded = 
metadataReport.registerServiceAppMapping(serviceInterface, 
DEFAULT_MAPPING_GROUP, newConfigContent, configItem.getTicket());
 -        } while (!succeeded && currentRetryTimes++ <= CAS_RETRY_TIMES);
  
 -        if (!succeeded) {
 +            int currentRetryTimes = 1;
-             boolean success;
++            boolean succeeded = false;
 +            String newConfigContent = appName;
 +            do {
 +                ConfigItem configItem = 
metadataReport.getConfigItem(serviceInterface, DEFAULT_MAPPING_GROUP);
 +                String oldConfigContent = configItem.getContent();
 +                if (StringUtils.isNotEmpty(oldConfigContent)) {
 +                    boolean contains = 
StringUtils.isContains(oldConfigContent, appName);
 +                    if (contains) {
 +                        break;
 +                    }
 +                    newConfigContent = oldConfigContent + COMMA_SEPARATOR + 
appName;
 +                }
-                 success = 
metadataReport.registerServiceAppMapping(serviceInterface, 
DEFAULT_MAPPING_GROUP, newConfigContent, configItem.getTicket());
-             } while (!success && currentRetryTimes++ <= CAS_RETRY_TIMES);
-         });
++                succeeded = 
metadataReport.registerServiceAppMapping(serviceInterface, 
DEFAULT_MAPPING_GROUP, newConfigContent, configItem.getTicket());
++            } while (!succeeded && currentRetryTimes++ <= CAS_RETRY_TIMES);
++            if (!succeeded) {
+             throw new RuntimeException();
+         }
+ 
+         return true;
      }
  
      @Override
      public Set<String> get(URL url) {
-         Set<String> serviceNames = new LinkedHashSet<>();
-         execute(() -> {
-             String serviceInterface = url.getServiceInterface();
-             String registryCluster = getRegistryCluster(url);
-             MetadataReport metadataReport = 
metadataReportInstance.getMetadataReport(registryCluster);
-             Set<String> apps = 
metadataReport.getServiceAppMapping(serviceInterface, url);
-             serviceNames.addAll(apps);
-         });
-         return serviceNames;
+         String serviceInterface = url.getServiceInterface();
+         String registryCluster = getRegistryCluster(url);
 -        MetadataReport metadataReport = 
MetadataReportInstance.getMetadataReport(registryCluster);
++        MetadataReport metadataReport = 
metadataReportInstance.getMetadataReport(registryCluster);
+         return metadataReport.getServiceAppMapping(serviceInterface, url);
      }
  
      @Override
      public Set<String> getAndListen(URL url, MappingListener mappingListener) 
{
-         Set<String> serviceNames = new LinkedHashSet<>();
-         execute(() -> {
-             String serviceInterface = url.getServiceInterface();
-             String registryCluster = getRegistryCluster(url);
-             MetadataReport metadataReport = 
metadataReportInstance.getMetadataReport(registryCluster);
-             Set<String> apps = 
metadataReport.getServiceAppMapping(serviceInterface, mappingListener, url);
-             serviceNames.addAll(apps);
-         });
-         return serviceNames;
+         String serviceInterface = url.getServiceInterface();
+         String registryCluster = getRegistryCluster(url);
 -        MetadataReport metadataReport = 
MetadataReportInstance.getMetadataReport(registryCluster);
++        MetadataReport metadataReport = 
metadataReportInstance.getMetadataReport(registryCluster);
+         return metadataReport.getServiceAppMapping(serviceInterface, 
mappingListener, url);
      }
  
 +    @Override
 +    public void setApplicationModel(ApplicationModel applicationModel) {
 +        super.setApplicationModel(applicationModel);
 +        metadataReportInstance = 
applicationModel.getBeanFactory().getBean(MetadataReportInstance.class);
 +    }
 +
      protected String getRegistryCluster(URL url) {
          String registryCluster = 
RegistryClusterIdentifier.getExtension(url).providerKey(url);
          if (registryCluster == null) {
diff --cc 
dubbo-registry/dubbo-registry-api/src/main/java/org/apache/dubbo/registry/client/metadata/ServiceInstanceMetadataCustomizer.java
index cc0f612,b3d6efb..ea0723c
--- 
a/dubbo-registry/dubbo-registry-api/src/main/java/org/apache/dubbo/registry/client/metadata/ServiceInstanceMetadataCustomizer.java
+++ 
b/dubbo-registry/dubbo-registry-api/src/main/java/org/apache/dubbo/registry/client/metadata/ServiceInstanceMetadataCustomizer.java
@@@ -40,14 -58,12 +58,14 @@@ public class ServiceInstanceMetadataCus
  
      @Override
      public void customize(ServiceInstance serviceInstance) {
 -        ExtensionLoader<MetadataParamsFilter> loader = 
ExtensionLoader.getExtensionLoader(MetadataParamsFilter.class);
 +        ApplicationModel applicationModel = 
serviceInstance.getApplicationModel();
 +        ExtensionLoader<MetadataParamsFilter> loader = 
applicationModel.getExtensionLoader(MetadataParamsFilter.class);
 +        Set<MetadataParamsFilter> paramsFilters = 
loader.getSupportedExtensionInstances();
  
          InMemoryWritableMetadataService localMetadataService
 -                = (InMemoryWritableMetadataService) 
WritableMetadataService.getDefaultExtension();
 +                = (InMemoryWritableMetadataService) 
WritableMetadataService.getDefaultExtension(applicationModel);
          // pick the first interface metadata available.
-         // FIXME, check the same key in different urls has the same value
+         // FIXME, check the same key in different urls have the same value
          Map<String, MetadataInfo> metadataInfos = 
localMetadataService.getMetadataInfos();
          if (CollectionUtils.isEmptyMap(metadataInfos)) {
              return;
@@@ -57,19 -73,19 +75,19 @@@
              return;
          }
          MetadataInfo.ServiceInfo serviceInfo = 
metadataInfo.getServices().values().iterator().next();
-         Map<String, String> allParams = new 
HashMap<>(serviceInfo.getUrl().getParameters());
+         URL url = serviceInfo.getUrl();
+         List<MetadataParamsFilter> paramsFilters = 
loader.getActivateExtension(url, "params-filter");
+         Map<String, String> allParams = new HashMap<>(url.getParameters());
  
          // load instance params users want to load.
-         // TODO, duplicate logic with that in ApplicationConfig
+         // TODO, duplicate snippet in ApplicationConfig
+         Map<String, String> extraParameters = Collections.emptyMap();
 -        Set<InfraAdapter> adapters = 
ExtensionLoader.getExtensionLoader(InfraAdapter.class).getSupportedExtensionInstances();
 +        Set<InfraAdapter> adapters = 
applicationModel.getExtensionLoader(InfraAdapter.class).getSupportedExtensionInstances();
          if (CollectionUtils.isNotEmpty(adapters)) {
              Map<String, String> inputParameters = new HashMap<>();
 -            inputParameters.put(APPLICATION_KEY, ApplicationModel.getName());
 +            inputParameters.put(APPLICATION_KEY, 
applicationModel.getApplicationName());
              for (InfraAdapter adapter : adapters) {
-                 Map<String, String> extraParameters = 
adapter.getExtraAttributes(inputParameters);
-                 if (CollectionUtils.isNotEmptyMap(extraParameters)) {
-                     extraParameters.forEach(allParams::putIfAbsent);
-                 }
+                 extraParameters = adapter.getExtraAttributes(inputParameters);
              }
          }
  
diff --cc 
dubbo-registry/dubbo-registry-api/src/main/java/org/apache/dubbo/registry/client/metadata/ServiceInstanceMetadataUtils.java
index 8cafaac,5c0e8ea..ddf4bd2
--- 
a/dubbo-registry/dubbo-registry-api/src/main/java/org/apache/dubbo/registry/client/metadata/ServiceInstanceMetadataUtils.java
+++ 
b/dubbo-registry/dubbo-registry-api/src/main/java/org/apache/dubbo/registry/client/metadata/ServiceInstanceMetadataUtils.java
@@@ -285,6 -292,13 +292,13 @@@ public class ServiceInstanceMetadataUti
          });
      }
  
+     private static void reportMetadataToRemote(ServiceInstance 
serviceInstance) {
+         if 
(REMOTE_METADATA_STORAGE_TYPE.equalsIgnoreCase(getMetadataStorageType(serviceInstance)))
 {
 -            RemoteMetadataServiceImpl remoteMetadataService = 
MetadataUtils.getRemoteMetadataService();
 -            
remoteMetadataService.publishMetadata(serviceInstance.getServiceName());
++            RemoteMetadataServiceImpl remoteMetadataService = 
MetadataUtils.getRemoteMetadataService(serviceInstance.getApplicationModel());
++            
remoteMetadataService.publishMetadata(serviceInstance.getApplicationModel().getApplicationName());
+         }
+     }
+ 
      /**
       * Set the default parameters via the specified {@link URL providerURL}
       *
diff --cc 
dubbo-registry/dubbo-registry-api/src/main/java/org/apache/dubbo/registry/client/metadata/store/InMemoryWritableMetadataService.java
index 4026103,ddbb163..4cd2618
--- 
a/dubbo-registry/dubbo-registry-api/src/main/java/org/apache/dubbo/registry/client/metadata/store/InMemoryWritableMetadataService.java
+++ 
b/dubbo-registry/dubbo-registry-api/src/main/java/org/apache/dubbo/registry/client/metadata/store/InMemoryWritableMetadataService.java
@@@ -75,9 -74,9 +75,9 @@@ import static org.apache.dubbo.rpc.Cons
   * @see WritableMetadataService
   * @since 2.7.5
   */
 -public class InMemoryWritableMetadataService implements 
WritableMetadataService {
 +public class InMemoryWritableMetadataService implements 
WritableMetadataService, ScopeModelAware {
  
-     final Logger logger = LoggerFactory.getLogger(getClass());
+     Logger logger = LoggerFactory.getLogger(getClass());
  
      private final Lock lock = new ReentrantLock();
  
diff --cc 
dubbo-registry/dubbo-registry-api/src/main/java/org/apache/dubbo/registry/client/migration/MigrationRuleListener.java
index 0299761,7c76b38..2a5dbf2
--- 
a/dubbo-registry/dubbo-registry-api/src/main/java/org/apache/dubbo/registry/client/migration/MigrationRuleListener.java
+++ 
b/dubbo-registry/dubbo-registry-api/src/main/java/org/apache/dubbo/registry/client/migration/MigrationRuleListener.java
@@@ -47,15 -48,25 +49,25 @@@ import java.util.concurrent.atomic.Atom
  
  import static org.apache.dubbo.common.constants.RegistryConstants.INIT;
  
+ /**
+  * Listens to {@MigrationRule} from Config Center.
+  *
+  * - Migration rule is of consumer application scope.
+  * - Listener is shared among all invokers (interfaces), it keeps the 
relation between interface and handler.
+  *
+  * There're two execution points:
+  * - Refer, invoker behaviour is determined with default rule.
+  * - Rule change, invoker behaviour is changed according to the newly 
received rule.
+  */
  @Activate
 -public class MigrationRuleListener implements RegistryProtocolListener, 
ConfigurationListener {
 +public class MigrationRuleListener implements RegistryProtocolListener, 
ConfigurationListener, ScopeModelAware {
      private static final Logger logger = 
LoggerFactory.getLogger(MigrationRuleListener.class);
      private static final String DUBBO_SERVICEDISCOVERY_MIGRATION = 
"DUBBO_SERVICEDISCOVERY_MIGRATION";
      private static final String MIGRATION_DELAY_KEY = 
"dubbo.application.migration.delay";
 -    private final String RULE_KEY = ApplicationModel.getName() + ".migration";
 +    private String ruleKey;
  
-     private final Map<MigrationInvoker, MigrationRuleHandler> handlers = new 
ConcurrentHashMap<>();
-     private final LinkedBlockingQueue<String> ruleQueue = new 
LinkedBlockingQueue<>();
+     protected final Map<MigrationInvoker, MigrationRuleHandler> handlers = 
new ConcurrentHashMap<>();
+     protected final LinkedBlockingQueue<String> ruleQueue = new 
LinkedBlockingQueue<>();
  
      private final AtomicBoolean executorSubmit = new AtomicBoolean(false);
      private final ExecutorService ruleManageExecutor = 
Executors.newFixedThreadPool(1, new 
NamedThreadFactory("Dubbo-Migration-Listener"));
@@@ -95,9 -98,9 +110,9 @@@
              setRawRule(INIT);
          }
  
 -        String localRawRule = 
ApplicationModel.getEnvironment().getLocalMigrationRule();
 +        String localRawRule = 
applicationModel.getApplicationEnvironment().getLocalMigrationRule();
          if (!StringUtils.isEmpty(localRawRule)) {
-             Executors.newSingleThreadScheduledExecutor(new 
NamedThreadFactory("DubboMigrationRuleDelayWorker", true))
+             localRuleMigrationFuture = 
Executors.newSingleThreadScheduledExecutor(new 
NamedThreadFactory("DubboMigrationRuleDelayWorker", true))
                  .schedule(() -> {
                      if (this.rawRule.equals(INIT)) {
                          this.process(new ConfigChangedEvent(null, null, 
localRawRule));
@@@ -226,8 -229,14 +241,14 @@@
      @Override
      public void onDestroy() {
          if (configuration != null) {
 -            configuration.removeListener(RULE_KEY, this);
 +            configuration.removeListener(ruleKey, this);
          }
+         if (ruleMigrationFuture != null) {
+             ruleMigrationFuture.cancel(true);
+         }
+         if (localRuleMigrationFuture != null) {
+             localRuleMigrationFuture.cancel(true);
+         }
      }
  
      public Map<MigrationInvoker, MigrationRuleHandler> getHandlers() {
diff --cc 
dubbo-registry/dubbo-registry-api/src/main/java/org/apache/dubbo/registry/integration/RegistryProtocol.java
index 9651696,a6997b0..25543bc
--- 
a/dubbo-registry/dubbo-registry-api/src/main/java/org/apache/dubbo/registry/integration/RegistryProtocol.java
+++ 
b/dubbo-registry/dubbo-registry-api/src/main/java/org/apache/dubbo/registry/integration/RegistryProtocol.java
@@@ -854,14 -817,14 +867,16 @@@ public class RegistryProtocol implement
                  logger.warn(t.getMessage(), t);
              }
              try {
-                 Map<URL, NotifyListener> overrideListeners = 
getProviderConfigurationListener(subscribeUrl).getOverrideListeners();
-                 NotifyListener listener = 
overrideListeners.remove(registerUrl);
-                 registry.unsubscribe(subscribeUrl, listener);
-                 ApplicationModel applicationModel = 
getApplicationModel(registerUrl.getScopeModel());
-                 if 
(applicationModel.getApplicationEnvironment().getConfiguration().convert(Boolean.class,
 ENABLE_CONFIGURATION_LISTEN, true)) {
-                     
applicationModel.getExtensionLoader(GovernanceRuleRepository.class).getDefaultExtension()
-                         .removeListener(subscribeUrl.getServiceKey() + 
CONFIGURATORS_SUFFIX,
-                             
serviceConfigurationListeners.remove(subscribeUrl.getServiceKey()));
+                 if (subscribeUrl != null) {
 -                    NotifyListener listener = 
RegistryProtocol.this.overrideListeners.remove(subscribeUrl);
++                    Map<URL, NotifyListener> overrideListeners = 
getProviderConfigurationListener(subscribeUrl).getOverrideListeners();
++                    NotifyListener listener = 
overrideListeners.remove(registerUrl);
+                     registry.unsubscribe(subscribeUrl, listener);
 -                    if 
(ApplicationModel.getEnvironment().getConfiguration().convert(Boolean.class, 
org.apache.dubbo.registry.Constants.ENABLE_CONFIGURATION_LISTEN, true)) {
 -                        
ExtensionLoader.getExtensionLoader(GovernanceRuleRepository.class).getDefaultExtension()
++                    ApplicationModel applicationModel = 
getApplicationModel(registerUrl.getScopeModel());
++                    if 
(applicationModel.getApplicationEnvironment().getConfiguration().convert(Boolean.class,
 ENABLE_CONFIGURATION_LISTEN, true)) {
++                        
applicationModel.getExtensionLoader(GovernanceRuleRepository.class).getDefaultExtension()
+                             .removeListener(subscribeUrl.getServiceKey() + 
CONFIGURATORS_SUFFIX,
 -                                
serviceConfigurationListeners.get(subscribeUrl.getServiceKey()));
++                                
serviceConfigurationListeners.remove(subscribeUrl.getServiceKey()));
+                     }
                  }
              } catch (Throwable t) {
                  logger.warn(t.getMessage(), t);
diff --cc 
dubbo-registry/dubbo-registry-api/src/main/java/org/apache/dubbo/registry/support/CacheableFailbackRegistry.java
index e8ce4f4,bd8c062..e13d29d
--- 
a/dubbo-registry/dubbo-registry-api/src/main/java/org/apache/dubbo/registry/support/CacheableFailbackRegistry.java
+++ 
b/dubbo-registry/dubbo-registry-api/src/main/java/org/apache/dubbo/registry/support/CacheableFailbackRegistry.java
@@@ -31,8 -32,7 +32,6 @@@ import org.apache.dubbo.common.utils.Co
  import org.apache.dubbo.common.utils.StringUtils;
  import org.apache.dubbo.common.utils.UrlUtils;
  import org.apache.dubbo.registry.NotifyListener;
- import org.apache.dubbo.rpc.model.ScopeModel;
- import org.apache.dubbo.rpc.model.ScopeModelUtil;
 -import org.apache.dubbo.registry.ProviderFirstParams;
  
  import java.util.ArrayList;
  import java.util.Collection;
diff --cc 
dubbo-registry/dubbo-registry-api/src/test/java/org/apache/dubbo/registry/client/DefaultServiceInstanceTest.java
index 2b65cb9,7369c27..13fde8e
--- 
a/dubbo-registry/dubbo-registry-api/src/test/java/org/apache/dubbo/registry/client/DefaultServiceInstanceTest.java
+++ 
b/dubbo-registry/dubbo-registry-api/src/test/java/org/apache/dubbo/registry/client/DefaultServiceInstanceTest.java
@@@ -38,9 -40,17 +42,16 @@@ public class DefaultServiceInstanceTes
      public DefaultServiceInstance instance;
  
      public static DefaultServiceInstance createInstance() {
-         DefaultServiceInstance instance = new DefaultServiceInstance("A", 
"127.0.0.1", 8080, ApplicationModel.defaultModel());
-         instance.getMetadata().put("dubbo.metadata-service.urls", "[ 
\"dubbo://192.168.0.102:20881/com.alibaba.cloud.dubbo.service.DubboMetadataService?anyhost=true&application=spring-cloud-alibaba-dubbo-provider&bind.ip=192.168.0.102&bind.port=20881&deprecated=false&dubbo=2.0.2&dynamic=true&generic=false&group=spring-cloud-alibaba-dubbo-provider&interface=com.alibaba.cloud.dubbo.service.DubboMetadataService&methods=getAllServiceKeys,getServiceRestMetadata,getExportedURLs,getAllExported
 [...]
-         instance.getMetadata().put("dubbo.metadata-service.url-params", 
"{\"dubbo\":{\"application\":\"dubbo-provider-demo\",\"deprecated\":\"false\",\"group\":\"dubbo-provider-demo\",\"version\":\"1.0.0\",\"timestamp\":\"1564845042651\",\"dubbo\":\"2.0.2\",\"provider.host\":\"192.168.0.102\",\"provider.port\":\"20880\"}}");
 -        DefaultServiceInstance instance = new DefaultServiceInstance("A", 
"127.0.0.1", 20880);
++        DefaultServiceInstance instance = new DefaultServiceInstance("A", 
"127.0.0.1", 20880, ApplicationModel.defaultModel());
+         Map<String, String> metadata = instance.getMetadata();
+         metadata.put(METADATA_STORAGE_TYPE_PROPERTY_NAME, "remote");
+         metadata.put(EXPORTED_SERVICES_REVISION_PROPERTY_NAME, "111");
+         metadata.put("site", "dubbo");
+ 
+         Map<String, Integer> protocolPorts = new HashMap<>();
+         protocolPorts.put("rest", 8080);
+         protocolPorts.put("dubbo", 20880);
+         setEndpoints(instance, protocolPorts);
 -
          return instance;
      }
  
diff --cc 
dubbo-registry/dubbo-registry-api/src/test/java/org/apache/dubbo/registry/client/migration/MigrationRuleListenerTest.java
index c2bde4b,10e8703..406b85d
--- 
a/dubbo-registry/dubbo-registry-api/src/test/java/org/apache/dubbo/registry/client/migration/MigrationRuleListenerTest.java
+++ 
b/dubbo-registry/dubbo-registry-api/src/test/java/org/apache/dubbo/registry/client/migration/MigrationRuleListenerTest.java
@@@ -25,32 -29,60 +29,61 @@@ import org.mockito.ArgumentCaptor
  import org.mockito.Mockito;
  
  public class MigrationRuleListenerTest {
+ 
+     private String localRule = "key: demo-consumer\n" +
+         "step: APPLICATION_FIRST\n" +
+         "threshold: 1.0\n" +
+         "proportion: 60\n" +
+         "delay: 60\n" +
+         "force: false\n" +
+         "interfaces:\n" +
+         "  - serviceKey: DemoService:1.0.0\n" +
+         "    threshold: 0.5\n" +
+         "    proportion: 30\n" +
+         "    delay: 30\n" +
+         "    force: true\n" +
+         "    step: APPLICATION_FIRST\n" +
+         "  - serviceKey: GreetingService:1.0.0\n" +
+         "    step: FORCE_APPLICATION";
+ 
+     private String remoteRule = "key: demo-consumer\n" +
+         "step: FORCE_APPLICATION\n" +
+         "threshold: 1.0\n" +
+         "proportion: 60\n" +
+         "delay: 60\n" +
+         "force: false\n" +
+         "interfaces:\n" +
+         "  - serviceKey: DemoService:1.0.0\n" +
+         "    threshold: 0.5\n" +
+         "    proportion: 30\n" +
+         "    delay: 30\n" +
+         "    force: true\n" +
+         "    step: FORCE_APPLICATION\n" +
+         "  - serviceKey: GreetingService:1.0.0\n" +
+         "    step: FORCE_INTERFACE";
+ 
+     private String dynamicRemoteRule = "key: demo-consumer\n" +
+         "step: APPLICATION_FIRST\n" +
+         "threshold: 1.0\n" +
+         "proportion: 60\n" +
+         "delay: 60\n" +
+         "force: false\n" +
+         "interfaces:\n";
+ 
+     /**
+      * Listener started with config center and local rule, no initial remote 
rule.
+      * Check local rule take effect
+      */
      @Test
      public void test() throws InterruptedException {
-         String rule = "key: demo-consumer\n" +
-                 "step: APPLICATION_FIRST\n" +
-                 "threshold: 1.0\n" +
-                 "proportion: 60\n" +
-                 "delay: 60\n" +
-                 "force: false\n" +
-                 "interfaces:\n" +
-                 "  - serviceKey: DemoService:1.0.0\n" +
-                 "    threshold: 0.5\n" +
-                 "    proportion: 30\n" +
-                 "    delay: 30\n" +
-                 "    force: true\n" +
-                 "    step: APPLICATION_FIRST\n" +
-                 "  - serviceKey: GreetingService:1.0.0\n" +
-                 "    step: FORCE_APPLICATION";
- 
          DynamicConfiguration dynamicConfiguration = 
Mockito.mock(DynamicConfiguration.class);
  
 -        
ApplicationModel.getEnvironment().setDynamicConfiguration(dynamicConfiguration);
 -        ApplicationModel.getEnvironment().setLocalMigrationRule(localRule);
 +        ApplicationModel.reset();
 +        
ApplicationModel.defaultModel().getApplicationEnvironment().setDynamicConfiguration(dynamicConfiguration);
-         
ApplicationModel.defaultModel().getApplicationEnvironment().setLocalMigrationRule(rule);
++        
ApplicationModel.defaultModel().getApplicationEnvironment().setLocalMigrationRule(localRule);
          ApplicationConfig applicationConfig = new ApplicationConfig();
          applicationConfig.setName("demo-consumer");
 -        ApplicationModel.getConfigManager().setApplication(applicationConfig);
 +        
ApplicationModel.defaultModel().getApplicationConfigManager().setApplication(applicationConfig);
  
          URL consumerURL = Mockito.mock(URL.class);
          Mockito.when(consumerURL.getServiceKey()).thenReturn("Test");
@@@ -60,11 -92,11 +93,12 @@@
          MigrationRuleHandler<?> handler = 
Mockito.mock(MigrationRuleHandler.class, 
Mockito.withSettings().verboseLogging());
  
          MigrationRuleListener migrationRuleListener = new 
MigrationRuleListener();
+ 
          MigrationInvoker<?> migrationInvoker = 
Mockito.mock(MigrationInvoker.class);
          migrationRuleListener.getHandlers().put(migrationInvoker, handler);
 +        
migrationRuleListener.setApplicationModel(ApplicationModel.defaultModel());
  
-         Thread.sleep(5000);
+         Thread.sleep(2000);
          Mockito.verify(handler, 
Mockito.timeout(5000)).doMigrate(Mockito.any());
  
          migrationRuleListener.onRefer(null, migrationInvoker, consumerURL, 
null);
diff --cc 
dubbo-registry/dubbo-registry-api/src/test/java/org/apache/dubbo/registry/client/migration/model/MigrationRuleTest.java
index 1091eee,31a254a..c89ebee
--- 
a/dubbo-registry/dubbo-registry-api/src/test/java/org/apache/dubbo/registry/client/migration/model/MigrationRuleTest.java
+++ 
b/dubbo-registry/dubbo-registry-api/src/test/java/org/apache/dubbo/registry/client/migration/model/MigrationRuleTest.java
@@@ -18,11 -18,10 +18,12 @@@ package org.apache.dubbo.registry.clien
  
  import org.apache.dubbo.common.URL;
  import org.apache.dubbo.metadata.ServiceNameMapping;
- import org.apache.dubbo.metadata.WritableMetadataService;
  
 +import org.apache.dubbo.rpc.model.ApplicationModel;
 +import org.apache.dubbo.rpc.model.ModuleModel;
  import org.junit.jupiter.api.Test;
+ import org.mockito.ArgumentMatchers;
+ import org.mockito.MockedStatic;
  import org.mockito.Mockito;
  
  import java.util.Collections;
@@@ -33,67 -42,71 +44,76 @@@ public class MigrationRuleTest 
  
      @Test
      public void test_parse() {
-         String rule = "key: demo-consumer\n" +
-             "step: APPLICATION_FIRST\n" +
-             "threshold: 1.0\n" +
-             "proportion: 60\n" +
-             "delay: 60\n" +
-             "force: false\n" +
-             "interfaces:\n" +
-             "  - serviceKey: DemoService:1.0.0\n" +
-             "    threshold: 0.5\n" +
-             "    proportion: 30\n" +
-             "    delay: 30\n" +
-             "    force: true\n" +
-             "    step: APPLICATION_FIRST\n" +
-             "  - serviceKey: GreetingService:1.0.0\n" +
-             "    step: FORCE_APPLICATION\n" +
-             "applications:\n" +
-             "  - serviceKey: TestApplication\n" +
-             "    threshold: 0.3\n" +
-             "    proportion: 20\n" +
-             "    delay: 10\n" +
-             "    force: false\n" +
-             "    step: FORCE_INTERFACE\n";
+         try (MockedStatic<ServiceNameMapping> mockStaticMapping = 
Mockito.mockStatic(ServiceNameMapping.class, 
withSettings().defaultAnswer(CALLS_REAL_METHODS))) {
+             
mockStaticMapping.when(ServiceNameMapping::getDefaultExtension).thenReturn(mapping);
+             
when(mapping.getServices(any())).thenReturn(Collections.emptySet());
  
-         MigrationRule migrationRule = MigrationRule.parse(rule);
-         assertEquals("demo-consumer", migrationRule.getKey());
-         assertEquals(MigrationStep.APPLICATION_FIRST, 
migrationRule.getStep());
-         assertEquals(1.0f, migrationRule.getThreshold());
-         assertEquals(60, migrationRule.getProportion());
-         assertEquals(60, migrationRule.getDelay());
-         assertEquals(false, migrationRule.getForce());
+             String rule = "key: demo-consumer\n" +
+                 "step: APPLICATION_FIRST\n" +
+                 "threshold: 1.0\n" +
+                 "proportion: 60\n" +
+                 "delay: 60\n" +
+                 "force: false\n" +
+                 "interfaces:\n" +
+                 "  - serviceKey: DemoService:1.0.0\n" +
+                 "    threshold: 0.5\n" +
+                 "    proportion: 30\n" +
+                 "    delay: 30\n" +
+                 "    force: true\n" +
+                 "    step: APPLICATION_FIRST\n" +
+                 "  - serviceKey: GreetingService:1.0.0\n" +
+                 "    step: FORCE_APPLICATION\n" +
+                 "applications:\n" +
+                 "  - serviceKey: TestApplication\n" +
+                 "    threshold: 0.3\n" +
+                 "    proportion: 20\n" +
+                 "    delay: 10\n" +
+                 "    force: false\n" +
+                 "    step: FORCE_INTERFACE\n";
+ 
+             MigrationRule migrationRule = MigrationRule.parse(rule);
+             assertEquals("demo-consumer", migrationRule.getKey());
+             assertEquals(MigrationStep.APPLICATION_FIRST, 
migrationRule.getStep());
+             assertEquals(1.0f, migrationRule.getThreshold());
+             assertEquals(60, migrationRule.getProportion());
+             assertEquals(60, migrationRule.getDelay());
+             assertEquals(false, migrationRule.getForce());
  
 -            URL url = Mockito.mock(URL.class);
 -            
Mockito.when(url.getDisplayServiceKey()).thenReturn("DemoService:1.0.0");
 -            
Mockito.when(url.getParameter(ArgumentMatchers.eq(REGISTRY_CLUSTER_TYPE_KEY), 
anyString())).thenReturn("default");
 -            
Mockito.when(url.getParameter(ArgumentMatchers.eq(REGISTRY_CLUSTER_TYPE_KEY), 
anyString())).thenReturn("default");
 +        URL url = Mockito.mock(URL.class);
 +        ModuleModel defaultModule = 
ApplicationModel.defaultModel().getDefaultModule();
 +        url.setScopeModel(defaultModule);
 +        
Mockito.when(url.getDisplayServiceKey()).thenReturn("DemoService:1.0.0");
++        
Mockito.when(url.getParameter(ArgumentMatchers.eq(REGISTRY_CLUSTER_TYPE_KEY), 
anyString())).thenReturn("default");
++        
Mockito.when(url.getParameter(ArgumentMatchers.eq(REGISTRY_CLUSTER_TYPE_KEY), 
anyString())).thenReturn("default");
  
-         assertEquals(migrationRule.getInterfaces().size(), 2);
+             assertEquals(migrationRule.getInterfaces().size(), 2);
  
-         assertEquals(0.5f, migrationRule.getThreshold(url));
-         assertEquals(30, migrationRule.getProportion(url));
-         assertEquals(30, migrationRule.getDelay(url));
-         assertEquals(true, migrationRule.getForce(url));
-         assertEquals(MigrationStep.APPLICATION_FIRST, 
migrationRule.getStep(url));
+             assertEquals(0.5f, migrationRule.getThreshold(url));
+             assertEquals(30, migrationRule.getProportion(url));
+             assertEquals(30, migrationRule.getDelay(url));
+             assertEquals(true, migrationRule.getForce(url));
+             assertEquals(MigrationStep.APPLICATION_FIRST, 
migrationRule.getStep(url));
  
-         
Mockito.when(url.getDisplayServiceKey()).thenReturn("GreetingService:1.0.0");
-         assertEquals(1.0f, migrationRule.getThreshold(url));
-         assertEquals(60, migrationRule.getProportion(url));
-         assertEquals(60, migrationRule.getDelay(url));
-         assertEquals(false, migrationRule.getForce(url));
-         assertEquals(MigrationStep.FORCE_APPLICATION, 
migrationRule.getStep(url));
+             
Mockito.when(url.getDisplayServiceKey()).thenReturn("GreetingService:1.0.0");
+             assertEquals(1.0f, migrationRule.getThreshold(url));
+             assertEquals(60, migrationRule.getProportion(url));
+             assertEquals(60, migrationRule.getDelay(url));
+             assertEquals(false, migrationRule.getForce(url));
+             assertEquals(MigrationStep.FORCE_APPLICATION, 
migrationRule.getStep(url));
  
 -            
Mockito.when(url.getDisplayServiceKey()).thenReturn("GreetingService:1.0.1");
 -            
Mockito.when(url.getServiceInterface()).thenReturn("GreetingService");
 -            Set<String> services =  new HashSet<>();
 -            services.add("TestApplication");
 -            when(mapping.getServices(any())).thenReturn(services);
 -            assertEquals(0.3f, migrationRule.getThreshold(url));
 -            assertEquals(20, migrationRule.getProportion(url));
 -            assertEquals(10, migrationRule.getDelay(url));
 -            assertEquals(false, migrationRule.getForce(url));
 -            assertEquals(MigrationStep.FORCE_INTERFACE, 
migrationRule.getStep(url));
 -        }
 +        
Mockito.when(url.getDisplayServiceKey()).thenReturn("GreetingService:1.0.1");
 +        Mockito.when(url.getServiceInterface()).thenReturn("GreetingService");
 +        WritableMetadataService metadataService = 
WritableMetadataService.getDefaultExtension(defaultModule);
 +        
metadataService.putCachedMapping(ServiceNameMapping.buildMappingKey(url), 
Collections.singleton("TestApplication"));
++
++        Set<String> services =  new HashSet<>();
++        services.add("TestApplication");
++        when(mapping.getServices(any())).thenReturn(services);
 +        assertEquals(0.3f, migrationRule.getThreshold(url));
 +        assertEquals(20, migrationRule.getProportion(url));
 +        assertEquals(10, migrationRule.getDelay(url));
 +        assertEquals(false, migrationRule.getForce(url));
 +        assertEquals(MigrationStep.FORCE_INTERFACE, 
migrationRule.getStep(url));
- 
 +        metadataService.removeCachedMapping("GreetingService");
      }
  }
diff --cc 
dubbo-registry/dubbo-registry-api/src/test/java/org/apache/dubbo/registry/support/ServiceOrientedRegistryTest.java
index 934ed20,e82b2b6..448ab72
--- 
a/dubbo-registry/dubbo-registry-api/src/test/java/org/apache/dubbo/registry/support/ServiceOrientedRegistryTest.java
+++ 
b/dubbo-registry/dubbo-registry-api/src/test/java/org/apache/dubbo/registry/support/ServiceOrientedRegistryTest.java
@@@ -23,8 -23,8 +23,9 @@@ import org.apache.dubbo.metadata.Writab
  import org.apache.dubbo.registry.NotifyListener;
  import org.apache.dubbo.registry.client.ServiceDiscoveryRegistry;
  import org.apache.dubbo.rpc.model.ApplicationModel;
 +import org.apache.dubbo.rpc.model.ModuleModel;
  
+ import org.junit.jupiter.api.AfterAll;
  import org.junit.jupiter.api.BeforeEach;
  import org.junit.jupiter.api.Test;
  
@@@ -83,15 -83,17 +84,20 @@@ public class ServiceOrientedRegistryTes
  
      @BeforeEach
      public void init() {
 +        ApplicationModel applicationModel = ApplicationModel.defaultModel();
 +        ModuleModel scopeModel = applicationModel.getDefaultModule();
 +        registryURL.setScopeModel(scopeModel);
          registry = ServiceDiscoveryRegistry.create(registryURL);
 -        metadataService = WritableMetadataService.getDefaultExtension();
 +        metadataService = 
WritableMetadataService.getDefaultExtension(scopeModel);
          notifyListener = new MyNotifyListener();
 -        ApplicationModel.getConfigManager().setApplication(new 
ApplicationConfig("Test"));
 +        applicationModel.getApplicationConfigManager().setApplication(new 
ApplicationConfig("Test"));
      }
  
+     @AfterAll
+     public static void clearUp() {
+         ApplicationModel.reset();
+     }
+ 
      @Test
      public void testSupports() {
          assertTrue(ServiceDiscoveryRegistry.supports(registryURL));
diff --cc 
dubbo-registry/dubbo-registry-nacos/src/main/java/org/apache/dubbo/registry/nacos/NacosServiceDiscovery.java
index be0c253,67f4c89..0048ca7
--- 
a/dubbo-registry/dubbo-registry-nacos/src/main/java/org/apache/dubbo/registry/nacos/NacosServiceDiscovery.java
+++ 
b/dubbo-registry/dubbo-registry-nacos/src/main/java/org/apache/dubbo/registry/nacos/NacosServiceDiscovery.java
@@@ -104,8 -110,8 +110,8 @@@ public class NacosServiceDiscovery exte
      @Override
      public List<ServiceInstance> getInstances(String serviceName) throws 
NullPointerException {
          return ThrowableFunction.execute(namingService, service ->
-                 service.selectInstances(serviceName, true)
-                         
.stream().map((i)->NacosNamingServiceUtils.toServiceInstance(registryURL, i))
 -                service.selectInstances(serviceName, Constants.DEFAULT_GROUP, 
true)
 -                        
.stream().map(NacosNamingServiceUtils::toServiceInstance)
++            service.selectInstances(serviceName, Constants.DEFAULT_GROUP, 
true)
++                
.stream().map((i)->NacosNamingServiceUtils.toServiceInstance(registryURL, i))
                          .collect(Collectors.toList())
          );
      }
diff --cc 
dubbo-registry/dubbo-registry-zookeeper/src/main/java/org/apache/dubbo/registry/zookeeper/util/CuratorFrameworkUtils.java
index 993e02a,d9e137c..d7fd458
--- 
a/dubbo-registry/dubbo-registry-zookeeper/src/main/java/org/apache/dubbo/registry/zookeeper/util/CuratorFrameworkUtils.java
+++ 
b/dubbo-registry/dubbo-registry-zookeeper/src/main/java/org/apache/dubbo/registry/zookeeper/util/CuratorFrameworkUtils.java
@@@ -76,12 -84,12 +85,12 @@@ public abstract class CuratorFrameworkU
      }
  
  
 -    public static List<ServiceInstance> 
build(Collection<org.apache.curator.x.discovery.ServiceInstance<ZookeeperInstance>>
 -                                                  instances) {
 -        return 
instances.stream().map(CuratorFrameworkUtils::build).collect(Collectors.toList());
 +    public static List<ServiceInstance> build(URL registryUrl, 
Collection<org.apache.curator.x.discovery.ServiceInstance<ZookeeperInstance>>
-                                                       instances) {
++        instances) {
 +        return instances.stream().map((i)->build(registryUrl, 
i)).collect(Collectors.toList());
      }
  
 -    public static ServiceInstance 
build(org.apache.curator.x.discovery.ServiceInstance<ZookeeperInstance> 
instance) {
 +    public static ServiceInstance build(URL registryUrl, 
org.apache.curator.x.discovery.ServiceInstance<ZookeeperInstance> instance) {
          String name = instance.getName();
          String host = instance.getAddress();
          int port = instance.getPort();
diff --cc 
dubbo-rpc/dubbo-rpc-dubbo/src/main/java/org/apache/dubbo/rpc/protocol/dubbo/DecodeableRpcResult.java
index 1c6a00b,05b84cb..d93d345
--- 
a/dubbo-rpc/dubbo-rpc-dubbo/src/main/java/org/apache/dubbo/rpc/protocol/dubbo/DecodeableRpcResult.java
+++ 
b/dubbo-rpc/dubbo-rpc-dubbo/src/main/java/org/apache/dubbo/rpc/protocol/dubbo/DecodeableRpcResult.java
@@@ -118,14 -118,16 +118,17 @@@ public class DecodeableRpcResult extend
      public void decode() throws Exception {
          if (!hasDecoded && channel != null && inputStream != null) {
              try {
-                 if 
(ConfigurationUtils.getSystemConfiguration(channel.getUrl().getScopeModel()).getBoolean(SERIALIZATION_SECURITY_CHECK_KEY,
 true)) {
-                     Object serializationType_obj = 
invocation.get(SERIALIZATION_ID_KEY);
-                     if (serializationType_obj != null) {
-                         if ((byte) serializationType_obj != 
serializationType) {
-                             throw new IOException("Unexpected serialization 
id:" + serializationType + " received from network, please check if the peer 
send the right id.");
+                 if (invocation != null) {
 -                    if 
(ConfigurationUtils.getSystemConfiguration().getBoolean(SERIALIZATION_SECURITY_CHECK_KEY,
 true)) {
++                    if 
(ConfigurationUtils.getSystemConfiguration(channel.getUrl().getScopeModel()).getBoolean(SERIALIZATION_SECURITY_CHECK_KEY,
 true)) {
+                         Object serializationTypeObj = 
invocation.get(SERIALIZATION_ID_KEY);
+                         if (serializationTypeObj != null) {
+                             if ((byte) serializationTypeObj != 
serializationType) {
+                                 throw new IOException("Unexpected 
serialization id:" + serializationType + " received from network, please check 
if the peer send the right id.");
+                             }
                          }
                      }
                  }
++
                  decode(channel, inputStream);
              } catch (Throwable e) {
                  if (log.isWarnEnabled()) {

Reply via email to