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

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


The following commit(s) were added to refs/heads/3.0 by this push:
     new 7d0ff11  fixbug: Unit test often time out (#8439)
7d0ff11 is described below

commit 7d0ff116c159bf075e0ec9751db2c7f5f1f97b12
Author: Xiong, Pin <[email protected]>
AuthorDate: Sun Aug 8 09:18:07 2021 -0500

    fixbug: Unit test often time out (#8439)
    
    1. Make sure zookeeper is shutdown after all testcases finished
    2. Remove unused import
    3. Update unnecessary multiple zookeeper instances to single zookeeper 
instance
    4. Define SingleRegistryCenter and MultipleRegistryCenter
---
 .../multiple/MultipleZooKeeperServer.java          | 225 ---------------------
 ...MultipleRegistryCenterInjvmIntegrationTest.java |  35 ++--
 .../MultipleRegistryCenterInjvmServiceImpl.java    |   2 +-
 ...RegistryCenterDubboProtocolIntegrationTest.java |  25 +--
 .../integration/single/SingleZooKeeperServer.java  | 202 ------------------
 .../SingleRegistryCenterInjvmIntegrationTest.java  |  32 +--
 .../DefaultMultipleRegistryCenter.java             | 111 ++++++++++
 .../DefaultSingleRegistryCenter.java               | 101 +++++++++
 .../MultipleRegistryCenter.java}                   |  18 +-
 .../RegistryCenter.java}                           |  23 ++-
 .../SingleRegistryCenter.java}                     |  16 +-
 dubbo-config/dubbo-config-spring/pom.xml           |  11 +
 .../org/apache/dubbo/config/spring/ConfigTest.java |  14 +-
 .../dubbo/config/spring/JavaConfigBeanTest.java    |  12 +-
 .../annotation/MethodConfigCallbackTest.java       |  17 +-
 .../XmlReferenceBeanConditionalTest.java           |  13 +-
 ...nfigAnnotationReferenceBeanConditionalTest.java |  13 +-
 .../JavaConfigRawReferenceBeanConditionalTest.java |  13 +-
 .../JavaConfigReferenceBeanConditionalTest4.java   |  13 +-
 .../configprops/SpringBootConfigPropsTest.java     |  10 +-
 .../SpringBootMultipleConfigPropsTest.java         |  11 +-
 .../importxml/SpringBootImportDubboXmlTest.java    |  13 +-
 .../annotation/DubboConfigConfigurationTest.java   |  30 +--
 .../context/annotation/EnableDubboConfigTest.java  |   2 +-
 .../spring/issues/issue6000/Issue6000Test.java     |  18 +-
 .../spring/issues/issue6252/Issue6252Test.java     |  14 +-
 .../spring/issues/issue7003/Issue7003Test.java     |  18 +-
 .../consumer/PropertyConfigurerTest.java           |  19 +-
 .../consumer2/PropertySourcesConfigurerTest.java   |  17 +-
 .../consumer3/PropertySourcesInJavaConfigTest.java |  15 +-
 .../reference/DubboConfigBeanInitializerTest.java  |  10 +-
 .../config/spring/reference/ReferenceKeyTest.java  |  20 +-
 .../javaconfig/JavaConfigReferenceBeanTest.java    |  12 +-
 .../spring/reference/localcall/LocalCallTest.java  |  13 +-
 .../DefaultSingleRegistryCenter.java               | 101 +++++++++
 .../spring/registrycenter/RegistryCenter.java}     |  23 ++-
 .../registrycenter/SingleRegistryCenter.java}      |  16 +-
 .../{ => registrycenter}/ZooKeeperServer.java      |   6 +-
 .../config/spring/schema/GenericServiceTest.java   |  21 +-
 39 files changed, 689 insertions(+), 596 deletions(-)

diff --git 
a/dubbo-config/dubbo-config-api/src/test/java/org/apache/dubbo/integration/multiple/MultipleZooKeeperServer.java
 
b/dubbo-config/dubbo-config-api/src/test/java/org/apache/dubbo/integration/multiple/MultipleZooKeeperServer.java
deleted file mode 100644
index 8780b70..0000000
--- 
a/dubbo-config/dubbo-config-api/src/test/java/org/apache/dubbo/integration/multiple/MultipleZooKeeperServer.java
+++ /dev/null
@@ -1,225 +0,0 @@
-/*
- * 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.integration.multiple;
-
-import org.apache.dubbo.common.utils.NetUtils;
-import org.apache.zookeeper.server.ServerConfig;
-import org.apache.zookeeper.server.ZooKeeperServerMain;
-import org.apache.zookeeper.server.quorum.QuorumPeerConfig;
-import org.slf4j.Logger;
-import org.slf4j.LoggerFactory;
-
-import java.io.File;
-import java.lang.reflect.Method;
-import java.util.Properties;
-import java.util.UUID;
-
-/**
- * The zookeeper server is just for testing.
- * Also there is only one static instance, which can be created.
- * <p>
- * Note: It can only be used if the following conditions are satisfied
- * <p>1. Integration testcase instead of unit testcase
- * <p>2. You can use only one zookeeper instance per Package, because the 
zookeeper is a static global instance.
- */
-public class MultipleZooKeeperServer {
-
-    private static final Logger logger = 
LoggerFactory.getLogger(MultipleZooKeeperServer.class);
-
-    /**
-     * Define a static zookeeper instance.
-     */
-    private static volatile InnerZooKeeper INSTANCE_ONE;
-
-    /**
-     * Define a static zookeeper instance.
-     */
-    private static volatile InnerZooKeeper INSTANCE_TWO;
-
-    /**
-     * Start the zookeeper instances.
-     */
-    public static void start() {
-        if (INSTANCE_ONE == null) {
-            INSTANCE_ONE = new 
InnerZooKeeper("multiple-zookeeper-server-one-for-test",
-                NetUtils.getAvailablePort());
-            INSTANCE_ONE.start();
-        }
-        if (INSTANCE_TWO == null) {
-            INSTANCE_TWO = new 
InnerZooKeeper("multiple-zookeeper-server-two-for-test",
-                NetUtils.getAvailablePort());
-            INSTANCE_TWO.start();
-        }
-    }
-
-    /**
-     * Returns the zookeeper-one server's port.
-     */
-    public static int getPortOne() {
-        return INSTANCE_ONE.getClientPort();
-    }
-
-    /**
-     * Returns the zookeeper-two server's port.
-     */
-    public static int getPortTwo() {
-        return INSTANCE_TWO.getClientPort();
-    }
-
-    /**
-     * Checks if all zookeeper servers are running.
-     */
-    public static boolean isRunning() {
-        return INSTANCE_ONE.isRunning() && INSTANCE_TWO.isRunning();
-    }
-
-    /**
-     * Shutdown all zookeeper instances.
-     */
-    public static void shutdown() {
-        if (INSTANCE_ONE != null) {
-            INSTANCE_ONE.shutdown();
-            INSTANCE_ONE = null;
-        }
-
-        if (INSTANCE_TWO != null) {
-            INSTANCE_TWO.shutdown();
-            INSTANCE_TWO = null;
-        }
-    }
-
-    /**
-     * from: 
https://github.com/spring-projects/spring-xd/blob/v1.3.1.RELEASE/spring-xd-dirt/src/main/java/org/springframework/xd/dirt/zookeeper/ZooKeeperUtils.java
-     * <p>
-     * Helper class to start an embedded instance of standalone (non 
clustered) ZooKeeper.
-     * <p>
-     * NOTE: at least an external standalone server (if not an ensemble) are 
recommended, even for
-     */
-    private static class InnerZooKeeper {
-
-        /**
-         * ZooKeeper client port. This will be determined dynamically upon 
startup.
-         */
-        private final int clientPort;
-
-        /**
-         * ZooKeeper name.
-         */
-        private final String zookeeperName;
-
-        /**
-         * Thread for running the ZooKeeper server.
-         */
-        private volatile Thread zkServerThread;
-
-        /**
-         * ZooKeeper server.
-         */
-        private volatile ZooKeeperServerMain zkServer;
-
-        /**
-         * Construct an EmbeddedZooKeeper with the provided port.
-         *
-         * @param zookeeperName zookeeper name
-         * @param clientPort port for ZooKeeper server to bind to
-         */
-        public InnerZooKeeper(String zookeeperName, int clientPort) {
-            this.zookeeperName = zookeeperName;
-            this.clientPort = clientPort;
-        }
-
-        /**
-         * Returns the port that clients should use to connect to this 
embedded server.
-         *
-         * @return dynamically determined client port
-         */
-        public int getClientPort() {
-            return this.clientPort;
-        }
-
-        /**
-         * Checks if the zookeeper server is running.
-         */
-        public boolean isRunning() {
-            return (zkServerThread != null);
-        }
-
-        /**
-         * Start the ZooKeeper server in a background thread.
-         * <p>
-         * any exceptions thrown during startup or execution.
-         */
-        private synchronized void start() {
-            if (zkServerThread == null) {
-                zkServerThread = new Thread(() -> {
-                    try {
-                        Properties properties = new Properties();
-                        File file = new 
File(System.getProperty("java.io.tmpdir")
-                            + File.separator + UUID.randomUUID());
-                        file.deleteOnExit();
-                        properties.setProperty("dataDir", 
file.getAbsolutePath());
-                        properties.setProperty("clientPort", 
String.valueOf(clientPort));
-
-                        QuorumPeerConfig quorumPeerConfig = new 
QuorumPeerConfig();
-                        quorumPeerConfig.parseProperties(properties);
-
-                        zkServer = new ZooKeeperServerMain();
-                        ServerConfig configuration = new ServerConfig();
-                        configuration.readFrom(quorumPeerConfig);
-
-                        zkServer.runFromConfig(configuration);
-                    } catch (Exception e) {
-                        logger.error("Exception running embedded ZooKeeper", 
e);
-                    }
-                }, zookeeperName);
-                zkServerThread.setDaemon(true);
-                zkServerThread.start();
-            }
-        }
-
-        /**
-         * Shutdown the ZooKeeper server.
-         */
-        private synchronized void shutdown() {
-            if (zkServerThread != null) {
-                // The shutdown method is protected...thus this hack to invoke 
it.
-                // This will log an exception on shutdown; see
-                // https://issues.apache.org/jira/browse/ZOOKEEPER-1873 for 
details.
-                try {
-                    Method shutdown = 
ZooKeeperServerMain.class.getDeclaredMethod("shutdown");
-                    shutdown.setAccessible(true);
-                    shutdown.invoke(zkServer);
-                } catch (Exception e) {
-                    throw new RuntimeException(e);
-                }
-
-                // It is expected that the thread will exit after
-                // the server is shutdown; this will block until
-                // the shutdown is complete.
-                try {
-                    zkServerThread.join(5000);
-                    zkServerThread = null;
-                } catch (InterruptedException e) {
-                    Thread.currentThread().interrupt();
-                    logger.warn("Interrupted while waiting for embedded 
ZooKeeper to exit");
-                    // abandoning zk thread
-                    zkServerThread = null;
-                }
-            }
-        }
-    }
-}
diff --git 
a/dubbo-config/dubbo-config-api/src/test/java/org/apache/dubbo/integration/multiple/injvm/MultipleRegistryCenterInjvmIntegrationTest.java
 
b/dubbo-config/dubbo-config-api/src/test/java/org/apache/dubbo/integration/multiple/injvm/MultipleRegistryCenterInjvmIntegrationTest.java
index 815c759..e0ac0bc 100644
--- 
a/dubbo-config/dubbo-config-api/src/test/java/org/apache/dubbo/integration/multiple/injvm/MultipleRegistryCenterInjvmIntegrationTest.java
+++ 
b/dubbo-config/dubbo-config-api/src/test/java/org/apache/dubbo/integration/multiple/injvm/MultipleRegistryCenterInjvmIntegrationTest.java
@@ -25,13 +25,14 @@ import org.apache.dubbo.config.RegistryConfig;
 import org.apache.dubbo.config.ProtocolConfig;
 import org.apache.dubbo.config.bootstrap.DubboBootstrap;
 import org.apache.dubbo.integration.IntegrationTest;
-import org.apache.dubbo.integration.multiple.MultipleZooKeeperServer;
-import 
org.apache.dubbo.integration.single.injvm.SingleRegistryCenterInjvmService;
+import org.apache.dubbo.registrycenter.DefaultMultipleRegistryCenter;
+import org.apache.dubbo.registrycenter.MultipleRegistryCenter;
 import org.apache.dubbo.rpc.ExporterListener;
 import org.apache.dubbo.rpc.Filter;
 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 org.slf4j.Logger;
 import org.slf4j.LoggerFactory;
 
@@ -76,13 +77,18 @@ public class MultipleRegistryCenterInjvmIntegrationTest 
implements IntegrationTe
      */
     private MultipleRegistryCenterInjvmFilter filter;
 
+    /**
+     * Default a registry center.
+     */
+    private MultipleRegistryCenter registryCenter;
+
     @BeforeEach
     public void setUp() throws Exception {
         logger.info(getClass().getSimpleName() + " testcase is beginning...");
         DubboBootstrap.reset();
         //start all zookeeper services only once
-        MultipleZooKeeperServer.start();
-
+        registryCenter = new DefaultMultipleRegistryCenter();
+        registryCenter.startup();
         // initialize service config
         serviceConfig = new ServiceConfig<>();
         serviceConfig.setInterface(MultipleRegistryCenterInjvmService.class);
@@ -91,10 +97,11 @@ public class MultipleRegistryCenterInjvmIntegrationTest 
implements IntegrationTe
         serviceConfig.setScope(SCOPE_LOCAL);
 
         // initailize bootstrap
+        for (RegistryConfig registryConfig : 
registryCenter.getRegistryConfigs()) {
+            DubboBootstrap.getInstance().registry(registryConfig);
+        }
         DubboBootstrap.getInstance()
             .application(new ApplicationConfig(PROVIDER_APPLICATION_NAME))
-            .registry(new RegistryConfig("zookeeper://127.0.0.1:" + 
MultipleZooKeeperServer.getPortOne()))
-            .registry(new RegistryConfig("zookeeper://127.0.0.1:" + 
MultipleZooKeeperServer.getPortTwo()))
             .protocol(new ProtocolConfig("injvm"))
             .service(serviceConfig);
     }
@@ -127,13 +134,14 @@ public class MultipleRegistryCenterInjvmIntegrationTest 
implements IntegrationTe
     /**
      * {@inheritDoc}
      */
+    @Test
     @Override
     public void integrate() {
         beforeExport();
         DubboBootstrap.getInstance().start();
         afterExport();
-        ReferenceConfig<SingleRegistryCenterInjvmService> referenceConfig = 
new ReferenceConfig<>();
-        referenceConfig.setInterface(SingleRegistryCenterInjvmService.class);
+        ReferenceConfig<MultipleRegistryCenterInjvmService> referenceConfig = 
new ReferenceConfig<>();
+        referenceConfig.setInterface(MultipleRegistryCenterInjvmService.class);
         referenceConfig.setBootstrap(DubboBootstrap.getInstance());
         referenceConfig.setScope(SCOPE_LOCAL);
         referenceConfig.get().hello("Dubbo in multiple registry center");
@@ -152,14 +160,14 @@ public class MultipleRegistryCenterInjvmIntegrationTest 
implements IntegrationTe
      */
     private void afterExport() {
         // The exported service is only one
-        
Assertions.assertEquals(serviceListener.getExportedServices().size(),1);
+        Assertions.assertEquals(serviceListener.getExportedServices().size(), 
1);
         // The exported service is MultipleRegistryCenterInjvmService
         
Assertions.assertEquals(serviceListener.getExportedServices().get(0).getInterfaceClass(),
             MultipleRegistryCenterInjvmService.class);
         // The MultipleRegistryCenterInjvmService is exported
         
Assertions.assertTrue(serviceListener.getExportedServices().get(0).isExported());
         // The exported exporter is only one
-        
Assertions.assertEquals(exporterListener.getExportedExporters().size(),1);
+        
Assertions.assertEquals(exporterListener.getExportedExporters().size(), 1);
         // The exported exporter contains MultipleRegistryCenterInjvmFilter
         Assertions.assertTrue(exporterListener.getFilters().contains(filter));
     }
@@ -172,7 +180,7 @@ public class MultipleRegistryCenterInjvmIntegrationTest 
implements IntegrationTe
      *     <li>The MultipleRegistryCenterInjvmFilter's response is right or 
not</li>
      * </ul>
      */
-    private void afterInvoke(){
+    private void afterInvoke() {
         // The MultipleRegistryCenterInjvmFilter has called
         Assertions.assertTrue(filter.hasCalled());
         // The MultipleRegistryCenterInjvmFilter doesn't exist error
@@ -191,7 +199,8 @@ public class MultipleRegistryCenterInjvmIntegrationTest 
implements IntegrationTe
         Assertions.assertTrue(serviceListener.getExportedServices().isEmpty());
         serviceListener = null;
         logger.info(getClass().getSimpleName() + " testcase is ending...");
-        // destroy zookeeper only once
-        MultipleZooKeeperServer.shutdown();
+        // destroy registry center
+        registryCenter.shutdown();
+        registryCenter = null;
     }
 }
diff --git 
a/dubbo-config/dubbo-config-api/src/test/java/org/apache/dubbo/integration/multiple/injvm/MultipleRegistryCenterInjvmServiceImpl.java
 
b/dubbo-config/dubbo-config-api/src/test/java/org/apache/dubbo/integration/multiple/injvm/MultipleRegistryCenterInjvmServiceImpl.java
index f04a5ea..533da89 100644
--- 
a/dubbo-config/dubbo-config-api/src/test/java/org/apache/dubbo/integration/multiple/injvm/MultipleRegistryCenterInjvmServiceImpl.java
+++ 
b/dubbo-config/dubbo-config-api/src/test/java/org/apache/dubbo/integration/multiple/injvm/MultipleRegistryCenterInjvmServiceImpl.java
@@ -25,6 +25,6 @@ public class MultipleRegistryCenterInjvmServiceImpl 
implements MultipleRegistryC
      */
     @Override
     public String hello(String name) {
-        return null;
+        return "Hello " + name;
     }
 }
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 fa62302..474c88b 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
@@ -37,6 +37,8 @@ import 
org.apache.dubbo.registry.client.metadata.store.InMemoryWritableMetadataS
 import org.apache.dubbo.registry.client.migration.MigrationInvoker;
 import org.apache.dubbo.registry.support.AbstractRegistryFactory;
 import org.apache.dubbo.registry.zookeeper.ZookeeperServiceDiscovery;
+import org.apache.dubbo.registrycenter.DefaultSingleRegistryCenter;
+import org.apache.dubbo.registrycenter.SingleRegistryCenter;
 import org.apache.dubbo.rpc.cluster.Directory;
 import org.junit.jupiter.api.Assertions;
 import org.junit.jupiter.api.BeforeEach;
@@ -98,14 +100,17 @@ public class 
SingleRegistryCenterDubboProtocolIntegrationTest implements Integra
      */
     private SingleRegistryCenterExportedServiceListener 
singleRegistryCenterExportedServiceListener;
 
+    /**
+     * Define a registry center.
+     */
+    private SingleRegistryCenter registryCenter;
+
     @BeforeEach
     public void setUp() throws Exception {
         logger.info(getClass().getSimpleName() + " testcase is beginning...");
         DubboBootstrap.reset();
-        //start zookeeper only once
-        logger.info(SingleZooKeeperServer.getZookeeperServerName() + " is 
beginning to start...");
-        SingleZooKeeperServer.start();
-        logger.info(SingleZooKeeperServer.getZookeeperServerName() + " has 
started.");
+        registryCenter = new DefaultSingleRegistryCenter();
+        registryCenter.startup();
         // initialize ServiceConfig
         serviceConfig = new ServiceConfig<>();
         
serviceConfig.setInterface(SingleRegistryCenterIntegrationService.class);
@@ -114,7 +119,7 @@ public class 
SingleRegistryCenterDubboProtocolIntegrationTest implements Integra
 
         DubboBootstrap.getInstance()
             .application(new ApplicationConfig(PROVIDER_APPLICATION_NAME))
-            .registry(registryConfig = new 
RegistryConfig("zookeeper://127.0.0.1:" + SingleZooKeeperServer.getPort()))
+            .registry(registryConfig = registryCenter.getRegistryConfig())
             .protocol(new ProtocolConfig(PROTOCOL_NAME, PROTOCOL_PORT))
             .service(serviceConfig);
     }
@@ -137,7 +142,6 @@ public class 
SingleRegistryCenterDubboProtocolIntegrationTest implements Integra
     /**
      * There are some checkpoints needed to check as follow :
      * <ul>
-     *     <li>ZookeeperServer's status</li>
      *     <li>ServiceConfig is exported or not</li>
      *     <li>ServiceConfig's exportedUrl has values or not</li>
      *     <li>DubboBootstrap is initialized or not</li>
@@ -147,8 +151,6 @@ public class 
SingleRegistryCenterDubboProtocolIntegrationTest implements Integra
      * </ul>
      */
     private void beforeExport() {
-        // ZookeeperServer's status
-        Assertions.assertTrue(SingleZooKeeperServer.isRunning());
         // ServiceConfig is exported or not
         Assertions.assertFalse(serviceConfig.isExported());
         // ServiceConfig's exportedUrl has values or not
@@ -387,9 +389,8 @@ public class 
SingleRegistryCenterDubboProtocolIntegrationTest implements Integra
         
Assertions.assertTrue(singleRegistryCenterExportedServiceListener.getExportedServices().isEmpty());
         singleRegistryCenterExportedServiceListener = null;
         logger.info(getClass().getSimpleName() + " testcase is ending...");
-        // destroy zookeeper only once
-        logger.info(SingleZooKeeperServer.getZookeeperServerName() + " is 
beginning to shutdown...");
-        SingleZooKeeperServer.shutdown();
-        logger.info(SingleZooKeeperServer.getZookeeperServerName() + " has 
shutdown.");
+        // destroy registry center
+        registryCenter.shutdown();
+        registryCenter = null;
     }
 }
diff --git 
a/dubbo-config/dubbo-config-api/src/test/java/org/apache/dubbo/integration/single/SingleZooKeeperServer.java
 
b/dubbo-config/dubbo-config-api/src/test/java/org/apache/dubbo/integration/single/SingleZooKeeperServer.java
deleted file mode 100644
index c27fdda..0000000
--- 
a/dubbo-config/dubbo-config-api/src/test/java/org/apache/dubbo/integration/single/SingleZooKeeperServer.java
+++ /dev/null
@@ -1,202 +0,0 @@
-/*
- * 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.integration.single;
-
-import org.apache.dubbo.common.utils.NetUtils;
-import org.apache.zookeeper.server.ServerConfig;
-import org.apache.zookeeper.server.ZooKeeperServerMain;
-import org.apache.zookeeper.server.quorum.QuorumPeerConfig;
-import org.slf4j.Logger;
-import org.slf4j.LoggerFactory;
-
-import java.io.File;
-import java.lang.reflect.Method;
-import java.util.Properties;
-import java.util.UUID;
-
-/**
- * The zookeeper server is just for testing.
- * Also there is only one static instance, which can be created.
- * <p>
- * Note: It can only be used if the following conditions are satisfied
- * <p>1. Integration testcase instead of unit testcase
- * <p>2. You can use only one zookeeper instance per Package, because the 
zookeeper is a static global instance.
- */
-public class SingleZooKeeperServer {
-
-    private static final Logger logger = 
LoggerFactory.getLogger(SingleZooKeeperServer.class);
-
-    /**
-     * Define a static zookeeper instance.
-     */
-    private static volatile InnerZooKeeper INSTANCE;
-
-    /**
-     * Start the zookeeper instance.
-     */
-    public static void start() {
-        if (INSTANCE == null) {
-            INSTANCE = new InnerZooKeeper(NetUtils.getAvailablePort());
-            INSTANCE.start();
-        }
-    }
-
-    /**
-     * Returns the zookeeper server's port.
-     */
-    public static int getPort() {
-        return INSTANCE.getClientPort();
-    }
-
-    /**
-     * Checks if the zookeeper server is running.
-     */
-    public static boolean isRunning(){
-        return INSTANCE.isRunning();
-    }
-
-    /**
-     * Returns the zookeeper server's name.
-     */
-    public static String getZookeeperServerName(){
-        return "single-zookeeper-server-for-test";
-    }
-
-    /**
-     * Shutdown the zookeeper instance.
-     */
-    public static void shutdown() {
-        if (INSTANCE != null) {
-            INSTANCE.shutdown();
-            INSTANCE = null;
-        }
-    }
-
-    /**
-     * from: 
https://github.com/spring-projects/spring-xd/blob/v1.3.1.RELEASE/spring-xd-dirt/src/main/java/org/springframework/xd/dirt/zookeeper/ZooKeeperUtils.java
-     * <p>
-     * Helper class to start an embedded instance of standalone (non 
clustered) ZooKeeper.
-     * <p>
-     * NOTE: at least an external standalone server (if not an ensemble) are 
recommended, even for
-     */
-    private static class InnerZooKeeper {
-
-        /**
-         * ZooKeeper client port. This will be determined dynamically upon 
startup.
-         */
-        private final int clientPort;
-
-        /**
-         * Thread for running the ZooKeeper server.
-         */
-        private volatile Thread zkServerThread;
-
-        /**
-         * ZooKeeper server.
-         */
-        private volatile ZooKeeperServerMain zkServer;
-
-        /**
-         * Construct an EmbeddedZooKeeper with the provided port.
-         *
-         * @param clientPort port for ZooKeeper server to bind to
-         */
-        public InnerZooKeeper(int clientPort) {
-            this.clientPort = clientPort;
-        }
-
-        /**
-         * Returns the port that clients should use to connect to this 
embedded server.
-         *
-         * @return dynamically determined client port
-         */
-        public int getClientPort() {
-            return this.clientPort;
-        }
-
-        /**
-         * Checks if the zookeeper server is running.
-         */
-        public boolean isRunning() {
-            return (zkServerThread != null);
-        }
-
-        /**
-         * Start the ZooKeeper server in a background thread.
-         * <p>
-         * any exceptions thrown during startup or execution.
-         */
-        private synchronized void start() {
-            if (zkServerThread == null) {
-                zkServerThread = new Thread(() -> {
-                    try {
-                        Properties properties = new Properties();
-                        File file = new 
File(System.getProperty("java.io.tmpdir")
-                            + File.separator + UUID.randomUUID());
-                        file.deleteOnExit();
-                        properties.setProperty("dataDir", 
file.getAbsolutePath());
-                        properties.setProperty("clientPort", 
String.valueOf(clientPort));
-
-                        QuorumPeerConfig quorumPeerConfig = new 
QuorumPeerConfig();
-                        quorumPeerConfig.parseProperties(properties);
-
-                        zkServer = new ZooKeeperServerMain();
-                        ServerConfig configuration = new ServerConfig();
-                        configuration.readFrom(quorumPeerConfig);
-
-                        zkServer.runFromConfig(configuration);
-                    } catch (Exception e) {
-                        logger.error("Exception running embedded ZooKeeper", 
e);
-                    }
-                }, getZookeeperServerName());
-                zkServerThread.setDaemon(true);
-                zkServerThread.start();
-            }
-        }
-
-        /**
-         * Shutdown the ZooKeeper server.
-         */
-        private synchronized void shutdown() {
-            if (zkServerThread != null) {
-                // The shutdown method is protected...thus this hack to invoke 
it.
-                // This will log an exception on shutdown; see
-                // https://issues.apache.org/jira/browse/ZOOKEEPER-1873 for 
details.
-                try {
-                    Method shutdown = 
ZooKeeperServerMain.class.getDeclaredMethod("shutdown");
-                    shutdown.setAccessible(true);
-                    shutdown.invoke(zkServer);
-                } catch (Exception e) {
-                    throw new RuntimeException(e);
-                }
-
-                // It is expected that the thread will exit after
-                // the server is shutdown; this will block until
-                // the shutdown is complete.
-                try {
-                    zkServerThread.join(5000);
-                    zkServerThread = null;
-                } catch (InterruptedException e) {
-                    Thread.currentThread().interrupt();
-                    logger.warn("Interrupted while waiting for embedded 
ZooKeeper to exit");
-                    // abandoning zk thread
-                    zkServerThread = null;
-                }
-            }
-        }
-    }
-}
diff --git 
a/dubbo-config/dubbo-config-api/src/test/java/org/apache/dubbo/integration/single/injvm/SingleRegistryCenterInjvmIntegrationTest.java
 
b/dubbo-config/dubbo-config-api/src/test/java/org/apache/dubbo/integration/single/injvm/SingleRegistryCenterInjvmIntegrationTest.java
index 429da7b..50e6c3f 100644
--- 
a/dubbo-config/dubbo-config-api/src/test/java/org/apache/dubbo/integration/single/injvm/SingleRegistryCenterInjvmIntegrationTest.java
+++ 
b/dubbo-config/dubbo-config-api/src/test/java/org/apache/dubbo/integration/single/injvm/SingleRegistryCenterInjvmIntegrationTest.java
@@ -21,11 +21,11 @@ import org.apache.dubbo.config.ServiceConfig;
 import org.apache.dubbo.config.ReferenceConfig;
 import org.apache.dubbo.config.ServiceListener;
 import org.apache.dubbo.config.ApplicationConfig;
-import org.apache.dubbo.config.RegistryConfig;
 import org.apache.dubbo.config.ProtocolConfig;
 import org.apache.dubbo.config.bootstrap.DubboBootstrap;
 import org.apache.dubbo.integration.IntegrationTest;
-import org.apache.dubbo.integration.single.SingleZooKeeperServer;
+import org.apache.dubbo.registrycenter.DefaultSingleRegistryCenter;
+import org.apache.dubbo.registrycenter.SingleRegistryCenter;
 import org.apache.dubbo.rpc.ExporterListener;
 import org.apache.dubbo.rpc.Filter;
 import org.junit.jupiter.api.AfterEach;
@@ -75,15 +75,17 @@ public class SingleRegistryCenterInjvmIntegrationTest 
implements IntegrationTest
      */
     private SingleRegistryCenterInjvmFilter filter;
 
+    /**
+     * Define a registry center.
+     */
+    private SingleRegistryCenter registryCenter;
+
     @BeforeEach
     public void setUp() throws Exception {
         logger.info(getClass().getSimpleName() + " testcase is beginning...");
         DubboBootstrap.reset();
-        //start zookeeper only once
-        logger.info(SingleZooKeeperServer.getZookeeperServerName() + " is 
beginning to start...");
-        SingleZooKeeperServer.start();
-        logger.info(SingleZooKeeperServer.getZookeeperServerName() + " has 
started.");
-
+        registryCenter = new DefaultSingleRegistryCenter();
+        registryCenter.startup();
         // initialize service config
         serviceConfig = new ServiceConfig<>();
         serviceConfig.setInterface(SingleRegistryCenterInjvmService.class);
@@ -94,7 +96,7 @@ public class SingleRegistryCenterInjvmIntegrationTest 
implements IntegrationTest
         // initailize bootstrap
         DubboBootstrap.getInstance()
             .application(new ApplicationConfig(PROVIDER_APPLICATION_NAME))
-            .registry(new RegistryConfig("zookeeper://127.0.0.1:" + 
SingleZooKeeperServer.getPort()))
+            .registry(registryCenter.getRegistryConfig())
             .protocol(new ProtocolConfig("injvm"))
             .service(serviceConfig);
     }
@@ -153,14 +155,14 @@ public class SingleRegistryCenterInjvmIntegrationTest 
implements IntegrationTest
      */
     private void afterExport() {
         // The exported service is only one
-        
Assertions.assertEquals(serviceListener.getExportedServices().size(),1);
+        Assertions.assertEquals(serviceListener.getExportedServices().size(), 
1);
         // The exported service is SingleRegistryCenterInjvmService
         
Assertions.assertEquals(serviceListener.getExportedServices().get(0).getInterfaceClass(),
             SingleRegistryCenterInjvmService.class);
         // The SingleRegistryCenterInjvmService is exported
         
Assertions.assertTrue(serviceListener.getExportedServices().get(0).isExported());
         // The exported exporter is only one
-        
Assertions.assertEquals(exporterListener.getExportedExporters().size(),1);
+        
Assertions.assertEquals(exporterListener.getExportedExporters().size(), 1);
         // The exported exporter contains SingleRegistryCenterInjvmFilter
         Assertions.assertTrue(exporterListener.getFilters().contains(filter));
     }
@@ -173,13 +175,13 @@ public class SingleRegistryCenterInjvmIntegrationTest 
implements IntegrationTest
      *     <li>The SingleRegistryCenterInjvmFilter's response is right or 
not</li>
      * </ul>
      */
-    private void afterInvoke(){
+    private void afterInvoke() {
         // The SingleRegistryCenterInjvmFilter has called
         Assertions.assertTrue(filter.hasCalled());
         // The SingleRegistryCenterInjvmFilter doesn't exist error
         Assertions.assertFalse(filter.hasError());
         // Check the SingleRegistryCenterInjvmFilter's response
-        Assertions.assertEquals("Hello Dubbo",filter.getResponse());
+        Assertions.assertEquals("Hello Dubbo", filter.getResponse());
     }
 
     @AfterEach
@@ -191,9 +193,7 @@ public class SingleRegistryCenterInjvmIntegrationTest 
implements IntegrationTest
         Assertions.assertTrue(serviceListener.getExportedServices().isEmpty());
         serviceListener = null;
         logger.info(getClass().getSimpleName() + " testcase is ending...");
-        // destroy zookeeper only once
-        logger.info(SingleZooKeeperServer.getZookeeperServerName() + " is 
beginning to shutdown...");
-        SingleZooKeeperServer.shutdown();
-        logger.info(SingleZooKeeperServer.getZookeeperServerName() + " has 
shutdown.");
+        registryCenter.shutdown();
+        registryCenter = null;
     }
 }
diff --git 
a/dubbo-config/dubbo-config-api/src/test/java/org/apache/dubbo/registrycenter/DefaultMultipleRegistryCenter.java
 
b/dubbo-config/dubbo-config-api/src/test/java/org/apache/dubbo/registrycenter/DefaultMultipleRegistryCenter.java
new file mode 100644
index 0000000..ba7f3ea
--- /dev/null
+++ 
b/dubbo-config/dubbo-config-api/src/test/java/org/apache/dubbo/registrycenter/DefaultMultipleRegistryCenter.java
@@ -0,0 +1,111 @@
+/*
+ * 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.registrycenter;
+
+import org.apache.curator.test.TestingServer;
+import org.apache.dubbo.common.logger.Logger;
+import org.apache.dubbo.common.logger.LoggerFactory;
+import org.apache.dubbo.config.RegistryConfig;
+import org.apache.dubbo.rpc.RpcException;
+
+import java.io.IOException;
+import java.util.ArrayList;
+import java.util.List;
+
+/**
+ * The default multiple registry center.
+ */
+public class DefaultMultipleRegistryCenter implements MultipleRegistryCenter {
+
+    private static final Logger logger = 
LoggerFactory.getLogger(DefaultMultipleRegistryCenter.class);
+
+    /**
+     * Define a zookeeper server.
+     */
+    private volatile TestingServer zookeeperServer1;
+
+    /**
+     * Define a zookeeper server.
+     */
+    private volatile TestingServer zookeeperServer2;
+
+    /**
+     * The zookeeper server's default port.
+     */
+    private static final int DEFAULT_PORT = 2181;
+
+    /**
+     * {@inheritDoc}
+     */
+    @Override
+    public void startup() throws RpcException {
+        try {
+            logger.info("The DefaultMultipleRegistryCenter is starting...");
+            this.zookeeperServer1 = new TestingServer(DEFAULT_PORT);
+            this.zookeeperServer2 = new TestingServer();
+            logger.info("The DefaultMultipleRegistryCenter is started 
successfully");
+        } catch (Exception exception) {
+            try {
+                if (this.zookeeperServer1 != null) {
+                    this.zookeeperServer1.close();
+                }
+                if (this.zookeeperServer2 != null) {
+                    this.zookeeperServer2.close();
+                }
+            } catch (IOException e) {
+                // ignore
+            } finally {
+                this.zookeeperServer1 = null;
+                this.zookeeperServer2 = null;
+            }
+            throw new RpcException("Failed to initialize 
DefaultMultipleRegistryCenter instance", exception);
+        }
+    }
+
+    /**
+     * {@inheritDoc}
+     */
+    @Override
+    public List<RegistryConfig> getRegistryConfigs() {
+        List<RegistryConfig> registryConfigs = new ArrayList<>(2);
+        registryConfigs.add(new RegistryConfig("zookeeper://" + 
this.zookeeperServer1.getConnectString()));
+        registryConfigs.add(new RegistryConfig("zookeeper://" + 
this.zookeeperServer2.getConnectString()));
+        return registryConfigs;
+    }
+
+    /**
+     * {@inheritDoc}
+     */
+    @Override
+    public void shutdown() throws RpcException {
+        try {
+            logger.info("The DefaultMultipleRegistryCenter is stopping...");
+            if (this.zookeeperServer1 != null) {
+                this.zookeeperServer1.close();
+            }
+            if (this.zookeeperServer2 != null) {
+                this.zookeeperServer2.close();
+            }
+            logger.info("The DefaultMultipleRegistryCenter is shutdown 
successfully");
+        } catch (IOException exception) {
+            throw new RpcException("Failed to close 
DefaultMultipleRegistryCenter instance", exception);
+        } finally {
+            this.zookeeperServer1 = null;
+            this.zookeeperServer2 = null;
+        }
+    }
+}
diff --git 
a/dubbo-config/dubbo-config-api/src/test/java/org/apache/dubbo/registrycenter/DefaultSingleRegistryCenter.java
 
b/dubbo-config/dubbo-config-api/src/test/java/org/apache/dubbo/registrycenter/DefaultSingleRegistryCenter.java
new file mode 100644
index 0000000..d76c5ce
--- /dev/null
+++ 
b/dubbo-config/dubbo-config-api/src/test/java/org/apache/dubbo/registrycenter/DefaultSingleRegistryCenter.java
@@ -0,0 +1,101 @@
+/*
+ * 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.registrycenter;
+
+import org.apache.curator.test.TestingServer;
+import org.apache.dubbo.common.logger.Logger;
+import org.apache.dubbo.common.logger.LoggerFactory;
+import org.apache.dubbo.config.RegistryConfig;
+import org.apache.dubbo.rpc.RpcException;
+
+import java.io.IOException;
+
+/**
+ * The default single registry center.
+ */
+public class DefaultSingleRegistryCenter implements SingleRegistryCenter {
+
+    /**
+     * Initialize {@link RegistryCenter} instance.
+     */
+    public DefaultSingleRegistryCenter() {
+        this(DEFAULT_PORT);
+    }
+
+    /**
+     * Initialize {@link RegistryCenter} instance.
+     *
+     * @param port the zookeeper server's port.
+     */
+    public DefaultSingleRegistryCenter(int port) {
+        this.port = port;
+    }
+
+    private static final Logger logger = 
LoggerFactory.getLogger(DefaultSingleRegistryCenter.class);
+
+    /**
+     * The zookeeper server's default port.
+     */
+    private static final int DEFAULT_PORT = 2181;
+    /**
+     * Define a zookeeper server.
+     */
+    private volatile TestingServer zookeeperServer;
+
+    /**
+     * The zookeeper server's port.
+     */
+    private int port;
+
+    /**
+     * {@inheritDoc}
+     */
+    @Override
+    public void startup() throws RpcException {
+        try {
+            logger.info("The DefaultSingleRegistryCenter is starting...");
+            this.zookeeperServer = new TestingServer(this.port, true);
+            logger.info("The DefaultSingleRegistryCenter is started 
successfully");
+        } catch (Exception exception) {
+            throw new RpcException("Failed to initialize 
DefaultSingleRegistryCenter instance", exception);
+        }
+    }
+
+    /**
+     * {@inheritDoc}
+     */
+    @Override
+    public RegistryConfig getRegistryConfig() {
+        return new RegistryConfig("zookeeper://" + 
this.zookeeperServer.getConnectString());
+    }
+
+    /**
+     * {@inheritDoc}
+     */
+    @Override
+    public void shutdown() throws RpcException {
+        try {
+            logger.info("The DefaultSingleRegistryCenter is stopping...");
+            if (this.zookeeperServer != null) {
+                this.zookeeperServer.close();
+            }
+            logger.info("The DefaultSingleRegistryCenter is shutdown 
successfully");
+        } catch (IOException exception) {
+            throw new RpcException("Failed to close 
DefaultSingleRegistryCenter instance", exception);
+        }
+    }
+}
diff --git 
a/dubbo-config/dubbo-config-api/src/test/java/org/apache/dubbo/integration/multiple/injvm/MultipleRegistryCenterInjvmServiceImpl.java
 
b/dubbo-config/dubbo-config-api/src/test/java/org/apache/dubbo/registrycenter/MultipleRegistryCenter.java
similarity index 71%
copy from 
dubbo-config/dubbo-config-api/src/test/java/org/apache/dubbo/integration/multiple/injvm/MultipleRegistryCenterInjvmServiceImpl.java
copy to 
dubbo-config/dubbo-config-api/src/test/java/org/apache/dubbo/registrycenter/MultipleRegistryCenter.java
index f04a5ea..543b52e 100644
--- 
a/dubbo-config/dubbo-config-api/src/test/java/org/apache/dubbo/integration/multiple/injvm/MultipleRegistryCenterInjvmServiceImpl.java
+++ 
b/dubbo-config/dubbo-config-api/src/test/java/org/apache/dubbo/registrycenter/MultipleRegistryCenter.java
@@ -14,17 +14,19 @@
  * See the License for the specific language governing permissions and
  * limitations under the License.
  */
-package org.apache.dubbo.integration.multiple.injvm;
+package org.apache.dubbo.registrycenter;
+
+import org.apache.dubbo.config.RegistryConfig;
+
+import java.util.List;
 
 /**
- * The simple implementation for {@link MultipleRegistryCenterInjvmService}
+ * Mock multiple registry center.
  */
-public class MultipleRegistryCenterInjvmServiceImpl implements 
MultipleRegistryCenterInjvmService {
+public interface MultipleRegistryCenter extends RegistryCenter {
+
     /**
-     * {@inheritDoc}
+     * Returns {@link RegistryConfig} instances.
      */
-    @Override
-    public String hello(String name) {
-        return null;
-    }
+    List<RegistryConfig> getRegistryConfigs();
 }
diff --git 
a/dubbo-config/dubbo-config-api/src/test/java/org/apache/dubbo/integration/multiple/injvm/MultipleRegistryCenterInjvmServiceImpl.java
 
b/dubbo-config/dubbo-config-api/src/test/java/org/apache/dubbo/registrycenter/RegistryCenter.java
similarity index 66%
copy from 
dubbo-config/dubbo-config-api/src/test/java/org/apache/dubbo/integration/multiple/injvm/MultipleRegistryCenterInjvmServiceImpl.java
copy to 
dubbo-config/dubbo-config-api/src/test/java/org/apache/dubbo/registrycenter/RegistryCenter.java
index f04a5ea..7daea27 100644
--- 
a/dubbo-config/dubbo-config-api/src/test/java/org/apache/dubbo/integration/multiple/injvm/MultipleRegistryCenterInjvmServiceImpl.java
+++ 
b/dubbo-config/dubbo-config-api/src/test/java/org/apache/dubbo/registrycenter/RegistryCenter.java
@@ -14,17 +14,24 @@
  * See the License for the specific language governing permissions and
  * limitations under the License.
  */
-package org.apache.dubbo.integration.multiple.injvm;
+package org.apache.dubbo.registrycenter;
+
+import org.apache.dubbo.rpc.RpcException;
 
 /**
- * The simple implementation for {@link MultipleRegistryCenterInjvmService}
+ * The mock registry center.
  */
-public class MultipleRegistryCenterInjvmServiceImpl implements 
MultipleRegistryCenterInjvmService {
+public interface RegistryCenter {
+
+    /**
+     * Start the registry center.
+     * @throws RpcException when an exception occurred
+     */
+    void startup() throws RpcException;
+
     /**
-     * {@inheritDoc}
+     * Stop the registry center.
+     * @throws RpcException when an exception occurred
      */
-    @Override
-    public String hello(String name) {
-        return null;
-    }
+    void shutdown() throws RpcException;
 }
diff --git 
a/dubbo-config/dubbo-config-api/src/test/java/org/apache/dubbo/integration/multiple/injvm/MultipleRegistryCenterInjvmServiceImpl.java
 
b/dubbo-config/dubbo-config-api/src/test/java/org/apache/dubbo/registrycenter/SingleRegistryCenter.java
similarity index 71%
copy from 
dubbo-config/dubbo-config-api/src/test/java/org/apache/dubbo/integration/multiple/injvm/MultipleRegistryCenterInjvmServiceImpl.java
copy to 
dubbo-config/dubbo-config-api/src/test/java/org/apache/dubbo/registrycenter/SingleRegistryCenter.java
index f04a5ea..2b12c74 100644
--- 
a/dubbo-config/dubbo-config-api/src/test/java/org/apache/dubbo/integration/multiple/injvm/MultipleRegistryCenterInjvmServiceImpl.java
+++ 
b/dubbo-config/dubbo-config-api/src/test/java/org/apache/dubbo/registrycenter/SingleRegistryCenter.java
@@ -14,17 +14,17 @@
  * See the License for the specific language governing permissions and
  * limitations under the License.
  */
-package org.apache.dubbo.integration.multiple.injvm;
+package org.apache.dubbo.registrycenter;
+
+import org.apache.dubbo.config.RegistryConfig;
 
 /**
- * The simple implementation for {@link MultipleRegistryCenterInjvmService}
+ * Mock single registry center.
  */
-public class MultipleRegistryCenterInjvmServiceImpl implements 
MultipleRegistryCenterInjvmService {
+public interface SingleRegistryCenter extends RegistryCenter {
+
     /**
-     * {@inheritDoc}
+     * Returns {@link RegistryConfig} instance.
      */
-    @Override
-    public String hello(String name) {
-        return null;
-    }
+    RegistryConfig getRegistryConfig();
 }
diff --git a/dubbo-config/dubbo-config-spring/pom.xml 
b/dubbo-config/dubbo-config-spring/pom.xml
index 2414579..42be9f0 100644
--- a/dubbo-config/dubbo-config-spring/pom.xml
+++ b/dubbo-config/dubbo-config-spring/pom.xml
@@ -191,6 +191,17 @@
             <artifactId>nacos-client</artifactId>
             <scope>test</scope>
         </dependency>
+        <dependency>
+            <groupId>org.apache.curator</groupId>
+            <artifactId>curator-test</artifactId>
+            <scope>test</scope>
+            <exclusions>
+                <exclusion>
+                    <groupId>com.google.guava</groupId>
+                    <artifactId>guava</artifactId>
+                </exclusion>
+            </exclusions>
+        </dependency>
     </dependencies>
 
     <build>
diff --git 
a/dubbo-config/dubbo-config-spring/src/test/java/org/apache/dubbo/config/spring/ConfigTest.java
 
b/dubbo-config/dubbo-config-spring/src/test/java/org/apache/dubbo/config/spring/ConfigTest.java
index bfc9217..8b026a8 100644
--- 
a/dubbo-config/dubbo-config-spring/src/test/java/org/apache/dubbo/config/spring/ConfigTest.java
+++ 
b/dubbo-config/dubbo-config-spring/src/test/java/org/apache/dubbo/config/spring/ConfigTest.java
@@ -42,6 +42,8 @@ import org.apache.dubbo.config.spring.impl.HelloServiceImpl;
 import org.apache.dubbo.config.spring.impl.NotifyService;
 import org.apache.dubbo.config.spring.registry.MockRegistry;
 import org.apache.dubbo.config.spring.registry.MockRegistryFactory;
+import 
org.apache.dubbo.config.spring.registrycenter.DefaultSingleRegistryCenter;
+import org.apache.dubbo.config.spring.registrycenter.SingleRegistryCenter;
 import org.apache.dubbo.registry.Registry;
 import org.apache.dubbo.registry.RegistryService;
 import org.apache.dubbo.rpc.Exporter;
@@ -53,6 +55,7 @@ import org.apache.dubbo.rpc.service.GenericService;
 import org.junit.jupiter.api.AfterEach;
 import org.junit.jupiter.api.Assertions;
 import org.junit.jupiter.api.BeforeAll;
+import org.junit.jupiter.api.AfterAll;
 import org.junit.jupiter.api.BeforeEach;
 import org.junit.jupiter.api.Disabled;
 import org.junit.jupiter.api.Test;
@@ -61,7 +64,6 @@ import 
org.springframework.context.annotation.AnnotationConfigApplicationContext
 import org.springframework.context.support.ClassPathXmlApplicationContext;
 
 import java.util.Collection;
-import java.util.HashMap;
 import java.util.List;
 import java.util.Map;
 
@@ -83,9 +85,17 @@ public class ConfigTest {
 
     private static String resourcePath = 
ConfigTest.class.getPackage().getName().replace('.', '/');
 
+    private static SingleRegistryCenter singleRegistryCenter;
+
     @BeforeAll
     public static void beforeAll() {
-        ZooKeeperServer.start();
+        singleRegistryCenter = new DefaultSingleRegistryCenter();
+        singleRegistryCenter.startup();
+    }
+
+    @AfterAll
+    public static void afterAll() {
+        singleRegistryCenter.shutdown();
     }
 
     @BeforeEach
diff --git 
a/dubbo-config/dubbo-config-spring/src/test/java/org/apache/dubbo/config/spring/JavaConfigBeanTest.java
 
b/dubbo-config/dubbo-config-spring/src/test/java/org/apache/dubbo/config/spring/JavaConfigBeanTest.java
index 9e65281..2514121 100644
--- 
a/dubbo-config/dubbo-config-spring/src/test/java/org/apache/dubbo/config/spring/JavaConfigBeanTest.java
+++ 
b/dubbo-config/dubbo-config-spring/src/test/java/org/apache/dubbo/config/spring/JavaConfigBeanTest.java
@@ -28,11 +28,14 @@ import org.apache.dubbo.config.context.ConfigManager;
 import org.apache.dubbo.config.spring.api.DemoService;
 import org.apache.dubbo.config.spring.context.annotation.EnableDubbo;
 import org.apache.dubbo.config.spring.impl.DemoServiceImpl;
+import 
org.apache.dubbo.config.spring.registrycenter.DefaultSingleRegistryCenter;
+import org.apache.dubbo.config.spring.registrycenter.SingleRegistryCenter;
 import org.apache.dubbo.rpc.Constants;
 import org.apache.dubbo.rpc.model.ApplicationModel;
 import org.junit.jupiter.api.AfterEach;
 import org.junit.jupiter.api.Assertions;
 import org.junit.jupiter.api.BeforeAll;
+import org.junit.jupiter.api.AfterAll;
 import org.junit.jupiter.api.BeforeEach;
 import org.junit.jupiter.api.Test;
 import 
org.springframework.context.annotation.AnnotationConfigApplicationContext;
@@ -46,10 +49,17 @@ public class JavaConfigBeanTest {
 
     private static final String MY_PROTOCOL_ID = "myProtocol";
     private static final String MY_REGISTRY_ID = "my-registry";
+    private static SingleRegistryCenter singleRegistryCenter;
 
     @BeforeAll
     public static void beforeAll() {
-        ZooKeeperServer.start();
+        singleRegistryCenter = new DefaultSingleRegistryCenter();
+        singleRegistryCenter.startup();
+    }
+
+    @AfterAll
+    public static void afterAll() {
+        singleRegistryCenter.shutdown();
     }
 
     @BeforeEach
diff --git 
a/dubbo-config/dubbo-config-spring/src/test/java/org/apache/dubbo/config/spring/beans/factory/annotation/MethodConfigCallbackTest.java
 
b/dubbo-config/dubbo-config-spring/src/test/java/org/apache/dubbo/config/spring/beans/factory/annotation/MethodConfigCallbackTest.java
index b2f436f..e81230f 100644
--- 
a/dubbo-config/dubbo-config-spring/src/test/java/org/apache/dubbo/config/spring/beans/factory/annotation/MethodConfigCallbackTest.java
+++ 
b/dubbo-config/dubbo-config-spring/src/test/java/org/apache/dubbo/config/spring/beans/factory/annotation/MethodConfigCallbackTest.java
@@ -19,13 +19,15 @@ package 
org.apache.dubbo.config.spring.beans.factory.annotation;
 import org.apache.dubbo.config.annotation.DubboReference;
 import org.apache.dubbo.config.annotation.Method;
 import org.apache.dubbo.config.bootstrap.DubboBootstrap;
-import org.apache.dubbo.config.spring.ZooKeeperServer;
 import org.apache.dubbo.config.spring.api.HelloService;
 import org.apache.dubbo.config.spring.api.MethodCallback;
 import 
org.apache.dubbo.config.spring.context.annotation.provider.ProviderConfiguration;
 import org.apache.dubbo.config.spring.impl.MethodCallbackImpl;
+import 
org.apache.dubbo.config.spring.registrycenter.DefaultSingleRegistryCenter;
+import org.apache.dubbo.config.spring.registrycenter.SingleRegistryCenter;
 import org.junit.jupiter.api.Assertions;
 import org.junit.jupiter.api.BeforeAll;
+import org.junit.jupiter.api.AfterAll;
 import org.junit.jupiter.api.Test;
 import org.junit.jupiter.api.extension.ExtendWith;
 import org.springframework.beans.factory.annotation.Autowired;
@@ -53,10 +55,19 @@ import 
org.springframework.test.context.junit.jupiter.SpringExtension;
 @DirtiesContext(classMode = DirtiesContext.ClassMode.AFTER_EACH_TEST_METHOD)
 public class MethodConfigCallbackTest {
 
+    private static SingleRegistryCenter singleRegistryCenter;
+
     @BeforeAll
-    public static void setUp() {
+    public static void beforeAll() {
+        singleRegistryCenter = new DefaultSingleRegistryCenter();
+        singleRegistryCenter.startup();
+        DubboBootstrap.reset();
+    }
+
+    @AfterAll
+    public static void afterAll() {
         DubboBootstrap.reset();
-        ZooKeeperServer.start();
+        singleRegistryCenter.shutdown();
     }
 
     @Autowired
diff --git 
a/dubbo-config/dubbo-config-spring/src/test/java/org/apache/dubbo/config/spring/boot/conditional1/XmlReferenceBeanConditionalTest.java
 
b/dubbo-config/dubbo-config-spring/src/test/java/org/apache/dubbo/config/spring/boot/conditional1/XmlReferenceBeanConditionalTest.java
index d88af40..99a4aee 100644
--- 
a/dubbo-config/dubbo-config-spring/src/test/java/org/apache/dubbo/config/spring/boot/conditional1/XmlReferenceBeanConditionalTest.java
+++ 
b/dubbo-config/dubbo-config-spring/src/test/java/org/apache/dubbo/config/spring/boot/conditional1/XmlReferenceBeanConditionalTest.java
@@ -17,8 +17,9 @@
 package org.apache.dubbo.config.spring.boot.conditional1;
 
 import org.apache.dubbo.config.bootstrap.DubboBootstrap;
-import org.apache.dubbo.config.spring.ZooKeeperServer;
 import org.apache.dubbo.config.spring.api.HelloService;
+import 
org.apache.dubbo.config.spring.registrycenter.DefaultSingleRegistryCenter;
+import org.apache.dubbo.config.spring.registrycenter.SingleRegistryCenter;
 import org.junit.jupiter.api.AfterAll;
 import org.junit.jupiter.api.Assertions;
 import org.junit.jupiter.api.BeforeAll;
@@ -49,15 +50,19 @@ import java.util.Map;
 //@ComponentScan
 public class XmlReferenceBeanConditionalTest {
 
+    private static SingleRegistryCenter singleRegistryCenter;
+
     @BeforeAll
-    public static void setUp(){
-        ZooKeeperServer.start();
+    public static void beforeAll(){
+        singleRegistryCenter = new DefaultSingleRegistryCenter();
+        singleRegistryCenter.startup();
         DubboBootstrap.reset();
     }
 
     @AfterAll
-    public static void tearDown(){
+    public static void afterAll(){
         DubboBootstrap.reset();
+        singleRegistryCenter.shutdown();
     }
 
     @Autowired
diff --git 
a/dubbo-config/dubbo-config-spring/src/test/java/org/apache/dubbo/config/spring/boot/conditional2/JavaConfigAnnotationReferenceBeanConditionalTest.java
 
b/dubbo-config/dubbo-config-spring/src/test/java/org/apache/dubbo/config/spring/boot/conditional2/JavaConfigAnnotationReferenceBeanConditionalTest.java
index d3af807..3a9ed93 100644
--- 
a/dubbo-config/dubbo-config-spring/src/test/java/org/apache/dubbo/config/spring/boot/conditional2/JavaConfigAnnotationReferenceBeanConditionalTest.java
+++ 
b/dubbo-config/dubbo-config-spring/src/test/java/org/apache/dubbo/config/spring/boot/conditional2/JavaConfigAnnotationReferenceBeanConditionalTest.java
@@ -19,10 +19,11 @@ package org.apache.dubbo.config.spring.boot.conditional2;
 import org.apache.dubbo.config.annotation.DubboReference;
 import org.apache.dubbo.config.bootstrap.DubboBootstrap;
 import org.apache.dubbo.config.spring.ReferenceBean;
-import org.apache.dubbo.config.spring.ZooKeeperServer;
 import org.apache.dubbo.config.spring.api.HelloService;
 import org.apache.dubbo.config.spring.context.annotation.EnableDubbo;
 import 
org.apache.dubbo.config.spring.context.annotation.provider.HelloServiceImpl;
+import 
org.apache.dubbo.config.spring.registrycenter.DefaultSingleRegistryCenter;
+import org.apache.dubbo.config.spring.registrycenter.SingleRegistryCenter;
 import org.junit.jupiter.api.AfterAll;
 import org.junit.jupiter.api.Assertions;
 import org.junit.jupiter.api.BeforeAll;
@@ -55,15 +56,19 @@ import java.util.Map;
 @EnableDubbo
 public class JavaConfigAnnotationReferenceBeanConditionalTest {
 
+    private static SingleRegistryCenter singleRegistryCenter;
+
     @BeforeAll
-    public static void setUp(){
-        ZooKeeperServer.start();
+    public static void beforeAll(){
+        singleRegistryCenter = new DefaultSingleRegistryCenter();
+        singleRegistryCenter.startup();
         DubboBootstrap.reset();
     }
 
     @AfterAll
-    public static void tearDown(){
+    public static void afterAll(){
         DubboBootstrap.reset();
+        singleRegistryCenter.shutdown();
     }
 
     @Autowired
diff --git 
a/dubbo-config/dubbo-config-spring/src/test/java/org/apache/dubbo/config/spring/boot/conditional3/JavaConfigRawReferenceBeanConditionalTest.java
 
b/dubbo-config/dubbo-config-spring/src/test/java/org/apache/dubbo/config/spring/boot/conditional3/JavaConfigRawReferenceBeanConditionalTest.java
index ec11f3c..32c52d9 100644
--- 
a/dubbo-config/dubbo-config-spring/src/test/java/org/apache/dubbo/config/spring/boot/conditional3/JavaConfigRawReferenceBeanConditionalTest.java
+++ 
b/dubbo-config/dubbo-config-spring/src/test/java/org/apache/dubbo/config/spring/boot/conditional3/JavaConfigRawReferenceBeanConditionalTest.java
@@ -18,11 +18,12 @@ package org.apache.dubbo.config.spring.boot.conditional3;
 
 import org.apache.dubbo.config.bootstrap.DubboBootstrap;
 import org.apache.dubbo.config.spring.ReferenceBean;
-import org.apache.dubbo.config.spring.ZooKeeperServer;
 import org.apache.dubbo.config.spring.api.HelloService;
 import org.apache.dubbo.config.spring.context.annotation.EnableDubbo;
 import 
org.apache.dubbo.config.spring.context.annotation.provider.HelloServiceImpl;
 import org.apache.dubbo.config.spring.reference.ReferenceBeanBuilder;
+import 
org.apache.dubbo.config.spring.registrycenter.DefaultSingleRegistryCenter;
+import org.apache.dubbo.config.spring.registrycenter.SingleRegistryCenter;
 import org.junit.jupiter.api.AfterAll;
 import org.junit.jupiter.api.Assertions;
 import org.junit.jupiter.api.BeforeAll;
@@ -55,15 +56,19 @@ import java.util.Map;
 @EnableDubbo
 public class JavaConfigRawReferenceBeanConditionalTest {
 
+    private static SingleRegistryCenter singleRegistryCenter;
+
     @BeforeAll
-    public static void setUp(){
-        ZooKeeperServer.start();
+    public static void beforeAll(){
+        singleRegistryCenter = new DefaultSingleRegistryCenter();
+        singleRegistryCenter.startup();
         DubboBootstrap.reset();
     }
 
     @AfterAll
-    public static void tearDown(){
+    public static void afterAll(){
         DubboBootstrap.reset();
+        singleRegistryCenter.shutdown();
     }
 
     @Autowired
diff --git 
a/dubbo-config/dubbo-config-spring/src/test/java/org/apache/dubbo/config/spring/boot/conditional4/JavaConfigReferenceBeanConditionalTest4.java
 
b/dubbo-config/dubbo-config-spring/src/test/java/org/apache/dubbo/config/spring/boot/conditional4/JavaConfigReferenceBeanConditionalTest4.java
index b6b9ff8..7bec3f4 100644
--- 
a/dubbo-config/dubbo-config-spring/src/test/java/org/apache/dubbo/config/spring/boot/conditional4/JavaConfigReferenceBeanConditionalTest4.java
+++ 
b/dubbo-config/dubbo-config-spring/src/test/java/org/apache/dubbo/config/spring/boot/conditional4/JavaConfigReferenceBeanConditionalTest4.java
@@ -19,10 +19,11 @@ package org.apache.dubbo.config.spring.boot.conditional4;
 import org.apache.dubbo.config.annotation.DubboReference;
 import org.apache.dubbo.config.bootstrap.DubboBootstrap;
 import org.apache.dubbo.config.spring.ReferenceBean;
-import org.apache.dubbo.config.spring.ZooKeeperServer;
 import org.apache.dubbo.config.spring.api.HelloService;
 import org.apache.dubbo.config.spring.context.annotation.EnableDubbo;
 import 
org.apache.dubbo.config.spring.context.annotation.provider.HelloServiceImpl;
+import 
org.apache.dubbo.config.spring.registrycenter.DefaultSingleRegistryCenter;
+import org.apache.dubbo.config.spring.registrycenter.SingleRegistryCenter;
 import org.junit.jupiter.api.AfterAll;
 import org.junit.jupiter.api.Assertions;
 import org.junit.jupiter.api.BeforeAll;
@@ -55,15 +56,19 @@ import java.util.Map;
 @EnableDubbo
 public class JavaConfigReferenceBeanConditionalTest4 {
 
+    private static SingleRegistryCenter singleRegistryCenter;
+
     @BeforeAll
-    public static void setUp(){
-        ZooKeeperServer.start();
+    public static void beforeAll(){
+        singleRegistryCenter = new DefaultSingleRegistryCenter();
+        singleRegistryCenter.startup();
         DubboBootstrap.reset();
     }
 
     @AfterAll
-    public static void tearDown(){
+    public static void afterAll(){
         DubboBootstrap.reset();
+        singleRegistryCenter.shutdown();
     }
 
     @Autowired
diff --git 
a/dubbo-config/dubbo-config-spring/src/test/java/org/apache/dubbo/config/spring/boot/configprops/SpringBootConfigPropsTest.java
 
b/dubbo-config/dubbo-config-spring/src/test/java/org/apache/dubbo/config/spring/boot/configprops/SpringBootConfigPropsTest.java
index 00eacbc..1fe5523 100644
--- 
a/dubbo-config/dubbo-config-spring/src/test/java/org/apache/dubbo/config/spring/boot/configprops/SpringBootConfigPropsTest.java
+++ 
b/dubbo-config/dubbo-config-spring/src/test/java/org/apache/dubbo/config/spring/boot/configprops/SpringBootConfigPropsTest.java
@@ -27,10 +27,11 @@ import org.apache.dubbo.config.ProtocolConfig;
 import org.apache.dubbo.config.ProviderConfig;
 import org.apache.dubbo.config.RegistryConfig;
 import org.apache.dubbo.config.context.ConfigManager;
-import org.apache.dubbo.config.spring.ZooKeeperServer;
+import org.apache.dubbo.config.spring.registrycenter.ZooKeeperServer;
 import org.apache.dubbo.config.spring.context.annotation.EnableDubbo;
 import org.junit.jupiter.api.Assertions;
 import org.junit.jupiter.api.BeforeAll;
+import org.junit.jupiter.api.AfterAll;
 import org.junit.jupiter.api.Test;
 import org.springframework.beans.factory.annotation.Autowired;
 import org.springframework.boot.test.context.SpringBootTest;
@@ -67,10 +68,15 @@ import java.util.List;
 public class SpringBootConfigPropsTest {
 
     @BeforeAll
-    public static void setUp() {
+    public static void beforeAll() {
         ZooKeeperServer.start();
     }
 
+    @AfterAll
+    public static void afterAll() {
+        ZooKeeperServer.shutdown();
+    }
+
     @Autowired
     private ConfigManager configManager;
 
diff --git 
a/dubbo-config/dubbo-config-spring/src/test/java/org/apache/dubbo/config/spring/boot/configprops/SpringBootMultipleConfigPropsTest.java
 
b/dubbo-config/dubbo-config-spring/src/test/java/org/apache/dubbo/config/spring/boot/configprops/SpringBootMultipleConfigPropsTest.java
index 2f2d293..734f724 100644
--- 
a/dubbo-config/dubbo-config-spring/src/test/java/org/apache/dubbo/config/spring/boot/configprops/SpringBootMultipleConfigPropsTest.java
+++ 
b/dubbo-config/dubbo-config-spring/src/test/java/org/apache/dubbo/config/spring/boot/configprops/SpringBootMultipleConfigPropsTest.java
@@ -28,10 +28,11 @@ import org.apache.dubbo.config.ProviderConfig;
 import org.apache.dubbo.config.RegistryConfig;
 import org.apache.dubbo.config.bootstrap.DubboBootstrap;
 import org.apache.dubbo.config.context.ConfigManager;
-import org.apache.dubbo.config.spring.ZooKeeperServer;
+import org.apache.dubbo.config.spring.registrycenter.ZooKeeperServer;
 import org.apache.dubbo.config.spring.context.annotation.EnableDubbo;
 import org.junit.jupiter.api.Assertions;
 import org.junit.jupiter.api.BeforeAll;
+import org.junit.jupiter.api.AfterAll;
 import org.junit.jupiter.api.Test;
 import org.springframework.beans.factory.annotation.Autowired;
 import org.springframework.boot.test.context.SpringBootTest;
@@ -67,11 +68,17 @@ import java.util.List;
 public class SpringBootMultipleConfigPropsTest {
 
     @BeforeAll
-    public static void setUp() {
+    public static void beforeAll() {
         ZooKeeperServer.start();
         DubboBootstrap.reset();
     }
 
+    @AfterAll
+    public static void afterAll() {
+        DubboBootstrap.reset();
+        ZooKeeperServer.shutdown();
+    }
+
     @Autowired
     private ConfigManager configManager;
 
diff --git 
a/dubbo-config/dubbo-config-spring/src/test/java/org/apache/dubbo/config/spring/boot/importxml/SpringBootImportDubboXmlTest.java
 
b/dubbo-config/dubbo-config-spring/src/test/java/org/apache/dubbo/config/spring/boot/importxml/SpringBootImportDubboXmlTest.java
index 9a8d4a2..9a86f86 100644
--- 
a/dubbo-config/dubbo-config-spring/src/test/java/org/apache/dubbo/config/spring/boot/importxml/SpringBootImportDubboXmlTest.java
+++ 
b/dubbo-config/dubbo-config-spring/src/test/java/org/apache/dubbo/config/spring/boot/importxml/SpringBootImportDubboXmlTest.java
@@ -17,8 +17,9 @@
 package org.apache.dubbo.config.spring.boot.importxml;
 
 import org.apache.dubbo.config.bootstrap.DubboBootstrap;
-import org.apache.dubbo.config.spring.ZooKeeperServer;
 import org.apache.dubbo.config.spring.api.HelloService;
+import 
org.apache.dubbo.config.spring.registrycenter.DefaultSingleRegistryCenter;
+import org.apache.dubbo.config.spring.registrycenter.SingleRegistryCenter;
 import org.junit.jupiter.api.AfterAll;
 import org.junit.jupiter.api.Assertions;
 import org.junit.jupiter.api.BeforeAll;
@@ -43,15 +44,19 @@ import 
org.springframework.context.annotation.ImportResource;
 
@ImportResource("classpath:/org/apache/dubbo/config/spring/boot/importxml/consumer/dubbo-consumer.xml")
 public class SpringBootImportDubboXmlTest {
 
+    private static SingleRegistryCenter singleRegistryCenter;
+
     @BeforeAll
-    public static void setUp(){
-        ZooKeeperServer.start();
+    public static void beforeAll(){
+        singleRegistryCenter = new DefaultSingleRegistryCenter();
+        singleRegistryCenter.startup();
         DubboBootstrap.reset();
     }
 
     @AfterAll
-    public static void tearDown(){
+    public static void afterAll(){
         DubboBootstrap.reset();
+        singleRegistryCenter.shutdown();
     }
 
     @Autowired
diff --git 
a/dubbo-config/dubbo-config-spring/src/test/java/org/apache/dubbo/config/spring/context/annotation/DubboConfigConfigurationTest.java
 
b/dubbo-config/dubbo-config-spring/src/test/java/org/apache/dubbo/config/spring/context/annotation/DubboConfigConfigurationTest.java
index 46646ae..10c9f71 100644
--- 
a/dubbo-config/dubbo-config-spring/src/test/java/org/apache/dubbo/config/spring/context/annotation/DubboConfigConfigurationTest.java
+++ 
b/dubbo-config/dubbo-config-spring/src/test/java/org/apache/dubbo/config/spring/context/annotation/DubboConfigConfigurationTest.java
@@ -22,7 +22,8 @@ import org.apache.dubbo.config.ProtocolConfig;
 import org.apache.dubbo.config.RegistryConfig;
 
 import org.apache.dubbo.config.bootstrap.DubboBootstrap;
-import org.apache.dubbo.config.spring.ZooKeeperServer;
+import 
org.apache.dubbo.config.spring.registrycenter.DefaultSingleRegistryCenter;
+import org.apache.dubbo.config.spring.registrycenter.SingleRegistryCenter;
 import org.junit.jupiter.api.AfterEach;
 import org.junit.jupiter.api.Assertions;
 import org.junit.jupiter.api.BeforeEach;
@@ -31,7 +32,6 @@ import 
org.springframework.context.annotation.AnnotationConfigApplicationContext
 import org.springframework.core.io.support.ResourcePropertySource;
 
 import java.io.IOException;
-import java.util.Map;
 
 /**
  * {@link DubboConfigConfiguration} Test
@@ -83,18 +83,20 @@ public class DubboConfigConfigurationTest {
 
     @Test
     public void testMultiple() {
-
-        ZooKeeperServer.start();
-
-        context.register(DubboConfigConfiguration.Multiple.class);
-        context.refresh();
-
-        RegistryConfig registry1 = context.getBean("registry1", 
RegistryConfig.class);
-        Assertions.assertEquals(2181, registry1.getPort());
-
-        RegistryConfig registry2 = context.getBean("registry2", 
RegistryConfig.class);
-        Assertions.assertEquals(2182, registry2.getPort());
-
+        SingleRegistryCenter singleRegistryCenter = new 
DefaultSingleRegistryCenter();
+        singleRegistryCenter.startup();
+        try{
+            context.register(DubboConfigConfiguration.Multiple.class);
+            context.refresh();
+
+            RegistryConfig registry1 = context.getBean("registry1", 
RegistryConfig.class);
+            Assertions.assertEquals(2181, registry1.getPort());
+
+            RegistryConfig registry2 = context.getBean("registry2", 
RegistryConfig.class);
+            Assertions.assertEquals(2182, registry2.getPort());
+        }finally {
+            singleRegistryCenter.shutdown();
+        }
     }
 
 }
diff --git 
a/dubbo-config/dubbo-config-spring/src/test/java/org/apache/dubbo/config/spring/context/annotation/EnableDubboConfigTest.java
 
b/dubbo-config/dubbo-config-spring/src/test/java/org/apache/dubbo/config/spring/context/annotation/EnableDubboConfigTest.java
index 830dd3e..9f12ad1 100644
--- 
a/dubbo-config/dubbo-config-spring/src/test/java/org/apache/dubbo/config/spring/context/annotation/EnableDubboConfigTest.java
+++ 
b/dubbo-config/dubbo-config-spring/src/test/java/org/apache/dubbo/config/spring/context/annotation/EnableDubboConfigTest.java
@@ -26,7 +26,7 @@ import org.apache.dubbo.config.RegistryConfig;
 
 import org.apache.dubbo.config.bootstrap.DubboBootstrap;
 import org.apache.dubbo.config.context.ConfigManager;
-import org.apache.dubbo.config.spring.ZooKeeperServer;
+import org.apache.dubbo.config.spring.registrycenter.ZooKeeperServer;
 import org.apache.dubbo.rpc.model.ApplicationModel;
 import org.junit.jupiter.api.AfterEach;
 import org.junit.jupiter.api.Assertions;
diff --git 
a/dubbo-config/dubbo-config-spring/src/test/java/org/apache/dubbo/config/spring/issues/issue6000/Issue6000Test.java
 
b/dubbo-config/dubbo-config-spring/src/test/java/org/apache/dubbo/config/spring/issues/issue6000/Issue6000Test.java
index bbe3250..a7a4670 100644
--- 
a/dubbo-config/dubbo-config-spring/src/test/java/org/apache/dubbo/config/spring/issues/issue6000/Issue6000Test.java
+++ 
b/dubbo-config/dubbo-config-spring/src/test/java/org/apache/dubbo/config/spring/issues/issue6000/Issue6000Test.java
@@ -17,11 +17,13 @@
 package org.apache.dubbo.config.spring.issues.issue6000;
 
 import org.apache.dubbo.config.bootstrap.DubboBootstrap;
-import org.apache.dubbo.config.spring.ZooKeeperServer;
 import org.apache.dubbo.config.spring.context.annotation.EnableDubbo;
 import org.apache.dubbo.config.spring.issues.issue6000.adubbo.HelloDubbo;
+import 
org.apache.dubbo.config.spring.registrycenter.DefaultSingleRegistryCenter;
+import org.apache.dubbo.config.spring.registrycenter.SingleRegistryCenter;
 import org.junit.jupiter.api.Assertions;
 import org.junit.jupiter.api.BeforeAll;
+import org.junit.jupiter.api.AfterAll;
 import org.junit.jupiter.api.Test;
 import 
org.springframework.context.annotation.AnnotationConfigApplicationContext;
 import org.springframework.context.annotation.ComponentScan;
@@ -38,15 +40,23 @@ import 
org.springframework.context.annotation.PropertySource;
 @PropertySource("classpath:/META-INF/issues/issue6000/config.properties")
 public class Issue6000Test {
 
+    private static SingleRegistryCenter singleRegistryCenter;
+
     @BeforeAll
-    public static void setUp() {
+    public static void beforeAll() {
+        singleRegistryCenter = new DefaultSingleRegistryCenter();
+        singleRegistryCenter.startup();
         DubboBootstrap.reset();
     }
 
+    @AfterAll
+    public static void afterAll() {
+        DubboBootstrap.reset();
+        singleRegistryCenter.shutdown();
+    }
+
     @Test
     public void test() throws Exception {
-        ZooKeeperServer.start();
-
         AnnotationConfigApplicationContext context = new 
AnnotationConfigApplicationContext(Issue6000Test.class);
         try {
 
diff --git 
a/dubbo-config/dubbo-config-spring/src/test/java/org/apache/dubbo/config/spring/issues/issue6252/Issue6252Test.java
 
b/dubbo-config/dubbo-config-spring/src/test/java/org/apache/dubbo/config/spring/issues/issue6252/Issue6252Test.java
index 9c96cb3..7090061 100644
--- 
a/dubbo-config/dubbo-config-spring/src/test/java/org/apache/dubbo/config/spring/issues/issue6252/Issue6252Test.java
+++ 
b/dubbo-config/dubbo-config-spring/src/test/java/org/apache/dubbo/config/spring/issues/issue6252/Issue6252Test.java
@@ -18,9 +18,10 @@ package org.apache.dubbo.config.spring.issues.issue6252;
 
 import org.apache.dubbo.config.annotation.DubboReference;
 import org.apache.dubbo.config.bootstrap.DubboBootstrap;
-import org.apache.dubbo.config.spring.ZooKeeperServer;
+import org.apache.dubbo.config.spring.registrycenter.ZooKeeperServer;
 import org.apache.dubbo.config.spring.api.DemoService;
 import org.apache.dubbo.config.spring.context.annotation.EnableDubboConfig;
+import org.junit.jupiter.api.AfterAll;
 import org.junit.jupiter.api.BeforeAll;
 import org.junit.jupiter.api.Test;
 import 
org.springframework.context.annotation.AnnotationConfigApplicationContext;
@@ -38,8 +39,15 @@ import org.springframework.context.annotation.PropertySource;
 public class Issue6252Test {
 
     @BeforeAll
-    public static void setUp() {
+    public static void beforeAll() {
+        ZooKeeperServer.start();
+        DubboBootstrap.reset();
+    }
+
+    @AfterAll
+    public static void afterAll() {
         DubboBootstrap.reset();
+        ZooKeeperServer.shutdown();
     }
 
     @DubboReference
@@ -47,8 +55,6 @@ public class Issue6252Test {
 
     @Test
     public void test() throws Exception {
-        ZooKeeperServer.start();
-
         AnnotationConfigApplicationContext context = new 
AnnotationConfigApplicationContext(Issue6252Test.class);
         try {
             DemoService demoService = context.getBean(DemoService.class);
diff --git 
a/dubbo-config/dubbo-config-spring/src/test/java/org/apache/dubbo/config/spring/issues/issue7003/Issue7003Test.java
 
b/dubbo-config/dubbo-config-spring/src/test/java/org/apache/dubbo/config/spring/issues/issue7003/Issue7003Test.java
index 62e82d9..8534009 100644
--- 
a/dubbo-config/dubbo-config-spring/src/test/java/org/apache/dubbo/config/spring/issues/issue7003/Issue7003Test.java
+++ 
b/dubbo-config/dubbo-config-spring/src/test/java/org/apache/dubbo/config/spring/issues/issue7003/Issue7003Test.java
@@ -20,10 +20,12 @@ import org.apache.dubbo.config.ReferenceConfigBase;
 import org.apache.dubbo.config.annotation.DubboReference;
 import org.apache.dubbo.config.bootstrap.DubboBootstrap;
 import org.apache.dubbo.config.spring.ReferenceBean;
-import org.apache.dubbo.config.spring.ZooKeeperServer;
 import org.apache.dubbo.config.spring.api.HelloService;
 import org.apache.dubbo.config.spring.context.annotation.EnableDubbo;
+import 
org.apache.dubbo.config.spring.registrycenter.DefaultSingleRegistryCenter;
+import org.apache.dubbo.config.spring.registrycenter.SingleRegistryCenter;
 import org.apache.dubbo.rpc.model.ApplicationModel;
+import org.junit.jupiter.api.AfterAll;
 import org.junit.jupiter.api.Assertions;
 import org.junit.jupiter.api.BeforeAll;
 import org.junit.jupiter.api.Test;
@@ -47,15 +49,23 @@ import java.util.Map;
 @PropertySource("classpath:/META-INF/issues/issue7003/config.properties")
 public class Issue7003Test {
 
+    private static SingleRegistryCenter singleRegistryCenter;
+
     @BeforeAll
-    public static void setUp() {
+    public static void beforeAll() {
+        singleRegistryCenter = new DefaultSingleRegistryCenter();
+        singleRegistryCenter.startup();
         DubboBootstrap.reset();
     }
 
+    @AfterAll
+    public static void afterAll() {
+        DubboBootstrap.reset();
+        singleRegistryCenter.shutdown();
+    }
+
     @Test
     public void test() throws Exception {
-        ZooKeeperServer.start();
-
         AnnotationConfigApplicationContext context = new 
AnnotationConfigApplicationContext(Issue7003Test.class);
         try {
 
diff --git 
a/dubbo-config/dubbo-config-spring/src/test/java/org/apache/dubbo/config/spring/propertyconfigurer/consumer/PropertyConfigurerTest.java
 
b/dubbo-config/dubbo-config-spring/src/test/java/org/apache/dubbo/config/spring/propertyconfigurer/consumer/PropertyConfigurerTest.java
index 9916b80..4635c33 100644
--- 
a/dubbo-config/dubbo-config-spring/src/test/java/org/apache/dubbo/config/spring/propertyconfigurer/consumer/PropertyConfigurerTest.java
+++ 
b/dubbo-config/dubbo-config-spring/src/test/java/org/apache/dubbo/config/spring/propertyconfigurer/consumer/PropertyConfigurerTest.java
@@ -17,10 +17,11 @@
 package org.apache.dubbo.config.spring.propertyconfigurer.consumer;
 
 import org.apache.dubbo.config.bootstrap.DubboBootstrap;
-import org.apache.dubbo.config.spring.ZooKeeperServer;
 import org.apache.dubbo.config.spring.api.HelloService;
 import org.apache.dubbo.config.spring.context.annotation.EnableDubbo;
-import org.apache.dubbo.rpc.model.ApplicationModel;
+import 
org.apache.dubbo.config.spring.registrycenter.DefaultSingleRegistryCenter;
+import org.apache.dubbo.config.spring.registrycenter.SingleRegistryCenter;
+import org.junit.jupiter.api.AfterAll;
 import org.junit.jupiter.api.Assertions;
 import org.junit.jupiter.api.BeforeAll;
 import org.junit.jupiter.api.Test;
@@ -29,15 +30,23 @@ import org.springframework.context.annotation.Bean;
 import org.springframework.context.annotation.ComponentScan;
 import org.springframework.context.annotation.Configuration;
 import org.springframework.context.annotation.ImportResource;
-import org.springframework.context.annotation.PropertySource;
 import org.springframework.context.support.ClassPathXmlApplicationContext;
 
 public class PropertyConfigurerTest {
 
+    private static SingleRegistryCenter singleRegistryCenter;
+
     @BeforeAll
-    public static void setUp() {
+    public static void beforeAll() {
+        singleRegistryCenter = new DefaultSingleRegistryCenter();
+        singleRegistryCenter.startup();
+        DubboBootstrap.reset();
+    }
+
+    @AfterAll
+    public static void afterAll() {
         DubboBootstrap.reset();
-        ZooKeeperServer.start();
+        singleRegistryCenter.shutdown();
     }
 
     @Test
diff --git 
a/dubbo-config/dubbo-config-spring/src/test/java/org/apache/dubbo/config/spring/propertyconfigurer/consumer2/PropertySourcesConfigurerTest.java
 
b/dubbo-config/dubbo-config-spring/src/test/java/org/apache/dubbo/config/spring/propertyconfigurer/consumer2/PropertySourcesConfigurerTest.java
index 89b5298..7caea6c 100644
--- 
a/dubbo-config/dubbo-config-spring/src/test/java/org/apache/dubbo/config/spring/propertyconfigurer/consumer2/PropertySourcesConfigurerTest.java
+++ 
b/dubbo-config/dubbo-config-spring/src/test/java/org/apache/dubbo/config/spring/propertyconfigurer/consumer2/PropertySourcesConfigurerTest.java
@@ -17,10 +17,12 @@
 package org.apache.dubbo.config.spring.propertyconfigurer.consumer2;
 
 import org.apache.dubbo.config.bootstrap.DubboBootstrap;
-import org.apache.dubbo.config.spring.ZooKeeperServer;
 import org.apache.dubbo.config.spring.api.HelloService;
 import org.apache.dubbo.config.spring.context.annotation.EnableDubbo;
 import 
org.apache.dubbo.config.spring.propertyconfigurer.consumer.DemoBeanFactoryPostProcessor;
+import 
org.apache.dubbo.config.spring.registrycenter.DefaultSingleRegistryCenter;
+import org.apache.dubbo.config.spring.registrycenter.SingleRegistryCenter;
+import org.junit.jupiter.api.AfterAll;
 import org.junit.jupiter.api.Assertions;
 import org.junit.jupiter.api.BeforeAll;
 import org.junit.jupiter.api.Test;
@@ -33,10 +35,19 @@ import 
org.springframework.context.support.ClassPathXmlApplicationContext;
 
 public class PropertySourcesConfigurerTest {
 
+    private static SingleRegistryCenter singleRegistryCenter;
+
     @BeforeAll
-    public static void setUp() {
+    public static void beforeAll() {
+        singleRegistryCenter = new DefaultSingleRegistryCenter();
+        singleRegistryCenter.startup();
+        DubboBootstrap.reset();
+    }
+
+    @AfterAll
+    public static void afterAll() {
         DubboBootstrap.reset();
-        ZooKeeperServer.start();
+        singleRegistryCenter.shutdown();
     }
 
     @Test
diff --git 
a/dubbo-config/dubbo-config-spring/src/test/java/org/apache/dubbo/config/spring/propertyconfigurer/consumer3/PropertySourcesInJavaConfigTest.java
 
b/dubbo-config/dubbo-config-spring/src/test/java/org/apache/dubbo/config/spring/propertyconfigurer/consumer3/PropertySourcesInJavaConfigTest.java
index cd521119..33b6a13 100644
--- 
a/dubbo-config/dubbo-config-spring/src/test/java/org/apache/dubbo/config/spring/propertyconfigurer/consumer3/PropertySourcesInJavaConfigTest.java
+++ 
b/dubbo-config/dubbo-config-spring/src/test/java/org/apache/dubbo/config/spring/propertyconfigurer/consumer3/PropertySourcesInJavaConfigTest.java
@@ -17,10 +17,12 @@
 package org.apache.dubbo.config.spring.propertyconfigurer.consumer3;
 
 import org.apache.dubbo.config.bootstrap.DubboBootstrap;
-import org.apache.dubbo.config.spring.ZooKeeperServer;
 import org.apache.dubbo.config.spring.api.HelloService;
 import org.apache.dubbo.config.spring.context.annotation.EnableDubbo;
 import 
org.apache.dubbo.config.spring.propertyconfigurer.consumer.DemoBeanFactoryPostProcessor;
+import 
org.apache.dubbo.config.spring.registrycenter.DefaultSingleRegistryCenter;
+import org.apache.dubbo.config.spring.registrycenter.SingleRegistryCenter;
+import org.junit.jupiter.api.AfterAll;
 import org.junit.jupiter.api.Assertions;
 import org.junit.jupiter.api.BeforeAll;
 import org.junit.jupiter.api.BeforeEach;
@@ -40,10 +42,17 @@ public class PropertySourcesInJavaConfigTest {
     private static final String SCAN_PACKAGE_NAME = 
"org.apache.dubbo.config.spring.propertyconfigurer.consumer3.notexist";
     private static final String PACKAGE_PATH = 
"/org/apache/dubbo/config/spring/propertyconfigurer/consumer3";
     private static final String PROVIDER_CONFIG_PATH = 
"org/apache/dubbo/config/spring/propertyconfigurer/provider/dubbo-provider.xml";
+    private static SingleRegistryCenter singleRegistryCenter;
 
     @BeforeAll
-    public static void setUp() {
-        ZooKeeperServer.start();
+    public static void beforeAll() {
+        singleRegistryCenter = new DefaultSingleRegistryCenter();
+        singleRegistryCenter.startup();
+    }
+
+    @AfterAll
+    public static void afterAll() {
+        singleRegistryCenter.shutdown();
     }
 
     @BeforeEach
diff --git 
a/dubbo-config/dubbo-config-spring/src/test/java/org/apache/dubbo/config/spring/reference/DubboConfigBeanInitializerTest.java
 
b/dubbo-config/dubbo-config-spring/src/test/java/org/apache/dubbo/config/spring/reference/DubboConfigBeanInitializerTest.java
index 0d3fe0c..c483dcf 100644
--- 
a/dubbo-config/dubbo-config-spring/src/test/java/org/apache/dubbo/config/spring/reference/DubboConfigBeanInitializerTest.java
+++ 
b/dubbo-config/dubbo-config-spring/src/test/java/org/apache/dubbo/config/spring/reference/DubboConfigBeanInitializerTest.java
@@ -19,12 +19,13 @@ package org.apache.dubbo.config.spring.reference;
 
 import org.apache.dubbo.config.annotation.DubboReference;
 import org.apache.dubbo.config.bootstrap.DubboBootstrap;
-import org.apache.dubbo.config.spring.ZooKeeperServer;
+import org.apache.dubbo.config.spring.registrycenter.ZooKeeperServer;
 import org.apache.dubbo.config.spring.api.HelloService;
 import org.apache.dubbo.config.spring.context.DubboConfigBeanInitializer;
 import 
org.apache.dubbo.config.spring.context.annotation.provider.ProviderConfiguration;
 import org.junit.jupiter.api.Assertions;
 import org.junit.jupiter.api.BeforeAll;
+import org.junit.jupiter.api.AfterAll;
 import org.junit.jupiter.api.Test;
 import org.junit.jupiter.api.extension.ExtendWith;
 import org.springframework.beans.factory.annotation.Autowired;
@@ -38,7 +39,6 @@ import org.springframework.test.context.ContextConfiguration;
 import org.springframework.test.context.TestPropertySource;
 import org.springframework.test.context.junit.jupiter.SpringExtension;
 
-import java.util.ArrayList;
 import java.util.Arrays;
 import java.util.List;
 
@@ -64,6 +64,12 @@ public class DubboConfigBeanInitializerTest {
         ZooKeeperServer.start();
     }
 
+    @AfterAll
+    public static void afterAll() {
+        ZooKeeperServer.shutdown();
+    }
+
+
     @Autowired
     private FooService fooService;
 
diff --git 
a/dubbo-config/dubbo-config-spring/src/test/java/org/apache/dubbo/config/spring/reference/ReferenceKeyTest.java
 
b/dubbo-config/dubbo-config-spring/src/test/java/org/apache/dubbo/config/spring/reference/ReferenceKeyTest.java
index 71d55e3..36fb780 100644
--- 
a/dubbo-config/dubbo-config-spring/src/test/java/org/apache/dubbo/config/spring/reference/ReferenceKeyTest.java
+++ 
b/dubbo-config/dubbo-config-spring/src/test/java/org/apache/dubbo/config/spring/reference/ReferenceKeyTest.java
@@ -26,9 +26,13 @@ import org.apache.dubbo.config.spring.api.DemoService;
 import org.apache.dubbo.config.spring.api.HelloService;
 import org.apache.dubbo.config.spring.impl.DemoServiceImpl;
 import org.apache.dubbo.config.spring.impl.HelloServiceImpl;
+import 
org.apache.dubbo.config.spring.registrycenter.DefaultSingleRegistryCenter;
+import org.apache.dubbo.config.spring.registrycenter.SingleRegistryCenter;
 import org.junit.jupiter.api.Assertions;
-import org.junit.jupiter.api.BeforeEach;
+import org.junit.jupiter.api.BeforeAll;
+import org.junit.jupiter.api.AfterAll;
 import org.junit.jupiter.api.Test;
+import org.junit.jupiter.api.BeforeEach;
 import org.springframework.beans.BeansException;
 import org.springframework.beans.factory.annotation.Autowired;
 import 
org.springframework.context.annotation.AnnotationConfigApplicationContext;
@@ -44,6 +48,20 @@ import java.util.Map;
 
 public class ReferenceKeyTest {
 
+    private static SingleRegistryCenter singleRegistryCenter;
+
+    @BeforeAll
+    public static void beforeAll() {
+        singleRegistryCenter = new DefaultSingleRegistryCenter();
+        singleRegistryCenter.startup();
+    }
+
+    @AfterAll
+    public static void afterAll() {
+        singleRegistryCenter.shutdown();
+    }
+
+
     @BeforeEach
     protected void setUp() {
         DubboBootstrap.reset();
diff --git 
a/dubbo-config/dubbo-config-spring/src/test/java/org/apache/dubbo/config/spring/reference/javaconfig/JavaConfigReferenceBeanTest.java
 
b/dubbo-config/dubbo-config-spring/src/test/java/org/apache/dubbo/config/spring/reference/javaconfig/JavaConfigReferenceBeanTest.java
index 0b0351a..805b09a 100644
--- 
a/dubbo-config/dubbo-config-spring/src/test/java/org/apache/dubbo/config/spring/reference/javaconfig/JavaConfigReferenceBeanTest.java
+++ 
b/dubbo-config/dubbo-config-spring/src/test/java/org/apache/dubbo/config/spring/reference/javaconfig/JavaConfigReferenceBeanTest.java
@@ -21,7 +21,7 @@ import org.apache.dubbo.config.annotation.DubboService;
 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.ZooKeeperServer;
+import org.apache.dubbo.config.spring.registrycenter.ZooKeeperServer;
 import org.apache.dubbo.config.spring.api.DemoService;
 import org.apache.dubbo.config.spring.api.HelloService;
 import org.apache.dubbo.config.spring.context.annotation.EnableDubbo;
@@ -30,11 +30,12 @@ import org.apache.dubbo.config.spring.impl.HelloServiceImpl;
 import org.apache.dubbo.config.spring.reference.ReferenceBeanBuilder;
 import org.apache.dubbo.rpc.service.GenericException;
 import org.apache.dubbo.rpc.service.GenericService;
-import org.junit.jupiter.api.AfterEach;
 import org.junit.jupiter.api.Assertions;
 import org.junit.jupiter.api.BeforeAll;
-import org.junit.jupiter.api.BeforeEach;
+import org.junit.jupiter.api.AfterAll;
 import org.junit.jupiter.api.Test;
+import org.junit.jupiter.api.BeforeEach;
+import org.junit.jupiter.api.AfterEach;
 import 
org.springframework.context.annotation.AnnotationConfigApplicationContext;
 import org.springframework.context.annotation.Bean;
 import org.springframework.context.annotation.Configuration;
@@ -53,6 +54,11 @@ public class JavaConfigReferenceBeanTest {
         ZooKeeperServer.start();
     }
 
+    @AfterAll
+    public static void afterAll() {
+        ZooKeeperServer.shutdown();
+    }
+
     @BeforeEach
     public void setUp() {
         DubboBootstrap.reset();
diff --git 
a/dubbo-config/dubbo-config-spring/src/test/java/org/apache/dubbo/config/spring/reference/localcall/LocalCallTest.java
 
b/dubbo-config/dubbo-config-spring/src/test/java/org/apache/dubbo/config/spring/reference/localcall/LocalCallTest.java
index eb8c8c1..1300c35 100644
--- 
a/dubbo-config/dubbo-config-spring/src/test/java/org/apache/dubbo/config/spring/reference/localcall/LocalCallTest.java
+++ 
b/dubbo-config/dubbo-config-spring/src/test/java/org/apache/dubbo/config/spring/reference/localcall/LocalCallTest.java
@@ -17,8 +17,9 @@
 package org.apache.dubbo.config.spring.reference.localcall;
 
 import org.apache.dubbo.config.bootstrap.DubboBootstrap;
-import org.apache.dubbo.config.spring.ZooKeeperServer;
 import org.apache.dubbo.config.spring.api.HelloService;
+import 
org.apache.dubbo.config.spring.registrycenter.DefaultSingleRegistryCenter;
+import org.apache.dubbo.config.spring.registrycenter.SingleRegistryCenter;
 import org.junit.jupiter.api.AfterAll;
 import org.junit.jupiter.api.Assertions;
 import org.junit.jupiter.api.BeforeAll;
@@ -38,15 +39,19 @@ import static 
org.springframework.test.annotation.DirtiesContext.ClassMode.AFTER
 @DirtiesContext(classMode = AFTER_EACH_TEST_METHOD)
 public class LocalCallTest {
 
+    private static SingleRegistryCenter singleRegistryCenter;
+
     @BeforeAll
-    public static void setUp() {
+    public static void beforeAll() {
+        singleRegistryCenter = new DefaultSingleRegistryCenter();
+        singleRegistryCenter.startup();
         DubboBootstrap.reset();
-        ZooKeeperServer.start();
     }
 
     @AfterAll
-    public static void tearDown() {
+    public static void afterAll() {
         DubboBootstrap.reset();
+        singleRegistryCenter.shutdown();
     }
 
     @Autowired
diff --git 
a/dubbo-config/dubbo-config-spring/src/test/java/org/apache/dubbo/config/spring/registrycenter/DefaultSingleRegistryCenter.java
 
b/dubbo-config/dubbo-config-spring/src/test/java/org/apache/dubbo/config/spring/registrycenter/DefaultSingleRegistryCenter.java
new file mode 100644
index 0000000..580dd2d
--- /dev/null
+++ 
b/dubbo-config/dubbo-config-spring/src/test/java/org/apache/dubbo/config/spring/registrycenter/DefaultSingleRegistryCenter.java
@@ -0,0 +1,101 @@
+/*
+ * 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.config.spring.registrycenter;
+
+import org.apache.curator.test.TestingServer;
+import org.apache.dubbo.common.logger.Logger;
+import org.apache.dubbo.common.logger.LoggerFactory;
+import org.apache.dubbo.config.RegistryConfig;
+import org.apache.dubbo.rpc.RpcException;
+
+import java.io.IOException;
+
+/**
+ * The default single registry center.
+ */
+public class DefaultSingleRegistryCenter implements SingleRegistryCenter {
+
+    /**
+     * Initialize {@link RegistryCenter} instance.
+     */
+    public DefaultSingleRegistryCenter() {
+        this(DEFAULT_PORT);
+    }
+
+    /**
+     * Initialize {@link RegistryCenter} instance.
+     *
+     * @param port the zookeeper server's port.
+     */
+    public DefaultSingleRegistryCenter(int port) {
+        this.port = port;
+    }
+
+    private static final Logger logger = 
LoggerFactory.getLogger(DefaultSingleRegistryCenter.class);
+
+    /**
+     * The zookeeper server's default port.
+     */
+    private static final int DEFAULT_PORT = 2181;
+    /**
+     * Define a zookeeper server.
+     */
+    private volatile TestingServer zookeeperServer;
+
+    /**
+     * The zookeeper server's port.
+     */
+    private int port;
+
+    /**
+     * {@inheritDoc}
+     */
+    @Override
+    public void startup() throws RpcException {
+        try {
+            logger.info("The DefaultSingleRegistryCenter is starting...");
+            this.zookeeperServer = new TestingServer(this.port, true);
+            logger.info("The DefaultSingleRegistryCenter is started 
successfully");
+        } catch (Exception exception) {
+            throw new RpcException("Failed to initialize 
DefaultSingleRegistryCenter instance", exception);
+        }
+    }
+
+    /**
+     * {@inheritDoc}
+     */
+    @Override
+    public RegistryConfig getRegistryConfig() {
+        return new RegistryConfig("zookeeper://" + 
this.zookeeperServer.getConnectString());
+    }
+
+    /**
+     * {@inheritDoc}
+     */
+    @Override
+    public void shutdown() throws RpcException {
+        try {
+            logger.info("The DefaultSingleRegistryCenter is stopping...");
+            if (this.zookeeperServer != null) {
+                this.zookeeperServer.close();
+            }
+            logger.info("The DefaultSingleRegistryCenter is shutdown 
successfully");
+        } catch (IOException exception) {
+            throw new RpcException("Failed to close 
DefaultSingleRegistryCenter instance", exception);
+        }
+    }
+}
diff --git 
a/dubbo-config/dubbo-config-api/src/test/java/org/apache/dubbo/integration/multiple/injvm/MultipleRegistryCenterInjvmServiceImpl.java
 
b/dubbo-config/dubbo-config-spring/src/test/java/org/apache/dubbo/config/spring/registrycenter/RegistryCenter.java
similarity index 65%
copy from 
dubbo-config/dubbo-config-api/src/test/java/org/apache/dubbo/integration/multiple/injvm/MultipleRegistryCenterInjvmServiceImpl.java
copy to 
dubbo-config/dubbo-config-spring/src/test/java/org/apache/dubbo/config/spring/registrycenter/RegistryCenter.java
index f04a5ea..a1cd686 100644
--- 
a/dubbo-config/dubbo-config-api/src/test/java/org/apache/dubbo/integration/multiple/injvm/MultipleRegistryCenterInjvmServiceImpl.java
+++ 
b/dubbo-config/dubbo-config-spring/src/test/java/org/apache/dubbo/config/spring/registrycenter/RegistryCenter.java
@@ -14,17 +14,24 @@
  * See the License for the specific language governing permissions and
  * limitations under the License.
  */
-package org.apache.dubbo.integration.multiple.injvm;
+package org.apache.dubbo.config.spring.registrycenter;
+
+import org.apache.dubbo.rpc.RpcException;
 
 /**
- * The simple implementation for {@link MultipleRegistryCenterInjvmService}
+ * The mock registry center.
  */
-public class MultipleRegistryCenterInjvmServiceImpl implements 
MultipleRegistryCenterInjvmService {
+public interface RegistryCenter {
+
+    /**
+     * Start the registry center.
+     * @throws RpcException when an exception occurred
+     */
+    void startup() throws RpcException;
+
     /**
-     * {@inheritDoc}
+     * Stop the registry center.
+     * @throws RpcException when an exception occurred
      */
-    @Override
-    public String hello(String name) {
-        return null;
-    }
+    void shutdown() throws RpcException;
 }
diff --git 
a/dubbo-config/dubbo-config-api/src/test/java/org/apache/dubbo/integration/multiple/injvm/MultipleRegistryCenterInjvmServiceImpl.java
 
b/dubbo-config/dubbo-config-spring/src/test/java/org/apache/dubbo/config/spring/registrycenter/SingleRegistryCenter.java
similarity index 71%
copy from 
dubbo-config/dubbo-config-api/src/test/java/org/apache/dubbo/integration/multiple/injvm/MultipleRegistryCenterInjvmServiceImpl.java
copy to 
dubbo-config/dubbo-config-spring/src/test/java/org/apache/dubbo/config/spring/registrycenter/SingleRegistryCenter.java
index f04a5ea..c5befdb 100644
--- 
a/dubbo-config/dubbo-config-api/src/test/java/org/apache/dubbo/integration/multiple/injvm/MultipleRegistryCenterInjvmServiceImpl.java
+++ 
b/dubbo-config/dubbo-config-spring/src/test/java/org/apache/dubbo/config/spring/registrycenter/SingleRegistryCenter.java
@@ -14,17 +14,17 @@
  * See the License for the specific language governing permissions and
  * limitations under the License.
  */
-package org.apache.dubbo.integration.multiple.injvm;
+package org.apache.dubbo.config.spring.registrycenter;
+
+import org.apache.dubbo.config.RegistryConfig;
 
 /**
- * The simple implementation for {@link MultipleRegistryCenterInjvmService}
+ * Mock single registry center.
  */
-public class MultipleRegistryCenterInjvmServiceImpl implements 
MultipleRegistryCenterInjvmService {
+public interface SingleRegistryCenter extends RegistryCenter {
+
     /**
-     * {@inheritDoc}
+     * Returns {@link RegistryConfig} instance.
      */
-    @Override
-    public String hello(String name) {
-        return null;
-    }
+    RegistryConfig getRegistryConfig();
 }
diff --git 
a/dubbo-config/dubbo-config-spring/src/test/java/org/apache/dubbo/config/spring/ZooKeeperServer.java
 
b/dubbo-config/dubbo-config-spring/src/test/java/org/apache/dubbo/config/spring/registrycenter/ZooKeeperServer.java
similarity index 90%
rename from 
dubbo-config/dubbo-config-spring/src/test/java/org/apache/dubbo/config/spring/ZooKeeperServer.java
rename to 
dubbo-config/dubbo-config-spring/src/test/java/org/apache/dubbo/config/spring/registrycenter/ZooKeeperServer.java
index 6e24ca4..c69000b 100644
--- 
a/dubbo-config/dubbo-config-spring/src/test/java/org/apache/dubbo/config/spring/ZooKeeperServer.java
+++ 
b/dubbo-config/dubbo-config-spring/src/test/java/org/apache/dubbo/config/spring/registrycenter/ZooKeeperServer.java
@@ -14,7 +14,9 @@
  * See the License for the specific language governing permissions and
  * limitations under the License.
  */
-package org.apache.dubbo.config.spring;
+package org.apache.dubbo.config.spring.registrycenter;
+
+import org.apache.dubbo.config.spring.EmbeddedZooKeeper;
 
 public class ZooKeeperServer {
 
@@ -32,7 +34,7 @@ public class ZooKeeperServer {
             }
     }
 
-    public static void stop() {
+    public static void shutdown() {
         if (zookeeper1 != null) {
             zookeeper1.stop();
         }
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 2c2b42c..04c9161 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
@@ -22,13 +22,11 @@ import org.apache.dubbo.config.ServiceConfigBase;
 import org.apache.dubbo.config.bootstrap.DubboBootstrap;
 import org.apache.dubbo.config.context.ConfigManager;
 import org.apache.dubbo.config.spring.ServiceBean;
-import org.apache.dubbo.config.spring.ZooKeeperServer;
 import org.apache.dubbo.config.spring.api.DemoService;
+import 
org.apache.dubbo.config.spring.registrycenter.DefaultSingleRegistryCenter;
+import org.apache.dubbo.config.spring.registrycenter.SingleRegistryCenter;
 import org.apache.dubbo.rpc.service.GenericService;
-import org.junit.jupiter.api.AfterEach;
-import org.junit.jupiter.api.Assertions;
-import org.junit.jupiter.api.BeforeAll;
-import org.junit.jupiter.api.Test;
+import org.junit.jupiter.api.*;
 import org.junit.jupiter.api.extension.ExtendWith;
 import org.springframework.beans.factory.annotation.Autowired;
 import org.springframework.beans.factory.annotation.Qualifier;
@@ -46,10 +44,19 @@ import static 
org.springframework.test.annotation.DirtiesContext.ClassMode.AFTER
 @ImportResource(locations = 
"classpath:/META-INF/spring/dubbo-generic-consumer.xml")
 public class GenericServiceTest {
 
+    private static SingleRegistryCenter singleRegistryCenter;
+
     @BeforeAll
-    public static void setUp() {
-        ZooKeeperServer.start();
+    public static void beforeAll() {
+        singleRegistryCenter = new DefaultSingleRegistryCenter();
+        singleRegistryCenter.startup();
+        DubboBootstrap.reset();
+    }
+
+    @AfterAll
+    public static void afterAll() {
         DubboBootstrap.reset();
+        singleRegistryCenter.shutdown();
     }
 
     @AfterEach

Reply via email to