diff --git a/dubbo-distribution/dubbo-all/pom.xml b/dubbo-distribution/dubbo-all/pom.xml
index 99187e7f11..783dbbe1a9 100644
--- a/dubbo-distribution/dubbo-all/pom.xml
+++ b/dubbo-distribution/dubbo-all/pom.xml
@@ -934,6 +934,10 @@
META-INF/dubbo/internal/org.apache.dubbo.rpc.model.PackableMethodFactory
+
+
+ META-INF/dubbo/internal/org.apache.dubbo.registry.integration.ServiceURLCustomizer
+
diff --git a/dubbo-registry/dubbo-registry-api/src/main/java/org/apache/dubbo/registry/integration/DefaultServiceURLCustomizer.java b/dubbo-registry/dubbo-registry-api/src/main/java/org/apache/dubbo/registry/integration/DefaultServiceURLCustomizer.java
new file mode 100644
index 0000000000..2473df54b7
--- /dev/null
+++ b/dubbo-registry/dubbo-registry-api/src/main/java/org/apache/dubbo/registry/integration/DefaultServiceURLCustomizer.java
@@ -0,0 +1,120 @@
+/*
+ * Licensed to the Apache Software Foundation (ASF) under one or more
+ * contributor license agreements. See the NOTICE file distributed with
+ * this work for additional information regarding copyright ownership.
+ * The ASF licenses this file to You under the Apache License, Version 2.0
+ * (the "License"); you may not use this file except in compliance with
+ * the License. You may obtain a copy of the License at
+ *
+ * http://www.apache.org/licenses/LICENSE-2.0
+ *
+ * Unless required by applicable law or agreed to in writing, software
+ * distributed under the License is distributed on an "AS IS" BASIS,
+ * WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied.
+ * See the License for the specific language governing permissions and
+ * limitations under the License.
+ */
+package org.apache.dubbo.registry.integration;
+
+import org.apache.dubbo.common.URL;
+import org.apache.dubbo.common.utils.CollectionUtils;
+import org.apache.dubbo.common.utils.StringUtils;
+import org.apache.dubbo.rpc.model.ApplicationModel;
+
+import java.util.Arrays;
+import java.util.Map;
+import java.util.stream.Stream;
+
+import static org.apache.dubbo.common.constants.CommonConstants.ALIVE_KEY;
+import static org.apache.dubbo.common.constants.CommonConstants.ANYHOST_KEY;
+import static org.apache.dubbo.common.constants.CommonConstants.BACKGROUND_KEY;
+import static org.apache.dubbo.common.constants.CommonConstants.COMMA_SPLIT_PATTERN;
+import static org.apache.dubbo.common.constants.CommonConstants.CORE_THREADS_KEY;
+import static org.apache.dubbo.common.constants.CommonConstants.EXECUTOR_MANAGEMENT_MODE;
+import static org.apache.dubbo.common.constants.CommonConstants.EXTRA_KEYS_KEY;
+import static org.apache.dubbo.common.constants.CommonConstants.HIDE_KEY_PREFIX;
+import static org.apache.dubbo.common.constants.CommonConstants.INTERFACE_KEY;
+import static org.apache.dubbo.common.constants.CommonConstants.METHODS_KEY;
+import static org.apache.dubbo.common.constants.CommonConstants.MONITOR_KEY;
+import static org.apache.dubbo.common.constants.CommonConstants.PID_KEY;
+import static org.apache.dubbo.common.constants.CommonConstants.QUEUES_KEY;
+import static org.apache.dubbo.common.constants.CommonConstants.REGISTRY_LOCAL_FILE_CACHE_ENABLED;
+import static org.apache.dubbo.common.constants.CommonConstants.THREADPOOL_KEY;
+import static org.apache.dubbo.common.constants.CommonConstants.THREADS_KEY;
+import static org.apache.dubbo.common.constants.CommonConstants.THREAD_NAME_KEY;
+import static org.apache.dubbo.common.constants.FilterConstants.VALIDATION_KEY;
+import static org.apache.dubbo.common.constants.QosConstants.ACCEPT_FOREIGN_IP;
+import static org.apache.dubbo.common.constants.QosConstants.QOS_ENABLE;
+import static org.apache.dubbo.common.constants.QosConstants.QOS_HOST;
+import static org.apache.dubbo.common.constants.QosConstants.QOS_PORT;
+import static org.apache.dubbo.common.constants.RegistryConstants.REGISTER_MODE_KEY;
+import static org.apache.dubbo.registry.Constants.SIMPLIFIED_KEY;
+import static org.apache.dubbo.registry.integration.RegistryProtocol.DEFAULT_REGISTER_PROVIDER_KEYS;
+import static org.apache.dubbo.remoting.Constants.BIND_IP_KEY;
+import static org.apache.dubbo.remoting.Constants.BIND_PORT_KEY;
+import static org.apache.dubbo.rpc.Constants.INTERFACES;
+
+public class DefaultServiceURLCustomizer implements ServiceURLCustomizer {
+
+ private static final String[] excludedParameters = new String[] {
+ MONITOR_KEY,
+ BIND_IP_KEY,
+ BIND_PORT_KEY,
+ QOS_ENABLE,
+ QOS_HOST,
+ QOS_PORT,
+ ACCEPT_FOREIGN_IP,
+ VALIDATION_KEY,
+ INTERFACES,
+ REGISTER_MODE_KEY,
+ PID_KEY,
+ REGISTRY_LOCAL_FILE_CACHE_ENABLED,
+ EXECUTOR_MANAGEMENT_MODE,
+ BACKGROUND_KEY,
+ ANYHOST_KEY,
+ THREAD_NAME_KEY,
+ THREADPOOL_KEY,
+ ALIVE_KEY,
+ QUEUES_KEY,
+ CORE_THREADS_KEY,
+ THREADS_KEY
+ };
+
+ @Override
+ public URL customize(URL serviceURL, ApplicationModel applicationModel) {
+ boolean simplified = (boolean) serviceURL.getAttribute(SIMPLIFIED_KEY, false);
+ if (simplified) {
+ String extraKeys = (String) serviceURL.getAttribute(EXTRA_KEYS_KEY, "");
+ // if path is not the same as interface name then we should keep INTERFACE_KEY,
+ // otherwise, the registry structure of zookeeper would be '/dubbo/path/providers',
+ // but what we expect is '/dubbo/interface/providers'
+ if (!serviceURL.getPath().equals(serviceURL.getParameter(INTERFACE_KEY))) {
+ if (StringUtils.isNotEmpty(extraKeys)) {
+ extraKeys += ",";
+ }
+ extraKeys += INTERFACE_KEY;
+ }
+ String[] paramsToRegistry = Stream.concat(
+ Arrays.stream(DEFAULT_REGISTER_PROVIDER_KEYS),
+ Arrays.stream(COMMA_SPLIT_PATTERN.split(extraKeys)))
+ .toArray(String[]::new);
+ return URL.valueOf(serviceURL, paramsToRegistry, serviceURL.getParameter(METHODS_KEY, (String[]) null));
+ }
+ return serviceURL.removeParameters(getFilteredKeys(serviceURL)).removeParameters(excludedParameters);
+ }
+
+ @Override
+ public int getPriority() {
+ return MAX_PRIORITY;
+ }
+
+ private String[] getFilteredKeys(URL url) {
+ Map params = url.getParameters();
+ if (CollectionUtils.isNotEmptyMap(params)) {
+ return params.keySet().stream()
+ .filter(k -> k.startsWith(HIDE_KEY_PREFIX))
+ .toArray(String[]::new);
+ }
+ return new String[0];
+ }
+}
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 6fb5f43f32..f05b8bdd94 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
@@ -20,6 +20,7 @@ import org.apache.dubbo.common.URL;
import org.apache.dubbo.common.config.configcenter.DynamicConfiguration;
import org.apache.dubbo.common.constants.RegistryConstants;
import org.apache.dubbo.common.deploy.ApplicationDeployer;
+import org.apache.dubbo.common.extension.ExtensionLoader;
import org.apache.dubbo.common.logger.ErrorTypeAwareLogger;
import org.apache.dubbo.common.logger.LoggerFactory;
import org.apache.dubbo.common.threadpool.manager.FrameworkExecutorRepository;
@@ -77,46 +78,32 @@ import java.util.concurrent.TimeUnit;
import java.util.concurrent.atomic.AtomicBoolean;
import java.util.stream.Collectors;
-import static org.apache.dubbo.common.constants.CommonConstants.ANYHOST_KEY;
import static org.apache.dubbo.common.constants.CommonConstants.APPLICATION_KEY;
-import static org.apache.dubbo.common.constants.CommonConstants.BACKGROUND_KEY;
import static org.apache.dubbo.common.constants.CommonConstants.CLUSTER_KEY;
import static org.apache.dubbo.common.constants.CommonConstants.COMMA_SPLIT_PATTERN;
import static org.apache.dubbo.common.constants.CommonConstants.CONSUMER;
import static org.apache.dubbo.common.constants.CommonConstants.DUBBO_VERSION_KEY;
import static org.apache.dubbo.common.constants.CommonConstants.ENABLED_KEY;
-import static org.apache.dubbo.common.constants.CommonConstants.EXECUTOR_MANAGEMENT_MODE;
import static org.apache.dubbo.common.constants.CommonConstants.EXTRA_KEYS_KEY;
import static org.apache.dubbo.common.constants.CommonConstants.GROUP_KEY;
-import static org.apache.dubbo.common.constants.CommonConstants.HIDE_KEY_PREFIX;
import static org.apache.dubbo.common.constants.CommonConstants.INTERFACE_KEY;
import static org.apache.dubbo.common.constants.CommonConstants.IPV6_KEY;
import static org.apache.dubbo.common.constants.CommonConstants.LOADBALANCE_KEY;
-import static org.apache.dubbo.common.constants.CommonConstants.METHODS_KEY;
-import static org.apache.dubbo.common.constants.CommonConstants.MONITOR_KEY;
import static org.apache.dubbo.common.constants.CommonConstants.PACKABLE_METHOD_FACTORY_KEY;
import static org.apache.dubbo.common.constants.CommonConstants.PATH_KEY;
-import static org.apache.dubbo.common.constants.CommonConstants.PID_KEY;
import static org.apache.dubbo.common.constants.CommonConstants.PROTOCOL_KEY;
-import static org.apache.dubbo.common.constants.CommonConstants.REGISTRY_LOCAL_FILE_CACHE_ENABLED;
import static org.apache.dubbo.common.constants.CommonConstants.REGISTRY_PROTOCOL_LISTENER_KEY;
import static org.apache.dubbo.common.constants.CommonConstants.RELEASE_KEY;
import static org.apache.dubbo.common.constants.CommonConstants.SIDE_KEY;
import static org.apache.dubbo.common.constants.CommonConstants.TIMEOUT_KEY;
import static org.apache.dubbo.common.constants.CommonConstants.VERSION_KEY;
-import static org.apache.dubbo.common.constants.FilterConstants.VALIDATION_KEY;
import static org.apache.dubbo.common.constants.LoggerCodeConstants.INTERNAL_ERROR;
import static org.apache.dubbo.common.constants.LoggerCodeConstants.REGISTRY_UNSUPPORTED_CATEGORY;
-import static org.apache.dubbo.common.constants.QosConstants.ACCEPT_FOREIGN_IP;
-import static org.apache.dubbo.common.constants.QosConstants.QOS_ENABLE;
-import static org.apache.dubbo.common.constants.QosConstants.QOS_HOST;
-import static org.apache.dubbo.common.constants.QosConstants.QOS_PORT;
import static org.apache.dubbo.common.constants.RegistryConstants.ALL_CATEGORIES;
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.DYNAMIC_KEY;
import static org.apache.dubbo.common.constants.RegistryConstants.OVERRIDE_PROTOCOL;
-import static org.apache.dubbo.common.constants.RegistryConstants.REGISTER_MODE_KEY;
import static org.apache.dubbo.common.constants.RegistryConstants.REGISTRY_KEY;
import static org.apache.dubbo.common.constants.RegistryConstants.SERVICE_REGISTRY_PROTOCOL;
import static org.apache.dubbo.common.utils.StringUtils.isEmpty;
@@ -130,8 +117,6 @@ import static org.apache.dubbo.registry.Constants.REGISTER_IP_KEY;
import static org.apache.dubbo.registry.Constants.REGISTER_KEY;
import static org.apache.dubbo.registry.Constants.REGISTRY_RETRY_PERIOD_KEY;
import static org.apache.dubbo.registry.Constants.SIMPLIFIED_KEY;
-import static org.apache.dubbo.remoting.Constants.BIND_IP_KEY;
-import static org.apache.dubbo.remoting.Constants.BIND_PORT_KEY;
import static org.apache.dubbo.remoting.Constants.CHECK_KEY;
import static org.apache.dubbo.remoting.Constants.CODEC_KEY;
import static org.apache.dubbo.remoting.Constants.CONNECTIONS_KEY;
@@ -140,7 +125,6 @@ import static org.apache.dubbo.remoting.Constants.PREFER_SERIALIZATION_KEY;
import static org.apache.dubbo.remoting.Constants.SERIALIZATION_KEY;
import static org.apache.dubbo.rpc.Constants.DEPRECATED_KEY;
import static org.apache.dubbo.rpc.Constants.GENERIC_KEY;
-import static org.apache.dubbo.rpc.Constants.INTERFACES;
import static org.apache.dubbo.rpc.Constants.MOCK_KEY;
import static org.apache.dubbo.rpc.Constants.TOKEN_KEY;
import static org.apache.dubbo.rpc.cluster.Constants.CONSUMER_URL_KEY;
@@ -184,18 +168,6 @@ public class RegistryProtocol implements Protocol, ScopeModelAware {
private FrameworkModel frameworkModel;
private ExporterFactory exporterFactory;
- // Filter the parameters that do not need to be output in url(Starting with .)
- private static String[] getFilteredKeys(URL url) {
- Map params = url.getParameters();
- if (CollectionUtils.isNotEmptyMap(params)) {
- return params.keySet().stream()
- .filter(k -> k.startsWith(HIDE_KEY_PREFIX))
- .toArray(String[]::new);
- } else {
- return new String[0];
- }
- }
-
public RegistryProtocol() {}
@Override
@@ -292,7 +264,7 @@ public class RegistryProtocol implements Protocol, ScopeModelAware {
// url to registry
final Registry registry = getRegistry(registryUrl);
- final URL registeredProviderUrl = getUrlToRegistry(providerUrl, registryUrl);
+ final URL registeredProviderUrl = customizeURL(providerUrl, registryUrl);
// decide if we need to delay publish (provider itself and registry should both need to register)
boolean register = providerUrl.getParameter(REGISTER_KEY, true) && registryUrl.getParameter(REGISTER_KEY, true);
@@ -354,10 +326,10 @@ public class RegistryProtocol implements Protocol, ScopeModelAware {
ReferenceCountExporter> exporter =
exporterFactory.createExporter(providerUrlKey, () -> protocol.export(invokerDelegate));
- return (ExporterChangeableWrapper) bounds.computeIfAbsent(providerUrlKey, _k -> new ConcurrentHashMap<>())
- .computeIfAbsent(registryUrlKey, s -> {
- return new ExporterChangeableWrapper<>((ReferenceCountExporter) exporter, originInvoker);
- });
+ return (ExporterChangeableWrapper) bounds.computeIfAbsent(providerUrlKey, k -> new ConcurrentHashMap<>())
+ .computeIfAbsent(
+ registryUrlKey,
+ s -> new ExporterChangeableWrapper<>((ReferenceCountExporter) exporter, originInvoker));
}
public void reExport(Exporter exporter, URL newInvokerUrl) {
@@ -402,10 +374,10 @@ public class RegistryProtocol implements Protocol, ScopeModelAware {
URL registeredUrl = exporter.getRegisterUrl();
URL registryUrl = getRegistryUrl(originInvoker);
- URL newProviderUrl = getUrlToRegistry(newInvokerUrl, registryUrl);
+ URL newProviderUrl = customizeURL(newInvokerUrl, registryUrl);
// update local exporter
- Invoker invokerDelegate = new InvokerDelegate(originInvoker, newInvokerUrl);
+ Invoker invokerDelegate = new InvokerDelegate<>(originInvoker, newInvokerUrl);
exporter.setExporter(protocol.export(invokerDelegate));
// update registry
@@ -501,45 +473,19 @@ public class RegistryProtocol implements Protocol, ScopeModelAware {
/**
* Return the url that is registered to the registry and filter the url parameter once
*
- * @param providerUrl
+ * @param providerUrl provider service url
+ * @param registryUrl registry center url
* @return url to registry.
*/
- private URL getUrlToRegistry(final URL providerUrl, final URL registryUrl) {
- // The address you see at the registry
- if (!registryUrl.getParameter(SIMPLIFIED_KEY, false)) {
- return providerUrl
- .removeParameters(getFilteredKeys(providerUrl))
- .removeParameters(
- MONITOR_KEY,
- BIND_IP_KEY,
- BIND_PORT_KEY,
- QOS_ENABLE,
- QOS_HOST,
- QOS_PORT,
- ACCEPT_FOREIGN_IP,
- VALIDATION_KEY,
- INTERFACES,
- REGISTER_MODE_KEY,
- PID_KEY,
- REGISTRY_LOCAL_FILE_CACHE_ENABLED,
- EXECUTOR_MANAGEMENT_MODE,
- BACKGROUND_KEY,
- ANYHOST_KEY);
- } else {
- String extraKeys = registryUrl.getParameter(EXTRA_KEYS_KEY, "");
- // if path is not the same as interface name then we should keep INTERFACE_KEY,
- // otherwise, the registry structure of zookeeper would be '/dubbo/path/providers',
- // but what we expect is '/dubbo/interface/providers'
- if (!providerUrl.getPath().equals(providerUrl.getParameter(INTERFACE_KEY))) {
- if (StringUtils.isNotEmpty(extraKeys)) {
- extraKeys += ",";
- }
- extraKeys += INTERFACE_KEY;
- }
- String[] paramsToRegistry =
- getParamsToRegistry(DEFAULT_REGISTER_PROVIDER_KEYS, COMMA_SPLIT_PATTERN.split(extraKeys));
- return URL.valueOf(providerUrl, paramsToRegistry, providerUrl.getParameter(METHODS_KEY, (String[]) null));
+ private URL customizeURL(final URL providerUrl, final URL registryUrl) {
+ URL newProviderURL = providerUrl.putAttribute(SIMPLIFIED_KEY, registryUrl.getParameter(SIMPLIFIED_KEY, false));
+ newProviderURL = newProviderURL.putAttribute(EXTRA_KEYS_KEY, registryUrl.getParameter(EXTRA_KEYS_KEY, ""));
+ ApplicationModel applicationModel = providerUrl.getOrDefaultApplicationModel();
+ ExtensionLoader loader = applicationModel.getExtensionLoader(ServiceURLCustomizer.class);
+ for (ServiceURLCustomizer customizer : loader.getSupportedExtensionInstances()) {
+ newProviderURL = customizer.customize(newProviderURL, applicationModel);
}
+ return newProviderURL;
}
private URL getSubscribedOverrideUrl(URL registeredProviderUrl) {
@@ -571,14 +517,12 @@ public class RegistryProtocol implements Protocol, ScopeModelAware {
*/
private String getProviderUrlKey(final Invoker> originInvoker) {
URL providerUrl = getProviderUrl(originInvoker);
- String key = providerUrl.removeParameters(DYNAMIC_KEY, ENABLED_KEY).toFullString();
- return key;
+ return providerUrl.removeParameters(DYNAMIC_KEY, ENABLED_KEY).toFullString();
}
private String getRegistryUrlKey(final Invoker> originInvoker) {
URL registryUrl = getRegistryUrl(originInvoker);
- String key = registryUrl.removeParameters(DYNAMIC_KEY, ENABLED_KEY).toFullString();
- return key;
+ return registryUrl.removeParameters(DYNAMIC_KEY, ENABLED_KEY).toFullString();
}
@Override
@@ -633,7 +577,7 @@ public class RegistryProtocol implements Protocol, ScopeModelAware {
Class type,
URL url,
URL consumerUrl) {
- return new ServiceDiscoveryMigrationInvoker(registryProtocol, cluster, registry, type, url, consumerUrl);
+ return new ServiceDiscoveryMigrationInvoker<>(registryProtocol, cluster, registry, type, url, consumerUrl);
}
/**
@@ -721,15 +665,6 @@ public class RegistryProtocol implements Protocol, ScopeModelAware {
.getActivateExtension(url, REGISTRY_PROTOCOL_LISTENER_KEY);
}
- // available to test
- public String[] getParamsToRegistry(String[] defaultKeys, String[] additionalParameterKeys) {
- int additionalLen = additionalParameterKeys.length;
- String[] registryParams = new String[defaultKeys.length + additionalLen];
- System.arraycopy(defaultKeys, 0, registryParams, 0, defaultKeys.length);
- System.arraycopy(additionalParameterKeys, 0, registryParams, defaultKeys.length, additionalLen);
- return registryParams;
- }
-
@Override
public void destroy() {
// FIXME all application models in framework are removed at this moment
@@ -757,7 +692,10 @@ public class RegistryProtocol implements Protocol, ScopeModelAware {
// already removed
continue;
}
- if (moduleModel.getServiceRepository().getExportedServices().size() > 0) {
+ if (!moduleModel
+ .getServiceRepository()
+ .getExportedServices()
+ .isEmpty()) {
moduleModel
.getExtensionLoader(GovernanceRuleRepository.class)
.getDefaultExtension()
@@ -1166,11 +1104,10 @@ public class RegistryProtocol implements Protocol, ScopeModelAware {
.getConfiguration()
.convert(Boolean.class, ENABLE_CONFIGURATION_LISTEN, true)) {
for (ModuleModel moduleModel : applicationModel.getPubModuleModels()) {
- if (moduleModel
- .getServiceRepository()
- .getExportedServices()
- .size()
- > 0) {
+ if (!moduleModel
+ .getServiceRepository()
+ .getExportedServices()
+ .isEmpty()) {
moduleModel
.getExtensionLoader(GovernanceRuleRepository.class)
.getDefaultExtension()
diff --git a/dubbo-registry/dubbo-registry-api/src/main/java/org/apache/dubbo/registry/integration/ServiceURLCustomizer.java b/dubbo-registry/dubbo-registry-api/src/main/java/org/apache/dubbo/registry/integration/ServiceURLCustomizer.java
new file mode 100644
index 0000000000..8229ba5875
--- /dev/null
+++ b/dubbo-registry/dubbo-registry-api/src/main/java/org/apache/dubbo/registry/integration/ServiceURLCustomizer.java
@@ -0,0 +1,39 @@
+/*
+ * Licensed to the Apache Software Foundation (ASF) under one or more
+ * contributor license agreements. See the NOTICE file distributed with
+ * this work for additional information regarding copyright ownership.
+ * The ASF licenses this file to You under the Apache License, Version 2.0
+ * (the "License"); you may not use this file except in compliance with
+ * the License. You may obtain a copy of the License at
+ *
+ * http://www.apache.org/licenses/LICENSE-2.0
+ *
+ * Unless required by applicable law or agreed to in writing, software
+ * distributed under the License is distributed on an "AS IS" BASIS,
+ * WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied.
+ * See the License for the specific language governing permissions and
+ * limitations under the License.
+ */
+package org.apache.dubbo.registry.integration;
+
+import org.apache.dubbo.common.URL;
+import org.apache.dubbo.common.extension.SPI;
+import org.apache.dubbo.common.lang.Prioritized;
+import org.apache.dubbo.rpc.model.ApplicationModel;
+
+import static org.apache.dubbo.common.extension.ExtensionScope.APPLICATION;
+
+/**
+ * Customize parameters for interface-level registration
+ */
+@SPI(scope = APPLICATION)
+public interface ServiceURLCustomizer extends Prioritized {
+
+ /**
+ * Customizes {@link URL the service url}
+ *
+ * @param serviceURL {@link URL the service url}
+ * @return new service url
+ */
+ URL customize(URL serviceURL, ApplicationModel applicationModel);
+}
diff --git a/dubbo-registry/dubbo-registry-api/src/main/resources/META-INF/dubbo/internal/org.apache.dubbo.registry.integration.ServiceURLCustomizer b/dubbo-registry/dubbo-registry-api/src/main/resources/META-INF/dubbo/internal/org.apache.dubbo.registry.integration.ServiceURLCustomizer
new file mode 100644
index 0000000000..83a3432c9b
--- /dev/null
+++ b/dubbo-registry/dubbo-registry-api/src/main/resources/META-INF/dubbo/internal/org.apache.dubbo.registry.integration.ServiceURLCustomizer
@@ -0,0 +1 @@
+default=org.apache.dubbo.registry.integration.DefaultServiceURLCustomizer