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

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


The following commit(s) were added to refs/heads/3.0-multi-instances by this 
push:
     new bba7e0f  Fix scope model of registry, metadata, cluster and so on
bba7e0f is described below

commit bba7e0f7e7694e03104cc339b723825ec1bb6eff
Author: gongdewei <[email protected]>
AuthorDate: Fri Aug 27 23:18:52 2021 +0800

    Fix scope model of registry, metadata, cluster and so on
---
 .../cluster/filter/DefaultFilterChainBuilder.java  |  8 ++-
 .../rpc/cluster/filter/FilterChainBuilder.java     |  4 +-
 .../rpc/cluster/filter/ProtocolFilterWrapper.java  |  9 ++-
 .../governance/GovernanceRuleRepository.java       |  4 +-
 .../common/beans/factory/ScopeBeanFactory.java     | 48 +++++++++++++--
 .../dubbo/common/extension/ExtensionLoader.java    |  5 +-
 .../org/apache/dubbo/config/ReferenceConfig.java   |  1 +
 .../dubbo/config/bootstrap/DubboBootstrap.java     | 25 ++------
 .../ConfigurableMetadataServiceExporter.java       |  2 +
 .../ServiceInstanceHostPortCustomizer.java         |  5 +-
 .../dubbo/config/utils/ReferenceConfigCache.java   |  9 ++-
 .../bootstrap/DubboBootstrapMultiInstanceTest.java |  5 +-
 ...ceDiscoveryRegistryRegistryServiceListener.java |  7 ++-
 ...RegistryCenterDubboProtocolIntegrationTest.java |  2 +-
 .../dubbo/metadata/AbstractServiceNameMapping.java | 18 ++++--
 .../apache/dubbo/metadata/ServiceNameMapping.java  |  3 +-
 .../dubbo/metadata/WritableMetadataService.java    |  7 +--
 .../registry/client/DefaultServiceInstance.java    | 10 ++--
 .../registry/client/RegistryClusterIdentifier.java |  2 +-
 .../client/SelfHostMetaServiceDiscovery.java       | 15 +++--
 .../dubbo/registry/client/ServiceDiscovery.java    |  3 +-
 .../registry/client/ServiceDiscoveryRegistry.java  |  6 +-
 .../client/ServiceDiscoveryRegistryDirectory.java  | 34 ++++++-----
 .../dubbo/registry/client/ServiceInstance.java     |  6 +-
 .../registry/client/ServiceInstanceCustomizer.java |  4 +-
 .../listener/ServiceInstancesChangedListener.java  |  2 +-
 ...MetadataServiceURLParamsMetadataCustomizer.java |  3 +-
 .../registry/client/metadata/MetadataUtils.java    |  2 +-
 .../metadata/ProtocolPortsMetadataCustomizer.java  |  2 +-
 .../ServiceInstanceMetadataCustomizer.java         |  9 +--
 .../metadata/ServiceInstanceMetadataUtils.java     |  8 +--
 .../store/InMemoryWritableMetadataService.java     | 11 +++-
 .../client/migration/MigrationRuleListener.java    | 28 ++++++---
 .../integration/AbstractConfiguratorListener.java  | 17 ++++--
 .../registry/integration/RegistryDirectory.java    | 24 +++++---
 .../registry/integration/RegistryProtocol.java     | 70 +++++++++++++++-------
 .../integration/RegistryProtocolListener.java      |  4 +-
 .../client/migration/model/MigrationRuleTest.java  |  9 ++-
 .../support/ServiceOrientedRegistryTest.java       |  8 ++-
 .../registry/dns/DNSServiceDiscoveryTest.java      | 12 ++--
 .../rpc/protocol/ProtocolListenerWrapper.java      |  5 +-
 .../rpc/protocol/ProtocolSerializationWrapper.java |  5 +-
 42 files changed, 300 insertions(+), 161 deletions(-)

diff --git 
a/dubbo-cluster/src/main/java/org/apache/dubbo/rpc/cluster/filter/DefaultFilterChainBuilder.java
 
b/dubbo-cluster/src/main/java/org/apache/dubbo/rpc/cluster/filter/DefaultFilterChainBuilder.java
index e2e26d2..39706bd 100644
--- 
a/dubbo-cluster/src/main/java/org/apache/dubbo/rpc/cluster/filter/DefaultFilterChainBuilder.java
+++ 
b/dubbo-cluster/src/main/java/org/apache/dubbo/rpc/cluster/filter/DefaultFilterChainBuilder.java
@@ -16,8 +16,8 @@
  */
 package org.apache.dubbo.rpc.cluster.filter;
 
+import org.apache.dubbo.common.URL;
 import org.apache.dubbo.common.extension.Activate;
-import org.apache.dubbo.common.extension.ExtensionLoader;
 import org.apache.dubbo.rpc.Filter;
 import org.apache.dubbo.rpc.Invoker;
 import org.apache.dubbo.rpc.cluster.ClusterInvoker;
@@ -33,7 +33,8 @@ public class DefaultFilterChainBuilder implements 
FilterChainBuilder {
     @Override
     public <T> Invoker<T> buildInvokerChain(final Invoker<T> originalInvoker, 
String key, String group) {
         Invoker<T> last = originalInvoker;
-        List<Filter> filters = 
ExtensionLoader.getExtensionLoader(Filter.class).getActivateExtension(originalInvoker.getUrl(),
 key, group);
+        URL url = originalInvoker.getUrl();
+        List<Filter> filters = 
url.getScopeModel().getExtensionLoader(Filter.class).getActivateExtension(url, 
key, group);
 
         if (!filters.isEmpty()) {
             for (int i = filters.size() - 1; i >= 0; i--) {
@@ -52,7 +53,8 @@ public class DefaultFilterChainBuilder implements 
FilterChainBuilder {
     @Override
     public <T> ClusterInvoker<T> buildClusterInvokerChain(final 
ClusterInvoker<T> originalInvoker, String key, String group) {
         ClusterInvoker<T> last = originalInvoker;
-        List<ClusterFilter> filters = 
ExtensionLoader.getExtensionLoader(ClusterFilter.class).getActivateExtension(originalInvoker.getUrl(),
 key, group);
+        URL url = originalInvoker.getUrl();
+        List<ClusterFilter> filters = 
url.getScopeModel().getExtensionLoader(ClusterFilter.class).getActivateExtension(url,
 key, group);
 
         if (!filters.isEmpty()) {
             for (int i = filters.size() - 1; i >= 0; i--) {
diff --git 
a/dubbo-cluster/src/main/java/org/apache/dubbo/rpc/cluster/filter/FilterChainBuilder.java
 
b/dubbo-cluster/src/main/java/org/apache/dubbo/rpc/cluster/filter/FilterChainBuilder.java
index 949a66c..7edab08 100644
--- 
a/dubbo-cluster/src/main/java/org/apache/dubbo/rpc/cluster/filter/FilterChainBuilder.java
+++ 
b/dubbo-cluster/src/main/java/org/apache/dubbo/rpc/cluster/filter/FilterChainBuilder.java
@@ -28,7 +28,9 @@ import org.apache.dubbo.rpc.RpcException;
 import org.apache.dubbo.rpc.cluster.ClusterInvoker;
 import org.apache.dubbo.rpc.cluster.Directory;
 
-@SPI("default")
+import static org.apache.dubbo.common.extension.ExtensionScope.APPLICATION;
+
+@SPI(value = "default", scope = APPLICATION)
 public interface FilterChainBuilder {
     /**
      * build consumer/provider filter chain
diff --git 
a/dubbo-cluster/src/main/java/org/apache/dubbo/rpc/cluster/filter/ProtocolFilterWrapper.java
 
b/dubbo-cluster/src/main/java/org/apache/dubbo/rpc/cluster/filter/ProtocolFilterWrapper.java
index 389b173..f954cd7 100644
--- 
a/dubbo-cluster/src/main/java/org/apache/dubbo/rpc/cluster/filter/ProtocolFilterWrapper.java
+++ 
b/dubbo-cluster/src/main/java/org/apache/dubbo/rpc/cluster/filter/ProtocolFilterWrapper.java
@@ -19,7 +19,6 @@ package org.apache.dubbo.rpc.cluster.filter;
 import org.apache.dubbo.common.URL;
 import org.apache.dubbo.common.constants.CommonConstants;
 import org.apache.dubbo.common.extension.Activate;
-import org.apache.dubbo.common.extension.ExtensionLoader;
 import org.apache.dubbo.common.utils.UrlUtils;
 import org.apache.dubbo.rpc.Exporter;
 import org.apache.dubbo.rpc.Invoker;
@@ -39,8 +38,6 @@ import static 
org.apache.dubbo.common.constants.CommonConstants.SERVICE_FILTER_K
 public class ProtocolFilterWrapper implements Protocol {
 
     private final Protocol protocol;
-    private static final FilterChainBuilder builder
-            = 
ExtensionLoader.getExtensionLoader(FilterChainBuilder.class).getDefaultExtension();
 
     public ProtocolFilterWrapper(Protocol protocol) {
         if (protocol == null) {
@@ -59,14 +56,20 @@ public class ProtocolFilterWrapper implements Protocol {
         if (UrlUtils.isRegistry(invoker.getUrl())) {
             return protocol.export(invoker);
         }
+        FilterChainBuilder builder = getFilterChainBuilder(invoker.getUrl());
         return protocol.export(builder.buildInvokerChain(invoker, 
SERVICE_FILTER_KEY, CommonConstants.PROVIDER));
     }
 
+    private <T> FilterChainBuilder getFilterChainBuilder(URL url) {
+        return 
url.getScopeModel().getExtensionLoader(FilterChainBuilder.class).getDefaultExtension();
+    }
+
     @Override
     public <T> Invoker<T> refer(Class<T> type, URL url) throws RpcException {
         if (UrlUtils.isRegistry(url)) {
             return protocol.refer(type, url);
         }
+        FilterChainBuilder builder = getFilterChainBuilder(url);
         return builder.buildInvokerChain(protocol.refer(type, url), 
REFERENCE_FILTER_KEY, CommonConstants.CONSUMER);
     }
 
diff --git 
a/dubbo-cluster/src/main/java/org/apache/dubbo/rpc/cluster/governance/GovernanceRuleRepository.java
 
b/dubbo-cluster/src/main/java/org/apache/dubbo/rpc/cluster/governance/GovernanceRuleRepository.java
index aaa604f..d375c8b 100644
--- 
a/dubbo-cluster/src/main/java/org/apache/dubbo/rpc/cluster/governance/GovernanceRuleRepository.java
+++ 
b/dubbo-cluster/src/main/java/org/apache/dubbo/rpc/cluster/governance/GovernanceRuleRepository.java
@@ -19,7 +19,9 @@ package org.apache.dubbo.rpc.cluster.governance;
 import org.apache.dubbo.common.config.configcenter.ConfigurationListener;
 import org.apache.dubbo.common.extension.SPI;
 
-@SPI("default")
+import static org.apache.dubbo.common.extension.ExtensionScope.APPLICATION;
+
+@SPI(value = "default", scope = APPLICATION)
 public interface GovernanceRuleRepository {
 
     String DEFAULT_GROUP = "dubbo";
diff --git 
a/dubbo-common/src/main/java/org/apache/dubbo/common/beans/factory/ScopeBeanFactory.java
 
b/dubbo-common/src/main/java/org/apache/dubbo/common/beans/factory/ScopeBeanFactory.java
index 1e56488..bdc45e4 100644
--- 
a/dubbo-common/src/main/java/org/apache/dubbo/common/beans/factory/ScopeBeanFactory.java
+++ 
b/dubbo-common/src/main/java/org/apache/dubbo/common/beans/factory/ScopeBeanFactory.java
@@ -28,6 +28,7 @@ import java.util.List;
 import java.util.Map;
 import java.util.concurrent.ConcurrentHashMap;
 import java.util.concurrent.atomic.AtomicInteger;
+import java.util.function.Function;
 import java.util.stream.Collectors;
 
 /**
@@ -76,6 +77,46 @@ public class ScopeBeanFactory {
         }
 
         Class<?> beanClass = bean.getClass();
+        if (name == null) {
+            name = beanClass.getName() + "#" + getNextId(beanClass);
+        }
+        initializeBean(name, bean);
+
+        registeredBeanInfos.add(new BeanInfo(name, bean));
+    }
+
+    public <T> T registerBeanIfAbsent(Class<T> type) {
+        return registerBeanIfAbsent(null, type);
+    }
+
+    public <T> T registerBeanIfAbsent(String name, Class<T> type) {
+        T bean = getBean(name, type);
+        if (bean == null) {
+            bean = registerBean(name, type);
+        }
+        return bean;
+    }
+
+    public <T> T registerBeanIfAbsent(Class<T> type, Function<? super 
Class<T>, ? extends T> mappingFunction) {
+        return registerBeanIfAbsent(null, type, mappingFunction);
+    }
+
+    public <T> T registerBeanIfAbsent(String name, Class<T> type, Function<? 
super Class<T>, ? extends T> mappingFunction) {
+        T bean = getBean(name, type);
+        if (bean == null) {
+            //TODO add lock
+            bean = mappingFunction.apply(type);
+            registerBean(name, bean);
+        }
+        return bean;
+    }
+
+    public <T> T initializeBean(T bean) {
+        this.initializeBean(null, bean);
+        return bean;
+    }
+
+    private void initializeBean(String name, Object bean) {
         try {
             if (bean instanceof ExtensionAccessorAware) {
                 ((ExtensionAccessorAware) 
bean).setExtensionAccessor(extensionAccessor);
@@ -84,13 +125,8 @@ public class ScopeBeanFactory {
                 processor.postProcessAfterInitialization(bean, name);
             }
         } catch (Exception e) {
-            throw new ScopeBeanException("register bean failed! name=" + name 
+ ", type=" + beanClass.getName(), e);
-        }
-
-        if (name == null) {
-            name = beanClass.getName() + "#" + getNextId(beanClass);
+            throw new ScopeBeanException("register bean failed! name=" + name 
+ ", type=" + bean.getClass().getName(), e);
         }
-        registeredBeanInfos.add(new BeanInfo(name, bean));
     }
 
     private boolean containsBean(String name, Object bean) {
diff --git 
a/dubbo-common/src/main/java/org/apache/dubbo/common/extension/ExtensionLoader.java
 
b/dubbo-common/src/main/java/org/apache/dubbo/common/extension/ExtensionLoader.java
index 166e9c0..c6a322b 100644
--- 
a/dubbo-common/src/main/java/org/apache/dubbo/common/extension/ExtensionLoader.java
+++ 
b/dubbo-common/src/main/java/org/apache/dubbo/common/extension/ExtensionLoader.java
@@ -693,10 +693,9 @@ public class ExtensionLoader<T> {
             }
             instance = postProcessBeforeInitialization(instance, name);
             injectExtension(instance);
-
+            instance = postProcessAfterInitialization(instance, name);
 
             if (wrap) {
-
                 List<Class<?>> wrapperClassesList = new ArrayList<>();
                 if (cachedWrapperClasses != null) {
                     wrapperClassesList.addAll(cachedWrapperClasses);
@@ -710,12 +709,12 @@ public class ExtensionLoader<T> {
                         if (wrapper == null
                             || (ArrayUtils.contains(wrapper.matches(), name) 
&& !ArrayUtils.contains(wrapper.mismatches(), name))) {
                             instance = injectExtension((T) 
wrapperClass.getConstructor(type).newInstance(instance));
+                            instance = 
postProcessAfterInitialization(instance, name);
                         }
                     }
                 }
             }
 
-            instance = postProcessAfterInitialization(instance, name);
             initExtension(instance);
             return instance;
         } catch (Throwable t) {
diff --git 
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
index 5c912c1..65c7154 100644
--- 
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
@@ -404,6 +404,7 @@ public class ReferenceConfig<T> extends 
ReferenceConfigBase<T> {
      */
     private void createInvokerForLocal(Map<String, String> 
referenceParameters) {
         URL url = new ServiceConfigURL(LOCAL_PROTOCOL, LOCALHOST_VALUE, 0, 
interfaceClass.getName()).addParameters(referenceParameters);
+        url.setScopeModel(getScopeModel());
         invoker = protocolSPI.refer(interfaceClass, url);
         if (logger.isInfoEnabled()) {
             logger.info("Using in jvm service " + interfaceClass.getName());
diff --git 
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
index f1edbd2..8c38076 100644
--- 
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
@@ -60,7 +60,6 @@ import 
org.apache.dubbo.config.bootstrap.builders.ReferenceBuilder;
 import org.apache.dubbo.config.bootstrap.builders.RegistryBuilder;
 import org.apache.dubbo.config.bootstrap.builders.ServiceBuilder;
 import org.apache.dubbo.config.context.ConfigManager;
-import org.apache.dubbo.config.metadata.ConfigurableMetadataServiceExporter;
 import org.apache.dubbo.config.utils.ConfigValidationUtils;
 import org.apache.dubbo.config.utils.ReferenceConfigCache;
 import org.apache.dubbo.metadata.MetadataService;
@@ -114,7 +113,6 @@ import static 
org.apache.dubbo.common.utils.StringUtils.isEmpty;
 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.metadata.WritableMetadataService.getDefaultExtension;
 import static 
org.apache.dubbo.registry.client.metadata.ServiceInstanceMetadataUtils.calInstanceRevision;
 import static 
org.apache.dubbo.registry.client.metadata.ServiceInstanceMetadataUtils.setMetadataStorageType;
 import static 
org.apache.dubbo.registry.support.AbstractRegistryFactory.getServiceDiscoveries;
@@ -271,6 +269,7 @@ public class DubboBootstrap {
         executorRepository = 
getExtensionLoader(ExecutorRepository.class).getDefaultExtension();
         DubboShutdownHook.getDubboShutdownHook().register();
         
ShutdownHookCallbacks.INSTANCE.addCallback(DubboBootstrap.this::destroy);
+        cache = ReferenceConfigCache.newCache();
 
         initInternalBeans();
     }
@@ -280,7 +279,7 @@ public class DubboBootstrap {
      */
     private void initInternalBeans() {
         ScopeBeanFactory beanFactory = applicationModel.getBeanFactory();
-
+        beanFactory.registerBean(this);
         beanFactory.registerBean(MetadataReportInstance.class);
         beanFactory.registerBean(RemoteMetadataServiceImpl.class);
         beanFactory.registerBean(FrameworkStatusReportService.class);
@@ -584,15 +583,7 @@ public class DubboBootstrap {
         return this;
     }
 
-    public DubboBootstrap cache(ReferenceConfigCache cache) {
-        this.cache = cache;
-        return this;
-    }
-
     public ReferenceConfigCache getCache() {
-        if (cache == null) {
-            cache = ReferenceConfigCache.getCache();
-        }
         return cache;
     }
 
@@ -1504,10 +1495,6 @@ public class DubboBootstrap {
     }
 
     private void referServices() {
-        if (cache == null) {
-            cache = ReferenceConfigCache.getCache();
-        }
-
         configManager.getReferences().forEach(rc -> {
             // TODO, compatible with  ReferenceConfig.refer()
             ReferenceConfig<?> referenceConfig = (ReferenceConfig<?>) rc;
@@ -1537,10 +1524,6 @@ public class DubboBootstrap {
 
     private void unreferServices() {
         try {
-            if (cache == null) {
-                cache = ReferenceConfigCache.getCache();
-            }
-
             asyncReferringFutures.forEach(future -> {
                 if (!future.isDone()) {
                     future.cancel(true);
@@ -1570,7 +1553,7 @@ public class DubboBootstrap {
         if (registered) {
             // scheduled task for updating Metadata and ServiceInstance
             executorRepository.nextScheduledExecutor().scheduleAtFixedRate(() 
-> {
-                InMemoryWritableMetadataService localMetadataService = 
(InMemoryWritableMetadataService) WritableMetadataService.getDefaultExtension();
+                InMemoryWritableMetadataService localMetadataService = 
(InMemoryWritableMetadataService) 
WritableMetadataService.getDefaultExtension(applicationModel);
                 localMetadataService.blockUntilUpdated();
                 try {
                     
ServiceInstanceMetadataUtils.refreshMetadataAndInstance(serviceInstance);
@@ -1625,7 +1608,7 @@ public class DubboBootstrap {
 
     private ServiceInstance createServiceInstance(String serviceName) {
         this.serviceInstance = new DefaultServiceInstance(serviceName);
-        serviceInstance.setScopeModel(applicationModel);
+        serviceInstance.setApplicationModel(applicationModel);
         setMetadataStorageType(serviceInstance, getMetadataType());
         ServiceInstanceMetadataUtils.customizeInstance(this.serviceInstance);
         return this.serviceInstance;
diff --git 
a/dubbo-config/dubbo-config-api/src/main/java/org/apache/dubbo/config/metadata/ConfigurableMetadataServiceExporter.java
 
b/dubbo-config/dubbo-config-api/src/main/java/org/apache/dubbo/config/metadata/ConfigurableMetadataServiceExporter.java
index 05d48fc..3a45a04 100644
--- 
a/dubbo-config/dubbo-config-api/src/main/java/org/apache/dubbo/config/metadata/ConfigurableMetadataServiceExporter.java
+++ 
b/dubbo-config/dubbo-config-api/src/main/java/org/apache/dubbo/config/metadata/ConfigurableMetadataServiceExporter.java
@@ -26,6 +26,7 @@ import org.apache.dubbo.config.MethodConfig;
 import org.apache.dubbo.config.ProtocolConfig;
 import org.apache.dubbo.config.RegistryConfig;
 import org.apache.dubbo.config.ServiceConfig;
+import org.apache.dubbo.config.bootstrap.DubboBootstrap;
 import org.apache.dubbo.config.context.ConfigManager;
 import org.apache.dubbo.metadata.MetadataService;
 import org.apache.dubbo.metadata.MetadataServiceExporter;
@@ -82,6 +83,7 @@ public class ConfigurableMetadataServiceExporter implements 
MetadataServiceExpor
             ApplicationConfig applicationConfig = getApplicationConfig();
             ServiceConfig<MetadataService> serviceConfig = new 
ServiceConfig<>();
             serviceConfig.setScopeModel(applicationModel.getDefaultModule());
+            
serviceConfig.setBootstrap(applicationModel.getBeanFactory().getBean(DubboBootstrap.class));
             serviceConfig.setApplication(applicationConfig);
             serviceConfig.setRegistry(new RegistryConfig("N/A"));
             serviceConfig.setProtocol(generateMetadataProtocol());
diff --git 
a/dubbo-config/dubbo-config-api/src/main/java/org/apache/dubbo/config/metadata/ServiceInstanceHostPortCustomizer.java
 
b/dubbo-config/dubbo-config-api/src/main/java/org/apache/dubbo/config/metadata/ServiceInstanceHostPortCustomizer.java
index 10dba8c..be79b1a 100644
--- 
a/dubbo-config/dubbo-config-api/src/main/java/org/apache/dubbo/config/metadata/ServiceInstanceHostPortCustomizer.java
+++ 
b/dubbo-config/dubbo-config-api/src/main/java/org/apache/dubbo/config/metadata/ServiceInstanceHostPortCustomizer.java
@@ -40,13 +40,14 @@ public class ServiceInstanceHostPortCustomizer implements 
ServiceInstanceCustomi
             return;
         }
 
-        WritableMetadataService writableMetadataService = 
WritableMetadataService.getDefaultExtension();
+        WritableMetadataService writableMetadataService = 
WritableMetadataService.getDefaultExtension(serviceInstance.getApplicationModel());
 
         String host = null;
         int port = -1;
         Set<URL> urls = writableMetadataService.getExportedServiceURLs();
         if (CollectionUtils.isNotEmpty(urls)) {
-            String preferredProtocol = 
ApplicationModel.defaultModel().getApplicationConfig().getProtocol();
+            ApplicationModel applicationModel = 
serviceInstance.getApplicationModel();
+            String preferredProtocol = 
applicationModel.getApplicationConfig().getProtocol();
             if (preferredProtocol != null) {
                 for (URL exportedURL : urls) {
                     if (preferredProtocol.equals(exportedURL.getProtocol())) {
diff --git 
a/dubbo-config/dubbo-config-api/src/main/java/org/apache/dubbo/config/utils/ReferenceConfigCache.java
 
b/dubbo-config/dubbo-config-api/src/main/java/org/apache/dubbo/config/utils/ReferenceConfigCache.java
index 56f82e4..1d71d13 100644
--- 
a/dubbo-config/dubbo-config-api/src/main/java/org/apache/dubbo/config/utils/ReferenceConfigCache.java
+++ 
b/dubbo-config/dubbo-config-api/src/main/java/org/apache/dubbo/config/utils/ReferenceConfigCache.java
@@ -28,6 +28,7 @@ import java.util.List;
 import java.util.Map;
 import java.util.concurrent.ConcurrentHashMap;
 import java.util.concurrent.ConcurrentMap;
+import java.util.concurrent.atomic.AtomicInteger;
 
 /**
  * A simple util class for cache {@link ReferenceConfigBase}.
@@ -65,6 +66,8 @@ public class ReferenceConfigCache {
         return ret.toString();
     };
 
+    private static final AtomicInteger nameIndex = new AtomicInteger();
+
     static final ConcurrentMap<String, ReferenceConfigCache> CACHE_HOLDER = 
new ConcurrentHashMap<String, ReferenceConfigCache>();
     private final String name;
     private final KeyGenerator generator;
@@ -86,6 +89,10 @@ public class ReferenceConfigCache {
         return getCache(DEFAULT_NAME);
     }
 
+    public static ReferenceConfigCache newCache() {
+        return getCache(DEFAULT_NAME + "#" + nameIndex.incrementAndGet());
+    }
+
     /**
      * Get the cache use specified name and {@link KeyGenerator}.
      * Create cache if not existed yet.
@@ -240,7 +247,7 @@ public class ReferenceConfigCache {
     @Override
     public String toString() {
         return "ReferenceConfigCache(name: " + name
-                + ")";
+            + ")";
     }
 
     public interface KeyGenerator {
diff --git 
a/dubbo-config/dubbo-config-api/src/test/java/org/apache/dubbo/config/bootstrap/DubboBootstrapMultiInstanceTest.java
 
b/dubbo-config/dubbo-config-api/src/test/java/org/apache/dubbo/config/bootstrap/DubboBootstrapMultiInstanceTest.java
index e6ebe39..80400c3 100644
--- 
a/dubbo-config/dubbo-config-api/src/test/java/org/apache/dubbo/config/bootstrap/DubboBootstrapMultiInstanceTest.java
+++ 
b/dubbo-config/dubbo-config-api/src/test/java/org/apache/dubbo/config/bootstrap/DubboBootstrapMultiInstanceTest.java
@@ -54,6 +54,9 @@ public class DubboBootstrapMultiInstanceTest {
         // bootstrap2: consumer app
         configConsumerApp(dubboBootstrap2).start();
         testConsumer(dubboBootstrap2);
+
+        DemoService demoServiceFromProvider = 
dubboBootstrap1.getCache().get(DemoService.class);
+        Assertions.assertNull(demoServiceFromProvider);
     }
 
     @Test
@@ -113,6 +116,7 @@ public class DubboBootstrapMultiInstanceTest {
     private void testConsumer(DubboBootstrap dubboBootstrap) {
         DemoService demoService = 
dubboBootstrap.getCache().get(DemoService.class);
         String result = demoService.sayName("dubbo");
+        System.out.println("result: " + result);
         Assertions.assertEquals("say:dubbo", result);
     }
 
@@ -137,5 +141,4 @@ public class DubboBootstrapMultiInstanceTest {
         return dubboBootstrap;
     }
 
-
 }
diff --git 
a/dubbo-config/dubbo-config-api/src/test/java/org/apache/dubbo/integration/multiple/servicediscoveryregistry/MultipleRegistryCenterServiceDiscoveryRegistryRegistryServiceListener.java
 
b/dubbo-config/dubbo-config-api/src/test/java/org/apache/dubbo/integration/multiple/servicediscoveryregistry/MultipleRegistryCenterServiceDiscoveryRegistryRegistryServiceListener.java
index a1dd4d7..4b03bc1 100644
--- 
a/dubbo-config/dubbo-config-api/src/test/java/org/apache/dubbo/integration/multiple/servicediscoveryregistry/MultipleRegistryCenterServiceDiscoveryRegistryRegistryServiceListener.java
+++ 
b/dubbo-config/dubbo-config-api/src/test/java/org/apache/dubbo/integration/multiple/servicediscoveryregistry/MultipleRegistryCenterServiceDiscoveryRegistryRegistryServiceListener.java
@@ -34,13 +34,14 @@ public class 
MultipleRegistryCenterServiceDiscoveryRegistryRegistryServiceListen
      * Create an {@link ServiceDiscoveryRegistryInfoWrapper} instance.
      */
     private ServiceDiscoveryRegistryInfoWrapper 
createServiceDiscoveryRegistryInfoWrapper(ServiceDiscoveryRegistry 
serviceDiscoveryRegistry){
-        String host = serviceDiscoveryRegistry.getUrl().getHost();
-        int port = serviceDiscoveryRegistry.getUrl().getPort();
+        URL url = serviceDiscoveryRegistry.getUrl();
+        String host = url.getHost();
+        int port = url.getPort();
         ServiceDiscoveryRegistryInfoWrapper 
serviceDiscoveryRegistryInfoWrapper = new ServiceDiscoveryRegistryInfoWrapper();
         serviceDiscoveryRegistryInfoWrapper.setHost(host);
         serviceDiscoveryRegistryInfoWrapper.setPort(port);
         
serviceDiscoveryRegistryInfoWrapper.setServiceDiscoveryRegistry(serviceDiscoveryRegistry);
-        
serviceDiscoveryRegistryInfoWrapper.setInMemoryWritableMetadataService((InMemoryWritableMetadataService)
 WritableMetadataService.getDefaultExtension());
+        
serviceDiscoveryRegistryInfoWrapper.setInMemoryWritableMetadataService((InMemoryWritableMetadataService)
 WritableMetadataService.getDefaultExtension(url.getScopeModel()));
         serviceDiscoveryRegistryInfoWrapper.setRegistered(true);
         return serviceDiscoveryRegistryInfoWrapper;
     }
diff --git 
a/dubbo-config/dubbo-config-api/src/test/java/org/apache/dubbo/integration/single/SingleRegistryCenterDubboProtocolIntegrationTest.java
 
b/dubbo-config/dubbo-config-api/src/test/java/org/apache/dubbo/integration/single/SingleRegistryCenterDubboProtocolIntegrationTest.java
index e1ffb81..8bcb6bf 100644
--- 
a/dubbo-config/dubbo-config-api/src/test/java/org/apache/dubbo/integration/single/SingleRegistryCenterDubboProtocolIntegrationTest.java
+++ 
b/dubbo-config/dubbo-config-api/src/test/java/org/apache/dubbo/integration/single/SingleRegistryCenterDubboProtocolIntegrationTest.java
@@ -228,7 +228,7 @@ public class 
SingleRegistryCenterDubboProtocolIntegrationTest implements Integra
         Assertions.assertTrue(services.contains(PROVIDER_APPLICATION_NAME));
 
         // obtain InMemoryWritableMetadataService instance
-        InMemoryWritableMetadataService inMemoryWritableMetadataService = 
(InMemoryWritableMetadataService) WritableMetadataService.getDefaultExtension();
+        InMemoryWritableMetadataService inMemoryWritableMetadataService = 
(InMemoryWritableMetadataService) 
WritableMetadataService.getDefaultExtension(serviceConfig.getScopeModel());
         // Exported url is right or not in InMemoryWritableMetadataService
         
Assertions.assertEquals(inMemoryWritableMetadataService.getExportedURLs().size(),
 1);
         // MetadataInfo exists or not in InMemoryWritableMetadataService
diff --git 
a/dubbo-metadata/dubbo-metadata-api/src/main/java/org/apache/dubbo/metadata/AbstractServiceNameMapping.java
 
b/dubbo-metadata/dubbo-metadata-api/src/main/java/org/apache/dubbo/metadata/AbstractServiceNameMapping.java
index da9b8e8..366bcea 100644
--- 
a/dubbo-metadata/dubbo-metadata-api/src/main/java/org/apache/dubbo/metadata/AbstractServiceNameMapping.java
+++ 
b/dubbo-metadata/dubbo-metadata-api/src/main/java/org/apache/dubbo/metadata/AbstractServiceNameMapping.java
@@ -20,6 +20,8 @@ import org.apache.dubbo.common.URL;
 import org.apache.dubbo.common.logger.Logger;
 import org.apache.dubbo.common.logger.LoggerFactory;
 import org.apache.dubbo.common.utils.StringUtils;
+import org.apache.dubbo.rpc.model.ApplicationModel;
+import org.apache.dubbo.rpc.model.ScopeModelAware;
 
 import java.util.Set;
 import java.util.TreeSet;
@@ -33,8 +35,16 @@ import static 
org.apache.dubbo.common.constants.RegistryConstants.SUBSCRIBED_SER
 import static org.apache.dubbo.common.utils.CollectionUtils.isEmpty;
 import static org.apache.dubbo.common.utils.StringUtils.isBlank;
 
-public abstract class AbstractServiceNameMapping implements ServiceNameMapping 
{
+public abstract class AbstractServiceNameMapping implements 
ServiceNameMapping, ScopeModelAware {
     protected final Logger logger = LoggerFactory.getLogger(getClass());
+    private ApplicationModel applicationModel;
+    private WritableMetadataService metadataService;
+
+    @Override
+    public void setApplicationModel(ApplicationModel applicationModel) {
+        this.applicationModel = applicationModel;
+        metadataService = 
WritableMetadataService.getDefaultExtension(applicationModel);
+    }
 
     /**
      * Get the service names from the specified Dubbo service interface, 
group, version and protocol
@@ -61,7 +71,7 @@ public abstract class AbstractServiceNameMapping implements 
ServiceNameMapping {
         }
 
         if (isEmpty(subscribedServices)) {
-            Set<String> cachedServices = 
WritableMetadataService.getDefaultExtension().getCachedMapping(ServiceNameMapping.buildMappingKey(subscribedURL));
+            Set<String> cachedServices = 
metadataService.getCachedMapping(ServiceNameMapping.buildMappingKey(subscribedURL));
             if(!isEmpty(cachedServices)) {
                 subscribedServices.addAll(cachedServices);
             }
@@ -71,7 +81,7 @@ public abstract class AbstractServiceNameMapping implements 
ServiceNameMapping {
             Set<String> mappedServices = get(subscribedURL);
             logger.info(subscribedURL.getServiceInterface() + " mapping to " + 
mappedServices + " instructed by remote metadata center.");
             subscribedServices.addAll(mappedServices);
-            
WritableMetadataService.getDefaultExtension().putCachedMapping(ServiceNameMapping.buildMappingKey(subscribedURL),
 subscribedServices);
+            
metadataService.putCachedMapping(ServiceNameMapping.buildMappingKey(subscribedURL),
 subscribedServices);
         }
         return subscribedServices;
     }
@@ -97,7 +107,7 @@ public abstract class AbstractServiceNameMapping implements 
ServiceNameMapping {
             }
         }
 
-        
WritableMetadataService.getDefaultExtension().putCachedMapping(ServiceNameMapping.buildMappingKey(subscribedURL),
 subscribedServices);
+        
metadataService.putCachedMapping(ServiceNameMapping.buildMappingKey(subscribedURL),
 subscribedServices);
 
         return subscribedServices;
     }
diff --git 
a/dubbo-metadata/dubbo-metadata-api/src/main/java/org/apache/dubbo/metadata/ServiceNameMapping.java
 
b/dubbo-metadata/dubbo-metadata-api/src/main/java/org/apache/dubbo/metadata/ServiceNameMapping.java
index 13626be..42bddb7 100644
--- 
a/dubbo-metadata/dubbo-metadata-api/src/main/java/org/apache/dubbo/metadata/ServiceNameMapping.java
+++ 
b/dubbo-metadata/dubbo-metadata-api/src/main/java/org/apache/dubbo/metadata/ServiceNameMapping.java
@@ -27,6 +27,7 @@ import java.util.Set;
 import static java.util.Collections.emptySet;
 import static 
org.apache.dubbo.common.constants.CommonConstants.COMMA_SEPARATOR;
 import static 
org.apache.dubbo.common.extension.ExtensionLoader.getExtensionLoader;
+import static org.apache.dubbo.common.extension.ExtensionScope.APPLICATION;
 import static org.apache.dubbo.common.utils.StringUtils.SLASH;
 
 /**
@@ -34,7 +35,7 @@ import static org.apache.dubbo.common.utils.StringUtils.SLASH;
  *
  * @since 2.7.5
  */
-@SPI("metadata")
+@SPI(value = "metadata", scope = APPLICATION)
 public interface ServiceNameMapping {
 
     String DEFAULT_MAPPING_GROUP = "mapping";
diff --git 
a/dubbo-metadata/dubbo-metadata-api/src/main/java/org/apache/dubbo/metadata/WritableMetadataService.java
 
b/dubbo-metadata/dubbo-metadata-api/src/main/java/org/apache/dubbo/metadata/WritableMetadataService.java
index e692658..799d3de 100644
--- 
a/dubbo-metadata/dubbo-metadata-api/src/main/java/org/apache/dubbo/metadata/WritableMetadataService.java
+++ 
b/dubbo-metadata/dubbo-metadata-api/src/main/java/org/apache/dubbo/metadata/WritableMetadataService.java
@@ -17,6 +17,7 @@
 package org.apache.dubbo.metadata;
 
 import org.apache.dubbo.common.URL;
+import org.apache.dubbo.common.extension.ExtensionAccessor;
 import org.apache.dubbo.common.extension.ExtensionLoader;
 import org.apache.dubbo.common.extension.ExtensionScope;
 import org.apache.dubbo.common.extension.SPI;
@@ -25,8 +26,6 @@ import org.apache.dubbo.rpc.model.ApplicationModel;
 import java.util.Map;
 import java.util.Set;
 
-import static 
org.apache.dubbo.common.extension.ExtensionLoader.getExtensionLoader;
-
 /**
  * Local {@link MetadataService} that extends {@link MetadataService} and 
provides the modification, which is used for
  * Dubbo's consumers and providers.
@@ -104,7 +103,7 @@ public interface WritableMetadataService extends 
MetadataService {
      *
      * @return non-null
      */
-    static WritableMetadataService getDefaultExtension() {
-        return 
getExtensionLoader(WritableMetadataService.class).getDefaultExtension();
+    static WritableMetadataService getDefaultExtension(ExtensionAccessor 
extensionAccessor) {
+        return 
extensionAccessor.getExtensionLoader(WritableMetadataService.class).getDefaultExtension();
     }
 }
diff --git 
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
index 8c4ac5c..7c5f764 100644
--- 
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
@@ -19,7 +19,7 @@ package org.apache.dubbo.registry.client;
 import org.apache.dubbo.metadata.MetadataInfo;
 
 import com.alibaba.fastjson.JSON;
-import org.apache.dubbo.rpc.model.ScopeModel;
+import org.apache.dubbo.rpc.model.ApplicationModel;
 
 import java.util.HashMap;
 import java.util.List;
@@ -213,13 +213,13 @@ public class DefaultServiceInstance implements 
ServiceInstance {
     }
 
     @Override
-    public void setScopeModel(ScopeModel scopeModel) {
-        this.attributes.put(SCOPE_MODEL,scopeModel);
+    public void setApplicationModel(ApplicationModel applicationModel) {
+        this.attributes.put(SCOPE_MODEL, applicationModel);
     }
 
     @Override
-    public ScopeModel getScopeModel() {
-        return (ScopeModel) this.attributes.get(SCOPE_MODEL);
+    public ApplicationModel getApplicationModel() {
+        return (ApplicationModel) this.attributes.get(SCOPE_MODEL);
     }
 
     public void setMetadata(Map<String, String> metadata) {
diff --git 
a/dubbo-registry/dubbo-registry-api/src/main/java/org/apache/dubbo/registry/client/RegistryClusterIdentifier.java
 
b/dubbo-registry/dubbo-registry-api/src/main/java/org/apache/dubbo/registry/client/RegistryClusterIdentifier.java
index 9d0e4a0..e44a5fd 100644
--- 
a/dubbo-registry/dubbo-registry-api/src/main/java/org/apache/dubbo/registry/client/RegistryClusterIdentifier.java
+++ 
b/dubbo-registry/dubbo-registry-api/src/main/java/org/apache/dubbo/registry/client/RegistryClusterIdentifier.java
@@ -30,7 +30,7 @@ public interface RegistryClusterIdentifier {
 
     static RegistryClusterIdentifier getExtension(URL url) {
         ExtensionLoader<RegistryClusterIdentifier> loader
-                = 
ExtensionLoader.getExtensionLoader(RegistryClusterIdentifier.class);
+                = 
url.getScopeModel().getExtensionLoader(RegistryClusterIdentifier.class);
         return loader.getExtension(url.getParameter(REGISTRY_CLUSTER_TYPE_KEY, 
"default"));
     }
 }
diff --git 
a/dubbo-registry/dubbo-registry-api/src/main/java/org/apache/dubbo/registry/client/SelfHostMetaServiceDiscovery.java
 
b/dubbo-registry/dubbo-registry-api/src/main/java/org/apache/dubbo/registry/client/SelfHostMetaServiceDiscovery.java
index f41fc7e..0ebdd45 100644
--- 
a/dubbo-registry/dubbo-registry-api/src/main/java/org/apache/dubbo/registry/client/SelfHostMetaServiceDiscovery.java
+++ 
b/dubbo-registry/dubbo-registry-api/src/main/java/org/apache/dubbo/registry/client/SelfHostMetaServiceDiscovery.java
@@ -35,6 +35,7 @@ import org.apache.dubbo.rpc.RpcException;
 import org.apache.dubbo.rpc.model.ApplicationModel;
 
 import com.alibaba.fastjson.JSONObject;
+import org.apache.dubbo.rpc.model.ScopeModelAware;
 
 import java.util.HashSet;
 import java.util.Iterator;
@@ -47,7 +48,7 @@ import java.util.concurrent.Executors;
 import java.util.concurrent.ScheduledExecutorService;
 import java.util.concurrent.TimeUnit;
 
-public abstract class SelfHostMetaServiceDiscovery implements ServiceDiscovery 
{
+public abstract class SelfHostMetaServiceDiscovery implements 
ServiceDiscovery, ScopeModelAware {
 
     private volatile boolean isDestroy;
 
@@ -96,6 +97,15 @@ public abstract class SelfHostMetaServiceDiscovery 
implements ServiceDiscovery {
      * Value - a revision calculate from {@link List} of {@link 
ServiceInstance}
      */
     private final ConcurrentHashMap<String, String> serviceInstanceRevisionMap 
= new ConcurrentHashMap<>();
+    private ApplicationModel applicationModel;
+    private WritableMetadataService metadataService;
+
+    @Override
+    public void setApplicationModel(ApplicationModel applicationModel) {
+        this.applicationModel = applicationModel;
+        metadataService = 
WritableMetadataService.getDefaultExtension(applicationModel);
+
+    }
 
     @Override
     public void initialize(URL registryURL) throws Exception {
@@ -106,7 +116,6 @@ public abstract class SelfHostMetaServiceDiscovery 
implements ServiceDiscovery {
         // Echo check: test if consumer is offline, remove 
MetadataChangeListener,
         // reduce the probability of failure when metadata update
         echoCheckExecutor.scheduleAtFixedRate(() -> {
-            WritableMetadataService metadataService = 
WritableMetadataService.getDefaultExtension();
             Map<String, InstanceMetadataChangedListener> listenerMap = 
metadataService.getInstanceMetadataChangedListenerMap();
             Iterator<Map.Entry<String, InstanceMetadataChangedListener>> 
iterator = listenerMap.entrySet().iterator();
 
@@ -139,7 +148,6 @@ public abstract class SelfHostMetaServiceDiscovery 
implements ServiceDiscovery {
     }
 
     private void updateMetadata(ServiceInstance serviceInstance) {
-        WritableMetadataService metadataService = 
WritableMetadataService.getDefaultExtension();
         String metadataString = 
JSONObject.toJSONString(serviceInstance.getMetadata());
         String metadataRevision = RevisionResolver.calRevision(metadataString);
 
@@ -196,7 +204,6 @@ public abstract class SelfHostMetaServiceDiscovery 
implements ServiceDiscovery {
         this.serviceInstance = null;
 
         // notify empty message to consumer
-        WritableMetadataService metadataService = 
WritableMetadataService.getDefaultExtension();
         metadataService.exportInstanceMetadata("");
         
metadataService.getInstanceMetadataChangedListenerMap().forEach((consumerId, 
listener) -> listener.onEvent(""));
         metadataService.getInstanceMetadataChangedListenerMap().clear();
diff --git 
a/dubbo-registry/dubbo-registry-api/src/main/java/org/apache/dubbo/registry/client/ServiceDiscovery.java
 
b/dubbo-registry/dubbo-registry-api/src/main/java/org/apache/dubbo/registry/client/ServiceDiscovery.java
index d97f66b..5569835 100644
--- 
a/dubbo-registry/dubbo-registry-api/src/main/java/org/apache/dubbo/registry/client/ServiceDiscovery.java
+++ 
b/dubbo-registry/dubbo-registry-api/src/main/java/org/apache/dubbo/registry/client/ServiceDiscovery.java
@@ -35,13 +35,14 @@ import java.util.stream.Stream;
 import static java.util.Collections.unmodifiableList;
 import static java.util.Collections.unmodifiableMap;
 import static 
org.apache.dubbo.common.constants.CommonConstants.REGISTRY_DELAY_NOTIFICATION_KEY;
+import static org.apache.dubbo.common.extension.ExtensionScope.APPLICATION;
 
 /**
  * The common operations of Service Discovery
  *
  * @since 2.7.5
  */
-@SPI("zookeeper")
+@SPI(value = "zookeeper", scope = APPLICATION)
 public interface ServiceDiscovery extends Prioritized {
 
     // ==================================== Lifecycle 
==================================== //
diff --git 
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
index bbe98a3..44357c7 100644
--- 
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,7 +102,7 @@ public class ServiceDiscoveryRegistry implements Registry {
     public ServiceDiscoveryRegistry(URL registryURL) {
         this.registryURL = registryURL;
         this.serviceDiscovery = createServiceDiscovery(registryURL);
-        this.writableMetadataService = 
WritableMetadataService.getDefaultExtension();
+        this.writableMetadataService = 
WritableMetadataService.getDefaultExtension(registryURL.getScopeModel());
     }
 
     public ServiceDiscovery getServiceDiscovery() {
@@ -437,14 +437,14 @@ public class ServiceDiscoveryRegistry implements Registry 
{
             }
 
             if (CollectionUtils.isEmpty(tempOldApps) && newApps.size() > 0) {
-                
WritableMetadataService.getDefaultExtension().putCachedMapping(ServiceNameMapping.buildMappingKey(url),
 newApps);
+                
writableMetadataService.putCachedMapping(ServiceNameMapping.buildMappingKey(url),
 newApps);
                 subscribeURLs(url, listener, newApps);
                 return;
             }
 
             for (String newAppName : newApps) {
                 if (!tempOldApps.contains(newAppName)) {
-                    
WritableMetadataService.getDefaultExtension().putCachedMapping(ServiceNameMapping.buildMappingKey(url),
 newApps);
+                    
writableMetadataService.putCachedMapping(ServiceNameMapping.buildMappingKey(url),
 newApps);
                     subscribeURLs(url, listener, newApps);
                     return;
                 }
diff --git 
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
index 828a988..4272888 100644
--- 
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
@@ -48,28 +48,32 @@ import static 
org.apache.dubbo.common.constants.RegistryConstants.EMPTY_PROTOCOL
 import static 
org.apache.dubbo.common.constants.RegistryConstants.REGISTRY_TYPE_KEY;
 import static 
org.apache.dubbo.common.constants.RegistryConstants.SERVICE_REGISTRY_TYPE;
 import static org.apache.dubbo.registry.Constants.CONFIGURATORS_SUFFIX;
+import static org.apache.dubbo.rpc.model.ScopeModelUtil.getApplicationModel;
 
 public class ServiceDiscoveryRegistryDirectory<T> extends DynamicDirectory<T> {
     private static final Logger logger = 
LoggerFactory.getLogger(ServiceDiscoveryRegistryDirectory.class);
 
     // instance address to invoker mapping.
     private volatile Map<String, Invoker<T>> urlInvokerMap; // The initial 
value is null and the midway may be assigned to null, please use the local 
variable reference
-    private final static ConsumerConfigurationListener 
CONSUMER_CONFIGURATION_LISTENER = new ConsumerConfigurationListener();
+    private final ConsumerConfigurationListener consumerConfigurationListener;
     private volatile ReferenceConfigurationListener 
referenceConfigurationListener;
     private volatile boolean enableConfigurationListen = true;
     private volatile List<URL> originalUrls = null; // initial for null
     private volatile Map<String, String> overrideQueryMap;
+    private final ApplicationModel applicationModel;
 
     public ServiceDiscoveryRegistryDirectory(Class<T> serviceType, URL url) {
         super(serviceType, url);
+        applicationModel = getApplicationModel(url.getScopeModel());
+        consumerConfigurationListener = new 
ConsumerConfigurationListener(applicationModel);
     }
 
     @Override
     public void subscribe(URL url) {
-        if 
(ApplicationModel.defaultModel().getEnvironment().getConfiguration().convert(Boolean.class,
 Constants.ENABLE_CONFIGURATION_LISTEN, true)) {
+        if 
(applicationModel.getEnvironment().getConfiguration().convert(Boolean.class, 
Constants.ENABLE_CONFIGURATION_LISTEN, true)) {
             enableConfigurationListen = true;
-            CONSUMER_CONFIGURATION_LISTENER.addNotifyListener(this);
-            referenceConfigurationListener = new 
ReferenceConfigurationListener(this, url);
+            consumerConfigurationListener.addNotifyListener(this);
+            referenceConfigurationListener = new 
ReferenceConfigurationListener(this.applicationModel, this, url);
         } else {
             enableConfigurationListen = false;
         }
@@ -80,8 +84,8 @@ public class ServiceDiscoveryRegistryDirectory<T> extends 
DynamicDirectory<T> {
     public void unSubscribe(URL url) {
         super.unSubscribe(url);
         this.originalUrls = null;
-        if 
(ApplicationModel.defaultModel().getEnvironment().getConfiguration().convert(Boolean.class,
 Constants.ENABLE_CONFIGURATION_LISTEN, true)) {
-            CONSUMER_CONFIGURATION_LISTENER.removeNotifyListener(this);
+        if 
(applicationModel.getEnvironment().getConfiguration().convert(Boolean.class, 
Constants.ENABLE_CONFIGURATION_LISTEN, true)) {
+            consumerConfigurationListener.removeNotifyListener(this);
             referenceConfigurationListener.stop();
         }
     }
@@ -142,7 +146,7 @@ public class ServiceDiscoveryRegistryDirectory<T> extends 
DynamicDirectory<T> {
     private void overrideDirectoryUrl() {
         // merge override parameters
         this.overrideDirectoryUrl = directoryUrl;
-        List<Configurator> localAppDynamicConfigurators = 
CONSUMER_CONFIGURATION_LISTENER.getConfigurators(); // local reference
+        List<Configurator> localAppDynamicConfigurators = 
consumerConfigurationListener.getConfigurators(); // local reference
         doOverrideUrl(localAppDynamicConfigurators);
         if (referenceConfigurationListener != null) {
             List<Configurator> localDynamicConfigurators = 
referenceConfigurationListener.getConfigurators(); // local reference
@@ -163,7 +167,7 @@ public class ServiceDiscoveryRegistryDirectory<T> extends 
DynamicDirectory<T> {
 
     private InstanceAddressURL overrideWithConfigurator(InstanceAddressURL 
providerUrl) {
         // override url with configurator from configurator from 
"app-name.configurators"
-        providerUrl = 
overrideWithConfigurators(CONSUMER_CONFIGURATION_LISTENER.getConfigurators(), 
providerUrl);
+        providerUrl = 
overrideWithConfigurators(consumerConfigurationListener.getConfigurators(), 
providerUrl);
 
         // override url with configurator from configurators from 
"service-name.configurators"
         if (referenceConfigurationListener != null) {
@@ -387,11 +391,12 @@ public class ServiceDiscoveryRegistryDirectory<T> extends 
DynamicDirectory<T> {
         logger.info(oldUrlInvokerMap.size() + " deprecated invokers deleted.");
     }
 
-    private static class ReferenceConfigurationListener extends 
AbstractConfiguratorListener {
+    private class ReferenceConfigurationListener extends 
AbstractConfiguratorListener {
         private final ServiceDiscoveryRegistryDirectory<?> directory;
         private final URL url;
 
-        ReferenceConfigurationListener(ServiceDiscoveryRegistryDirectory<?> 
directory, URL url) {
+        ReferenceConfigurationListener(ApplicationModel applicationModel, 
ServiceDiscoveryRegistryDirectory<?> directory, URL url) {
+            super(applicationModel);
             this.directory = directory;
             this.url = url;
             this.initWith(DynamicConfiguration.getRuleKey(url) + 
CONFIGURATORS_SUFFIX);
@@ -413,15 +418,16 @@ public class ServiceDiscoveryRegistryDirectory<T> extends 
DynamicDirectory<T> {
         }
     }
 
-    private static class ConsumerConfigurationListener extends 
AbstractConfiguratorListener {
+    private class ConsumerConfigurationListener extends 
AbstractConfiguratorListener {
         private final List<ServiceDiscoveryRegistryDirectory<?>> listeners = 
new ArrayList<>();
 
-        ConsumerConfigurationListener() {
+        ConsumerConfigurationListener(ApplicationModel applicationModel) {
+            super(applicationModel);
         }
 
         void addNotifyListener(ServiceDiscoveryRegistryDirectory<?> listener) {
             if (listeners.size() == 0) {
-                this.initWith(ApplicationModel.defaultModel().getName() + 
CONFIGURATORS_SUFFIX);
+                this.initWith(applicationModel.getName() + 
CONFIGURATORS_SUFFIX);
             }
             this.listeners.add(listener);
         }
@@ -429,7 +435,7 @@ public class ServiceDiscoveryRegistryDirectory<T> extends 
DynamicDirectory<T> {
         void removeNotifyListener(ServiceDiscoveryRegistryDirectory<?> 
listener) {
             this.listeners.remove(listener);
             if (listeners.size() == 0) {
-                this.stopListen(ApplicationModel.defaultModel().getName() + 
CONFIGURATORS_SUFFIX);
+                this.stopListen(applicationModel.getName() + 
CONFIGURATORS_SUFFIX);
             }
         }
 
diff --git 
a/dubbo-registry/dubbo-registry-api/src/main/java/org/apache/dubbo/registry/client/ServiceInstance.java
 
b/dubbo-registry/dubbo-registry-api/src/main/java/org/apache/dubbo/registry/client/ServiceInstance.java
index 5192b17..9b442ac 100644
--- 
a/dubbo-registry/dubbo-registry-api/src/main/java/org/apache/dubbo/registry/client/ServiceInstance.java
+++ 
b/dubbo-registry/dubbo-registry-api/src/main/java/org/apache/dubbo/registry/client/ServiceInstance.java
@@ -16,7 +16,7 @@
  */
 package org.apache.dubbo.registry.client;
 
-import org.apache.dubbo.rpc.model.ScopeModel;
+import org.apache.dubbo.rpc.model.ApplicationModel;
 
 import java.io.Serializable;
 import java.util.Map;
@@ -92,9 +92,9 @@ public interface ServiceInstance extends Serializable {
 
     Map<String, Object> getAttributes();
 
-    void setScopeModel(ScopeModel scopeModel);
+    void setApplicationModel(ApplicationModel applicationModel);
 
-    ScopeModel getScopeModel();
+    ApplicationModel getApplicationModel();
 
     /**
      * Get the value of metadata by the specified name
diff --git 
a/dubbo-registry/dubbo-registry-api/src/main/java/org/apache/dubbo/registry/client/ServiceInstanceCustomizer.java
 
b/dubbo-registry/dubbo-registry-api/src/main/java/org/apache/dubbo/registry/client/ServiceInstanceCustomizer.java
index 99cffc1..e91b166 100644
--- 
a/dubbo-registry/dubbo-registry-api/src/main/java/org/apache/dubbo/registry/client/ServiceInstanceCustomizer.java
+++ 
b/dubbo-registry/dubbo-registry-api/src/main/java/org/apache/dubbo/registry/client/ServiceInstanceCustomizer.java
@@ -19,13 +19,15 @@ package org.apache.dubbo.registry.client;
 import org.apache.dubbo.common.extension.SPI;
 import org.apache.dubbo.common.lang.Prioritized;
 
+import static org.apache.dubbo.common.extension.ExtensionScope.APPLICATION;
+
 /**
  * The interface to customize {@link ServiceInstance the service instance}
  *
  * @see ServiceInstance#getMetadata()
  * @since 2.7.5
  */
-@SPI
+@SPI(scope = APPLICATION)
 public interface ServiceInstanceCustomizer extends Prioritized {
 
     /**
diff --git 
a/dubbo-registry/dubbo-registry-api/src/main/java/org/apache/dubbo/registry/client/event/listener/ServiceInstancesChangedListener.java
 
b/dubbo-registry/dubbo-registry-api/src/main/java/org/apache/dubbo/registry/client/event/listener/ServiceInstancesChangedListener.java
index b83915d..e1fa0ca 100644
--- 
a/dubbo-registry/dubbo-registry-api/src/main/java/org/apache/dubbo/registry/client/event/listener/ServiceInstancesChangedListener.java
+++ 
b/dubbo-registry/dubbo-registry-api/src/main/java/org/apache/dubbo/registry/client/event/listener/ServiceInstancesChangedListener.java
@@ -330,7 +330,7 @@ public class ServiceInstancesChangedListener {
                 logger.debug("Instance " + instance.getAddress() + " is using 
metadata type " + metadataType);
             }
             if (REMOTE_METADATA_STORAGE_TYPE.equals(metadataType)) {
-                RemoteMetadataServiceImpl remoteMetadataService = 
MetadataUtils.getRemoteMetadataService(instance.getScopeModel());
+                RemoteMetadataServiceImpl remoteMetadataService = 
MetadataUtils.getRemoteMetadataService(instance.getApplicationModel());
                 metadataInfo = remoteMetadataService.getMetadata(instance);
             } else {
                 // change the instance used to communicate to avoid all 
requests route to the same instance
diff --git 
a/dubbo-registry/dubbo-registry-api/src/main/java/org/apache/dubbo/registry/client/metadata/MetadataServiceURLParamsMetadataCustomizer.java
 
b/dubbo-registry/dubbo-registry-api/src/main/java/org/apache/dubbo/registry/client/metadata/MetadataServiceURLParamsMetadataCustomizer.java
index e04aff4..dc21c3b 100644
--- 
a/dubbo-registry/dubbo-registry-api/src/main/java/org/apache/dubbo/registry/client/metadata/MetadataServiceURLParamsMetadataCustomizer.java
+++ 
b/dubbo-registry/dubbo-registry-api/src/main/java/org/apache/dubbo/registry/client/metadata/MetadataServiceURLParamsMetadataCustomizer.java
@@ -23,7 +23,6 @@ import 
org.apache.dubbo.registry.client.ServiceInstanceCustomizer;
 import java.util.Map;
 
 import static org.apache.dubbo.common.utils.StringUtils.isBlank;
-import static 
org.apache.dubbo.metadata.WritableMetadataService.getDefaultExtension;
 import static 
org.apache.dubbo.registry.client.metadata.ServiceInstanceMetadataUtils.METADATA_SERVICE_URL_PARAMS_PROPERTY_NAME;
 import static 
org.apache.dubbo.registry.client.metadata.ServiceInstanceMetadataUtils.getMetadataServiceParameter;
 
@@ -47,7 +46,7 @@ public class MetadataServiceURLParamsMetadataCustomizer 
implements ServiceInstan
     }
 
     private String resolveMetadataPropertyValue(ServiceInstance 
serviceInstance) {
-        WritableMetadataService writableMetadataService = 
getDefaultExtension();
+        WritableMetadataService writableMetadataService = 
WritableMetadataService.getDefaultExtension(serviceInstance.getApplicationModel());
         return 
getMetadataServiceParameter(writableMetadataService.getMetadataServiceURL());
     }
 }
diff --git 
a/dubbo-registry/dubbo-registry-api/src/main/java/org/apache/dubbo/registry/client/metadata/MetadataUtils.java
 
b/dubbo-registry/dubbo-registry-api/src/main/java/org/apache/dubbo/registry/client/metadata/MetadataUtils.java
index 6468efa..df1a4a7 100644
--- 
a/dubbo-registry/dubbo-registry-api/src/main/java/org/apache/dubbo/registry/client/metadata/MetadataUtils.java
+++ 
b/dubbo-registry/dubbo-registry-api/src/main/java/org/apache/dubbo/registry/client/metadata/MetadataUtils.java
@@ -58,7 +58,7 @@ public class MetadataUtils {
 
     public static void publishServiceDefinition(URL url) {
         // store in local
-        
WritableMetadataService.getDefaultExtension().publishServiceDefinition(url);
+        
WritableMetadataService.getDefaultExtension(url.getScopeModel()).publishServiceDefinition(url);
         // send to remote
         if 
(REMOTE_METADATA_STORAGE_TYPE.equalsIgnoreCase(url.getParameter(METADATA_KEY))) 
{
             
getRemoteMetadataService(url.getScopeModel()).publishServiceDefinition(url);
diff --git 
a/dubbo-registry/dubbo-registry-api/src/main/java/org/apache/dubbo/registry/client/metadata/ProtocolPortsMetadataCustomizer.java
 
b/dubbo-registry/dubbo-registry-api/src/main/java/org/apache/dubbo/registry/client/metadata/ProtocolPortsMetadataCustomizer.java
index 12099ce..ec17ae0 100644
--- 
a/dubbo-registry/dubbo-registry-api/src/main/java/org/apache/dubbo/registry/client/metadata/ProtocolPortsMetadataCustomizer.java
+++ 
b/dubbo-registry/dubbo-registry-api/src/main/java/org/apache/dubbo/registry/client/metadata/ProtocolPortsMetadataCustomizer.java
@@ -36,7 +36,7 @@ public class ProtocolPortsMetadataCustomizer implements 
ServiceInstanceCustomize
 
     @Override
     public void customize(ServiceInstance serviceInstance) {
-        WritableMetadataService writableMetadataService = 
WritableMetadataService.getDefaultExtension();
+        WritableMetadataService writableMetadataService = 
WritableMetadataService.getDefaultExtension(serviceInstance.getApplicationModel());
 
         Map<String, Integer> protocols = new HashMap<>();
         writableMetadataService.getExportedServiceURLs()
diff --git 
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
index 4786264..5a03a3a 100644
--- 
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,11 +40,12 @@ public class ServiceInstanceMetadataCustomizer implements 
ServiceInstanceCustomi
 
     @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
         Map<String, MetadataInfo> metadataInfos = 
localMetadataService.getMetadataInfos();
@@ -60,10 +61,10 @@ public class ServiceInstanceMetadataCustomizer implements 
ServiceInstanceCustomi
 
         // load instance params users want to load.
         // TODO, duplicate logic with that in ApplicationConfig
-        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.defaultModel().getName());
+            inputParameters.put(APPLICATION_KEY, applicationModel.getName());
             for (InfraAdapter adapter : adapters) {
                 Map<String, String> extraParameters = 
adapter.getExtraAttributes(inputParameters);
                 if (CollectionUtils.isNotEmptyMap(extraParameters)) {
diff --git 
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
index a23f15b..b2e19b7 100644
--- 
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
@@ -33,8 +33,6 @@ import 
org.apache.dubbo.registry.client.ServiceInstanceCustomizer;
 import 
org.apache.dubbo.registry.client.metadata.store.InMemoryWritableMetadataService;
 import 
org.apache.dubbo.registry.client.metadata.store.RemoteMetadataServiceImpl;
 import org.apache.dubbo.registry.support.AbstractRegistryFactory;
-import org.apache.dubbo.rpc.model.ApplicationModel;
-
 
 import java.util.ArrayList;
 import java.util.LinkedHashMap;
@@ -233,7 +231,7 @@ public class ServiceInstanceMetadataUtils {
         if (registryCluster == null) {
             registryCluster = DEFAULT_KEY;
         }
-        WritableMetadataService writableMetadataService = 
WritableMetadataService.getDefaultExtension();
+        WritableMetadataService writableMetadataService = 
WritableMetadataService.getDefaultExtension(instance.getApplicationModel());
         MetadataInfo metadataInfo = 
writableMetadataService.getMetadataInfos().get(registryCluster);
         if (metadataInfo == null) {
             metadataInfo = ((InMemoryWritableMetadataService) 
writableMetadataService).getDefaultMetadataInfo();
@@ -258,8 +256,8 @@ public class ServiceInstanceMetadataUtils {
     }
 
     public static void refreshMetadataAndInstance(ServiceInstance 
serviceInstance) {
-        RemoteMetadataServiceImpl remoteMetadataService = 
MetadataUtils.getRemoteMetadataService(serviceInstance.getScopeModel());
-        
remoteMetadataService.publishMetadata(ApplicationModel.defaultModel().getName());
+        RemoteMetadataServiceImpl remoteMetadataService = 
MetadataUtils.getRemoteMetadataService(serviceInstance.getApplicationModel());
+        
remoteMetadataService.publishMetadata(serviceInstance.getApplicationModel().getName());
 
         
AbstractRegistryFactory.getServiceDiscoveries().forEach(serviceDiscovery -> {
             ServiceInstance instance = serviceDiscovery.getLocalInstance();
diff --git 
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
index 17f8547..74dbee6 100644
--- 
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
@@ -32,6 +32,7 @@ import 
org.apache.dubbo.metadata.definition.ServiceDefinitionBuilder;
 import org.apache.dubbo.metadata.definition.model.ServiceDefinition;
 import org.apache.dubbo.registry.client.RegistryClusterIdentifier;
 import org.apache.dubbo.rpc.model.ApplicationModel;
+import org.apache.dubbo.rpc.model.ScopeModelAware;
 import org.apache.dubbo.rpc.support.ProtocolUtils;
 
 import com.google.gson.Gson;
@@ -74,7 +75,7 @@ import static org.apache.dubbo.rpc.Constants.GENERIC_KEY;
  * @see WritableMetadataService
  * @since 2.7.5
  */
-public class InMemoryWritableMetadataService implements 
WritableMetadataService {
+public class InMemoryWritableMetadataService implements 
WritableMetadataService, ScopeModelAware {
 
     final Logger logger = LoggerFactory.getLogger(getClass());
 
@@ -113,12 +114,18 @@ public class InMemoryWritableMetadataService implements 
WritableMetadataService
     ConcurrentNavigableMap<String, SortedSet<URL>> subscribedServiceURLs = new 
ConcurrentSkipListMap<>();
 
     ConcurrentNavigableMap<String, String> serviceDefinitions = new 
ConcurrentSkipListMap<>();
+    private ApplicationModel applicationModel;
 
     public InMemoryWritableMetadataService() {
         this.metadataInfos = new ConcurrentHashMap<>();
     }
 
     @Override
+    public void setApplicationModel(ApplicationModel applicationModel) {
+        this.applicationModel = applicationModel;
+    }
+
+    @Override
     public SortedSet<String> getSubscribedURLs() {
         return getAllUnmodifiableServiceURLs(subscribedServiceURLs);
     }
@@ -167,7 +174,7 @@ public class InMemoryWritableMetadataService implements 
WritableMetadataService
         try {
             String[] clusters = getRegistryCluster(url).split(",");
             for (String cluster : clusters) {
-                MetadataInfo metadataInfo = 
metadataInfos.computeIfAbsent(cluster, k -> new 
MetadataInfo(ApplicationModel.defaultModel().getName()));
+                MetadataInfo metadataInfo = 
metadataInfos.computeIfAbsent(cluster, k -> new 
MetadataInfo(applicationModel.getName()));
                 metadataInfo.addService(new ServiceInfo(url));
             }
             metadataSemaphore.release();
diff --git 
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
index bb44230..eefa8bb 100644
--- 
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
@@ -33,6 +33,7 @@ import 
org.apache.dubbo.registry.integration.RegistryProtocolListener;
 import org.apache.dubbo.rpc.Exporter;
 import org.apache.dubbo.rpc.cluster.ClusterInvoker;
 import org.apache.dubbo.rpc.model.ApplicationModel;
+import org.apache.dubbo.rpc.model.ScopeModelAware;
 
 import java.util.Map;
 import java.util.Objects;
@@ -47,11 +48,11 @@ import java.util.concurrent.atomic.AtomicBoolean;
 import static org.apache.dubbo.common.constants.RegistryConstants.INIT;
 
 @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.defaultModel().getName() 
+ ".migration";
+    private String ruleKey;
 
     private final Map<MigrationInvoker, MigrationRuleHandler> handlers = new 
ConcurrentHashMap<>();
     private final LinkedBlockingQueue<String> ruleQueue = new 
LinkedBlockingQueue<>();
@@ -63,15 +64,26 @@ public class MigrationRuleListener implements 
RegistryProtocolListener, Configur
 
     private volatile String rawRule;
     private volatile MigrationRule rule;
+    private ApplicationModel applicationModel;
 
     public MigrationRuleListener() {
-        this.configuration = 
ApplicationModel.defaultModel().getEnvironment().getDynamicConfiguration().orElse(null);
+    }
+
+    @Override
+    public void setApplicationModel(ApplicationModel applicationModel) {
+        this.applicationModel = applicationModel;
+        init();
+    }
+
+    private void init() {
+        this.ruleKey = applicationModel.getName() + ".migration";
+        this.configuration = 
applicationModel.getEnvironment().getDynamicConfiguration().orElse(null);
 
         if (this.configuration != null) {
-            logger.info("Listening for migration rules on dataId " + RULE_KEY 
+ ", group " + DUBBO_SERVICEDISCOVERY_MIGRATION);
-            configuration.addListener(RULE_KEY, 
DUBBO_SERVICEDISCOVERY_MIGRATION, this);
+            logger.info("Listening for migration rules on dataId " + ruleKey + 
", group " + DUBBO_SERVICEDISCOVERY_MIGRATION);
+            configuration.addListener(ruleKey, 
DUBBO_SERVICEDISCOVERY_MIGRATION, this);
 
-            String rawRule = configuration.getConfig(RULE_KEY, 
DUBBO_SERVICEDISCOVERY_MIGRATION);
+            String rawRule = configuration.getConfig(ruleKey, 
DUBBO_SERVICEDISCOVERY_MIGRATION);
             if (StringUtils.isEmpty(rawRule)) {
                 rawRule = INIT;
             }
@@ -83,7 +95,7 @@ public class MigrationRuleListener implements 
RegistryProtocolListener, Configur
             setRawRule(INIT);
         }
 
-        String localRawRule = 
ApplicationModel.defaultModel().getEnvironment().getLocalMigrationRule();
+        String localRawRule = 
applicationModel.getEnvironment().getLocalMigrationRule();
         if (!StringUtils.isEmpty(localRawRule)) {
             Executors.newSingleThreadScheduledExecutor(new 
NamedThreadFactory("DubboMigrationRuleDelayWorker", true))
                 .schedule(() -> {
@@ -214,7 +226,7 @@ public class MigrationRuleListener implements 
RegistryProtocolListener, Configur
     @Override
     public void onDestroy() {
         if (configuration != null) {
-            configuration.removeListener(RULE_KEY, this);
+            configuration.removeListener(ruleKey, this);
         }
     }
 
diff --git 
a/dubbo-registry/dubbo-registry-api/src/main/java/org/apache/dubbo/registry/integration/AbstractConfiguratorListener.java
 
b/dubbo-registry/dubbo-registry-api/src/main/java/org/apache/dubbo/registry/integration/AbstractConfiguratorListener.java
index 1e2d0fd..87abfc7 100644
--- 
a/dubbo-registry/dubbo-registry-api/src/main/java/org/apache/dubbo/registry/integration/AbstractConfiguratorListener.java
+++ 
b/dubbo-registry/dubbo-registry-api/src/main/java/org/apache/dubbo/registry/integration/AbstractConfiguratorListener.java
@@ -21,13 +21,13 @@ import 
org.apache.dubbo.common.config.configcenter.ConfigChangeType;
 import org.apache.dubbo.common.config.configcenter.ConfigChangedEvent;
 import org.apache.dubbo.common.config.configcenter.ConfigurationListener;
 import org.apache.dubbo.common.config.configcenter.DynamicConfiguration;
-import org.apache.dubbo.common.extension.ExtensionLoader;
 import org.apache.dubbo.common.logger.Logger;
 import org.apache.dubbo.common.logger.LoggerFactory;
 import org.apache.dubbo.common.utils.StringUtils;
 import org.apache.dubbo.rpc.cluster.Configurator;
 import org.apache.dubbo.rpc.cluster.configurator.parser.ConfigParser;
 import org.apache.dubbo.rpc.cluster.governance.GovernanceRuleRepository;
+import org.apache.dubbo.rpc.model.ApplicationModel;
 
 import java.util.Collections;
 import java.util.HashSet;
@@ -48,12 +48,21 @@ public abstract class AbstractConfiguratorListener 
implements ConfigurationListe
     private static final Logger logger = 
LoggerFactory.getLogger(AbstractConfiguratorListener.class);
 
     protected List<Configurator> configurators = Collections.emptyList();
-    protected GovernanceRuleRepository ruleRepository = 
ExtensionLoader.getExtensionLoader(
-            GovernanceRuleRepository.class).getDefaultExtension();
+    protected GovernanceRuleRepository ruleRepository;
 
     protected Set<String> securityKey = new HashSet<>();
+    protected ApplicationModel applicationModel;
+
+    public AbstractConfiguratorListener(ApplicationModel applicationModel) {
+        this.applicationModel = applicationModel;
+
+        ruleRepository = applicationModel.getExtensionLoader(
+            GovernanceRuleRepository.class).getDefaultExtension();
+
+        initSecurityKey();
+    }
 
-    {
+    private void initSecurityKey() {
         // accessLogKey and FileRouterFactory key
         securityKey.add(ACCESS_LOG_KEY);
         securityKey.add(ROUTER_KEY);
diff --git 
a/dubbo-registry/dubbo-registry-api/src/main/java/org/apache/dubbo/registry/integration/RegistryDirectory.java
 
b/dubbo-registry/dubbo-registry-api/src/main/java/org/apache/dubbo/registry/integration/RegistryDirectory.java
index 53bcf1b..77f472b 100644
--- 
a/dubbo-registry/dubbo-registry-api/src/main/java/org/apache/dubbo/registry/integration/RegistryDirectory.java
+++ 
b/dubbo-registry/dubbo-registry-api/src/main/java/org/apache/dubbo/registry/integration/RegistryDirectory.java
@@ -78,6 +78,7 @@ import static 
org.apache.dubbo.registry.integration.InterfaceCompatibleRegistryP
 import static org.apache.dubbo.remoting.Constants.CHECK_KEY;
 import static org.apache.dubbo.rpc.Constants.MOCK_KEY;
 import static org.apache.dubbo.rpc.cluster.Constants.ROUTER_KEY;
+import static org.apache.dubbo.rpc.model.ScopeModelUtil.getApplicationModel;
 
 
 /**
@@ -86,7 +87,7 @@ import static 
org.apache.dubbo.rpc.cluster.Constants.ROUTER_KEY;
 public class RegistryDirectory<T> extends DynamicDirectory<T> {
     private static final Logger logger = 
LoggerFactory.getLogger(RegistryDirectory.class);
 
-    private static final ConsumerConfigurationListener 
CONSUMER_CONFIGURATION_LISTENER = new ConsumerConfigurationListener();
+    private final ConsumerConfigurationListener consumerConfigurationListener;
     private ReferenceConfigurationListener referenceConfigurationListener;
 
     // Map<url, Invoker> cache service url to invoker mapping.
@@ -94,23 +95,26 @@ public class RegistryDirectory<T> extends 
DynamicDirectory<T> {
     protected volatile Map<URL, Invoker<T>> urlInvokerMap;
     // The initial value is null and the midway may be assigned to null, 
please use the local variable reference
     protected volatile Set<URL> cachedInvokerUrls;
+    private final ApplicationModel applicationModel;
 
     public RegistryDirectory(Class<T> serviceType, URL url) {
         super(serviceType, url);
+        applicationModel = getApplicationModel(url.getScopeModel());
+        consumerConfigurationListener = new 
ConsumerConfigurationListener(applicationModel);
     }
 
     @Override
     public void subscribe(URL url) {
         setSubscribeUrl(url);
-        CONSUMER_CONFIGURATION_LISTENER.addNotifyListener(this);
-        referenceConfigurationListener = new 
ReferenceConfigurationListener(this, url);
+        consumerConfigurationListener.addNotifyListener(this);
+        referenceConfigurationListener = new 
ReferenceConfigurationListener(applicationModel, this, url);
         registry.subscribe(url, this);
     }
 
     @Override
     public void unSubscribe(URL url) {
         setSubscribeUrl(null);
-        CONSUMER_CONFIGURATION_LISTENER.removeNotifyListener(this);
+        consumerConfigurationListener.removeNotifyListener(this);
         referenceConfigurationListener.stop();
         registry.unsubscribe(url, this);
     }
@@ -408,7 +412,7 @@ public class RegistryDirectory<T> extends 
DynamicDirectory<T> {
         providerUrl = overrideWithConfigurators(this.configurators, 
providerUrl);
 
         // override url with configurator from configurator from 
"app-name.configurators"
-        providerUrl = 
overrideWithConfigurators(CONSUMER_CONFIGURATION_LISTENER.getConfigurators(), 
providerUrl);
+        providerUrl = 
overrideWithConfigurators(consumerConfigurationListener.getConfigurators(), 
providerUrl);
 
         // override url with configurator from configurators from 
"service-name.configurators"
         if (referenceConfigurationListener != null) {
@@ -592,7 +596,7 @@ public class RegistryDirectory<T> extends 
DynamicDirectory<T> {
         this.overrideDirectoryUrl = directoryUrl;
         List<Configurator> localConfigurators = this.configurators; // local 
reference
         doOverrideUrl(localConfigurators);
-        List<Configurator> localAppDynamicConfigurators = 
CONSUMER_CONFIGURATION_LISTENER.getConfigurators(); // local reference
+        List<Configurator> localAppDynamicConfigurators = 
consumerConfigurationListener.getConfigurators(); // local reference
         doOverrideUrl(localAppDynamicConfigurators);
         if (referenceConfigurationListener != null) {
             List<Configurator> localDynamicConfigurators = 
referenceConfigurationListener.getConfigurators(); // local reference
@@ -612,7 +616,8 @@ public class RegistryDirectory<T> extends 
DynamicDirectory<T> {
         private RegistryDirectory directory;
         private URL url;
 
-        ReferenceConfigurationListener(RegistryDirectory directory, URL url) {
+        ReferenceConfigurationListener(ApplicationModel applicationModel, 
RegistryDirectory directory, URL url) {
+            super(applicationModel);
             this.directory = directory;
             this.url = url;
             this.initWith(DynamicConfiguration.getRuleKey(url) + 
CONFIGURATORS_SUFFIX);
@@ -632,8 +637,9 @@ public class RegistryDirectory<T> extends 
DynamicDirectory<T> {
     private static class ConsumerConfigurationListener extends 
AbstractConfiguratorListener {
         List<RegistryDirectory> listeners = new ArrayList<>();
 
-        ConsumerConfigurationListener() {
-            this.initWith(ApplicationModel.defaultModel().getName() + 
CONFIGURATORS_SUFFIX);
+        ConsumerConfigurationListener(ApplicationModel applicationModel) {
+            super(applicationModel);
+            this.initWith(applicationModel.getName() + CONFIGURATORS_SUFFIX);
         }
 
         void addNotifyListener(RegistryDirectory listener) {
diff --git 
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
index 0f7abe6..0d86281 100644
--- 
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
@@ -19,7 +19,6 @@ package org.apache.dubbo.registry.integration;
 import org.apache.dubbo.common.URL;
 import org.apache.dubbo.common.config.ConfigurationUtils;
 import org.apache.dubbo.common.config.configcenter.DynamicConfiguration;
-import org.apache.dubbo.common.extension.ExtensionLoader;
 import org.apache.dubbo.common.logger.Logger;
 import org.apache.dubbo.common.logger.LoggerFactory;
 import org.apache.dubbo.common.timer.HashedWheelTimer;
@@ -50,7 +49,10 @@ import org.apache.dubbo.rpc.cluster.Constants;
 import org.apache.dubbo.rpc.cluster.governance.GovernanceRuleRepository;
 import org.apache.dubbo.rpc.cluster.support.MergeableCluster;
 import org.apache.dubbo.rpc.model.ApplicationModel;
+import org.apache.dubbo.rpc.model.FrameworkModel;
 import org.apache.dubbo.rpc.model.ProviderModel;
+import org.apache.dubbo.rpc.model.ScopeModel;
+import org.apache.dubbo.rpc.model.ScopeModelAware;
 import org.apache.dubbo.rpc.protocol.InvokerWrapper;
 import org.apache.dubbo.rpc.support.ProtocolUtils;
 
@@ -91,11 +93,11 @@ import static 
org.apache.dubbo.common.constants.RegistryConstants.CATEGORY_KEY;
 import static 
org.apache.dubbo.common.constants.RegistryConstants.CONFIGURATORS_CATEGORY;
 import static 
org.apache.dubbo.common.constants.RegistryConstants.OVERRIDE_PROTOCOL;
 import static org.apache.dubbo.common.constants.RegistryConstants.REGISTRY_KEY;
-import static 
org.apache.dubbo.common.constants.RegistryConstants.REGISTRY_PROTOCOL;
 import static 
org.apache.dubbo.common.constants.RegistryConstants.SERVICE_REGISTRY_PROTOCOL;
 import static org.apache.dubbo.common.utils.UrlUtils.classifyUrls;
 import static org.apache.dubbo.registry.Constants.CONFIGURATORS_SUFFIX;
 import static 
org.apache.dubbo.registry.Constants.DEFAULT_REGISTRY_RETRY_PERIOD;
+import static org.apache.dubbo.registry.Constants.ENABLE_CONFIGURATION_LISTEN;
 import static org.apache.dubbo.registry.Constants.PROVIDER_PROTOCOL;
 import static org.apache.dubbo.registry.Constants.REGISTER_IP_KEY;
 import static org.apache.dubbo.registry.Constants.REGISTER_KEY;
@@ -118,11 +120,12 @@ import static 
org.apache.dubbo.rpc.cluster.Constants.EXPORT_KEY;
 import static org.apache.dubbo.rpc.cluster.Constants.REFER_KEY;
 import static org.apache.dubbo.rpc.cluster.Constants.WARMUP_KEY;
 import static org.apache.dubbo.rpc.cluster.Constants.WEIGHT_KEY;
+import static org.apache.dubbo.rpc.model.ScopeModelUtil.getApplicationModel;
 
 /**
  * TODO, replace RegistryProtocol completely in the future.
  */
-public class RegistryProtocol implements Protocol {
+public class RegistryProtocol implements Protocol, ScopeModelAware {
     public static final String[] DEFAULT_REGISTER_PROVIDER_KEYS = {
         APPLICATION_KEY, CODEC_KEY, EXCHANGER_KEY, SERIALIZATION_KEY, 
CLUSTER_KEY, CONNECTIONS_KEY, DEPRECATED_KEY,
         GROUP_KEY, LOADBALANCE_KEY, MOCK_KEY, PATH_KEY, TIMEOUT_KEY, 
TOKEN_KEY, VERSION_KEY, WARMUP_KEY,
@@ -136,7 +139,6 @@ public class RegistryProtocol implements Protocol {
     private final static Logger logger = 
LoggerFactory.getLogger(RegistryProtocol.class);
     private final Map<URL, NotifyListener> overrideListeners = new 
ConcurrentHashMap<>();
     private final Map<String, ServiceConfigurationListener> 
serviceConfigurationListeners = new ConcurrentHashMap<>();
-    private final ProviderConfigurationListener providerConfigurationListener 
= new ProviderConfigurationListener();
     //To solve the problem of RMI repeated exposure port conflicts, the 
services that have been exposed are no longer exposed.
     //provider url <--> exporter
     private final ConcurrentMap<String, ExporterChangeableWrapper<?>> bounds = 
new ConcurrentHashMap<>();
@@ -146,6 +148,7 @@ public class RegistryProtocol implements Protocol {
 
     private ConcurrentMap<URL, ReExportTask> reExportFailedTasks = new 
ConcurrentHashMap<>();
     private HashedWheelTimer retryTimer = new HashedWheelTimer(new 
NamedThreadFactory("DubboReexportTimer", true), DEFAULT_REGISTRY_RETRY_PERIOD, 
TimeUnit.MILLISECONDS, 128);
+    private FrameworkModel frameworkModel;
 
     //Filter the parameters that do not need to be output in url(Starting with 
.)
     private static String[] getFilteredKeys(URL url) {
@@ -159,6 +162,11 @@ public class RegistryProtocol implements Protocol {
         }
     }
 
+    @Override
+    public void setFrameworkModel(FrameworkModel frameworkModel) {
+        this.frameworkModel = frameworkModel;
+    }
+
     public void setProtocol(Protocol protocol) {
         this.protocol = protocol;
     }
@@ -186,7 +194,8 @@ public class RegistryProtocol implements Protocol {
     }
 
     private void registerStatedUrl(URL registryUrl, URL registeredProviderUrl, 
boolean registered) {
-        ProviderModel model = 
ApplicationModel.defaultModel().getProviderModel(registeredProviderUrl.getServiceKey());
+        ApplicationModel applicationModel = 
getApplicationModel(registryUrl.getScopeModel());
+        ProviderModel model = 
applicationModel.getProviderModel(registeredProviderUrl.getServiceKey());
         model.addStatedUrl(new ProviderModel.RegisterStatedURL(
             registeredProviderUrl,
             registryUrl,
@@ -237,7 +246,8 @@ public class RegistryProtocol implements Protocol {
     }
 
     private <T> void notifyExport(ExporterChangeableWrapper<T> exporter) {
-        List<RegistryProtocolListener> listeners = 
ExtensionLoader.getExtensionLoader(RegistryProtocolListener.class)
+        ScopeModel scopeModel = exporter.getRegisterUrl().getScopeModel();
+        List<RegistryProtocolListener> listeners = 
scopeModel.getExtensionLoader(RegistryProtocolListener.class)
             .getActivateExtension(exporter.getOriginInvoker().getUrl(), 
"registry.protocol.listener");
         if (CollectionUtils.isNotEmpty(listeners)) {
             for (RegistryProtocolListener listener : listeners) {
@@ -247,8 +257,13 @@ public class RegistryProtocol implements Protocol {
     }
 
     private URL overrideUrlWithConfig(URL providerUrl, OverrideListener 
listener) {
+        ApplicationModel applicationModel = 
getApplicationModel(providerUrl.getScopeModel());
+        ProviderConfigurationListener providerConfigurationListener = 
getProviderConfigurationListener(providerUrl);
         providerUrl = providerConfigurationListener.overrideUrl(providerUrl);
-        ServiceConfigurationListener serviceConfigurationListener = new 
ServiceConfigurationListener(providerUrl, listener);
+
+        URL finalProviderUrl = providerUrl;
+        ServiceConfigurationListener serviceConfigurationListener = 
applicationModel.getBeanFactory().registerBeanIfAbsent(ServiceConfigurationListener.class,
+            type -> new ServiceConfigurationListener(applicationModel, 
finalProviderUrl, listener));
         serviceConfigurationListeners.put(providerUrl.getServiceKey(), 
serviceConfigurationListener);
         return serviceConfigurationListener.overrideUrl(providerUrl);
     }
@@ -340,7 +355,8 @@ public class RegistryProtocol implements Protocol {
     }
 
     private ProviderModel.RegisterStatedURL getStatedUrl(URL registryUrl, URL 
providerUrl) {
-        ProviderModel providerModel = 
ApplicationModel.defaultModel().getServiceRepository()
+        ApplicationModel applicationModel = 
getApplicationModel(registryUrl.getScopeModel());
+        ProviderModel providerModel = applicationModel.getServiceRepository()
             .lookupExportedService(providerUrl.getServiceKey());
 
         List<ProviderModel.RegisterStatedURL> statedUrls = 
providerModel.getStatedUrl();
@@ -534,7 +550,7 @@ public class RegistryProtocol implements Protocol {
     }
 
     protected List<RegistryProtocolListener> findRegistryProtocolListeners(URL 
url) {
-        return 
ExtensionLoader.getExtensionLoader(RegistryProtocolListener.class)
+        return 
url.getScopeModel().getExtensionLoader(RegistryProtocolListener.class)
             .getActivateExtension(url, "registry.protocol.listener");
     }
 
@@ -549,7 +565,7 @@ public class RegistryProtocol implements Protocol {
 
     @Override
     public void destroy() {
-        List<RegistryProtocolListener> listeners = 
ExtensionLoader.getExtensionLoader(RegistryProtocolListener.class)
+        List<RegistryProtocolListener> listeners = 
frameworkModel.getExtensionLoader(RegistryProtocolListener.class)
             .getLoadedExtensionInstances();
         if (CollectionUtils.isNotEmpty(listeners)) {
             for (RegistryProtocolListener listener : listeners) {
@@ -563,10 +579,11 @@ public class RegistryProtocol implements Protocol {
         }
         bounds.clear();
 
-        if 
(ApplicationModel.defaultModel().getEnvironment().getConfiguration().convert(Boolean.class,
 org.apache.dubbo.registry.Constants.ENABLE_CONFIGURATION_LISTEN, true)) {
-            
ExtensionLoader.getExtensionLoader(GovernanceRuleRepository.class).getDefaultExtension()
-                .removeListener(ApplicationModel.defaultModel().getName() + 
CONFIGURATORS_SUFFIX, providerConfigurationListener);
-        }
+        //TODO  destroy registry protocol
+//        if 
(applicationModel.getEnvironment().getConfiguration().convert(Boolean.class, 
org.apache.dubbo.registry.Constants.ENABLE_CONFIGURATION_LISTEN, true)) {
+//            
frameworkModel.getExtensionLoader(GovernanceRuleRepository.class).getDefaultExtension()
+//                .removeListener(applicationModel.getName() + 
CONFIGURATORS_SUFFIX, providerConfigurationListener);
+//        }
     }
 
     @Override
@@ -684,7 +701,7 @@ public class RegistryProtocol implements Protocol {
             URL currentUrl = exporter.getInvoker().getUrl();
             //Merged with this configuration
             URL newUrl = getConfigedInvokerUrl(configurators, originUrl);
-            newUrl = 
getConfigedInvokerUrl(providerConfigurationListener.getConfigurators(), newUrl);
+            newUrl = 
getConfigedInvokerUrl(getProviderConfigurationListener(originUrl).getConfigurators(),
 newUrl);
             newUrl = 
getConfigedInvokerUrl(serviceConfigurationListeners.get(originUrl.getServiceKey())
                 .getConfigurators(), newUrl);
             if (!currentUrl.equals(newUrl)) {
@@ -714,14 +731,21 @@ public class RegistryProtocol implements Protocol {
         }
     }
 
+    private ProviderConfigurationListener getProviderConfigurationListener(URL 
url) {
+        ApplicationModel applicationModel = 
getApplicationModel(url.getScopeModel());
+        return 
applicationModel.getBeanFactory().registerBeanIfAbsent(ProviderConfigurationListener.class,
+            type -> new ProviderConfigurationListener(applicationModel) );
+    }
+
     private class ServiceConfigurationListener extends 
AbstractConfiguratorListener {
         private URL providerUrl;
         private OverrideListener notifyListener;
 
-        public ServiceConfigurationListener(URL providerUrl, OverrideListener 
notifyListener) {
+        public ServiceConfigurationListener(ApplicationModel applicationModel, 
URL providerUrl, OverrideListener notifyListener) {
+            super(applicationModel);
             this.providerUrl = providerUrl;
             this.notifyListener = notifyListener;
-            if 
(ApplicationModel.defaultModel().getEnvironment().getConfiguration().convert(Boolean.class,
 org.apache.dubbo.registry.Constants.ENABLE_CONFIGURATION_LISTEN, true)) {
+            if 
(applicationModel.getEnvironment().getConfiguration().convert(Boolean.class, 
ENABLE_CONFIGURATION_LISTEN, true)) {
                 this.initWith(DynamicConfiguration.getRuleKey(providerUrl) + 
CONFIGURATORS_SUFFIX);
             }
         }
@@ -738,9 +762,10 @@ public class RegistryProtocol implements Protocol {
 
     private class ProviderConfigurationListener extends 
AbstractConfiguratorListener {
 
-        public ProviderConfigurationListener() {
-            if 
(ApplicationModel.defaultModel().getEnvironment().getConfiguration().convert(Boolean.class,
 org.apache.dubbo.registry.Constants.ENABLE_CONFIGURATION_LISTEN, true)) {
-                this.initWith(ApplicationModel.defaultModel().getName() + 
CONFIGURATORS_SUFFIX);
+        public ProviderConfigurationListener(ApplicationModel 
applicationModel) {
+            super(applicationModel);
+            if 
(applicationModel.getEnvironment().getConfiguration().convert(Boolean.class, 
ENABLE_CONFIGURATION_LISTEN, true)) {
+                this.initWith(applicationModel.getName() + 
CONFIGURATORS_SUFFIX);
             }
         }
 
@@ -808,8 +833,9 @@ public class RegistryProtocol implements Protocol {
             try {
                 NotifyListener listener = 
RegistryProtocol.this.overrideListeners.remove(subscribeUrl);
                 registry.unsubscribe(subscribeUrl, listener);
-                if 
(ApplicationModel.defaultModel().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.getEnvironment().getConfiguration().convert(Boolean.class, 
ENABLE_CONFIGURATION_LISTEN, true)) {
+                    
applicationModel.getExtensionLoader(GovernanceRuleRepository.class).getDefaultExtension()
                         .removeListener(subscribeUrl.getServiceKey() + 
CONFIGURATORS_SUFFIX,
                             
serviceConfigurationListeners.get(subscribeUrl.getServiceKey()));
                 }
diff --git 
a/dubbo-registry/dubbo-registry-api/src/main/java/org/apache/dubbo/registry/integration/RegistryProtocolListener.java
 
b/dubbo-registry/dubbo-registry-api/src/main/java/org/apache/dubbo/registry/integration/RegistryProtocolListener.java
index 41c57db..eafc84e 100644
--- 
a/dubbo-registry/dubbo-registry-api/src/main/java/org/apache/dubbo/registry/integration/RegistryProtocolListener.java
+++ 
b/dubbo-registry/dubbo-registry-api/src/main/java/org/apache/dubbo/registry/integration/RegistryProtocolListener.java
@@ -21,11 +21,13 @@ import org.apache.dubbo.common.extension.SPI;
 import org.apache.dubbo.rpc.Exporter;
 import org.apache.dubbo.rpc.cluster.ClusterInvoker;
 
+import static org.apache.dubbo.common.extension.ExtensionScope.APPLICATION;
+
 /**
  * RegistryProtocol listener is introduced to provide a chance to user to 
customize or change export and refer behavior
  * of RegistryProtocol. For example: re-export or re-refer on the fly when 
certain condition meets.
  */
-@SPI
+@SPI(scope = APPLICATION)
 public interface RegistryProtocolListener {
     /**
      * Notify RegistryProtocol's listeners when a service is registered
diff --git 
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
index ad110e1..1091eee 100644
--- 
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
@@ -20,6 +20,8 @@ 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.Mockito;
 
@@ -63,6 +65,8 @@ public class MigrationRuleTest {
         assertEquals(false, migrationRule.getForce());
 
         URL url = Mockito.mock(URL.class);
+        ModuleModel defaultModule = 
ApplicationModel.defaultModel().getDefaultModule();
+        url.setScopeModel(defaultModule);
         
Mockito.when(url.getDisplayServiceKey()).thenReturn("DemoService:1.0.0");
 
         assertEquals(migrationRule.getInterfaces().size(), 2);
@@ -82,13 +86,14 @@ public class MigrationRuleTest {
 
         
Mockito.when(url.getDisplayServiceKey()).thenReturn("GreetingService:1.0.1");
         Mockito.when(url.getServiceInterface()).thenReturn("GreetingService");
-        
WritableMetadataService.getDefaultExtension().putCachedMapping(ServiceNameMapping.buildMappingKey(url),
 Collections.singleton("TestApplication"));
+        WritableMetadataService metadataService = 
WritableMetadataService.getDefaultExtension(defaultModule);
+        
metadataService.putCachedMapping(ServiceNameMapping.buildMappingKey(url), 
Collections.singleton("TestApplication"));
         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));
 
-        
WritableMetadataService.getDefaultExtension().removeCachedMapping("GreetingService");
+        metadataService.removeCachedMapping("GreetingService");
     }
 }
diff --git 
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
index 27d2bbe..db589f9 100644
--- 
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
@@ -24,6 +24,7 @@ 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.BeforeEach;
 import org.junit.jupiter.api.Test;
 
@@ -82,10 +83,13 @@ public class ServiceOrientedRegistryTest {
 
     @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.defaultModel().getConfigManager().setApplication(new 
ApplicationConfig("Test"));
+        applicationModel.getConfigManager().setApplication(new 
ApplicationConfig("Test"));
     }
 
     @Test
diff --git 
a/dubbo-registry/dubbo-registry-dns/src/test/java/org/apache/dubbo/registry/dns/DNSServiceDiscoveryTest.java
 
b/dubbo-registry/dubbo-registry-dns/src/test/java/org/apache/dubbo/registry/dns/DNSServiceDiscoveryTest.java
index c42df40..f77ad95 100644
--- 
a/dubbo-registry/dubbo-registry-dns/src/test/java/org/apache/dubbo/registry/dns/DNSServiceDiscoveryTest.java
+++ 
b/dubbo-registry/dubbo-registry-dns/src/test/java/org/apache/dubbo/registry/dns/DNSServiceDiscoveryTest.java
@@ -72,6 +72,7 @@ public class DNSServiceDiscoveryTest {
 
     @Test
     public void testProvider() throws Exception {
+        ApplicationModel applicationModel = ApplicationModel.defaultModel();
         ServiceDiscovery dnsServiceDiscovery = new DNSServiceDiscovery();
 
         URL registryURL = URL.valueOf("dns://");
@@ -84,7 +85,7 @@ public class DNSServiceDiscoveryTest {
 
         dnsServiceDiscovery.register(serviceInstance);
 
-        WritableMetadataService metadataService = 
WritableMetadataService.getDefaultExtension();
+        WritableMetadataService metadataService = 
WritableMetadataService.getDefaultExtension(applicationModel);
         InstanceMetadataChangedListener changeListener = 
Mockito.mock(InstanceMetadataChangedListener.class);
 
         String metadataString = metadataService
@@ -106,23 +107,24 @@ public class DNSServiceDiscoveryTest {
 
     @Test
     public void testConsumer() throws Exception {
+        ApplicationModel applicationModel = ApplicationModel.defaultModel();
         DNSServiceDiscovery dnsServiceDiscovery = new DNSServiceDiscovery();
 
         URL registryURL = URL.valueOf("dns://")
                 .addParameter(DNSClientConst.DNS_POLLING_CYCLE, 100)
                 .addParameter(Constants.ECHO_POLLING_CYCLE_KEY, 100);
-        
ApplicationModel.defaultModel().getEnvironment().getAppExternalConfigMap()
+        applicationModel.getEnvironment().getAppExternalConfigMap()
                 .put(METADATA_PROXY_TIMEOUT_KEY, String.valueOf(500));
         dnsServiceDiscovery.initialize(registryURL);
 
-        WritableMetadataService metadataService = 
WritableMetadataService.getDefaultExtension();
+        WritableMetadataService metadataService = 
WritableMetadataService.getDefaultExtension(applicationModel);
         ServiceInstance serviceInstance = new 
DefaultServiceInstance("TestService", "localhost", 12345);
         serviceInstance.getMetadata().put("a", "b");
 
         dnsServiceDiscovery.register(serviceInstance);
 
         int port = NetUtils.getAvailablePort();
-        
ApplicationModel.defaultModel().getApplicationConfig().setMetadataServicePort(port);
+        applicationModel.getApplicationConfig().setMetadataServicePort(port);
 
         WritableMetadataService spiedMetadataService = 
Mockito.spy(metadataService);
 
@@ -164,7 +166,7 @@ public class DNSServiceDiscoveryTest {
         serviceConfig.unexport();
 
         dnsServiceDiscovery.destroy();
-        
ApplicationModel.defaultModel().getEnvironment().getAppExternalConfigMap()
+        applicationModel.getEnvironment().getAppExternalConfigMap()
                 .remove(METADATA_PROXY_TIMEOUT_KEY);
     }
 
diff --git 
a/dubbo-rpc/dubbo-rpc-api/src/main/java/org/apache/dubbo/rpc/protocol/ProtocolListenerWrapper.java
 
b/dubbo-rpc/dubbo-rpc-api/src/main/java/org/apache/dubbo/rpc/protocol/ProtocolListenerWrapper.java
index 3461389..06ecbfc 100644
--- 
a/dubbo-rpc/dubbo-rpc-api/src/main/java/org/apache/dubbo/rpc/protocol/ProtocolListenerWrapper.java
+++ 
b/dubbo-rpc/dubbo-rpc-api/src/main/java/org/apache/dubbo/rpc/protocol/ProtocolListenerWrapper.java
@@ -18,7 +18,6 @@ package org.apache.dubbo.rpc.protocol;
 
 import org.apache.dubbo.common.URL;
 import org.apache.dubbo.common.extension.Activate;
-import org.apache.dubbo.common.extension.ExtensionLoader;
 import org.apache.dubbo.common.utils.StringUtils;
 import org.apache.dubbo.common.utils.UrlUtils;
 import org.apache.dubbo.rpc.Exporter;
@@ -64,7 +63,7 @@ public class ProtocolListenerWrapper implements Protocol {
             return protocol.export(invoker);
         }
         return new ListenerExporterWrapper<T>(protocol.export(invoker),
-                
Collections.unmodifiableList(ExtensionLoader.getExtensionLoader(ExporterListener.class)
+                
Collections.unmodifiableList(invoker.getUrl().getScopeModel().getExtensionLoader(ExporterListener.class)
                         .getActivateExtension(invoker.getUrl(), 
EXPORTER_LISTENER_KEY)));
     }
 
@@ -78,7 +77,7 @@ public class ProtocolListenerWrapper implements Protocol {
         if (StringUtils.isEmpty(url.getParameter(REGISTRY_CLUSTER_TYPE_KEY))) {
             invoker = new ListenerInvokerWrapper<>(invoker,
                     Collections.unmodifiableList(
-                            
ExtensionLoader.getExtensionLoader(InvokerListener.class)
+                        
invoker.getUrl().getScopeModel().getExtensionLoader(InvokerListener.class)
                                     .getActivateExtension(url, 
INVOKER_LISTENER_KEY)));
         }
         return invoker;
diff --git 
a/dubbo-rpc/dubbo-rpc-api/src/main/java/org/apache/dubbo/rpc/protocol/ProtocolSerializationWrapper.java
 
b/dubbo-rpc/dubbo-rpc-api/src/main/java/org/apache/dubbo/rpc/protocol/ProtocolSerializationWrapper.java
index 756eec3..544bb3a 100644
--- 
a/dubbo-rpc/dubbo-rpc-api/src/main/java/org/apache/dubbo/rpc/protocol/ProtocolSerializationWrapper.java
+++ 
b/dubbo-rpc/dubbo-rpc-api/src/main/java/org/apache/dubbo/rpc/protocol/ProtocolSerializationWrapper.java
@@ -23,10 +23,11 @@ import org.apache.dubbo.rpc.Invoker;
 import org.apache.dubbo.rpc.Protocol;
 import org.apache.dubbo.rpc.ProtocolServer;
 import org.apache.dubbo.rpc.RpcException;
-import org.apache.dubbo.rpc.model.ApplicationModel;
 
 import java.util.List;
 
+import static org.apache.dubbo.rpc.model.ScopeModelUtil.getApplicationModel;
+
 @Activate
 public class ProtocolSerializationWrapper implements Protocol {
     private Protocol protocol;
@@ -42,7 +43,7 @@ public class ProtocolSerializationWrapper implements Protocol 
{
 
     @Override
     public <T> Exporter<T> export(Invoker<T> invoker) throws RpcException {
-        
ApplicationModel.defaultModel().getServiceRepository().registerProviderUrl(invoker.getUrl());
+        
getApplicationModel(invoker.getUrl().getScopeModel()).getServiceRepository().registerProviderUrl(invoker.getUrl());
         return protocol.export(invoker);
     }
 

Reply via email to