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

albumenj pushed a commit to branch master
in repository https://gitbox.apache.org/repos/asf/dubbo.git


The following commit(s) were added to refs/heads/master by this push:
     new b62832b  Solve the problem of repeatedly registering the 
BeanDefinition of the provider (#7494)
b62832b is described below

commit b62832b21a0191bf28fa290707ad016029474838
Author: zhox <[email protected]>
AuthorDate: Wed May 5 20:59:40 2021 +0800

    Solve the problem of repeatedly registering the BeanDefinition of the 
provider (#7494)
    
    * 解决PojoUtils.java#getDefaultValue获取boolean默认值不正确的问题,并补充对应的测试用例
    
    * Solve the problem of repeatedly registering the BeanDefinition of the 
provider
    
    * Solve the problem of repeatedly registering the BeanDefinition of the 
provider
    
    * An exception is thrown when registering a duplicate ServiceBean
    
    * 1 fix with DubboBeanDefinitionParser.java: Prohibit repeated generation 
of name for ServiceBean
    
    * 1 fix with DubboBeanDefinitionParser.java: Prohibit repeated generation 
of name of ServiceBean
    
    * 1 fix with multiple-services-with-methods.xml: improve test config
    
    * Revert "1 fix with multiple-services-with-methods.xml: improve test 
config"
    
    This reverts commit 7ce4e3b2
    
    * Update multiple-services-with-methods.xml
    
    improve test config
    
    * Modify the default generation method of ServiceBean id;
    add test case scenario: an exception is thrown when ServiceBean is 
duplicate registered;
    
    * import BeanDefinitionStoreException.class
    
    * Revert "import BeanDefinitionStoreException.class"
    
    This reverts commit e3c1be44
    
    * Revert "Modify the default generation method of ServiceBean id; add test 
case scenario: an exception is thrown when ServiceBean is duplicate registered;"
    
    This reverts commit 73f8ea62
    
    * Revert "Update multiple-services-with-methods.xml"
    
    This reverts commit ddc3615b
    
    * Revert "1 fix with DubboBeanDefinitionParser.java: Prohibit repeated 
generation of name of ServiceBean"
    
    This reverts commit 1b159909
    
    * Revert "1 fix with DubboBeanDefinitionParser.java: Prohibit repeated 
generation of name for ServiceBean"
    
    This reverts commit f41e1ecb
    
    * Update DubboBeanDefinitionParser.java
    
    revert all commit
    
    * Update DubboBeanDefinitionParser.java
    
    revert all commit
    
    * Prevent the same ServiceBean exported
    
    * Prevent the same ServiceBean exported
    
    * 1 modify with ServiceConfig.java: if there is an 'id'attribute, it will 
be used first
    
    * 1 modify with ServiceConfig.java: After the service is exported, set the 
export to false
    
    * Revert "1 modify with ServiceConfig.java: After the service is exported, 
set the export to false"
    
    This reverts commit b482cd44
    
    * Solve the issue of the ServiceBean duplication export
    
    * fix UT
    
    * Prevent the same ServiceBean exported
    
    * 1 fix with ServiceConfig.java and ServiceBean.java
    
    * adjust log print
    
    * 1 fix with DubboBootstrap.java: adjust log print
    
    * fix unit test
    
    * fix UT
    
    * fix UT
    
    * FIX UT
    
    * add reset method to AbstractRegistryFactory.java for ut .
    and improve code note
    
    Co-authored-by: zhongxiong.zeng <[email protected]>
    Co-authored-by: [email protected] <xiong837652>
---
 .../dubbo/common/extension/ExtensionLoader.java    |  3 +
 .../apache/dubbo/rpc/model/ApplicationModel.java   |  1 +
 .../org/apache/dubbo/config/ServiceConfig.java     | 34 +++++++++
 .../dubbo/config/bootstrap/DubboBootstrap.java     | 67 +++++++++++++++---
 .../dubbo/config/AbstractInterfaceConfigTest.java  |  6 +-
 .../apache/dubbo/config/ReferenceConfigTest.java   | 12 ++--
 .../org/apache/dubbo/config/ServiceConfigTest.java | 70 +++++++++++--------
 .../PublishingServiceDefinitionListenerTest.java   |  6 +-
 .../config/url/ExporterSideConfigUrlTest.java      |  6 +-
 .../dubbo/config/url/InvokerSideConfigUrlTest.java |  2 +
 .../ReferenceAnnotationBeanPostProcessorTest.java  | 16 ++---
 .../ServiceAnnotationBeanPostProcessorTest.java    |  9 +--
 .../annotation/ServiceClassPostProcessorTest.java  |  6 +-
 .../MultipleServicesWithMethodConfigsTest.java     |  4 +-
 .../DubboComponentScanRegistrarTest.java           |  3 +-
 .../spring/context/annotation/EnableDubboTest.java |  6 +-
 .../spring/schema/DubboNamespaceHandlerTest.java   | 18 ++++-
 .../config/spring/schema/GenericServiceTest.java   |  6 +-
 .../spring/multiple-services-with-methods.xml      |  4 +-
 .../demo-provider-duplicate-service-bean.xml}      | 81 ++++++++++------------
 .../metadata/report/MetadataReportInstance.java    |  9 +++
 .../support/AbstractMetadataReportFactory.java     | 11 +++
 .../registry/support/AbstractRegistryFactory.java  |  4 +-
 .../registry/dubbo/RegistryStatusCheckerTest.java  |  2 +-
 24 files changed, 254 insertions(+), 132 deletions(-)

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 88c1281..6697fe0 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
@@ -172,6 +172,7 @@ public class ExtensionLoader<T> {
     }
 
     // For testing purposes only
+    @Deprecated
     public static void resetExtensionLoader(Class type) {
         ExtensionLoader loader = EXTENSION_LOADERS.get(type);
         if (loader != null) {
@@ -185,6 +186,8 @@ public class ExtensionLoader<T> {
         }
     }
 
+    // only for unit test
+    @Deprecated
     public static void destroyAll() {
         EXTENSION_INSTANCES.forEach((_type, instance) -> {
             if (instance instanceof Lifecycle) {
diff --git 
a/dubbo-common/src/main/java/org/apache/dubbo/rpc/model/ApplicationModel.java 
b/dubbo-common/src/main/java/org/apache/dubbo/rpc/model/ApplicationModel.java
index 6238b80..4038146 100644
--- 
a/dubbo-common/src/main/java/org/apache/dubbo/rpc/model/ApplicationModel.java
+++ 
b/dubbo-common/src/main/java/org/apache/dubbo/rpc/model/ApplicationModel.java
@@ -119,6 +119,7 @@ public class ApplicationModel {
     }
 
     // only for unit test
+    @Deprecated
     public static void reset() {
         getServiceRepository().destroy();
         getConfigManager().destroy();
diff --git 
a/dubbo-config/dubbo-config-api/src/main/java/org/apache/dubbo/config/ServiceConfig.java
 
b/dubbo-config/dubbo-config-api/src/main/java/org/apache/dubbo/config/ServiceConfig.java
index 885da0d..5e8bed2 100644
--- 
a/dubbo-config/dubbo-config-api/src/main/java/org/apache/dubbo/config/ServiceConfig.java
+++ 
b/dubbo-config/dubbo-config-api/src/main/java/org/apache/dubbo/config/ServiceConfig.java
@@ -118,6 +118,8 @@ public class ServiceConfig<T> extends ServiceConfigBase<T> {
     private static final ScheduledExecutorService DELAY_EXPORT_EXECUTOR =
             Executors.newSingleThreadScheduledExecutor(new 
NamedThreadFactory("DubboServiceDelayExporter", true));
 
+    private String serviceName;
+
     private static final Protocol PROTOCOL = 
ExtensionLoader.getExtensionLoader(Protocol.class).getAdaptiveExtension();
 
     /**
@@ -742,4 +744,36 @@ public class ServiceConfig<T> extends ServiceConfigBase<T> 
{
     public void setBootstrap(DubboBootstrap bootstrap) {
         this.bootstrap = bootstrap;
     }
+
+    public String getServiceName() {
+
+        if(!StringUtils.isBlank(serviceName)){
+            return serviceName;
+        }
+        String generateVersion = version;
+        String generateGroup = group;
+
+        if (StringUtils.isBlank(version) && provider != null) {
+            generateVersion = provider.getVersion();
+        }
+
+        if (StringUtils.isBlank(group) && provider != null) {
+            generateGroup = provider.getGroup();
+        }
+        StringBuilder stringBuilder = new StringBuilder();
+        stringBuilder.append("ServiceBean:");
+
+        if (!StringUtils.isBlank(generateGroup)) {
+            stringBuilder.append(generateGroup);
+        }
+
+        stringBuilder.append("/").append(interfaceName);
+
+        if (!StringUtils.isBlank(generateVersion)) {
+            stringBuilder.append(":").append(generateVersion);
+        }
+
+        serviceName = stringBuilder.toString();
+        return serviceName;
+    }
 }
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 0a2c21c..10ad5e8 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
@@ -62,6 +62,7 @@ import org.apache.dubbo.metadata.MetadataServiceExporter;
 import org.apache.dubbo.metadata.WritableMetadataService;
 import org.apache.dubbo.metadata.report.MetadataReportFactory;
 import org.apache.dubbo.metadata.report.MetadataReportInstance;
+import org.apache.dubbo.metadata.report.support.AbstractMetadataReportFactory;
 import org.apache.dubbo.registry.client.DefaultServiceInstance;
 import org.apache.dubbo.registry.client.ServiceInstance;
 import org.apache.dubbo.registry.client.ServiceInstanceCustomizer;
@@ -76,6 +77,7 @@ import java.io.IOException;
 import java.util.ArrayList;
 import java.util.Collection;
 import java.util.HashMap;
+import java.util.Map;
 import java.util.List;
 import java.util.Set;
 import java.util.SortedSet;
@@ -83,6 +85,7 @@ import java.util.concurrent.CompletableFuture;
 import java.util.concurrent.ExecutorService;
 import java.util.concurrent.Future;
 import java.util.concurrent.TimeUnit;
+import java.util.concurrent.ConcurrentHashMap;
 import java.util.concurrent.atomic.AtomicBoolean;
 import java.util.concurrent.locks.Condition;
 import java.util.concurrent.locks.Lock;
@@ -176,7 +179,7 @@ public class DubboBootstrap {
 
     private volatile MetadataServiceExporter metadataServiceExporter;
 
-    private List<ServiceConfigBase<?>> exportedServices = new ArrayList<>();
+    private Map<String, ServiceConfigBase<?>> exportedServices = new 
ConcurrentHashMap<>();
 
     private List<Future<?>> asyncExportingFutures = new ArrayList<>();
 
@@ -1054,23 +1057,33 @@ public class DubboBootstrap {
             if (exportAsync) {
                 ExecutorService executor = 
executorRepository.getServiceExporterExecutor();
                 Future<?> future = executor.submit(() -> {
-                       try {
-                        sc.export();
-                        exportedServices.add(sc);
-                       }catch (Throwable t) {
-                               logger.error("export async catch error : " + 
t.getMessage(), t);
-                                       }
+                    try {
+                        exportService(serviceConfig);
+                    } catch (Throwable t) {
+                        logger.error("export async catch error : " + 
t.getMessage(), t);
+                    }
                 });
                 asyncExportingFutures.add(future);
             } else {
-                sc.export();
-                exportedServices.add(sc);
+                exportService(serviceConfig);
             }
         });
     }
 
+    private void exportService(ServiceConfig sc) {
+        if (exportedServices.containsKey(sc.getServiceName())) {
+            throw new IllegalStateException("There are multiple ServiceBean 
instances with the same service name: [" +
+                    sc.getServiceName() + "], instances: [" +
+                    exportedServices.get(sc.getServiceName()).toString() + ", 
" +
+                    sc.toString() + "]. Only one service can be exported for 
the same triple (group, interface, version), " +
+                    "please modify the group or version if you really need to 
export multiple services of the same interface.");
+        }
+        sc.export();
+        exportedServices.put(sc.getServiceName(), sc);
+    }
+
     private void unexportServices() {
-        exportedServices.forEach(sc -> {
+        exportedServices.forEach((serviceName, sc) -> {
             configManager.removeConfig(sc);
             sc.unexport();
         });
@@ -1384,4 +1397,38 @@ public class DubboBootstrap {
     public void setReady(boolean ready) {
         this.ready.set(ready);
     }
+
+
+    /**
+     * Try reset dubbo status for new instance.
+     * @deprecated  For testing purposes only
+     */
+    @Deprecated
+    public static void reset() {
+        reset(true);
+    }
+
+    /**
+     * Try reset dubbo status for new instance.
+     * @deprecated For testing purposes only
+     */
+    @Deprecated
+    public static void reset(boolean destroy) {
+        if (destroy) {
+            if (instance != null) {
+                instance.destroy();
+                instance = null;
+            }
+            ApplicationModel.reset();
+            AbstractRegistryFactory.reset();
+            MetadataReportInstance.destroy();
+            AbstractMetadataReportFactory.clear();
+            
ExtensionLoader.resetExtensionLoader(DynamicConfigurationFactory.class);
+            ExtensionLoader.resetExtensionLoader(MetadataReportFactory.class);
+            ExtensionLoader.destroyAll();
+        } else {
+            instance = null;
+            ApplicationModel.reset();
+        }
+    }
 }
diff --git 
a/dubbo-config/dubbo-config-api/src/test/java/org/apache/dubbo/config/AbstractInterfaceConfigTest.java
 
b/dubbo-config/dubbo-config-api/src/test/java/org/apache/dubbo/config/AbstractInterfaceConfigTest.java
index 3a4a83c..c369670 100644
--- 
a/dubbo-config/dubbo-config-api/src/test/java/org/apache/dubbo/config/AbstractInterfaceConfigTest.java
+++ 
b/dubbo-config/dubbo-config-api/src/test/java/org/apache/dubbo/config/AbstractInterfaceConfigTest.java
@@ -18,13 +18,13 @@ package org.apache.dubbo.config;
 
 import org.apache.dubbo.common.constants.CommonConstants;
 import org.apache.dubbo.config.api.Greeting;
+import org.apache.dubbo.config.bootstrap.DubboBootstrap;
 import org.apache.dubbo.config.mock.GreetingLocal1;
 import org.apache.dubbo.config.mock.GreetingLocal2;
 import org.apache.dubbo.config.mock.GreetingLocal3;
 import org.apache.dubbo.config.mock.GreetingMock1;
 import org.apache.dubbo.config.mock.GreetingMock2;
 import org.apache.dubbo.config.utils.ConfigValidationUtils;
-import org.apache.dubbo.rpc.model.ApplicationModel;
 
 import org.junit.jupiter.api.AfterAll;
 import org.junit.jupiter.api.AfterEach;
@@ -42,14 +42,14 @@ public class AbstractInterfaceConfigTest {
 
     @BeforeAll
     public static void setUp(@TempDir Path folder) {
-        ApplicationModel.reset();
+        DubboBootstrap.reset();
         dubboProperties = 
folder.resolve(CommonConstants.DUBBO_PROPERTIES_KEY).toFile();
         System.setProperty(CommonConstants.DUBBO_PROPERTIES_KEY, 
dubboProperties.getAbsolutePath());
     }
 
     @AfterAll
     public static void tearDown() {
-        ApplicationModel.reset();
+        DubboBootstrap.reset();
         System.clearProperty(CommonConstants.DUBBO_PROPERTIES_KEY);
     }
 
diff --git 
a/dubbo-config/dubbo-config-api/src/test/java/org/apache/dubbo/config/ReferenceConfigTest.java
 
b/dubbo-config/dubbo-config-api/src/test/java/org/apache/dubbo/config/ReferenceConfigTest.java
index 775596c..2000a42 100644
--- 
a/dubbo-config/dubbo-config-api/src/test/java/org/apache/dubbo/config/ReferenceConfigTest.java
+++ 
b/dubbo-config/dubbo-config-api/src/test/java/org/apache/dubbo/config/ReferenceConfigTest.java
@@ -20,26 +20,20 @@ import org.apache.dubbo.config.annotation.Argument;
 import org.apache.dubbo.config.annotation.Method;
 import org.apache.dubbo.config.annotation.Reference;
 import org.apache.dubbo.config.api.DemoService;
+import org.apache.dubbo.config.bootstrap.DubboBootstrap;
 import org.apache.dubbo.config.provider.impl.DemoServiceImpl;
-import org.apache.dubbo.rpc.model.ApplicationModel;
 
 import org.junit.jupiter.api.AfterEach;
 import org.junit.jupiter.api.Assertions;
-import org.junit.jupiter.api.BeforeEach;
 import org.junit.jupiter.api.Test;
 
 import static org.apache.dubbo.rpc.Constants.LOCAL_PROTOCOL;
 
 public class ReferenceConfigTest {
 
-    @BeforeEach
-    public void setUp() {
-        ApplicationModel.reset();
-    }
-
     @AfterEach
     public void tearDown() {
-        ApplicationModel.reset();
+        DubboBootstrap.reset();
     }
 
     @Test
@@ -122,6 +116,8 @@ public class ReferenceConfigTest {
         } catch (Exception e) {
             e.printStackTrace();
         } finally {
+            sc.unexport();
+            rc.destroy();
             System.clearProperty("java.net.preferIPv4Stack");
         }
         Assertions.assertTrue(success);
diff --git 
a/dubbo-config/dubbo-config-api/src/test/java/org/apache/dubbo/config/ServiceConfigTest.java
 
b/dubbo-config/dubbo-config-api/src/test/java/org/apache/dubbo/config/ServiceConfigTest.java
index ab5c670..0b53eb8 100644
--- 
a/dubbo-config/dubbo-config-api/src/test/java/org/apache/dubbo/config/ServiceConfigTest.java
+++ 
b/dubbo-config/dubbo-config-api/src/test/java/org/apache/dubbo/config/ServiceConfigTest.java
@@ -20,6 +20,7 @@ package org.apache.dubbo.config;
 import org.apache.dubbo.common.URL;
 import org.apache.dubbo.config.api.DemoService;
 import org.apache.dubbo.config.api.Greeting;
+import org.apache.dubbo.config.bootstrap.DubboBootstrap;
 import org.apache.dubbo.config.mock.MockProtocol2;
 import org.apache.dubbo.config.mock.MockRegistryFactory2;
 import org.apache.dubbo.config.mock.TestProxyFactory;
@@ -137,23 +138,26 @@ public class ServiceConfigTest {
     @Test
     public void testExport() throws Exception {
         service.export();
-
-        assertThat(service.getExportedUrls(), hasSize(1));
-        URL url = service.toUrl();
-        assertThat(url.getProtocol(), equalTo("mockprotocol2"));
-        assertThat(url.getPath(), equalTo(DemoService.class.getName()));
-        assertThat(url.getParameters(), hasEntry(ANYHOST_KEY, "true"));
-        assertThat(url.getParameters(), hasEntry(APPLICATION_KEY, "app"));
-        assertThat(url.getParameters(), hasKey(BIND_IP_KEY));
-        assertThat(url.getParameters(), hasKey(BIND_PORT_KEY));
-        assertThat(url.getParameters(), hasEntry(EXPORT_KEY, "true"));
-        assertThat(url.getParameters(), hasEntry("echo.0.callback", "false"));
-        assertThat(url.getParameters(), hasEntry(GENERIC_KEY, "false"));
-        assertThat(url.getParameters(), hasEntry(INTERFACE_KEY, 
DemoService.class.getName()));
-        assertThat(url.getParameters(), hasKey(METHODS_KEY));
-        assertThat(url.getParameters().get(METHODS_KEY), 
containsString("echo"));
-        assertThat(url.getParameters(), hasEntry(SIDE_KEY, PROVIDER));
-        Mockito.verify(protocolDelegate).export(Mockito.any(Invoker.class));
+        try {
+            assertThat(service.getExportedUrls(), hasSize(1));
+            URL url = service.toUrl();
+            assertThat(url.getProtocol(), equalTo("mockprotocol2"));
+            assertThat(url.getPath(), equalTo(DemoService.class.getName()));
+            assertThat(url.getParameters(), hasEntry(ANYHOST_KEY, "true"));
+            assertThat(url.getParameters(), hasEntry(APPLICATION_KEY, "app"));
+            assertThat(url.getParameters(), hasKey(BIND_IP_KEY));
+            assertThat(url.getParameters(), hasKey(BIND_PORT_KEY));
+            assertThat(url.getParameters(), hasEntry(EXPORT_KEY, "true"));
+            assertThat(url.getParameters(), hasEntry("echo.0.callback", 
"false"));
+            assertThat(url.getParameters(), hasEntry(GENERIC_KEY, "false"));
+            assertThat(url.getParameters(), hasEntry(INTERFACE_KEY, 
DemoService.class.getName()));
+            assertThat(url.getParameters(), hasKey(METHODS_KEY));
+            assertThat(url.getParameters().get(METHODS_KEY), 
containsString("echo"));
+            assertThat(url.getParameters(), hasEntry(SIDE_KEY, PROVIDER));
+            
Mockito.verify(protocolDelegate).export(Mockito.any(Invoker.class));
+        }finally {
+            service.unexport();
+        }
     }
 
     @Test
@@ -176,20 +180,27 @@ public class ServiceConfigTest {
     @Test
     public void testProxy() throws Exception {
         service2.export();
-
-        assertThat(service2.getExportedUrls(), hasSize(1));
-        assertEquals(2, TestProxyFactory.count); // local injvm and registry 
protocol, so expected is 2
-        TestProxyFactory.count = 0;
+        try {
+            assertThat(service2.getExportedUrls(), hasSize(1));
+            assertEquals(2, TestProxyFactory.count); // local injvm and 
registry protocol, so expected is 2
+            TestProxyFactory.count = 0;
+        }finally {
+            service2.unexport();
+        }
     }
 
 
     @Test
     public void testDelayExport() throws Exception {
         delayService.export();
-        assertTrue(delayService.getExportedUrls().isEmpty());
-        //add 300ms to ensure that the delayService has been exported
-        TimeUnit.MILLISECONDS.sleep(delayService.getDelay() + 300);
-        assertThat(delayService.getExportedUrls(), hasSize(1));
+        try {
+            assertTrue(delayService.getExportedUrls().isEmpty());
+            //add 300ms to ensure that the delayService has been exported
+            TimeUnit.MILLISECONDS.sleep(delayService.getDelay() + 300);
+            assertThat(delayService.getExportedUrls(), hasSize(1));
+        }finally {
+            delayService.unexport();
+        }
     }
 
     @Test
@@ -257,6 +268,7 @@ public class ServiceConfigTest {
             ServiceConfig service = new ServiceConfig();
             service.setGeneric("illegal");
         });
+        DubboBootstrap.reset();
     }
 
 //    @Test
@@ -278,7 +290,11 @@ public class ServiceConfigTest {
     @Test
     public void testApplicationInUrl() {
         service.export();
-        
Assertions.assertNotNull(service.toUrl().getParameter(APPLICATION_KEY));
-        Assertions.assertEquals("app", 
service.toUrl().getParameter(APPLICATION_KEY));
+        try {
+            
Assertions.assertNotNull(service.toUrl().getParameter(APPLICATION_KEY));
+            Assertions.assertEquals("app", 
service.toUrl().getParameter(APPLICATION_KEY));
+        }finally {
+            service.unexport();
+        }
     }
 }
diff --git 
a/dubbo-config/dubbo-config-api/src/test/java/org/apache/dubbo/config/event/listener/PublishingServiceDefinitionListenerTest.java
 
b/dubbo-config/dubbo-config-api/src/test/java/org/apache/dubbo/config/event/listener/PublishingServiceDefinitionListenerTest.java
index b4a0356..05ba478 100644
--- 
a/dubbo-config/dubbo-config-api/src/test/java/org/apache/dubbo/config/event/listener/PublishingServiceDefinitionListenerTest.java
+++ 
b/dubbo-config/dubbo-config-api/src/test/java/org/apache/dubbo/config/event/listener/PublishingServiceDefinitionListenerTest.java
@@ -21,6 +21,7 @@ import org.apache.dubbo.config.ApplicationConfig;
 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.bootstrap.EchoService;
 import org.apache.dubbo.config.bootstrap.EchoServiceImpl;
 import org.apache.dubbo.config.context.ConfigManager;
@@ -51,7 +52,7 @@ public class PublishingServiceDefinitionListenerTest {
 
     @BeforeEach
     public void init() {
-        ApplicationModel.reset();
+        DubboBootstrap.reset();
         String metadataType = DEFAULT_METADATA_STORAGE_TYPE;
         ConfigManager configManager = ApplicationModel.getConfigManager();
         ApplicationConfig applicationConfig = new 
ApplicationConfig("dubbo-demo-provider");
@@ -62,7 +63,7 @@ public class PublishingServiceDefinitionListenerTest {
 
     @AfterEach
     public void reset() {
-        ApplicationModel.reset();
+        DubboBootstrap.reset();
     }
 
     /**
@@ -82,5 +83,6 @@ public class PublishingServiceDefinitionListenerTest {
         ServiceDefinition serviceDefinitionBuild = 
ServiceDefinitionBuilder.build(serviceConfig.getInterfaceClass());
 
         assertEquals(serviceDefinition, new 
Gson().toJson(serviceDefinitionBuild));
+        serviceConfig.unexport();
     }
 }
diff --git 
a/dubbo-config/dubbo-config-api/src/test/java/org/apache/dubbo/config/url/ExporterSideConfigUrlTest.java
 
b/dubbo-config/dubbo-config-api/src/test/java/org/apache/dubbo/config/url/ExporterSideConfigUrlTest.java
index 5c19d04..2fd9a9e 100644
--- 
a/dubbo-config/dubbo-config-api/src/test/java/org/apache/dubbo/config/url/ExporterSideConfigUrlTest.java
+++ 
b/dubbo-config/dubbo-config-api/src/test/java/org/apache/dubbo/config/url/ExporterSideConfigUrlTest.java
@@ -19,7 +19,7 @@ package org.apache.dubbo.config.url;
 
 import org.apache.dubbo.common.logger.Logger;
 import org.apache.dubbo.common.logger.LoggerFactory;
-import org.apache.dubbo.rpc.model.ApplicationModel;
+import org.apache.dubbo.config.bootstrap.DubboBootstrap;
 
 import org.junit.jupiter.api.AfterEach;
 import org.junit.jupiter.api.BeforeAll;
@@ -43,13 +43,13 @@ public class ExporterSideConfigUrlTest extends UrlTestBase {
 
     @BeforeEach
     public void setUp() {
-        ApplicationModel.reset();
+        DubboBootstrap.reset();
         initServConf();
     }
 
     @AfterEach()
     public void teardown() {
-        ApplicationModel.reset();
+        DubboBootstrap.reset();
     }
 
     @Test
diff --git 
a/dubbo-config/dubbo-config-api/src/test/java/org/apache/dubbo/config/url/InvokerSideConfigUrlTest.java
 
b/dubbo-config/dubbo-config-api/src/test/java/org/apache/dubbo/config/url/InvokerSideConfigUrlTest.java
index 1850b90..c979f66 100644
--- 
a/dubbo-config/dubbo-config-api/src/test/java/org/apache/dubbo/config/url/InvokerSideConfigUrlTest.java
+++ 
b/dubbo-config/dubbo-config-api/src/test/java/org/apache/dubbo/config/url/InvokerSideConfigUrlTest.java
@@ -208,6 +208,8 @@ public class InvokerSideConfigUrlTest extends UrlTestBase {
         try {
             refConf.destroy();
         } catch (Exception e) {
+        }finally {
+            servConf.unexport();
         }
     }
 
diff --git 
a/dubbo-config/dubbo-config-spring/src/test/java/org/apache/dubbo/config/spring/beans/factory/annotation/ReferenceAnnotationBeanPostProcessorTest.java
 
b/dubbo-config/dubbo-config-spring/src/test/java/org/apache/dubbo/config/spring/beans/factory/annotation/ReferenceAnnotationBeanPostProcessorTest.java
index d262850..f8855cc 100644
--- 
a/dubbo-config/dubbo-config-spring/src/test/java/org/apache/dubbo/config/spring/beans/factory/annotation/ReferenceAnnotationBeanPostProcessorTest.java
+++ 
b/dubbo-config/dubbo-config-spring/src/test/java/org/apache/dubbo/config/spring/beans/factory/annotation/ReferenceAnnotationBeanPostProcessorTest.java
@@ -19,18 +19,16 @@ package 
org.apache.dubbo.config.spring.beans.factory.annotation;
 import org.apache.dubbo.config.annotation.Argument;
 import org.apache.dubbo.config.annotation.Method;
 import org.apache.dubbo.config.annotation.Reference;
+import org.apache.dubbo.config.bootstrap.DubboBootstrap;
 import org.apache.dubbo.config.spring.ReferenceBean;
 import org.apache.dubbo.config.spring.api.DemoService;
 import org.apache.dubbo.config.spring.api.HelloService;
 import org.apache.dubbo.config.utils.ReferenceConfigCache;
-import org.apache.dubbo.rpc.model.ApplicationModel;
 
 import org.aspectj.lang.ProceedingJoinPoint;
 import org.aspectj.lang.annotation.Around;
 import org.aspectj.lang.annotation.Aspect;
-import org.junit.jupiter.api.AfterAll;
 import org.junit.jupiter.api.Assertions;
-import org.junit.jupiter.api.BeforeAll;
 import org.junit.jupiter.api.Test;
 import org.junit.jupiter.api.extension.ExtendWith;
 import org.springframework.beans.factory.annotation.Autowired;
@@ -44,6 +42,7 @@ import org.springframework.stereotype.Component;
 import org.springframework.test.annotation.DirtiesContext;
 import org.springframework.test.context.ContextConfiguration;
 import org.springframework.test.context.TestPropertySource;
+import org.springframework.test.context.event.annotation.AfterTestMethod;
 import org.springframework.test.context.junit.jupiter.SpringExtension;
 
 import java.util.Collection;
@@ -73,14 +72,9 @@ import static org.junit.jupiter.api.Assertions.assertTrue;
 @DirtiesContext(classMode = DirtiesContext.ClassMode.AFTER_EACH_TEST_METHOD)
 public class ReferenceAnnotationBeanPostProcessorTest {
 
-    @BeforeAll
-    public static void setUp() {
-        ApplicationModel.reset();
-    }
-
-    @AfterAll
-    public static void tearDown() {
-        ApplicationModel.reset();
+    @AfterTestMethod
+    public void setUp() {
+        DubboBootstrap.reset();
     }
 
     private static final String AOP_SUFFIX = "(based on AOP)";
diff --git 
a/dubbo-config/dubbo-config-spring/src/test/java/org/apache/dubbo/config/spring/beans/factory/annotation/ServiceAnnotationBeanPostProcessorTest.java
 
b/dubbo-config/dubbo-config-spring/src/test/java/org/apache/dubbo/config/spring/beans/factory/annotation/ServiceAnnotationBeanPostProcessorTest.java
index 15921a4..5df5d9b 100644
--- 
a/dubbo-config/dubbo-config-spring/src/test/java/org/apache/dubbo/config/spring/beans/factory/annotation/ServiceAnnotationBeanPostProcessorTest.java
+++ 
b/dubbo-config/dubbo-config-spring/src/test/java/org/apache/dubbo/config/spring/beans/factory/annotation/ServiceAnnotationBeanPostProcessorTest.java
@@ -16,9 +16,9 @@
  */
 package org.apache.dubbo.config.spring.beans.factory.annotation;
 
+import org.apache.dubbo.config.bootstrap.DubboBootstrap;
 import org.apache.dubbo.config.spring.ServiceBean;
 import org.apache.dubbo.config.spring.api.HelloService;
-import org.apache.dubbo.rpc.model.ApplicationModel;
 
 import org.junit.jupiter.api.AfterEach;
 import org.junit.jupiter.api.Assertions;
@@ -54,14 +54,9 @@ import java.util.Map;
 @DirtiesContext(classMode = DirtiesContext.ClassMode.AFTER_EACH_TEST_METHOD)
 public class ServiceAnnotationBeanPostProcessorTest {
 
-    @BeforeEach
-    public void setUp() {
-        ApplicationModel.reset();
-    }
-
     @AfterEach
     public void tearDown() {
-        ApplicationModel.reset();
+        DubboBootstrap.reset();
     }
 
     @Autowired
diff --git 
a/dubbo-config/dubbo-config-spring/src/test/java/org/apache/dubbo/config/spring/beans/factory/annotation/ServiceClassPostProcessorTest.java
 
b/dubbo-config/dubbo-config-spring/src/test/java/org/apache/dubbo/config/spring/beans/factory/annotation/ServiceClassPostProcessorTest.java
index 0523459..d82e516 100644
--- 
a/dubbo-config/dubbo-config-spring/src/test/java/org/apache/dubbo/config/spring/beans/factory/annotation/ServiceClassPostProcessorTest.java
+++ 
b/dubbo-config/dubbo-config-spring/src/test/java/org/apache/dubbo/config/spring/beans/factory/annotation/ServiceClassPostProcessorTest.java
@@ -16,9 +16,9 @@
  */
 package org.apache.dubbo.config.spring.beans.factory.annotation;
 
+import org.apache.dubbo.config.bootstrap.DubboBootstrap;
 import org.apache.dubbo.config.spring.ServiceBean;
 import org.apache.dubbo.config.spring.api.HelloService;
-import org.apache.dubbo.rpc.model.ApplicationModel;
 
 import org.junit.jupiter.api.Assertions;
 import org.junit.jupiter.api.BeforeEach;
@@ -55,12 +55,12 @@ public class ServiceClassPostProcessorTest {
 
     @BeforeEach
     public void setUp() {
-        ApplicationModel.reset();
+        DubboBootstrap.reset();
     }
 
     @BeforeEach
     public void tearDown() {
-        ApplicationModel.reset();
+        DubboBootstrap.reset();
     }
 
     @Autowired
diff --git 
a/dubbo-config/dubbo-config-spring/src/test/java/org/apache/dubbo/config/spring/beans/factory/config/MultipleServicesWithMethodConfigsTest.java
 
b/dubbo-config/dubbo-config-spring/src/test/java/org/apache/dubbo/config/spring/beans/factory/config/MultipleServicesWithMethodConfigsTest.java
index d256a46..7bc1922 100644
--- 
a/dubbo-config/dubbo-config-spring/src/test/java/org/apache/dubbo/config/spring/beans/factory/config/MultipleServicesWithMethodConfigsTest.java
+++ 
b/dubbo-config/dubbo-config-spring/src/test/java/org/apache/dubbo/config/spring/beans/factory/config/MultipleServicesWithMethodConfigsTest.java
@@ -16,7 +16,7 @@
  */
 package org.apache.dubbo.config.spring.beans.factory.config;
 
-import org.apache.dubbo.rpc.model.ApplicationModel;
+import org.apache.dubbo.config.bootstrap.DubboBootstrap;
 
 import org.junit.jupiter.api.BeforeAll;
 import org.junit.jupiter.api.Test;
@@ -36,7 +36,7 @@ public class MultipleServicesWithMethodConfigsTest {
 
     @BeforeAll
     public static void setUp() {
-        ApplicationModel.reset();
+        DubboBootstrap.reset();
     }
 
     @Autowired
diff --git 
a/dubbo-config/dubbo-config-spring/src/test/java/org/apache/dubbo/config/spring/context/annotation/DubboComponentScanRegistrarTest.java
 
b/dubbo-config/dubbo-config-spring/src/test/java/org/apache/dubbo/config/spring/context/annotation/DubboComponentScanRegistrarTest.java
index 5bf43aa..d3175c0 100644
--- 
a/dubbo-config/dubbo-config-spring/src/test/java/org/apache/dubbo/config/spring/context/annotation/DubboComponentScanRegistrarTest.java
+++ 
b/dubbo-config/dubbo-config-spring/src/test/java/org/apache/dubbo/config/spring/context/annotation/DubboComponentScanRegistrarTest.java
@@ -16,6 +16,7 @@
  */
 package org.apache.dubbo.config.spring.context.annotation;
 
+import org.apache.dubbo.config.bootstrap.DubboBootstrap;
 import org.apache.dubbo.config.spring.api.DemoService;
 import 
org.apache.dubbo.config.spring.context.annotation.consumer.ConsumerConfiguration;
 import 
org.apache.dubbo.config.spring.context.annotation.provider.DemoServiceImpl;
@@ -43,7 +44,7 @@ public class DubboComponentScanRegistrarTest {
 
     @BeforeEach
     public void setUp() {
-        ApplicationModel.reset();
+        DubboBootstrap.reset();
     }
 
     @AfterEach
diff --git 
a/dubbo-config/dubbo-config-spring/src/test/java/org/apache/dubbo/config/spring/context/annotation/EnableDubboTest.java
 
b/dubbo-config/dubbo-config-spring/src/test/java/org/apache/dubbo/config/spring/context/annotation/EnableDubboTest.java
index 41dafbb..e35c2f2 100644
--- 
a/dubbo-config/dubbo-config-spring/src/test/java/org/apache/dubbo/config/spring/context/annotation/EnableDubboTest.java
+++ 
b/dubbo-config/dubbo-config-spring/src/test/java/org/apache/dubbo/config/spring/context/annotation/EnableDubboTest.java
@@ -17,10 +17,10 @@
 package org.apache.dubbo.config.spring.context.annotation;
 
 import org.apache.dubbo.config.RegistryConfig;
+import org.apache.dubbo.config.bootstrap.DubboBootstrap;
 import org.apache.dubbo.config.spring.api.DemoService;
 import 
org.apache.dubbo.config.spring.context.annotation.consumer.test.TestConsumerConfiguration;
 import 
org.apache.dubbo.config.spring.context.annotation.provider.DemoServiceImpl;
-import org.apache.dubbo.rpc.model.ApplicationModel;
 
 import org.junit.jupiter.api.AfterEach;
 import org.junit.jupiter.api.Assertions;
@@ -54,13 +54,13 @@ public class EnableDubboTest {
 
     @BeforeEach
     public void setUp() {
-        ApplicationModel.reset();
+        DubboBootstrap.reset();
         context = new AnnotationConfigApplicationContext();
     }
 
     @AfterEach
     public void tearDown() {
-        ApplicationModel.reset();
+        DubboBootstrap.reset();
         context.close();
     }
 
diff --git 
a/dubbo-config/dubbo-config-spring/src/test/java/org/apache/dubbo/config/spring/schema/DubboNamespaceHandlerTest.java
 
b/dubbo-config/dubbo-config-spring/src/test/java/org/apache/dubbo/config/spring/schema/DubboNamespaceHandlerTest.java
index b56069b..2b4defe 100644
--- 
a/dubbo-config/dubbo-config-spring/src/test/java/org/apache/dubbo/config/spring/schema/DubboNamespaceHandlerTest.java
+++ 
b/dubbo-config/dubbo-config-spring/src/test/java/org/apache/dubbo/config/spring/schema/DubboNamespaceHandlerTest.java
@@ -21,6 +21,7 @@ import org.apache.dubbo.config.ModuleConfig;
 import org.apache.dubbo.config.MonitorConfig;
 import org.apache.dubbo.config.ProtocolConfig;
 import org.apache.dubbo.config.ProviderConfig;
+import org.apache.dubbo.config.bootstrap.DubboBootstrap;
 import org.apache.dubbo.config.spring.ConfigTest;
 import org.apache.dubbo.config.spring.ServiceBean;
 import org.apache.dubbo.config.spring.api.DemoService;
@@ -51,7 +52,7 @@ import static org.hamcrest.MatcherAssert.assertThat;
 public class DubboNamespaceHandlerTest {
     @BeforeEach
     public void setUp() {
-        ApplicationModel.reset();
+        DubboBootstrap.reset();
     }
 
     @AfterEach
@@ -218,4 +219,19 @@ public class DubboNamespaceHandlerTest {
         assertThat(prefix, is("welcome:"));
         ctx.close();
     }
+
+
+    @Test
+    public void testDuplicateServiceBean() {
+        try {
+            ClassPathXmlApplicationContext ctx = new 
ClassPathXmlApplicationContext("classpath:/org/apache/dubbo/config/spring/demo-provider-duplicate-service-bean.xml");
+            ctx.start();
+            ctx.stop();
+            ctx.close();
+        } catch (IllegalStateException e) {
+            Assertions.assertTrue(e.getMessage().contains("There are multiple 
ServiceBean instances with the same service name"));
+            return;
+        }
+        Assertions.fail();
+    }
 }
\ No newline at end of file
diff --git 
a/dubbo-config/dubbo-config-spring/src/test/java/org/apache/dubbo/config/spring/schema/GenericServiceTest.java
 
b/dubbo-config/dubbo-config-spring/src/test/java/org/apache/dubbo/config/spring/schema/GenericServiceTest.java
index 72862bf..2ac4517 100644
--- 
a/dubbo-config/dubbo-config-spring/src/test/java/org/apache/dubbo/config/spring/schema/GenericServiceTest.java
+++ 
b/dubbo-config/dubbo-config-spring/src/test/java/org/apache/dubbo/config/spring/schema/GenericServiceTest.java
@@ -16,9 +16,9 @@
  */
 package org.apache.dubbo.config.spring.schema;
 
+import org.apache.dubbo.config.bootstrap.DubboBootstrap;
 import org.apache.dubbo.config.spring.ReferenceBean;
 import org.apache.dubbo.config.spring.ServiceBean;
-import org.apache.dubbo.rpc.model.ApplicationModel;
 
 import org.junit.jupiter.api.AfterEach;
 import org.junit.jupiter.api.BeforeEach;
@@ -42,12 +42,12 @@ public class GenericServiceTest {
 
     @BeforeEach
     public void setUp() {
-        ApplicationModel.reset();
+        DubboBootstrap.reset();
     }
 
     @AfterEach
     public void tearDown() {
-        ApplicationModel.reset();
+        DubboBootstrap.reset();
     }
 
     @Autowired
diff --git 
a/dubbo-config/dubbo-config-spring/src/test/resources/META-INF/spring/multiple-services-with-methods.xml
 
b/dubbo-config/dubbo-config-spring/src/test/resources/META-INF/spring/multiple-services-with-methods.xml
index 848990d..7699db8 100644
--- 
a/dubbo-config/dubbo-config-spring/src/test/resources/META-INF/spring/multiple-services-with-methods.xml
+++ 
b/dubbo-config/dubbo-config-spring/src/test/resources/META-INF/spring/multiple-services-with-methods.xml
@@ -32,12 +32,12 @@
 
     <!-- service configuration -->
     <dubbo:service interface="org.apache.dubbo.config.spring.api.DemoService"
-                   class="org.apache.dubbo.config.spring.impl.DemoServiceImpl">
+                   class="org.apache.dubbo.config.spring.impl.DemoServiceImpl" 
group="group1">
         <dubbo:method name="sayName" timeout="500" />
     </dubbo:service>
 
     <dubbo:service interface="org.apache.dubbo.config.spring.api.DemoService"
-                   
class="org.apache.dubbo.config.spring.impl.DemoServiceImpl_LongWaiting">
+                   
class="org.apache.dubbo.config.spring.impl.DemoServiceImpl_LongWaiting" 
group="group2">
         <dubbo:method name="sayName" timeout="1000" />
     </dubbo:service>
 
diff --git 
a/dubbo-config/dubbo-config-spring/src/test/resources/META-INF/spring/multiple-services-with-methods.xml
 
b/dubbo-config/dubbo-config-spring/src/test/resources/org/apache/dubbo/config/spring/demo-provider-duplicate-service-bean.xml
similarity index 77%
copy from 
dubbo-config/dubbo-config-spring/src/test/resources/META-INF/spring/multiple-services-with-methods.xml
copy to 
dubbo-config/dubbo-config-spring/src/test/resources/org/apache/dubbo/config/spring/demo-provider-duplicate-service-bean.xml
index 848990d..f4c6f15 100644
--- 
a/dubbo-config/dubbo-config-spring/src/test/resources/META-INF/spring/multiple-services-with-methods.xml
+++ 
b/dubbo-config/dubbo-config-spring/src/test/resources/org/apache/dubbo/config/spring/demo-provider-duplicate-service-bean.xml
@@ -1,45 +1,38 @@
-<!--
-  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.
-  -->
-<beans xmlns:xsi="http://www.w3.org/2001/XMLSchema-instance";
-       xmlns:dubbo="http://dubbo.apache.org/schema/dubbo";
-       xmlns="http://www.springframework.org/schema/beans";
-       xsi:schemaLocation="http://www.springframework.org/schema/beans 
http://www.springframework.org/schema/beans/spring-beans-4.3.xsd
-    http://dubbo.apache.org/schema/dubbo 
http://dubbo.apache.org/schema/dubbo/dubbo.xsd
-    ">
-
-    <!-- current application configuration -->
-    <dubbo:application id="application" name="demo-provider"/>
-
-    <!-- registry center configuration -->
-    <dubbo:registry id="registry" address="N/A"/>
-
-    <!-- protocol configuration -->
-    <dubbo:protocol name="dubbo" port="-1"/>
-
-    <!-- service configuration -->
-    <dubbo:service interface="org.apache.dubbo.config.spring.api.DemoService"
-                   class="org.apache.dubbo.config.spring.impl.DemoServiceImpl">
-        <dubbo:method name="sayName" timeout="500" />
-    </dubbo:service>
-
-    <dubbo:service interface="org.apache.dubbo.config.spring.api.DemoService"
-                   
class="org.apache.dubbo.config.spring.impl.DemoServiceImpl_LongWaiting">
-        <dubbo:method name="sayName" timeout="1000" />
-    </dubbo:service>
-
-
+<!--
+  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.
+  -->
+<beans xmlns:xsi="http://www.w3.org/2001/XMLSchema-instance";
+       xmlns:dubbo="http://dubbo.apache.org/schema/dubbo";
+       xmlns="http://www.springframework.org/schema/beans";
+       xsi:schemaLocation="http://www.springframework.org/schema/beans 
http://www.springframework.org/schema/beans/spring-beans-4.3.xsd
+    http://dubbo.apache.org/schema/dubbo 
http://dubbo.apache.org/schema/dubbo/dubbo.xsd
+    ">
+
+    <dubbo:application name="service-class"/>
+
+    <dubbo:registry address="N/A"/>
+
+    <dubbo:protocol name="dubbo" port="20887"/>
+    <!-- service configuration -->
+    <dubbo:service interface="org.apache.dubbo.config.spring.api.DemoService"
+                   class="org.apache.dubbo.config.spring.impl.DemoServiceImpl" 
group = "ready_for_duplicate_service_bean">
+    </dubbo:service>
+
+    <dubbo:service interface="org.apache.dubbo.config.spring.api.DemoService"
+                   class="org.apache.dubbo.config.spring.impl.DemoServiceImpl" 
group = "ready_for_duplicate_service_bean">
+    </dubbo:service>
+
 </beans>
\ No newline at end of file
diff --git 
a/dubbo-metadata/dubbo-metadata-api/src/main/java/org/apache/dubbo/metadata/report/MetadataReportInstance.java
 
b/dubbo-metadata/dubbo-metadata-api/src/main/java/org/apache/dubbo/metadata/report/MetadataReportInstance.java
index a10dabd..073b783 100644
--- 
a/dubbo-metadata/dubbo-metadata-api/src/main/java/org/apache/dubbo/metadata/report/MetadataReportInstance.java
+++ 
b/dubbo-metadata/dubbo-metadata-api/src/main/java/org/apache/dubbo/metadata/report/MetadataReportInstance.java
@@ -82,4 +82,13 @@ public class MetadataReportInstance {
             throw new IllegalStateException("the metadata report was not 
inited.");
         }
     }
+
+    // only for unit test
+    @Deprecated
+    public static void destroy() {
+        if (init.get()) {
+            metadataReports.clear();
+            init.compareAndSet(true, false);
+        }
+    }
 }
diff --git 
a/dubbo-metadata/dubbo-metadata-api/src/main/java/org/apache/dubbo/metadata/report/support/AbstractMetadataReportFactory.java
 
b/dubbo-metadata/dubbo-metadata-api/src/main/java/org/apache/dubbo/metadata/report/support/AbstractMetadataReportFactory.java
index f2867d7..2c6cf68 100644
--- 
a/dubbo-metadata/dubbo-metadata-api/src/main/java/org/apache/dubbo/metadata/report/support/AbstractMetadataReportFactory.java
+++ 
b/dubbo-metadata/dubbo-metadata-api/src/main/java/org/apache/dubbo/metadata/report/support/AbstractMetadataReportFactory.java
@@ -65,4 +65,15 @@ public abstract class AbstractMetadataReportFactory 
implements MetadataReportFac
     }
 
     protected abstract MetadataReport createMetadataReport(URL url);
+
+    // only for unit test
+    @Deprecated
+    public static void clear() {
+        LOCK.lock();
+        try {
+            SERVICE_STORE_MAP.clear();
+        } finally {
+            LOCK.unlock();
+        }
+    }
 }
diff --git 
a/dubbo-registry/dubbo-registry-api/src/main/java/org/apache/dubbo/registry/support/AbstractRegistryFactory.java
 
b/dubbo-registry/dubbo-registry-api/src/main/java/org/apache/dubbo/registry/support/AbstractRegistryFactory.java
index 4093f50..7acab0f 100644
--- 
a/dubbo-registry/dubbo-registry-api/src/main/java/org/apache/dubbo/registry/support/AbstractRegistryFactory.java
+++ 
b/dubbo-registry/dubbo-registry-api/src/main/java/org/apache/dubbo/registry/support/AbstractRegistryFactory.java
@@ -229,8 +229,10 @@ public abstract class AbstractRegistryFactory implements 
RegistryFactory {
     }
 
     // for unit test
-    public static void clearRegistryNotDestroy() {
+    @Deprecated
+    public static void reset() {
         REGISTRIES.clear();
+        destroyed.set(false);
     }
 
 }
diff --git 
a/dubbo-registry/dubbo-registry-default/src/test/java/org/apache/dubbo/registry/dubbo/RegistryStatusCheckerTest.java
 
b/dubbo-registry/dubbo-registry-default/src/test/java/org/apache/dubbo/registry/dubbo/RegistryStatusCheckerTest.java
index d8ae08a..c876581 100644
--- 
a/dubbo-registry/dubbo-registry-default/src/test/java/org/apache/dubbo/registry/dubbo/RegistryStatusCheckerTest.java
+++ 
b/dubbo-registry/dubbo-registry-default/src/test/java/org/apache/dubbo/registry/dubbo/RegistryStatusCheckerTest.java
@@ -47,7 +47,7 @@ public class RegistryStatusCheckerTest {
 
     @BeforeEach
     public void setUp() {
-        AbstractRegistryFactory.clearRegistryNotDestroy();
+        AbstractRegistryFactory.reset();
         
ApplicationModel.getServiceRepository().registerService(RegistryService.class);
     }
 

Reply via email to