You are viewing a plain text version of this content. The canonical link for it is here.
Posted to commits@dubbo.apache.org by li...@apache.org on 2021/01/30 11:28:12 UTC

[dubbo-spi-extensions] branch 2.7.x updated (ce6bc20 -> f6d4d2d)

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

liujun pushed a change to branch 2.7.x
in repository https://gitbox.apache.org/repos/asf/dubbo-spi-extensions.git.


    from ce6bc20  add flatten plugin
     new 971ffaf  升级版本号,修复 #9, 增加使用SPI扫描的测试
     new 9efb793  fix #10 中的问题 fix #7 增加BigDecimal, BigInteger的支持
     new a79a304  取消调试时注释掉的代码
     new 3f3407a  no message
     new fa8e7e1  增加checkstyle 和 rat, 并相应修改
     new 1d0cb55  彻底解决 #10 中的3号问题
     new f6d4d2d  Merge pull request #12 from KeRan213539/api-docs-20210120

The 39 revisions listed above as "new" are entirely new to this
repository and will be described in separate emails.  The revisions
listed as "add" were already present in the repository and have only
been added to this reference.


Summary of changes:
 .../codestyle}/checkstyle.xml                      |  15 +--
 .../dubbo_codestyle_for_idea.xml}                  |  30 ++---
 .../apache/dubbo/apidocs/annotations/ApiDoc.java   |   1 +
 .../dubbo/apidocs/annotations/ApiModule.java       |   1 +
 .../core/DubboApiDocsAnnotationScanner.java        | 139 +++++++++++++++++----
 .../apidocs/core/beans/ApiParamsCacheItem.java     |  13 ++
 .../dubbo/apidocs/core/beans/HtmlTypeEnum.java     |  10 ++
 .../core/providers/DubboDocProviderImpl.java       |   4 -
 .../apache/dubbo/apidocs/utils/ClassTypeUtil.java  |  81 ++++++++----
 .../apidocs/examples/api/IQuickStartDemo.java      |  29 ++++-
 ...an1SubBean1.java => QuickStartRequestBase.java} |  53 ++++----
 .../examples/params/QuickStartRequestBean.java     |   4 +-
 ...equestBean.java => QuickStartRequestBean2.java} |  39 +++---
 .../examples/params/QuickStartRespBean.java        |   4 +-
 .../src/main/resources/application.yml             |  17 +++
 .../src/main/resources/bootstrap.yml               |  17 +++
 .../examples-provider/pom.xml                      |   5 -
 .../examples/api/impl/QuickStartDemoImpl.java      |  36 +++++-
 .../examples/spi/DubboDocExporterListener.java     |  18 ++-
 .../examples/spi/TestConfigInitializer.java        |  18 +--
 .../examples/spi/TestConfigPostProcessor.java      |  26 ++--
 .../org.apache.dubbo.config.ConfigInitializer      |   1 +
 .../org.apache.dubbo.config.ConfigPostProcessor    |   1 +
 .../dubbo/org.apache.dubbo.rpc.ExporterListener    |   1 +
 .../src/main/resources/application.yml             |  22 +++-
 dubbo-api-docs/pom.xml                             |  84 ++++++++++++-
 26 files changed, 508 insertions(+), 161 deletions(-)
 copy {codestyle => dubbo-api-docs/codestyle}/checkstyle.xml (55%)
 copy dubbo-api-docs/{dubbo-api-docs-annotations/pom.xml => codestyle/dubbo_codestyle_for_idea.xml} (53%)
 copy dubbo-api-docs/dubbo-api-docs-examples/examples-api/src/main/java/org/apache/dubbo/apidocs/examples/params/{DemoParamBean1SubBean1.java => QuickStartRequestBase.java} (52%)
 copy dubbo-api-docs/dubbo-api-docs-examples/examples-api/src/main/java/org/apache/dubbo/apidocs/examples/params/{QuickStartRequestBean.java => QuickStartRequestBean2.java} (59%)
 copy dubbo-test/src/test/java/org/apache/dubbo/config/mock/MockExporterListener.java => dubbo-api-docs/dubbo-api-docs-examples/examples-provider/src/main/java/org/apache/dubbo/apidocs/examples/spi/DubboDocExporterListener.java (72%)
 copy dubbo-spi-registry/dubbo-registry-redis/src/main/java/org/apache/dubbo/registry/redis/RedisRegistryFactory.java => dubbo-api-docs/dubbo-api-docs-examples/examples-provider/src/main/java/org/apache/dubbo/apidocs/examples/spi/TestConfigInitializer.java (66%)
 copy dubbo-test/src/test/java/org/apache/dubbo/config/bootstrap/EchoServiceImpl.java => dubbo-api-docs/dubbo-api-docs-examples/examples-provider/src/main/java/org/apache/dubbo/apidocs/examples/spi/TestConfigPostProcessor.java (56%)
 create mode 100644 dubbo-api-docs/dubbo-api-docs-examples/examples-provider/src/main/resources/META-INF/dubbo/org.apache.dubbo.config.ConfigInitializer
 create mode 100644 dubbo-api-docs/dubbo-api-docs-examples/examples-provider/src/main/resources/META-INF/dubbo/org.apache.dubbo.config.ConfigPostProcessor
 create mode 100644 dubbo-api-docs/dubbo-api-docs-examples/examples-provider/src/main/resources/META-INF/dubbo/org.apache.dubbo.rpc.ExporterListener


[dubbo-spi-extensions] 04/39: adjust modules

Posted by li...@apache.org.
This is an automated email from the ASF dual-hosted git repository.

liujun pushed a commit to branch 2.7.x
in repository https://gitbox.apache.org/repos/asf/dubbo-spi-extensions.git

commit c340ddf942ade45eef3b230168b9e6f46e5b4b15
Author: ken.lj <ke...@gmail.com>
AuthorDate: Mon May 18 14:40:16 2020 +0800

    adjust modules
---
 .../dubbo-configcenter-apollo/pom.xml              |  52 --
 .../support/apollo/ApolloDynamicConfiguration.java | 258 ---------
 .../apollo/ApolloDynamicConfigurationFactory.java  |  31 -
 ...config.configcenter.DynamicConfigurationFactory |   1 -
 .../apollo/ApolloDynamicConfigurationTest.java     | 191 -------
 .../src/test/resources/META-INF/app.properties     |   1 -
 .../src/test/resources/mockdata-dubbo.properties   |   2 -
 .../dubbo-configcenter-nacos/pom.xml               |  45 --
 .../support/nacos/NacosDynamicConfiguration.java   | 381 -------------
 .../nacos/NacosDynamicConfigurationFactory.java    |  41 --
 ...config.configcenter.DynamicConfigurationFactory |   1 -
 .../nacos/NacosDynamicConfigurationTest.java       | 188 ------
 dubbo-spi-configcenter/pom.xml                     |   2 -
 .../dubbo-metadata-report-redis/pom.xml            |  57 --
 .../metadata/store/redis/RedisMetadataReport.java  | 201 -------
 .../store/redis/RedisMetadataReportFactory.java    |  34 --
 ...che.dubbo.metadata.report.MetadataReportFactory |   1 -
 .../store/redis/RedisMetadata4TstService.java      |  28 -
 .../store/redis/RedisMetadataReportTest.java       | 220 -------
 dubbo-spi-metadata/pom.xml                         |   1 -
 dubbo-spi-registry/dubbo-registry-multiple/pom.xml |  65 ---
 .../dubbo/registry/multiple/MultipleRegistry.java  | 337 -----------
 .../registry/multiple/MultipleRegistryFactory.java |  33 --
 .../org.apache.dubbo.registry.RegistryFactory      |   1 -
 .../multiple/MultipleRegistry2S2RTest.java         | 213 -------
 .../multiple/MultipleRegistryTestUtil.java         | 145 -----
 dubbo-spi-registry/dubbo-registry-nacos/pom.xml    |  83 ---
 .../apache/dubbo/registry/nacos/NacosRegistry.java | 629 ---------------------
 .../dubbo/registry/nacos/NacosRegistryFactory.java |  42 --
 .../registry/nacos/NacosServiceDiscovery.java      | 130 -----
 .../dubbo/registry/nacos/NacosServiceName.java     | 234 --------
 .../nacos/util/NacosInstanceManageUtil.java        |  67 ---
 .../nacos/util/NacosNamingServiceUtils.java        | 192 -------
 .../org.apache.dubbo.registry.RegistryFactory      |   1 -
 ...g.apache.dubbo.registry.client.ServiceDiscovery |   1 -
 dubbo-spi-registry/pom.xml                         |   2 -
 .../dubbo-remoting-zookeeper/pom.xml               |  56 --
 .../dubbo/remoting/zookeeper/ChildListener.java    |  25 -
 .../dubbo/remoting/zookeeper/DataListener.java     |  25 -
 .../apache/dubbo/remoting/zookeeper/EventType.java |  65 ---
 .../dubbo/remoting/zookeeper/StateListener.java    |  33 --
 .../dubbo/remoting/zookeeper/ZookeeperClient.java  |  65 ---
 .../remoting/zookeeper/ZookeeperTransporter.java   |  30 -
 .../zookeeper/curator/CuratorZookeeperClient.java  | 398 -------------
 .../curator/CuratorZookeeperTransporter.java       |  30 -
 .../zookeeper/support/AbstractZookeeperClient.java | 226 --------
 .../support/AbstractZookeeperTransporter.java      | 182 ------
 ...e.dubbo.remoting.zookeeper.ZookeeperTransporter |   1 -
 .../curator/CuratorZookeeperClientTest.java        | 195 -------
 .../curator/CuratorZookeeperTransporterTest.java   |  57 --
 .../support/AbstractZookeeperTransporterTest.java  | 225 --------
 dubbo-spi-remoting/pom.xml                         |   1 -
 .../dubbo-serialization-jdk/pom.xml                |  43 --
 .../serialize/java/CompactedJavaSerialization.java |  59 --
 .../serialize/java/CompactedObjectInputStream.java |  64 ---
 .../java/CompactedObjectOutputStream.java          |  43 --
 .../common/serialize/java/JavaObjectInput.java     |  91 ---
 .../common/serialize/java/JavaObjectOutput.java    |  61 --
 .../common/serialize/java/JavaSerialization.java   |  59 --
 .../nativejava/NativeJavaObjectInput.java          | 118 ----
 .../nativejava/NativeJavaObjectOutput.java         | 115 ----
 .../nativejava/NativeJavaSerialization.java        |  60 --
 ...org.apache.dubbo.common.serialize.Serialization |   3 -
 dubbo-spi-serialization/pom.xml                    |   1 -
 64 files changed, 6242 deletions(-)

diff --git a/dubbo-spi-configcenter/dubbo-configcenter-apollo/pom.xml b/dubbo-spi-configcenter/dubbo-configcenter-apollo/pom.xml
deleted file mode 100644
index 8d3dc0e..0000000
--- a/dubbo-spi-configcenter/dubbo-configcenter-apollo/pom.xml
+++ /dev/null
@@ -1,52 +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.
-  -->
-<project xmlns="http://maven.apache.org/POM/4.0.0" xmlns:xsi="http://www.w3.org/2001/XMLSchema-instance" xsi:schemaLocation="http://maven.apache.org/POM/4.0.0 http://maven.apache.org/maven-v4_0_0.xsd">
-    <modelVersion>4.0.0</modelVersion>
-
-    <parent>
-        <groupId>org.apache.dubbo</groupId>
-        <artifactId>dubbo-configcenter</artifactId>
-        <version>2.7.7-SNAPSHOT</version>
-    </parent>
-
-    <artifactId>dubbo-configcenter-apollo</artifactId>
-    <packaging>jar</packaging>
-    <name>${project.artifactId}</name>
-    <description>The Apollo implementation of the configcenter api</description>
-    <properties>
-        <skip_maven_deploy>false</skip_maven_deploy>
-        <apollo_mock_server_version>1.1.1</apollo_mock_server_version>
-    </properties>
-
-    <dependencies>
-        <dependency>
-            <groupId>org.apache.dubbo</groupId>
-            <artifactId>dubbo-common</artifactId>
-            <version>${project.parent.version}</version>
-        </dependency>
-        <dependency>
-            <groupId>com.ctrip.framework.apollo</groupId>
-            <artifactId>apollo-client</artifactId>
-        </dependency>
-        <dependency>
-            <groupId>com.ctrip.framework.apollo</groupId>
-            <artifactId>apollo-mockserver</artifactId>
-            <version>${apollo_mock_server_version}</version>
-            <scope>test</scope>
-        </dependency>
-    </dependencies>
-</project>
\ No newline at end of file
diff --git a/dubbo-spi-configcenter/dubbo-configcenter-apollo/src/main/java/org/apache/dubbo/configcenter/support/apollo/ApolloDynamicConfiguration.java b/dubbo-spi-configcenter/dubbo-configcenter-apollo/src/main/java/org/apache/dubbo/configcenter/support/apollo/ApolloDynamicConfiguration.java
deleted file mode 100644
index f191178..0000000
--- a/dubbo-spi-configcenter/dubbo-configcenter-apollo/src/main/java/org/apache/dubbo/configcenter/support/apollo/ApolloDynamicConfiguration.java
+++ /dev/null
@@ -1,258 +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.configcenter.support.apollo;
-
-import org.apache.dubbo.common.URL;
-import org.apache.dubbo.common.config.configcenter.ConfigChangeType;
-import org.apache.dubbo.common.config.configcenter.ConfigChangedEvent;
-import org.apache.dubbo.common.config.configcenter.ConfigurationListener;
-import org.apache.dubbo.common.config.configcenter.DynamicConfiguration;
-import org.apache.dubbo.common.logger.Logger;
-import org.apache.dubbo.common.logger.LoggerFactory;
-import org.apache.dubbo.common.utils.StringUtils;
-
-import com.ctrip.framework.apollo.Config;
-import com.ctrip.framework.apollo.ConfigChangeListener;
-import com.ctrip.framework.apollo.ConfigFile;
-import com.ctrip.framework.apollo.ConfigService;
-import com.ctrip.framework.apollo.core.enums.ConfigFileFormat;
-import com.ctrip.framework.apollo.enums.ConfigSourceType;
-import com.ctrip.framework.apollo.enums.PropertyChangeType;
-import com.ctrip.framework.apollo.model.ConfigChange;
-
-import java.util.Arrays;
-import java.util.Collections;
-import java.util.Set;
-import java.util.concurrent.ConcurrentHashMap;
-import java.util.concurrent.ConcurrentMap;
-import java.util.concurrent.CopyOnWriteArraySet;
-import java.util.stream.Collectors;
-
-import static org.apache.dubbo.common.config.configcenter.Constants.CONFIG_NAMESPACE_KEY;
-import static org.apache.dubbo.common.constants.CommonConstants.ANYHOST_VALUE;
-import static org.apache.dubbo.common.constants.CommonConstants.APPLICATION_KEY;
-import static org.apache.dubbo.common.constants.CommonConstants.CHECK_KEY;
-import static org.apache.dubbo.common.constants.CommonConstants.CLUSTER_KEY;
-import static org.apache.dubbo.common.constants.CommonConstants.COMMA_SPLIT_PATTERN;
-import static org.apache.dubbo.common.constants.CommonConstants.GROUP_KEY;
-
-/**
- * Apollo implementation, https://github.com/ctripcorp/apollo
- *
- * Apollo will be used for management of both governance rules and .properties files, by default, these two different
- * kinds of data share the same namespace 'dubbo'. To gain better performance, we recommend separate them by giving
- * namespace and group different values, for example:
- *
- * <dubbo:config-center namespace="governance" group="dubbo" />, 'dubbo=governance' is for governance rules while
- * 'group=dubbo' is for properties files.
- *
- * Please see http://dubbo.apache.org/zh-cn/docs/user/configuration/config-center.html for details.
- */
-public class ApolloDynamicConfiguration implements DynamicConfiguration {
-    private static final Logger logger = LoggerFactory.getLogger(ApolloDynamicConfiguration.class);
-    private static final String APOLLO_ENV_KEY = "env";
-    private static final String APOLLO_ADDR_KEY = "apollo.meta";
-    private static final String APOLLO_CLUSTER_KEY = "apollo.cluster";
-    private static final String APOLLO_PROTOCOL_PREFIX = "http://";
-    private static final String APOLLO_APPLICATION_KEY = "application";
-    private static final String APOLLO_APPID_KEY = "app.id";
-
-    private URL url;
-    private Config dubboConfig;
-    private ConfigFile dubboConfigFile;
-    private ConcurrentMap<String, ApolloListener> listeners = new ConcurrentHashMap<>();
-
-    ApolloDynamicConfiguration(URL url) {
-        this.url = url;
-        // Instead of using Dubbo's configuration, I would suggest use the original configuration method Apollo provides.
-        String configEnv = url.getParameter(APOLLO_ENV_KEY);
-        String configAddr = getAddressWithProtocolPrefix(url);
-        String configCluster = url.getParameter(CLUSTER_KEY);
-        String configAppId = url.getParameter(APOLLO_APPID_KEY);
-        if (StringUtils.isEmpty(System.getProperty(APOLLO_ENV_KEY)) && configEnv != null) {
-            System.setProperty(APOLLO_ENV_KEY, configEnv);
-        }
-        if (StringUtils.isEmpty(System.getProperty(APOLLO_ADDR_KEY)) && !ANYHOST_VALUE.equals(url.getHost())) {
-            System.setProperty(APOLLO_ADDR_KEY, configAddr);
-        }
-        if (StringUtils.isEmpty(System.getProperty(APOLLO_CLUSTER_KEY)) && configCluster != null) {
-            System.setProperty(APOLLO_CLUSTER_KEY, configCluster);
-        }
-        if (StringUtils.isEmpty(System.getProperty(APOLLO_APPID_KEY)) && configAppId != null) {
-            System.setProperty(APOLLO_APPID_KEY, configAppId);
-        }
-
-        String namespace = url.getParameter(CONFIG_NAMESPACE_KEY, DEFAULT_GROUP);
-        String apolloNamespace = StringUtils.isEmpty(namespace) ? url.getParameter(GROUP_KEY, DEFAULT_GROUP) : namespace;
-        dubboConfig = ConfigService.getConfig(apolloNamespace);
-        dubboConfigFile = ConfigService.getConfigFile(apolloNamespace, ConfigFileFormat.Properties);
-
-        // Decide to fail or to continue when failed to connect to remote server.
-        boolean check = url.getParameter(CHECK_KEY, true);
-        if (dubboConfig.getSourceType() != ConfigSourceType.REMOTE) {
-            if (check) {
-                throw new IllegalStateException("Failed to connect to config center, the config center is Apollo, " +
-                        "the address is: " + (StringUtils.isNotEmpty(configAddr) ? configAddr : configEnv));
-            } else {
-                logger.warn("Failed to connect to config center, the config center is Apollo, " +
-                        "the address is: " + (StringUtils.isNotEmpty(configAddr) ? configAddr : configEnv) +
-                        ", will use the local cache value instead before eventually the connection is established.");
-            }
-        }
-    }
-
-    private String getAddressWithProtocolPrefix(URL url) {
-        String address = url.getBackupAddress();
-        if (StringUtils.isNotEmpty(address)) {
-            address = Arrays.stream(COMMA_SPLIT_PATTERN.split(address))
-                    .map(addr -> {
-                        if (addr.startsWith(APOLLO_PROTOCOL_PREFIX)) {
-                            return addr;
-                        }
-                        return APOLLO_PROTOCOL_PREFIX + addr;
-                    })
-                    .collect(Collectors.joining(","));
-        }
-        return address;
-    }
-
-    /**
-     * Since all governance rules will lay under dubbo group, this method now always uses the default dubboConfig and
-     * ignores the group parameter.
-     */
-    @Override
-    public void addListener(String key, String group, ConfigurationListener listener) {
-        ApolloListener apolloListener = listeners.computeIfAbsent(group + key, k -> createTargetListener(key, group));
-        apolloListener.addListener(listener);
-        dubboConfig.addChangeListener(apolloListener, Collections.singleton(key));
-    }
-
-    @Override
-    public void removeListener(String key, String group, ConfigurationListener listener) {
-        ApolloListener apolloListener = listeners.get(group + key);
-        if (apolloListener != null) {
-            apolloListener.removeListener(listener);
-            if (!apolloListener.hasInternalListener()) {
-                dubboConfig.removeChangeListener(apolloListener);
-            }
-        }
-    }
-
-    @Override
-    public String getConfig(String key, String group, long timeout) throws IllegalStateException {
-        if (StringUtils.isNotEmpty(group)) {
-            if (group.equals(url.getParameter(APPLICATION_KEY))) {
-                return ConfigService.getAppConfig().getProperty(key, null);
-            } else {
-                return ConfigService.getConfig(group).getProperty(key, null);
-            }
-        }
-        return dubboConfig.getProperty(key, null);
-    }
-
-    /**
-     * Recommend specify namespace and group when using Apollo.
-     * <p>
-     * <dubbo:config-center namespace="governance" group="dubbo" />, 'dubbo=governance' is for governance rules while
-     * 'group=dubbo' is for properties files.
-     *
-     * @param key     default value is 'dubbo.properties', currently useless for Apollo.
-     * @param group
-     * @param timeout
-     * @return
-     * @throws IllegalStateException
-     */
-    @Override
-    public String getProperties(String key, String group, long timeout) throws IllegalStateException {
-        if (StringUtils.isEmpty(group)) {
-            return dubboConfigFile.getContent();
-        }
-        if (group.equals(url.getParameter(APPLICATION_KEY))) {
-            return ConfigService.getConfigFile(APOLLO_APPLICATION_KEY, ConfigFileFormat.Properties).getContent();
-        }
-
-        ConfigFile configFile = ConfigService.getConfigFile(group, ConfigFileFormat.Properties);
-        if (configFile == null) {
-            throw new IllegalStateException("There is no namespace named " + group + " in Apollo.");
-        }
-        return configFile.getContent();
-    }
-
-    /**
-     * This method will be used by Configuration to get valid value at runtime.
-     * The group is expected to be 'app level', which can be fetched from the 'config.appnamespace' in url if necessary.
-     * But I think Apollo's inheritance feature of namespace can solve the problem .
-     */
-    @Override
-    public String getInternalProperty(String key) {
-        return dubboConfig.getProperty(key, null);
-    }
-
-    /**
-     * Ignores the group parameter.
-     *
-     * @param key   property key the native listener will listen on
-     * @param group to distinguish different set of properties
-     * @return
-     */
-    private ApolloListener createTargetListener(String key, String group) {
-        return new ApolloListener();
-    }
-
-    public class ApolloListener implements ConfigChangeListener {
-
-        private Set<ConfigurationListener> listeners = new CopyOnWriteArraySet<>();
-
-        ApolloListener() {
-        }
-
-        @Override
-        public void onChange(com.ctrip.framework.apollo.model.ConfigChangeEvent changeEvent) {
-            for (String key : changeEvent.changedKeys()) {
-                ConfigChange change = changeEvent.getChange(key);
-                if ("".equals(change.getNewValue())) {
-                    logger.warn("an empty rule is received for " + key + ", the current working rule is " +
-                            change.getOldValue() + ", the empty rule will not take effect.");
-                    return;
-                }
-
-                ConfigChangedEvent event = new ConfigChangedEvent(key, change.getNamespace(), change.getNewValue(), getChangeType(change));
-                listeners.forEach(listener -> listener.process(event));
-            }
-        }
-
-        private ConfigChangeType getChangeType(ConfigChange change) {
-            if (change.getChangeType() == PropertyChangeType.DELETED) {
-                return ConfigChangeType.DELETED;
-            }
-            return ConfigChangeType.MODIFIED;
-        }
-
-        void addListener(ConfigurationListener configurationListener) {
-            this.listeners.add(configurationListener);
-        }
-
-        void removeListener(ConfigurationListener configurationListener) {
-            this.listeners.remove(configurationListener);
-        }
-
-        boolean hasInternalListener() {
-            return listeners != null && listeners.size() > 0;
-        }
-    }
-
-}
diff --git a/dubbo-spi-configcenter/dubbo-configcenter-apollo/src/main/java/org/apache/dubbo/configcenter/support/apollo/ApolloDynamicConfigurationFactory.java b/dubbo-spi-configcenter/dubbo-configcenter-apollo/src/main/java/org/apache/dubbo/configcenter/support/apollo/ApolloDynamicConfigurationFactory.java
deleted file mode 100644
index 6a8ce30..0000000
--- a/dubbo-spi-configcenter/dubbo-configcenter-apollo/src/main/java/org/apache/dubbo/configcenter/support/apollo/ApolloDynamicConfigurationFactory.java
+++ /dev/null
@@ -1,31 +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.configcenter.support.apollo;
-
-import org.apache.dubbo.common.URL;
-import org.apache.dubbo.common.config.configcenter.AbstractDynamicConfigurationFactory;
-import org.apache.dubbo.common.config.configcenter.DynamicConfiguration;
-
-/**
- *
- */
-public class ApolloDynamicConfigurationFactory extends AbstractDynamicConfigurationFactory {
-    @Override
-    protected DynamicConfiguration createDynamicConfiguration(URL url) {
-        return new ApolloDynamicConfiguration(url);
-    }
-}
diff --git a/dubbo-spi-configcenter/dubbo-configcenter-apollo/src/main/resources/META-INF/dubbo/internal/org.apache.dubbo.common.config.configcenter.DynamicConfigurationFactory b/dubbo-spi-configcenter/dubbo-configcenter-apollo/src/main/resources/META-INF/dubbo/internal/org.apache.dubbo.common.config.configcenter.DynamicConfigurationFactory
deleted file mode 100644
index 0ea08c5..0000000
--- a/dubbo-spi-configcenter/dubbo-configcenter-apollo/src/main/resources/META-INF/dubbo/internal/org.apache.dubbo.common.config.configcenter.DynamicConfigurationFactory
+++ /dev/null
@@ -1 +0,0 @@
-apollo=org.apache.dubbo.configcenter.support.apollo.ApolloDynamicConfigurationFactory
\ No newline at end of file
diff --git a/dubbo-spi-configcenter/dubbo-configcenter-apollo/src/test/java/org/apache/dubbo/configcenter/support/apollo/ApolloDynamicConfigurationTest.java b/dubbo-spi-configcenter/dubbo-configcenter-apollo/src/test/java/org/apache/dubbo/configcenter/support/apollo/ApolloDynamicConfigurationTest.java
deleted file mode 100644
index ca48bd6..0000000
--- a/dubbo-spi-configcenter/dubbo-configcenter-apollo/src/test/java/org/apache/dubbo/configcenter/support/apollo/ApolloDynamicConfigurationTest.java
+++ /dev/null
@@ -1,191 +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.configcenter.support.apollo;
-
-import org.apache.dubbo.common.URL;
-import org.apache.dubbo.common.config.configcenter.ConfigChangeType;
-import org.apache.dubbo.common.config.configcenter.ConfigurationListener;
-
-import com.ctrip.framework.apollo.mockserver.EmbeddedApollo;
-import com.google.common.util.concurrent.SettableFuture;
-import org.junit.After;
-import org.junit.Before;
-import org.junit.ClassRule;
-import org.junit.Test;
-
-import java.io.FileOutputStream;
-import java.io.IOException;
-import java.util.Properties;
-import java.util.Random;
-import java.util.concurrent.TimeUnit;
-
-import static org.junit.jupiter.api.Assertions.assertEquals;
-import static org.junit.jupiter.api.Assertions.assertNull;
-import static org.junit.jupiter.api.Assertions.fail;
-
-/**
- * Apollo dynamic configuration mock test.
- * Notice: EmbeddedApollo(apollo mock server) only support < junit5, please not upgrade the junit version in this UT,
- * the junit version in this UT is junit4, and the dependency comes from apollo-mockserver.
- */
-public class ApolloDynamicConfigurationTest {
-    private static final String SESSION_TIMEOUT_KEY = "session";
-    private static final String DEFAULT_NAMESPACE = "dubbo";
-    private static ApolloDynamicConfiguration apolloDynamicConfiguration;
-    private static URL url;
-
-    /**
-     * The constant embeddedApollo.
-     */
-    @ClassRule
-    public static EmbeddedApollo embeddedApollo = new EmbeddedApollo();
-
-    /**
-     * Sets up.
-     */
-    @Before
-    public void setUp() {
-        String apolloUrl = System.getProperty("apollo.configService");
-        String urlForDubbo = "apollo://" + apolloUrl.substring(apolloUrl.lastIndexOf("/") + 1) + "/org.apache.dubbo.apollo.testService?namespace=dubbo&check=true";
-        url = URL.valueOf(urlForDubbo).addParameter(SESSION_TIMEOUT_KEY, 15000);
-    }
-
-//    /**
-//     * Embedded Apollo does not work as expected.
-//     */
-//    @Test
-//    public void testProperties() {
-//        URL url = this.url.addParameter(GROUP_KEY, "dubbo")
-//                .addParameter("namespace", "governance");
-//
-//        apolloDynamicConfiguration = new ApolloDynamicConfiguration(url);
-//        putData("dubbo", "dubbo.registry.address", "zookeeper://127.0.0.1:2181");
-//        assertEquals("zookeeper://127.0.0.1:2181", apolloDynamicConfiguration.getProperties(null, "dubbo"));
-//
-//        putData("governance", "router.tag", "router tag rule");
-//        assertEquals("router tag rule", apolloDynamicConfiguration.getConfig("router.tag", "governance"));
-//
-//    }
-
-    /**
-     * Test get rule.
-     */
-    @Test
-    public void testGetRule() {
-        String mockKey = "mockKey1";
-        String mockValue = String.valueOf(new Random().nextInt());
-        putMockRuleData(mockKey, mockValue, DEFAULT_NAMESPACE);
-        apolloDynamicConfiguration = new ApolloDynamicConfiguration(url);
-        assertEquals(mockValue, apolloDynamicConfiguration.getConfig(mockKey, DEFAULT_NAMESPACE, 3000L));
-
-        mockKey = "notExistKey";
-        assertNull(apolloDynamicConfiguration.getConfig(mockKey, DEFAULT_NAMESPACE, 3000L));
-    }
-
-    /**
-     * Test get internal property.
-     *
-     * @throws InterruptedException the interrupted exception
-     */
-    @Test
-    public void testGetInternalProperty() throws InterruptedException {
-        String mockKey = "mockKey2";
-        String mockValue = String.valueOf(new Random().nextInt());
-        putMockRuleData(mockKey, mockValue, DEFAULT_NAMESPACE);
-        TimeUnit.MILLISECONDS.sleep(1000);
-        apolloDynamicConfiguration = new ApolloDynamicConfiguration(url);
-        assertEquals(mockValue, apolloDynamicConfiguration.getInternalProperty(mockKey));
-
-        mockValue = "mockValue2";
-        System.setProperty(mockKey, mockValue);
-        assertEquals(mockValue, apolloDynamicConfiguration.getInternalProperty(mockKey));
-
-        mockKey = "notExistKey";
-        assertNull(apolloDynamicConfiguration.getInternalProperty(mockKey));
-    }
-
-    /**
-     * Test add listener.
-     *
-     * @throws Exception the exception
-     */
-    @Test
-    public void testAddListener() throws Exception {
-        String mockKey = "mockKey3";
-        String mockValue = String.valueOf(new Random().nextInt());
-
-        final SettableFuture<org.apache.dubbo.common.config.configcenter.ConfigChangedEvent> future = SettableFuture.create();
-
-        apolloDynamicConfiguration = new ApolloDynamicConfiguration(url);
-
-        apolloDynamicConfiguration.addListener(mockKey, DEFAULT_NAMESPACE, new ConfigurationListener() {
-            @Override
-            public void process(org.apache.dubbo.common.config.configcenter.ConfigChangedEvent event) {
-                future.set(event);
-            }
-        });
-
-        putData(mockKey, mockValue);
-        org.apache.dubbo.common.config.configcenter.ConfigChangedEvent result = future.get(3000, TimeUnit.MILLISECONDS);
-        assertEquals(mockValue, result.getContent());
-        assertEquals(mockKey, result.getKey());
-        assertEquals(ConfigChangeType.MODIFIED, result.getChangeType());
-    }
-
-    private static void putData(String namespace, String key, String value) {
-        embeddedApollo.addOrModifyProperty(namespace, key, value);
-    }
-
-    private static void putData(String key, String value) {
-        embeddedApollo.addOrModifyProperty(DEFAULT_NAMESPACE, key, value);
-    }
-
-    private static void putMockRuleData(String key, String value, String group) {
-        String fileName = ApolloDynamicConfigurationTest.class.getResource("/").getPath() + "mockdata-" + group + ".properties";
-        putMockData(key, value, fileName);
-    }
-
-    private static void putMockData(String key, String value, String fileName) {
-        Properties pro = new Properties();
-        FileOutputStream oFile = null;
-        try {
-            oFile = new FileOutputStream(fileName);
-            pro.setProperty(key, value);
-            pro.store(oFile, "put mock data");
-        } catch (IOException exx) {
-            fail(exx.getMessage());
-
-        } finally {
-            if (null != oFile) {
-                try {
-                    oFile.close();
-                } catch (IOException e) {
-                    fail(e.getMessage());
-                }
-            }
-        }
-    }
-
-    /**
-     * Tear down.
-     */
-    @After
-    public void tearDown() {
-
-    }
-
-}
\ No newline at end of file
diff --git a/dubbo-spi-configcenter/dubbo-configcenter-apollo/src/test/resources/META-INF/app.properties b/dubbo-spi-configcenter/dubbo-configcenter-apollo/src/test/resources/META-INF/app.properties
deleted file mode 100644
index 4d963e2..0000000
--- a/dubbo-spi-configcenter/dubbo-configcenter-apollo/src/test/resources/META-INF/app.properties
+++ /dev/null
@@ -1 +0,0 @@
-app.id=someAppId
\ No newline at end of file
diff --git a/dubbo-spi-configcenter/dubbo-configcenter-apollo/src/test/resources/mockdata-dubbo.properties b/dubbo-spi-configcenter/dubbo-configcenter-apollo/src/test/resources/mockdata-dubbo.properties
deleted file mode 100644
index f995a3b..0000000
--- a/dubbo-spi-configcenter/dubbo-configcenter-apollo/src/test/resources/mockdata-dubbo.properties
+++ /dev/null
@@ -1,2 +0,0 @@
-key1=value1
-key2=value2
\ No newline at end of file
diff --git a/dubbo-spi-configcenter/dubbo-configcenter-nacos/pom.xml b/dubbo-spi-configcenter/dubbo-configcenter-nacos/pom.xml
deleted file mode 100644
index 42dcc69..0000000
--- a/dubbo-spi-configcenter/dubbo-configcenter-nacos/pom.xml
+++ /dev/null
@@ -1,45 +0,0 @@
-<?xml version="1.0" encoding="UTF-8"?>
-<!--
-  ~ 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.
-  -->
-
-<project xmlns="http://maven.apache.org/POM/4.0.0"
-         xmlns:xsi="http://www.w3.org/2001/XMLSchema-instance"
-         xsi:schemaLocation="http://maven.apache.org/POM/4.0.0 http://maven.apache.org/xsd/maven-4.0.0.xsd">
-    <parent>
-        <groupId>org.apache.dubbo</groupId>
-        <artifactId>dubbo-configcenter</artifactId>
-        <version>2.7.7-SNAPSHOT</version>
-    </parent>
-    <modelVersion>4.0.0</modelVersion>
-
-    <artifactId>dubbo-configcenter-nacos</artifactId>
-    <packaging>jar</packaging>
-    <name>${project.artifactId}</name>
-    <description>The nacos implementation of the config-center api</description>
-
-    <dependencies>
-        <dependency>
-            <groupId>org.apache.dubbo</groupId>
-            <artifactId>dubbo-common</artifactId>
-            <version>${project.parent.version}</version>
-        </dependency>
-        <dependency>
-            <groupId>com.alibaba.nacos</groupId>
-            <artifactId>nacos-client</artifactId>
-        </dependency>
-    </dependencies>
-</project>
diff --git a/dubbo-spi-configcenter/dubbo-configcenter-nacos/src/main/java/org/apache/dubbo/configcenter/support/nacos/NacosDynamicConfiguration.java b/dubbo-spi-configcenter/dubbo-configcenter-nacos/src/main/java/org/apache/dubbo/configcenter/support/nacos/NacosDynamicConfiguration.java
deleted file mode 100644
index 2227015..0000000
--- a/dubbo-spi-configcenter/dubbo-configcenter-nacos/src/main/java/org/apache/dubbo/configcenter/support/nacos/NacosDynamicConfiguration.java
+++ /dev/null
@@ -1,381 +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.configcenter.support.nacos;
-
-import org.apache.dubbo.common.URL;
-import org.apache.dubbo.common.config.configcenter.ConfigChangeType;
-import org.apache.dubbo.common.config.configcenter.ConfigChangedEvent;
-import org.apache.dubbo.common.config.configcenter.ConfigurationListener;
-import org.apache.dubbo.common.config.configcenter.DynamicConfiguration;
-import org.apache.dubbo.common.logger.Logger;
-import org.apache.dubbo.common.logger.LoggerFactory;
-import org.apache.dubbo.common.utils.StringUtils;
-
-import com.alibaba.fastjson.JSON;
-import com.alibaba.fastjson.JSONArray;
-import com.alibaba.fastjson.JSONObject;
-import com.alibaba.nacos.api.NacosFactory;
-import com.alibaba.nacos.api.config.ConfigService;
-import com.alibaba.nacos.api.config.listener.AbstractSharedListener;
-import com.alibaba.nacos.api.exception.NacosException;
-import com.alibaba.nacos.client.config.http.HttpAgent;
-import com.alibaba.nacos.client.config.impl.HttpSimpleClient;
-
-import java.io.IOException;
-import java.lang.reflect.Field;
-import java.util.List;
-import java.util.Map;
-import java.util.Properties;
-import java.util.Set;
-import java.util.SortedSet;
-import java.util.TreeSet;
-import java.util.concurrent.ConcurrentHashMap;
-import java.util.concurrent.ConcurrentMap;
-import java.util.concurrent.CopyOnWriteArraySet;
-import java.util.concurrent.Executor;
-import java.util.stream.Stream;
-
-import static com.alibaba.nacos.api.PropertyKeyConst.ACCESS_KEY;
-import static com.alibaba.nacos.api.PropertyKeyConst.CLUSTER_NAME;
-import static com.alibaba.nacos.api.PropertyKeyConst.CONFIG_LONG_POLL_TIMEOUT;
-import static com.alibaba.nacos.api.PropertyKeyConst.CONFIG_RETRY_TIME;
-import static com.alibaba.nacos.api.PropertyKeyConst.CONTEXT_PATH;
-import static com.alibaba.nacos.api.PropertyKeyConst.ENABLE_REMOTE_SYNC_CONFIG;
-import static com.alibaba.nacos.api.PropertyKeyConst.ENCODE;
-import static com.alibaba.nacos.api.PropertyKeyConst.ENDPOINT;
-import static com.alibaba.nacos.api.PropertyKeyConst.ENDPOINT_PORT;
-import static com.alibaba.nacos.api.PropertyKeyConst.IS_USE_CLOUD_NAMESPACE_PARSING;
-import static com.alibaba.nacos.api.PropertyKeyConst.IS_USE_ENDPOINT_PARSING_RULE;
-import static com.alibaba.nacos.api.PropertyKeyConst.MAX_RETRY;
-import static com.alibaba.nacos.api.PropertyKeyConst.NAMESPACE;
-import static com.alibaba.nacos.api.PropertyKeyConst.NAMING_CLIENT_BEAT_THREAD_COUNT;
-import static com.alibaba.nacos.api.PropertyKeyConst.NAMING_LOAD_CACHE_AT_START;
-import static com.alibaba.nacos.api.PropertyKeyConst.NAMING_POLLING_THREAD_COUNT;
-import static com.alibaba.nacos.api.PropertyKeyConst.RAM_ROLE_NAME;
-import static com.alibaba.nacos.api.PropertyKeyConst.SECRET_KEY;
-import static com.alibaba.nacos.api.PropertyKeyConst.SERVER_ADDR;
-import static com.alibaba.nacos.client.naming.utils.UtilAndComs.NACOS_NAMING_LOG_NAME;
-import static java.util.Arrays.asList;
-import static java.util.Collections.emptyList;
-import static org.apache.dubbo.common.constants.RemotingConstants.BACKUP_KEY;
-import static org.apache.dubbo.common.utils.StringUtils.HYPHEN_CHAR;
-import static org.apache.dubbo.common.utils.StringUtils.SLASH_CHAR;
-
-/**
- * The nacos implementation of {@link DynamicConfiguration}
- */
-public class NacosDynamicConfiguration implements DynamicConfiguration {
-
-    private static final String GET_CONFIG_KEYS_PATH = "/v1/cs/configs";
-
-    private final Logger logger = LoggerFactory.getLogger(getClass());
-    /**
-     * the default timeout in millis to get config from nacos
-     */
-    private static final long DEFAULT_TIMEOUT = 5000L;
-
-    private Properties nacosProperties;
-
-    /**
-     * The nacos configService
-     */
-    private final ConfigService configService;
-
-    private HttpAgent httpAgent;
-
-    /**
-     * The map store the key to {@link NacosConfigListener} mapping
-     */
-    private final ConcurrentMap<String, NacosConfigListener> watchListenerMap;
-
-    NacosDynamicConfiguration(URL url) {
-        this.nacosProperties = buildNacosProperties(url);
-        this.configService = buildConfigService(url);
-        this.httpAgent = getHttpAgent(configService);
-        watchListenerMap = new ConcurrentHashMap<>();
-    }
-
-    private ConfigService buildConfigService(URL url) {
-        ConfigService configService = null;
-        try {
-            configService = NacosFactory.createConfigService(nacosProperties);
-        } catch (NacosException e) {
-            if (logger.isErrorEnabled()) {
-                logger.error(e.getErrMsg(), e);
-            }
-            throw new IllegalStateException(e);
-        }
-        return configService;
-    }
-
-    private HttpAgent getHttpAgent(ConfigService configService) {
-        HttpAgent agent = null;
-        try {
-            Field field = configService.getClass().getDeclaredField("agent");
-            field.setAccessible(true);
-            agent = (HttpAgent) field.get(configService);
-        } catch (Exception e) {
-            throw new IllegalStateException(e);
-        }
-        return agent;
-    }
-
-    private Properties buildNacosProperties(URL url) {
-        Properties properties = new Properties();
-        setServerAddr(url, properties);
-        setProperties(url, properties);
-        return properties;
-    }
-
-    private void setServerAddr(URL url, Properties properties) {
-        StringBuilder serverAddrBuilder =
-                new StringBuilder(url.getHost()) // Host
-                        .append(":")
-                        .append(url.getPort()); // Port
-
-        // Append backup parameter as other servers
-        String backup = url.getParameter(BACKUP_KEY);
-        if (backup != null) {
-            serverAddrBuilder.append(",").append(backup);
-        }
-        String serverAddr = serverAddrBuilder.toString();
-        properties.put(SERVER_ADDR, serverAddr);
-    }
-
-    private static void setProperties(URL url, Properties properties) {
-        putPropertyIfAbsent(url, properties, NACOS_NAMING_LOG_NAME);
-        putPropertyIfAbsent(url, properties, IS_USE_CLOUD_NAMESPACE_PARSING);
-        putPropertyIfAbsent(url, properties, IS_USE_ENDPOINT_PARSING_RULE);
-        putPropertyIfAbsent(url, properties, ENDPOINT);
-        putPropertyIfAbsent(url, properties, ENDPOINT_PORT);
-        putPropertyIfAbsent(url, properties, NAMESPACE);
-        putPropertyIfAbsent(url, properties, ACCESS_KEY);
-        putPropertyIfAbsent(url, properties, SECRET_KEY);
-        putPropertyIfAbsent(url, properties, RAM_ROLE_NAME);
-        putPropertyIfAbsent(url, properties, CONTEXT_PATH);
-        putPropertyIfAbsent(url, properties, CLUSTER_NAME);
-        putPropertyIfAbsent(url, properties, ENCODE);
-        putPropertyIfAbsent(url, properties, CONFIG_LONG_POLL_TIMEOUT);
-        putPropertyIfAbsent(url, properties, CONFIG_RETRY_TIME);
-        putPropertyIfAbsent(url, properties, MAX_RETRY);
-        putPropertyIfAbsent(url, properties, ENABLE_REMOTE_SYNC_CONFIG);
-        putPropertyIfAbsent(url, properties, NAMING_LOAD_CACHE_AT_START, "true");
-        putPropertyIfAbsent(url, properties, NAMING_CLIENT_BEAT_THREAD_COUNT);
-        putPropertyIfAbsent(url, properties, NAMING_POLLING_THREAD_COUNT);
-    }
-
-    private static void putPropertyIfAbsent(URL url, Properties properties, String propertyName) {
-        String propertyValue = url.getParameter(propertyName);
-        if (StringUtils.isNotEmpty(propertyValue)) {
-            properties.setProperty(propertyName, propertyValue);
-        }
-    }
-
-    private static void putPropertyIfAbsent(URL url, Properties properties, String propertyName, String defaultValue) {
-        String propertyValue = url.getParameter(propertyName);
-        if (StringUtils.isNotEmpty(propertyValue)) {
-            properties.setProperty(propertyName, propertyValue);
-        } else {
-            properties.setProperty(propertyName, defaultValue);
-        }
-    }
-
-    /**
-     * Ignores the group parameter.
-     *
-     * @param key   property key the native listener will listen on
-     * @param group to distinguish different set of properties
-     * @return
-     */
-    private NacosConfigListener createTargetListener(String key, String group) {
-        NacosConfigListener configListener = new NacosConfigListener();
-        configListener.fillContext(key, group);
-        return configListener;
-    }
-
-    @Override
-    public void addListener(String key, String group, ConfigurationListener listener) {
-        String resolvedGroup = resolveGroup(group);
-        String listenerKey = buildListenerKey(key, group);
-        NacosConfigListener nacosConfigListener = watchListenerMap.computeIfAbsent(listenerKey, k -> createTargetListener(key, resolvedGroup));
-        nacosConfigListener.addListener(listener);
-        try {
-            configService.addListener(key, resolvedGroup, nacosConfigListener);
-        } catch (NacosException e) {
-            logger.error(e.getMessage());
-        }
-    }
-
-    @Override
-    public void removeListener(String key, String group, ConfigurationListener listener) {
-        String listenerKey = buildListenerKey(key, group);
-        NacosConfigListener eventListener = watchListenerMap.get(listenerKey);
-        if (eventListener != null) {
-            eventListener.removeListener(listener);
-        }
-    }
-
-    @Override
-    public String getConfig(String key, String group, long timeout) throws IllegalStateException {
-        String resolvedGroup = resolveGroup(group);
-        try {
-            long nacosTimeout = timeout < 0 ? getDefaultTimeout() : timeout;
-            if (StringUtils.isEmpty(resolvedGroup)) {
-                resolvedGroup = DEFAULT_GROUP;
-            }
-            return configService.getConfig(key, resolvedGroup, nacosTimeout);
-        } catch (NacosException e) {
-            logger.error(e.getMessage());
-        }
-        return null;
-    }
-
-    @Override
-    public Object getInternalProperty(String key) {
-        try {
-            return configService.getConfig(key, DEFAULT_GROUP, getDefaultTimeout());
-        } catch (NacosException e) {
-            logger.error(e.getMessage());
-        }
-        return null;
-    }
-
-    @Override
-    public boolean publishConfig(String key, String group, String content) {
-        boolean published = false;
-        String resolvedGroup = resolveGroup(group);
-        try {
-            String value = configService.getConfig(key, resolvedGroup, getDefaultTimeout());
-            if (StringUtils.isNotEmpty(value)) {
-                content = value + "," + content;
-            }
-            published = configService.publishConfig(key, resolvedGroup, content);
-        } catch (NacosException e) {
-            logger.error(e.getErrMsg());
-        }
-        return published;
-    }
-
-    @Override
-    public long getDefaultTimeout() {
-        return DEFAULT_TIMEOUT;
-    }
-
-    /**
-     * TODO Nacos does not support atomic update of the value mapped to a key.
-     *
-     * @param key
-     * @param group the specified group
-     * @return
-     */
-    @Override
-    public SortedSet<String> getConfigKeys(String group) {
-        // TODO use Nacos Client API to replace HTTP Open API
-        SortedSet<String> keys = new TreeSet<>();
-        try {
-            List<String> paramsValues = asList(
-                    "search", "accurate",
-                    "dataId", "",
-                    "group", resolveGroup(group),
-                    "pageNo", "1",
-                    "pageSize", String.valueOf(Integer.MAX_VALUE)
-            );
-            String encoding = getProperty(ENCODE, "UTF-8");
-            HttpSimpleClient.HttpResult result = httpAgent.httpGet(GET_CONFIG_KEYS_PATH, emptyList(), paramsValues, encoding, 5 * 1000);
-            Stream<String> keysStream = toKeysStream(result.content);
-            keysStream.forEach(keys::add);
-        } catch (IOException e) {
-            if (logger.isErrorEnabled()) {
-                logger.error(e.getMessage(), e);
-            }
-        }
-        return keys;
-    }
-
-    private Stream<String> toKeysStream(String content) {
-        JSONObject jsonObject = JSON.parseObject(content);
-        JSONArray pageItems = jsonObject.getJSONArray("pageItems");
-        return pageItems.stream()
-                .map(object -> (JSONObject) object)
-                .map(json -> json.getString("dataId"));
-    }
-
-    private String getProperty(String name, String defaultValue) {
-        return nacosProperties.getProperty(name, defaultValue);
-    }
-
-    public class NacosConfigListener extends AbstractSharedListener {
-
-        private Set<ConfigurationListener> listeners = new CopyOnWriteArraySet<>();
-        /**
-         * cache data to store old value
-         */
-        private Map<String, String> cacheData = new ConcurrentHashMap<>();
-
-        @Override
-        public Executor getExecutor() {
-            return null;
-        }
-
-        /**
-         * receive
-         *
-         * @param dataId     data ID
-         * @param group      group
-         * @param configInfo content
-         */
-        @Override
-        public void innerReceive(String dataId, String group, String configInfo) {
-            String oldValue = cacheData.get(dataId);
-            ConfigChangedEvent event = new ConfigChangedEvent(dataId, group, configInfo, getChangeType(configInfo, oldValue));
-            if (configInfo == null) {
-                cacheData.remove(dataId);
-            } else {
-                cacheData.put(dataId, configInfo);
-            }
-            listeners.forEach(listener -> listener.process(event));
-        }
-
-        void addListener(ConfigurationListener configurationListener) {
-
-            this.listeners.add(configurationListener);
-        }
-
-        void removeListener(ConfigurationListener configurationListener) {
-            this.listeners.remove(configurationListener);
-        }
-
-        private ConfigChangeType getChangeType(String configInfo, String oldValue) {
-            if (StringUtils.isBlank(configInfo)) {
-                return ConfigChangeType.DELETED;
-            }
-            if (StringUtils.isBlank(oldValue)) {
-                return ConfigChangeType.ADDED;
-            }
-            return ConfigChangeType.MODIFIED;
-        }
-    }
-
-    protected String buildListenerKey(String key, String group) {
-        return key + HYPHEN_CHAR + resolveGroup(group);
-    }
-
-    protected String resolveGroup(String group) {
-        return group.replace(SLASH_CHAR, HYPHEN_CHAR);
-    }
-}
diff --git a/dubbo-spi-configcenter/dubbo-configcenter-nacos/src/main/java/org/apache/dubbo/configcenter/support/nacos/NacosDynamicConfigurationFactory.java b/dubbo-spi-configcenter/dubbo-configcenter-nacos/src/main/java/org/apache/dubbo/configcenter/support/nacos/NacosDynamicConfigurationFactory.java
deleted file mode 100644
index 61c02b4..0000000
--- a/dubbo-spi-configcenter/dubbo-configcenter-nacos/src/main/java/org/apache/dubbo/configcenter/support/nacos/NacosDynamicConfigurationFactory.java
+++ /dev/null
@@ -1,41 +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.configcenter.support.nacos;
-
-import org.apache.dubbo.common.URL;
-import org.apache.dubbo.common.config.configcenter.AbstractDynamicConfigurationFactory;
-import org.apache.dubbo.common.config.configcenter.DynamicConfiguration;
-import org.apache.dubbo.common.constants.CommonConstants;
-
-import com.alibaba.nacos.api.PropertyKeyConst;
-
-/**
- * The nacos implementation of {@link AbstractDynamicConfigurationFactory}
- */
-public class NacosDynamicConfigurationFactory extends AbstractDynamicConfigurationFactory {
-
-    @Override
-    protected DynamicConfiguration createDynamicConfiguration(URL url) {
-        URL nacosURL = url;
-        if (CommonConstants.DUBBO.equals(url.getParameter(PropertyKeyConst.NAMESPACE))) {
-            // Nacos use empty string as default name space, replace default namespace "dubbo" to ""
-            nacosURL = url.removeParameter(PropertyKeyConst.NAMESPACE);
-        }
-        return new NacosDynamicConfiguration(nacosURL);
-    }
-}
diff --git a/dubbo-spi-configcenter/dubbo-configcenter-nacos/src/main/resources/META-INF/dubbo/internal/org.apache.dubbo.common.config.configcenter.DynamicConfigurationFactory b/dubbo-spi-configcenter/dubbo-configcenter-nacos/src/main/resources/META-INF/dubbo/internal/org.apache.dubbo.common.config.configcenter.DynamicConfigurationFactory
deleted file mode 100644
index b9c75a4..0000000
--- a/dubbo-spi-configcenter/dubbo-configcenter-nacos/src/main/resources/META-INF/dubbo/internal/org.apache.dubbo.common.config.configcenter.DynamicConfigurationFactory
+++ /dev/null
@@ -1 +0,0 @@
-nacos=org.apache.dubbo.configcenter.support.nacos.NacosDynamicConfigurationFactory
\ No newline at end of file
diff --git a/dubbo-spi-configcenter/dubbo-configcenter-nacos/src/test/java/org/apache/dubbo/configcenter/support/nacos/NacosDynamicConfigurationTest.java b/dubbo-spi-configcenter/dubbo-configcenter-nacos/src/test/java/org/apache/dubbo/configcenter/support/nacos/NacosDynamicConfigurationTest.java
deleted file mode 100644
index afafc1c..0000000
--- a/dubbo-spi-configcenter/dubbo-configcenter-nacos/src/test/java/org/apache/dubbo/configcenter/support/nacos/NacosDynamicConfigurationTest.java
+++ /dev/null
@@ -1,188 +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.configcenter.support.nacos;
-
-import org.apache.dubbo.common.URL;
-import org.apache.dubbo.common.config.configcenter.ConfigChangedEvent;
-import org.apache.dubbo.common.config.configcenter.ConfigurationListener;
-import org.apache.dubbo.common.config.configcenter.DynamicConfiguration;
-
-import com.alibaba.nacos.api.NacosFactory;
-import com.alibaba.nacos.api.config.ConfigService;
-import com.alibaba.nacos.api.exception.NacosException;
-import org.junit.jupiter.api.AfterAll;
-import org.junit.jupiter.api.Assertions;
-import org.junit.jupiter.api.BeforeAll;
-import org.junit.jupiter.api.Disabled;
-import org.junit.jupiter.api.Test;
-
-import java.util.HashMap;
-import java.util.Map;
-import java.util.SortedSet;
-import java.util.concurrent.CountDownLatch;
-
-import static org.junit.jupiter.api.Assertions.assertEquals;
-import static org.junit.jupiter.api.Assertions.assertTrue;
-
-
-/**
- * Unit test for nacos config center support
- */
-//FIXME: waiting for embedded Nacos suport, then we can open the switch.
-@Disabled("https://github.com/alibaba/nacos/issues/1188")
-public class NacosDynamicConfigurationTest {
-    private static final String SESSION_TIMEOUT_KEY = "session";
-
-    private static NacosDynamicConfiguration config;
-
-    /**
-     * A test client to put data to Nacos server for testing purpose
-     */
-    private static ConfigService nacosClient;
-
-    @Test
-    public void testGetConfig() throws Exception {
-        put("org.apache.dubbo.nacos.testService.configurators", "hello");
-        Thread.sleep(200);
-        put("dubbo.properties", "test", "aaa=bbb");
-        Thread.sleep(200);
-        put("org.apache.dubbo.demo.DemoService:1.0.0.test:xxxx.configurators", "helloworld");
-        Thread.sleep(200);
-        Assertions.assertEquals("hello", config.getConfig("org.apache.dubbo.nacos.testService.configurators", DynamicConfiguration.DEFAULT_GROUP));
-        Assertions.assertEquals("aaa=bbb", config.getConfig("dubbo.properties", "test"));
-        Assertions.assertEquals("helloworld", config.getConfig("org.apache.dubbo.demo.DemoService:1.0.0.test:xxxx.configurators", DynamicConfiguration.DEFAULT_GROUP));
-    }
-
-    @Test
-    public void testAddListener() throws Exception {
-        CountDownLatch latch = new CountDownLatch(4);
-        TestListener listener1 = new TestListener(latch);
-        TestListener listener2 = new TestListener(latch);
-        TestListener listener3 = new TestListener(latch);
-        TestListener listener4 = new TestListener(latch);
-
-
-        config.addListener("AService.configurators", listener1);
-        config.addListener("AService.configurators", listener2);
-        config.addListener("testapp.tag-router", listener3);
-        config.addListener("testapp.tag-router", listener4);
-
-        put("AService.configurators", "new value1");
-        Thread.sleep(200);
-        put("testapp.tag-router", "new value2");
-        Thread.sleep(200);
-        put("testapp", "new value3");
-        Thread.sleep(5000);
-
-        latch.await();
-
-        Assertions.assertEquals(1, listener1.getCount("AService.configurators"));
-        Assertions.assertEquals(1, listener2.getCount("AService.configurators"));
-        Assertions.assertEquals(1, listener3.getCount("testapp.tag-router"));
-        Assertions.assertEquals(1, listener4.getCount("testapp.tag-router"));
-
-        Assertions.assertEquals("new value1", listener1.getValue());
-        Assertions.assertEquals("new value1", listener2.getValue());
-        Assertions.assertEquals("new value2", listener3.getValue());
-        Assertions.assertEquals("new value2", listener4.getValue());
-
-    }
-
-    @Test
-    public void testGetConfigKeys() {
-
-        put("key1", "a");
-        put("key2", "b");
-
-        SortedSet<String> keys = config.getConfigKeys(DynamicConfiguration.DEFAULT_GROUP);
-
-        Assertions.assertFalse(keys.isEmpty());
-
-    }
-
-    private void put(String key, String value) {
-        put(key, DynamicConfiguration.DEFAULT_GROUP, value);
-    }
-
-    private void put(String key, String group, String value) {
-        try {
-            nacosClient.publishConfig(key, group, value);
-        } catch (Exception e) {
-            System.out.println("Error put value to nacos.");
-        }
-    }
-
-    @BeforeAll
-    public static void setUp() {
-        String urlForDubbo = "nacos://" + "127.0.0.1:8848" + "/org.apache.dubbo.nacos.testService";
-        // timeout in 15 seconds.
-        URL url = URL.valueOf(urlForDubbo)
-                .addParameter(SESSION_TIMEOUT_KEY, 15000);
-        config = new NacosDynamicConfiguration(url);
-
-
-        try {
-            nacosClient = NacosFactory.createConfigService("127.0.0.1:8848");
-        } catch (NacosException e) {
-            e.printStackTrace();
-        }
-    }
-
-    @Test
-    public void testPublishConfig() {
-        String key = "user-service";
-        String group = "org.apache.dubbo.service.UserService";
-        String content = "test";
-
-        assertTrue(config.publishConfig(key, group, content));
-        assertEquals("test", config.getProperties(key, group));
-    }
-
-    @AfterAll
-    public static void tearDown() {
-
-    }
-
-    private class TestListener implements ConfigurationListener {
-        private CountDownLatch latch;
-        private String value;
-        private Map<String, Integer> countMap = new HashMap<>();
-
-        public TestListener(CountDownLatch latch) {
-            this.latch = latch;
-        }
-
-        @Override
-        public void process(ConfigChangedEvent event) {
-            System.out.println(this + ": " + event);
-            Integer count = countMap.computeIfAbsent(event.getKey(), k -> 0);
-            countMap.put(event.getKey(), ++count);
-            value = event.getContent();
-            latch.countDown();
-        }
-
-        public int getCount(String key) {
-            return countMap.get(key);
-        }
-
-        public String getValue() {
-            return value;
-        }
-    }
-
-}
diff --git a/dubbo-spi-configcenter/pom.xml b/dubbo-spi-configcenter/pom.xml
index 0e3813a..458b80b 100644
--- a/dubbo-spi-configcenter/pom.xml
+++ b/dubbo-spi-configcenter/pom.xml
@@ -30,9 +30,7 @@
     </properties>
 
     <modules>
-        <module>dubbo-configcenter-apollo</module>
         <module>dubbo-configcenter-consul</module>
         <module>dubbo-configcenter-etcd</module>
-        <module>dubbo-configcenter-nacos</module>
     </modules>
 </project>
diff --git a/dubbo-spi-metadata/dubbo-metadata-report-redis/pom.xml b/dubbo-spi-metadata/dubbo-metadata-report-redis/pom.xml
deleted file mode 100644
index 70bd32d..0000000
--- a/dubbo-spi-metadata/dubbo-metadata-report-redis/pom.xml
+++ /dev/null
@@ -1,57 +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.
-  -->
-<project xmlns="http://maven.apache.org/POM/4.0.0" xmlns:xsi="http://www.w3.org/2001/XMLSchema-instance" xsi:schemaLocation="http://maven.apache.org/POM/4.0.0 http://maven.apache.org/xsd/maven-4.0.0.xsd">
-    <parent>
-        <groupId>org.apache.dubbo</groupId>
-        <artifactId>dubbo-metadata</artifactId>
-        <version>2.7.7-SNAPSHOT</version>
-    </parent>
-    <modelVersion>4.0.0</modelVersion>
-
-    <artifactId>dubbo-metadata-report-redis</artifactId>
-    <properties>
-        <jedis.version>2.9.0</jedis.version>
-    </properties>
-
-    <dependencies>
-        <dependency>
-            <groupId>org.apache.dubbo</groupId>
-            <artifactId>dubbo-metadata-api</artifactId>
-            <version>${project.parent.version}</version>
-        </dependency>
-        <dependency>
-            <groupId>redis.clients</groupId>
-            <artifactId>jedis</artifactId>
-            <version>${jedis.version}</version>
-        </dependency>
-        <dependency>
-            <groupId>org.apache.curator</groupId>
-            <artifactId>curator-test</artifactId>
-            <scope>test</scope>
-        </dependency>
-        <dependency>
-            <groupId>com.github.kstyrc</groupId>
-            <artifactId>embedded-redis</artifactId>
-            <scope>test</scope>
-        </dependency>
-        <dependency>
-            <groupId>org.apache.commons</groupId>
-            <artifactId>commons-lang3</artifactId>
-            <scope>test</scope>
-        </dependency>
-    </dependencies>
-</project>
diff --git a/dubbo-spi-metadata/dubbo-metadata-report-redis/src/main/java/org/apache/dubbo/metadata/store/redis/RedisMetadataReport.java b/dubbo-spi-metadata/dubbo-metadata-report-redis/src/main/java/org/apache/dubbo/metadata/store/redis/RedisMetadataReport.java
deleted file mode 100644
index c00be04..0000000
--- a/dubbo-spi-metadata/dubbo-metadata-report-redis/src/main/java/org/apache/dubbo/metadata/store/redis/RedisMetadataReport.java
+++ /dev/null
@@ -1,201 +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.metadata.store.redis;
-
-import org.apache.dubbo.common.URL;
-import org.apache.dubbo.common.logger.Logger;
-import org.apache.dubbo.common.logger.LoggerFactory;
-import org.apache.dubbo.common.utils.StringUtils;
-import org.apache.dubbo.metadata.report.identifier.BaseMetadataIdentifier;
-import org.apache.dubbo.metadata.report.identifier.KeyTypeEnum;
-import org.apache.dubbo.metadata.report.identifier.MetadataIdentifier;
-import org.apache.dubbo.metadata.report.identifier.ServiceMetadataIdentifier;
-import org.apache.dubbo.metadata.report.identifier.SubscriberMetadataIdentifier;
-import org.apache.dubbo.metadata.report.support.AbstractMetadataReport;
-import org.apache.dubbo.rpc.RpcException;
-
-import org.apache.commons.pool2.impl.GenericObjectPoolConfig;
-import redis.clients.jedis.HostAndPort;
-import redis.clients.jedis.Jedis;
-import redis.clients.jedis.JedisCluster;
-import redis.clients.jedis.JedisPool;
-import redis.clients.jedis.JedisPoolConfig;
-
-import java.util.ArrayList;
-import java.util.Arrays;
-import java.util.Collections;
-import java.util.HashSet;
-import java.util.List;
-import java.util.Set;
-
-import static org.apache.dubbo.common.constants.CommonConstants.CLUSTER_KEY;
-import static org.apache.dubbo.common.constants.CommonConstants.DEFAULT_TIMEOUT;
-import static org.apache.dubbo.common.constants.CommonConstants.TIMEOUT_KEY;
-import static org.apache.dubbo.metadata.MetadataConstants.META_DATA_STORE_TAG;
-
-/**
- * RedisMetadataReport
- */
-public class RedisMetadataReport extends AbstractMetadataReport {
-
-    private final static String REDIS_DATABASE_KEY = "database";
-    private final static Logger logger = LoggerFactory.getLogger(RedisMetadataReport.class);
-
-    JedisPool pool;
-    Set<HostAndPort> jedisClusterNodes;
-    private int timeout;
-    private String password;
-
-
-    public RedisMetadataReport(URL url) {
-        super(url);
-        timeout = url.getParameter(TIMEOUT_KEY, DEFAULT_TIMEOUT);
-        if (url.getParameter(CLUSTER_KEY, false)) {
-            jedisClusterNodes = new HashSet<HostAndPort>();
-            List<URL> urls = url.getBackupUrls();
-            for (URL tmpUrl : urls) {
-                jedisClusterNodes.add(new HostAndPort(tmpUrl.getHost(), tmpUrl.getPort()));
-            }
-        } else {
-            int database = url.getParameter(REDIS_DATABASE_KEY, 0);
-            pool = new JedisPool(new JedisPoolConfig(), url.getHost(), url.getPort(), timeout, url.getPassword(), database);
-        }
-    }
-
-    @Override
-    protected void doStoreProviderMetadata(MetadataIdentifier providerMetadataIdentifier, String serviceDefinitions) {
-        this.storeMetadata(providerMetadataIdentifier, serviceDefinitions);
-    }
-
-    @Override
-    protected void doStoreConsumerMetadata(MetadataIdentifier consumerMetadataIdentifier, String value) {
-        this.storeMetadata(consumerMetadataIdentifier, value);
-    }
-
-    @Override
-    protected void doSaveMetadata(ServiceMetadataIdentifier serviceMetadataIdentifier, URL url) {
-        this.storeMetadata(serviceMetadataIdentifier, URL.encode(url.toFullString()));
-    }
-
-    @Override
-    protected void doRemoveMetadata(ServiceMetadataIdentifier serviceMetadataIdentifier) {
-        this.deleteMetadata(serviceMetadataIdentifier);
-    }
-
-    @Override
-    protected List<String> doGetExportedURLs(ServiceMetadataIdentifier metadataIdentifier) {
-        String content = getMetadata(metadataIdentifier);
-        if (StringUtils.isEmpty(content)) {
-            return Collections.emptyList();
-        }
-        return new ArrayList<String>(Arrays.asList(URL.decode(content)));
-    }
-
-    @Override
-    protected void doSaveSubscriberData(SubscriberMetadataIdentifier subscriberMetadataIdentifier, String urlListStr) {
-        this.storeMetadata(subscriberMetadataIdentifier, urlListStr);
-    }
-
-    @Override
-    protected String doGetSubscribedURLs(SubscriberMetadataIdentifier subscriberMetadataIdentifier) {
-        return this.getMetadata(subscriberMetadataIdentifier);
-    }
-
-    @Override
-    public String getServiceDefinition(MetadataIdentifier metadataIdentifier) {
-        return this.getMetadata(metadataIdentifier);
-    }
-
-    private void storeMetadata(BaseMetadataIdentifier metadataIdentifier, String v) {
-        if (pool != null) {
-            storeMetadataStandalone(metadataIdentifier, v);
-        } else {
-            storeMetadataInCluster(metadataIdentifier, v);
-        }
-    }
-
-    private void storeMetadataInCluster(BaseMetadataIdentifier metadataIdentifier, String v) {
-        try (JedisCluster jedisCluster = new JedisCluster(jedisClusterNodes, timeout, timeout, 2, password, new GenericObjectPoolConfig())) {
-            jedisCluster.set(metadataIdentifier.getIdentifierKey() + META_DATA_STORE_TAG, v);
-        } catch (Throwable e) {
-            logger.error("Failed to put " + metadataIdentifier + " to redis cluster " + v + ", cause: " + e.getMessage(), e);
-            throw new RpcException("Failed to put " + metadataIdentifier + " to redis cluster " + v + ", cause: " + e.getMessage(), e);
-        }
-    }
-
-    private void storeMetadataStandalone(BaseMetadataIdentifier metadataIdentifier, String v) {
-        try (Jedis jedis = pool.getResource()) {
-            jedis.set(metadataIdentifier.getUniqueKey(KeyTypeEnum.UNIQUE_KEY), v);
-        } catch (Throwable e) {
-            logger.error("Failed to put " + metadataIdentifier + " to redis " + v + ", cause: " + e.getMessage(), e);
-            throw new RpcException("Failed to put " + metadataIdentifier + " to redis " + v + ", cause: " + e.getMessage(), e);
-        }
-    }
-
-    private void deleteMetadata(BaseMetadataIdentifier metadataIdentifier) {
-        if (pool != null) {
-            deleteMetadataStandalone(metadataIdentifier);
-        } else {
-            deleteMetadataInCluster(metadataIdentifier);
-        }
-    }
-
-    private void deleteMetadataInCluster(BaseMetadataIdentifier metadataIdentifier) {
-        try (JedisCluster jedisCluster = new JedisCluster(jedisClusterNodes, timeout, timeout, 2, password, new GenericObjectPoolConfig())) {
-            jedisCluster.del(metadataIdentifier.getIdentifierKey() + META_DATA_STORE_TAG);
-        } catch (Throwable e) {
-            logger.error("Failed to delete " + metadataIdentifier + " from redis cluster , cause: " + e.getMessage(), e);
-            throw new RpcException("Failed to delete " + metadataIdentifier + " from redis cluster , cause: " + e.getMessage(), e);
-        }
-    }
-
-    private void deleteMetadataStandalone(BaseMetadataIdentifier metadataIdentifier) {
-        try (Jedis jedis = pool.getResource()) {
-            jedis.del(metadataIdentifier.getUniqueKey(KeyTypeEnum.UNIQUE_KEY));
-        } catch (Throwable e) {
-            logger.error("Failed to delete " + metadataIdentifier + " from redis , cause: " + e.getMessage(), e);
-            throw new RpcException("Failed to delete " + metadataIdentifier + " from redis , cause: " + e.getMessage(), e);
-        }
-    }
-
-    private String getMetadata(BaseMetadataIdentifier metadataIdentifier) {
-        if (pool != null) {
-            return getMetadataStandalone(metadataIdentifier);
-        } else {
-            return getMetadataInCluster(metadataIdentifier);
-        }
-    }
-
-    private String getMetadataInCluster(BaseMetadataIdentifier metadataIdentifier) {
-        try (JedisCluster jedisCluster = new JedisCluster(jedisClusterNodes, timeout, timeout, 2, password, new GenericObjectPoolConfig())) {
-            return jedisCluster.get(metadataIdentifier.getIdentifierKey() + META_DATA_STORE_TAG);
-        } catch (Throwable e) {
-            logger.error("Failed to get " + metadataIdentifier + " from redis cluster , cause: " + e.getMessage(), e);
-            throw new RpcException("Failed to get " + metadataIdentifier + " from redis cluster , cause: " + e.getMessage(), e);
-        }
-    }
-
-    private String getMetadataStandalone(BaseMetadataIdentifier metadataIdentifier) {
-        try (Jedis jedis = pool.getResource()) {
-            return jedis.get(metadataIdentifier.getUniqueKey(KeyTypeEnum.UNIQUE_KEY));
-        } catch (Throwable e) {
-            logger.error("Failed to get " + metadataIdentifier + " from redis , cause: " + e.getMessage(), e);
-            throw new RpcException("Failed to get " + metadataIdentifier + " from redis , cause: " + e.getMessage(), e);
-        }
-    }
-
-}
diff --git a/dubbo-spi-metadata/dubbo-metadata-report-redis/src/main/java/org/apache/dubbo/metadata/store/redis/RedisMetadataReportFactory.java b/dubbo-spi-metadata/dubbo-metadata-report-redis/src/main/java/org/apache/dubbo/metadata/store/redis/RedisMetadataReportFactory.java
deleted file mode 100644
index bd08877..0000000
--- a/dubbo-spi-metadata/dubbo-metadata-report-redis/src/main/java/org/apache/dubbo/metadata/store/redis/RedisMetadataReportFactory.java
+++ /dev/null
@@ -1,34 +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.metadata.store.redis;
-
-import org.apache.dubbo.common.URL;
-import org.apache.dubbo.metadata.report.MetadataReport;
-import org.apache.dubbo.metadata.report.support.AbstractMetadataReportFactory;
-
-/**
- * RedisMetadataReportFactory.
- */
-public class RedisMetadataReportFactory extends AbstractMetadataReportFactory {
-
-
-    @Override
-    public MetadataReport createMetadataReport(URL url) {
-        return new RedisMetadataReport(url);
-    }
-
-}
diff --git a/dubbo-spi-metadata/dubbo-metadata-report-redis/src/main/resources/META-INF/dubbo/internal/org.apache.dubbo.metadata.report.MetadataReportFactory b/dubbo-spi-metadata/dubbo-metadata-report-redis/src/main/resources/META-INF/dubbo/internal/org.apache.dubbo.metadata.report.MetadataReportFactory
deleted file mode 100644
index 2e6effa..0000000
--- a/dubbo-spi-metadata/dubbo-metadata-report-redis/src/main/resources/META-INF/dubbo/internal/org.apache.dubbo.metadata.report.MetadataReportFactory
+++ /dev/null
@@ -1 +0,0 @@
-redis=org.apache.dubbo.metadata.store.redis.RedisMetadataReportFactory
diff --git a/dubbo-spi-metadata/dubbo-metadata-report-redis/src/test/java/org/apache/dubbo/metadata/store/redis/RedisMetadata4TstService.java b/dubbo-spi-metadata/dubbo-metadata-report-redis/src/test/java/org/apache/dubbo/metadata/store/redis/RedisMetadata4TstService.java
deleted file mode 100644
index 0a8d51b..0000000
--- a/dubbo-spi-metadata/dubbo-metadata-report-redis/src/test/java/org/apache/dubbo/metadata/store/redis/RedisMetadata4TstService.java
+++ /dev/null
@@ -1,28 +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.metadata.store.redis;
-
-/**
- * 2018/10/26
- */
-public interface RedisMetadata4TstService {
-
-
-    int getCounter();
-
-    void printResult(String var);
-}
diff --git a/dubbo-spi-metadata/dubbo-metadata-report-redis/src/test/java/org/apache/dubbo/metadata/store/redis/RedisMetadataReportTest.java b/dubbo-spi-metadata/dubbo-metadata-report-redis/src/test/java/org/apache/dubbo/metadata/store/redis/RedisMetadataReportTest.java
deleted file mode 100644
index 900bf37..0000000
--- a/dubbo-spi-metadata/dubbo-metadata-report-redis/src/test/java/org/apache/dubbo/metadata/store/redis/RedisMetadataReportTest.java
+++ /dev/null
@@ -1,220 +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.metadata.store.redis;
-
-import org.apache.commons.lang3.SystemUtils;
-import org.apache.dubbo.common.URL;
-import org.apache.dubbo.common.utils.NetUtils;
-import org.apache.dubbo.metadata.definition.ServiceDefinitionBuilder;
-import org.apache.dubbo.metadata.definition.model.FullServiceDefinition;
-import org.apache.dubbo.metadata.report.identifier.KeyTypeEnum;
-import org.apache.dubbo.metadata.report.identifier.MetadataIdentifier;
-import org.apache.dubbo.rpc.RpcException;
-
-import com.google.gson.Gson;
-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.junit.jupiter.api.TestInfo;
-import redis.clients.jedis.Jedis;
-import redis.clients.jedis.exceptions.JedisConnectionException;
-import redis.clients.jedis.exceptions.JedisDataException;
-import redis.embedded.RedisServer;
-import redis.embedded.RedisServerBuilder;
-
-import java.io.IOException;
-import java.util.HashMap;
-import java.util.Map;
-
-import static org.apache.dubbo.common.constants.CommonConstants.CONSUMER_SIDE;
-import static org.apache.dubbo.common.constants.CommonConstants.PROVIDER_SIDE;
-import static org.apache.dubbo.metadata.report.support.Constants.SYNC_REPORT_KEY;
-
-/**
- * 2018/10/9
- */
-public class RedisMetadataReportTest {
-    RedisMetadataReport redisMetadataReport;
-    RedisMetadataReport syncRedisMetadataReport;
-    RedisServer redisServer;
-    URL registryUrl;
-
-    @BeforeEach
-    public void constructor(TestInfo testInfo) throws IOException {
-        int redisPort = NetUtils.getAvailablePort();
-        String methodName = testInfo.getTestMethod().get().getName();
-        if ("testAuthRedisMetadata".equals(methodName) || ("testWrongAuthRedisMetadata".equals(methodName))) {
-            String password = "チェリー";
-            RedisServerBuilder builder = RedisServer.builder().port(redisPort).setting("requirepass " + password);
-            if (SystemUtils.IS_OS_WINDOWS) {
-                // set maxheap to fix Windows error 0x70 while starting redis
-                builder.setting("maxheap 128mb");
-            }
-            redisServer = builder.build();
-            registryUrl = URL.valueOf("redis://username:" + password + "@localhost:" + redisPort);
-        } else {
-            RedisServerBuilder builder = RedisServer.builder().port(redisPort);
-            if (SystemUtils.IS_OS_WINDOWS) {
-                // set maxheap to fix Windows error 0x70 while starting redis
-                builder.setting("maxheap 128mb");
-            }
-            redisServer = builder.build();
-            registryUrl = URL.valueOf("redis://localhost:" + redisPort);
-        }
-
-        this.redisServer.start();
-        redisMetadataReport = (RedisMetadataReport) new RedisMetadataReportFactory().createMetadataReport(registryUrl);
-        URL asyncRegistryUrl = URL.valueOf("redis://localhost:" + redisPort + "?" + SYNC_REPORT_KEY + "=true");
-        syncRedisMetadataReport = (RedisMetadataReport) new RedisMetadataReportFactory().createMetadataReport(registryUrl);
-    }
-
-    @AfterEach
-    public void tearDown() throws Exception {
-        this.redisServer.stop();
-    }
-
-    @Test
-    public void testAsyncStoreProvider() throws ClassNotFoundException {
-        testStoreProvider(redisMetadataReport, "1.0.0.redis.md.p1", 3000);
-    }
-
-    @Test
-    public void testSyncStoreProvider() throws ClassNotFoundException {
-        testStoreProvider(syncRedisMetadataReport, "1.0.0.redis.md.p2", 3);
-    }
-
-    private void testStoreProvider(RedisMetadataReport redisMetadataReport, String version, long moreTime) throws ClassNotFoundException {
-        String interfaceName = "org.apache.dubbo.metadata.store.redis.RedisMetadata4TstService";
-        String group = null;
-        String application = "vic.redis.md";
-        MetadataIdentifier providerMetadataIdentifier = storePrivider(redisMetadataReport, interfaceName, version, group, application);
-        Jedis jedis = null;
-        try {
-            jedis = redisMetadataReport.pool.getResource();
-            String keyTmp = providerMetadataIdentifier.getUniqueKey(KeyTypeEnum.UNIQUE_KEY);
-            String value = jedis.get(keyTmp);
-            if (value == null) {
-                Thread.sleep(moreTime);
-                value = jedis.get(keyTmp);
-            }
-
-            Assertions.assertNotNull(value);
-
-            Gson gson = new Gson();
-            FullServiceDefinition fullServiceDefinition = gson.fromJson(value, FullServiceDefinition.class);
-            Assertions.assertEquals(fullServiceDefinition.getParameters().get("paramTest"), "redisTest");
-        } catch (Throwable e) {
-            throw new RpcException("Failed to put to redis . cause: " + e.getMessage(), e);
-        } finally {
-            if (jedis != null) {
-                jedis.del(providerMetadataIdentifier.getUniqueKey(KeyTypeEnum.UNIQUE_KEY));
-            }
-            redisMetadataReport.pool.close();
-        }
-    }
-
-    @Test
-    public void testAsyncStoreConsumer() throws ClassNotFoundException {
-        testStoreConsumer(redisMetadataReport, "1.0.0.redis.md.c1", 3000);
-    }
-
-    @Test
-    public void testSyncStoreConsumer() throws ClassNotFoundException {
-        testStoreConsumer(syncRedisMetadataReport, "1.0.0.redis.md.c2", 3);
-    }
-
-    private void testStoreConsumer(RedisMetadataReport redisMetadataReport, String version, long moreTime) throws ClassNotFoundException {
-        String interfaceName = "org.apache.dubbo.metadata.store.redis.RedisMetadata4TstService";
-        String group = null;
-        String application = "vic.redis.md";
-        MetadataIdentifier consumerMetadataIdentifier = storeConsumer(redisMetadataReport, interfaceName, version, group, application);
-        Jedis jedis = null;
-        try {
-            jedis = redisMetadataReport.pool.getResource();
-            String keyTmp = consumerMetadataIdentifier.getUniqueKey(KeyTypeEnum.UNIQUE_KEY);
-            String value = jedis.get(keyTmp);
-            if (value == null) {
-                Thread.sleep(moreTime);
-                value = jedis.get(keyTmp);
-            }
-            Assertions.assertEquals(value, "{\"paramConsumerTest\":\"redisCm\"}");
-        } catch (Throwable e) {
-            throw new RpcException("Failed to put to redis . cause: " + e.getMessage(), e);
-        } finally {
-            if (jedis != null) {
-                jedis.del(consumerMetadataIdentifier.getUniqueKey(KeyTypeEnum.UNIQUE_KEY));
-            }
-            redisMetadataReport.pool.close();
-        }
-    }
-
-    private MetadataIdentifier storePrivider(RedisMetadataReport redisMetadataReport, String interfaceName, String version, String group, String application) throws ClassNotFoundException {
-        URL url = URL.valueOf("xxx://" + NetUtils.getLocalAddress().getHostName() + ":4444/" + interfaceName + "?paramTest=redisTest&version=" + version + "&application="
-                + application + (group == null ? "" : "&group=" + group));
-
-        MetadataIdentifier providerMetadataIdentifier = new MetadataIdentifier(interfaceName, version, group, PROVIDER_SIDE, application);
-        Class interfaceClass = Class.forName(interfaceName);
-        FullServiceDefinition fullServiceDefinition = ServiceDefinitionBuilder.buildFullDefinition(interfaceClass, url.getParameters());
-
-        redisMetadataReport.storeProviderMetadata(providerMetadataIdentifier, fullServiceDefinition);
-        try {
-            Thread.sleep(300);
-        } catch (InterruptedException e) {
-            e.printStackTrace();
-        }
-        return providerMetadataIdentifier;
-    }
-
-    private MetadataIdentifier storeConsumer(RedisMetadataReport redisMetadataReport, String interfaceName, String version, String group, String application) throws ClassNotFoundException {
-        URL url = URL.valueOf("xxx://" + NetUtils.getLocalAddress().getHostName() + ":4444/" + interfaceName + "?version=" + version + "&application="
-                + application + (group == null ? "" : "&group=" + group));
-
-        MetadataIdentifier consumerMetadataIdentifier = new MetadataIdentifier(interfaceName, version, group, CONSUMER_SIDE, application);
-        Class interfaceClass = Class.forName(interfaceName);
-
-        Map<String, String> tmp = new HashMap<>();
-        tmp.put("paramConsumerTest", "redisCm");
-        redisMetadataReport.storeConsumerMetadata(consumerMetadataIdentifier, tmp);
-        try {
-            Thread.sleep(300);
-        } catch (InterruptedException e) {
-            e.printStackTrace();
-        }
-        return consumerMetadataIdentifier;
-    }
-
-    @Test
-    public void testAuthRedisMetadata() throws ClassNotFoundException {
-        testStoreProvider(redisMetadataReport, "1.0.0.redis.md.p1", 3000);
-    }
-
-    @Test
-    public void testWrongAuthRedisMetadata() throws ClassNotFoundException {
-        registryUrl = registryUrl.setPassword("123456");
-        redisMetadataReport = (RedisMetadataReport) new RedisMetadataReportFactory().createMetadataReport(registryUrl);
-        try {
-            testStoreProvider(redisMetadataReport, "1.0.0.redis.md.p1", 3000);
-        } catch (RpcException e) {
-            if (e.getCause() instanceof JedisConnectionException && e.getCause().getCause() instanceof JedisDataException) {
-                Assertions.assertEquals("ERR invalid password", e.getCause().getCause().getMessage());
-            } else {
-                Assertions.fail("no invalid password exception!");
-            }
-        }
-    }
-}
diff --git a/dubbo-spi-metadata/pom.xml b/dubbo-spi-metadata/pom.xml
index ffd446a..72fef74 100644
--- a/dubbo-spi-metadata/pom.xml
+++ b/dubbo-spi-metadata/pom.xml
@@ -32,7 +32,6 @@
     </properties>
 
     <modules>
-        <module>dubbo-metadata-report-redis</module>
         <module>dubbo-metadata-report-consul</module>
         <module>dubbo-metadata-report-etcd</module>
         <module>dubbo-metadata-report-nacos</module>
diff --git a/dubbo-spi-registry/dubbo-registry-multiple/pom.xml b/dubbo-spi-registry/dubbo-registry-multiple/pom.xml
deleted file mode 100644
index 375ed2e..0000000
--- a/dubbo-spi-registry/dubbo-registry-multiple/pom.xml
+++ /dev/null
@@ -1,65 +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.
-  -->
-<project xmlns="http://maven.apache.org/POM/4.0.0" xmlns:xsi="http://www.w3.org/2001/XMLSchema-instance" xsi:schemaLocation="http://maven.apache.org/POM/4.0.0 http://maven.apache.org/maven-v4_0_0.xsd">
-    <modelVersion>4.0.0</modelVersion>
-    <parent>
-        <groupId>org.apache.dubbo</groupId>
-        <artifactId>dubbo-registry</artifactId>
-        <version>2.7.7-SNAPSHOT</version>
-    </parent>
-    <artifactId>dubbo-registry-multiple</artifactId>
-    <packaging>jar</packaging>
-    <name>${project.artifactId}</name>
-    <description>The multiple registry module of dubbo project</description>
-    <properties>
-        <skip_maven_deploy>false</skip_maven_deploy>
-    </properties>
-    <dependencies>
-        <dependency>
-            <groupId>org.apache.dubbo</groupId>
-            <artifactId>dubbo-registry-api</artifactId>
-            <version>${project.parent.version}</version>
-        </dependency>
-        <dependency>
-            <groupId>org.apache.dubbo</groupId>
-            <artifactId>dubbo-registry-zookeeper</artifactId>
-            <version>${project.parent.version}</version>
-            <scope>test</scope>
-        </dependency>
-        <dependency>
-            <groupId>org.apache.dubbo</groupId>
-            <artifactId>dubbo-registry-redis</artifactId>
-            <version>${project.parent.version}</version>
-            <scope>test</scope>
-        </dependency>
-        <dependency>
-            <groupId>org.apache.curator</groupId>
-            <artifactId>curator-test</artifactId>
-            <scope>test</scope>
-        </dependency>
-        <dependency>
-            <groupId>com.github.kstyrc</groupId>
-            <artifactId>embedded-redis</artifactId>
-            <scope>test</scope>
-        </dependency>
-        <dependency>
-            <groupId>org.apache.commons</groupId>
-            <artifactId>commons-lang3</artifactId>
-            <scope>test</scope>
-        </dependency>
-    </dependencies>
-</project>
diff --git a/dubbo-spi-registry/dubbo-registry-multiple/src/main/java/org/apache/dubbo/registry/multiple/MultipleRegistry.java b/dubbo-spi-registry/dubbo-registry-multiple/src/main/java/org/apache/dubbo/registry/multiple/MultipleRegistry.java
deleted file mode 100644
index 8ad2c10..0000000
--- a/dubbo-spi-registry/dubbo-registry-multiple/src/main/java/org/apache/dubbo/registry/multiple/MultipleRegistry.java
+++ /dev/null
@@ -1,337 +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.registry.multiple;
-
-
-import org.apache.dubbo.common.URL;
-import org.apache.dubbo.common.constants.CommonConstants;
-import org.apache.dubbo.common.extension.ExtensionLoader;
-import org.apache.dubbo.common.utils.CollectionUtils;
-import org.apache.dubbo.registry.NotifyListener;
-import org.apache.dubbo.registry.Registry;
-import org.apache.dubbo.registry.RegistryFactory;
-import org.apache.dubbo.registry.support.AbstractRegistry;
-
-import java.util.ArrayList;
-import java.util.HashMap;
-import java.util.HashSet;
-import java.util.List;
-import java.util.Map;
-import java.util.Set;
-import java.util.concurrent.ConcurrentHashMap;
-
-import static org.apache.dubbo.common.constants.RegistryConstants.EMPTY_PROTOCOL;
-
-/**
- * MultipleRegistry
- */
-public class MultipleRegistry extends AbstractRegistry {
-
-    public static final String REGISTRY_FOR_SERVICE = "service-registry";
-    public static final String REGISTRY_FOR_REFERENCE = "reference-registry";
-
-    protected RegistryFactory registryFactory = ExtensionLoader.getExtensionLoader(RegistryFactory.class).getAdaptiveExtension();
-    private final Map<String, Registry> serviceRegistries = new ConcurrentHashMap<>(4);
-    private final Map<String, Registry> referenceRegistries = new ConcurrentHashMap<String, Registry>(4);
-    private final Map<NotifyListener, MultipleNotifyListenerWrapper> multipleNotifyListenerMap = new ConcurrentHashMap<NotifyListener, MultipleNotifyListenerWrapper>(32);
-    protected List<String> origServiceRegistryURLs;
-    protected List<String> origReferenceRegistryURLs;
-    protected List<String> effectServiceRegistryURLs;
-    protected List<String> effectReferenceRegistryURLs;
-    private URL registryUrl;
-    private String applicationName;
-
-    public MultipleRegistry(URL url) {
-        this(url, true, true);
-
-        boolean defaultRegistry = url.getParameter(CommonConstants.DEFAULT_KEY, true);
-        if (defaultRegistry && effectServiceRegistryURLs.isEmpty() && effectReferenceRegistryURLs.isEmpty()) {
-            throw new IllegalArgumentException("Illegal registry url. You need to configure parameter " +
-                    REGISTRY_FOR_SERVICE + " or " + REGISTRY_FOR_REFERENCE);
-        }
-    }
-
-    public MultipleRegistry(URL url, boolean initServiceRegistry, boolean initReferenceRegistry) {
-        super(url);
-        this.registryUrl = url;
-        this.applicationName = url.getParameter(CommonConstants.APPLICATION_KEY);
-        init();
-        checkApplicationName(this.applicationName);
-        // This urls contain parameter and it donot inherit from the parameter of url in MultipleRegistry
-
-        Map<String, Registry> registryMap = new HashMap<>();
-        if (initServiceRegistry) {
-            initServiceRegistry(url, registryMap);
-        }
-        if (initReferenceRegistry) {
-            initReferenceRegistry(url, registryMap);
-        }
-    }
-
-    protected void initServiceRegistry(URL url, Map<String, Registry> registryMap) {
-        origServiceRegistryURLs = url.getParameter(REGISTRY_FOR_SERVICE, new ArrayList<String>());
-        effectServiceRegistryURLs = this.filterServiceRegistry(origServiceRegistryURLs);
-        for (String tmpUrl : effectServiceRegistryURLs) {
-            if (registryMap.get(tmpUrl) != null) {
-                serviceRegistries.put(tmpUrl, registryMap.get(tmpUrl));
-                continue;
-            }
-            Registry registry = registryFactory.getRegistry(URL.valueOf(tmpUrl));
-            registryMap.put(tmpUrl, registry);
-            serviceRegistries.put(tmpUrl, registry);
-        }
-    }
-
-    protected void initReferenceRegistry(URL url, Map<String, Registry> registryMap) {
-        origReferenceRegistryURLs = url.getParameter(REGISTRY_FOR_REFERENCE, new ArrayList<String>());
-        effectReferenceRegistryURLs = this.filterReferenceRegistry(origReferenceRegistryURLs);
-        for (String tmpUrl : effectReferenceRegistryURLs) {
-            if (registryMap.get(tmpUrl) != null) {
-                referenceRegistries.put(tmpUrl, registryMap.get(tmpUrl));
-                continue;
-            }
-            Registry registry = registryFactory.getRegistry(URL.valueOf(tmpUrl));
-            registryMap.put(tmpUrl, registry);
-            referenceRegistries.put(tmpUrl, registry);
-        }
-    }
-
-
-    @Override
-    public URL getUrl() {
-        return registryUrl;
-    }
-
-    @Override
-    public boolean isAvailable() {
-        boolean available = serviceRegistries.isEmpty() ? true : false;
-        for (Registry serviceRegistry : serviceRegistries.values()) {
-            if (serviceRegistry.isAvailable()) {
-                available = true;
-            }
-        }
-        if (!available) {
-            return false;
-        }
-
-        available = referenceRegistries.isEmpty() ? true : false;
-        for (Registry referenceRegistry : referenceRegistries.values()) {
-            if (referenceRegistry.isAvailable()) {
-                available = true;
-            }
-        }
-        if (!available) {
-            return false;
-        }
-        return true;
-    }
-
-    @Override
-    public void destroy() {
-        Set<Registry> registries = new HashSet<Registry>(serviceRegistries.values());
-        registries.addAll(referenceRegistries.values());
-        for (Registry registry : registries) {
-            registry.destroy();
-        }
-    }
-
-    @Override
-    public void register(URL url) {
-        super.register(url);
-        for (Registry registry : serviceRegistries.values()) {
-            registry.register(url);
-        }
-    }
-
-    @Override
-    public void unregister(URL url) {
-        super.unregister(url);
-        for (Registry registry : serviceRegistries.values()) {
-            registry.unregister(url);
-        }
-    }
-
-    @Override
-    public void subscribe(URL url, NotifyListener listener) {
-        MultipleNotifyListenerWrapper multipleNotifyListenerWrapper = new MultipleNotifyListenerWrapper(listener);
-        multipleNotifyListenerMap.put(listener, multipleNotifyListenerWrapper);
-        for (Registry registry : referenceRegistries.values()) {
-            SingleNotifyListener singleNotifyListener = new SingleNotifyListener(multipleNotifyListenerWrapper, registry);
-            multipleNotifyListenerWrapper.putRegistryMap(registry.getUrl(), singleNotifyListener);
-            registry.subscribe(url, singleNotifyListener);
-        }
-        super.subscribe(url, multipleNotifyListenerWrapper);
-    }
-
-    @Override
-    public void unsubscribe(URL url, NotifyListener listener) {
-        MultipleNotifyListenerWrapper notifyListener = multipleNotifyListenerMap.remove(listener);
-        for (Registry registry : referenceRegistries.values()) {
-            SingleNotifyListener singleNotifyListener = notifyListener.registryMap.get(registry.getUrl());
-            registry.unsubscribe(url, singleNotifyListener);
-        }
-
-        if (notifyListener != null) {
-            super.unsubscribe(url, notifyListener);
-            notifyListener.destroy();
-        }
-    }
-
-    @Override
-    public List<URL> lookup(URL url) {
-        List<URL> urls = new ArrayList<URL>();
-        for (Registry registry : referenceRegistries.values()) {
-            List<URL> tmpUrls = registry.lookup(url);
-            if (!CollectionUtils.isEmpty(tmpUrls)) {
-                urls.addAll(tmpUrls);
-            }
-        }
-        return urls;
-    }
-
-    protected void init() {
-    }
-
-    protected List<String> filterServiceRegistry(List<String> serviceRegistryURLs) {
-        return serviceRegistryURLs;
-    }
-
-    protected List<String> filterReferenceRegistry(List<String> referenceRegistryURLs) {
-        return referenceRegistryURLs;
-    }
-
-
-    protected void checkApplicationName(String applicationName) {
-    }
-
-    protected String getApplicationName() {
-        return applicationName;
-    }
-
-    public Map<String, Registry> getServiceRegistries() {
-        return serviceRegistries;
-    }
-
-    public Map<String, Registry> getReferenceRegistries() {
-        return referenceRegistries;
-    }
-
-    public List<String> getOrigServiceRegistryURLs() {
-        return origServiceRegistryURLs;
-    }
-
-    public List<String> getOrigReferenceRegistryURLs() {
-        return origReferenceRegistryURLs;
-    }
-
-    public List<String> getEffectServiceRegistryURLs() {
-        return effectServiceRegistryURLs;
-    }
-
-    public List<String> getEffectReferenceRegistryURLs() {
-        return effectReferenceRegistryURLs;
-    }
-
-    static protected class MultipleNotifyListenerWrapper implements NotifyListener {
-
-        Map<URL, SingleNotifyListener> registryMap = new ConcurrentHashMap<URL, SingleNotifyListener>(4);
-        NotifyListener sourceNotifyListener;
-
-        public MultipleNotifyListenerWrapper(NotifyListener sourceNotifyListener) {
-            this.sourceNotifyListener = sourceNotifyListener;
-        }
-
-        public void putRegistryMap(URL registryURL, SingleNotifyListener singleNotifyListener) {
-            this.registryMap.put(registryURL, singleNotifyListener);
-        }
-
-        public void destroy() {
-            for (SingleNotifyListener singleNotifyListener : registryMap.values()) {
-                if (singleNotifyListener != null) {
-                    singleNotifyListener.destroy();
-                }
-            }
-            registryMap.clear();
-            sourceNotifyListener = null;
-        }
-
-        public synchronized void notifySourceListener() {
-            List<URL> notifyURLs = new ArrayList<URL>();
-            URL emptyURL = null;
-            for (SingleNotifyListener singleNotifyListener : registryMap.values()) {
-                List<URL> tmpUrls = singleNotifyListener.getUrlList();
-                if (CollectionUtils.isEmpty(tmpUrls)) {
-                    continue;
-                }
-                // empty protocol
-                if (tmpUrls.size() == 1
-                        && tmpUrls.get(0) != null
-                        && EMPTY_PROTOCOL.equals(tmpUrls.get(0).getProtocol())) {
-                    // if only one empty
-                    if (emptyURL == null) {
-                        emptyURL = tmpUrls.get(0);
-                    }
-                    continue;
-                }
-                notifyURLs.addAll(tmpUrls);
-            }
-            // if no notify URL, add empty protocol URL
-            if (emptyURL != null && notifyURLs.isEmpty()) {
-                notifyURLs.add(emptyURL);
-            }
-            this.notify(notifyURLs);
-        }
-
-        @Override
-        public void notify(List<URL> urls) {
-            sourceNotifyListener.notify(urls);
-        }
-
-        public Map<URL, SingleNotifyListener> getRegistryMap() {
-            return registryMap;
-        }
-    }
-
-    static protected class SingleNotifyListener implements NotifyListener {
-
-        MultipleNotifyListenerWrapper multipleNotifyListenerWrapper;
-        Registry registry;
-        volatile List<URL> urlList;
-
-        public SingleNotifyListener(MultipleNotifyListenerWrapper multipleNotifyListenerWrapper, Registry registry) {
-            this.registry = registry;
-            this.multipleNotifyListenerWrapper = multipleNotifyListenerWrapper;
-        }
-
-        @Override
-        public synchronized void notify(List<URL> urls) {
-            this.urlList = urls;
-            if (multipleNotifyListenerWrapper != null) {
-                this.multipleNotifyListenerWrapper.notifySourceListener();
-            }
-        }
-
-        public void destroy() {
-            this.multipleNotifyListenerWrapper = null;
-            this.registry = null;
-        }
-
-        public List<URL> getUrlList() {
-            return urlList;
-        }
-    }
-}
diff --git a/dubbo-spi-registry/dubbo-registry-multiple/src/main/java/org/apache/dubbo/registry/multiple/MultipleRegistryFactory.java b/dubbo-spi-registry/dubbo-registry-multiple/src/main/java/org/apache/dubbo/registry/multiple/MultipleRegistryFactory.java
deleted file mode 100644
index 69d695b..0000000
--- a/dubbo-spi-registry/dubbo-registry-multiple/src/main/java/org/apache/dubbo/registry/multiple/MultipleRegistryFactory.java
+++ /dev/null
@@ -1,33 +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.registry.multiple;
-
-import org.apache.dubbo.common.URL;
-import org.apache.dubbo.registry.Registry;
-import org.apache.dubbo.registry.support.AbstractRegistryFactory;
-
-/**
- * MultipleRegistryFactory
- */
-public class MultipleRegistryFactory extends AbstractRegistryFactory {
-
-    @Override
-    protected Registry createRegistry(URL url) {
-        return new MultipleRegistry(url);
-    }
-
-}
diff --git a/dubbo-spi-registry/dubbo-registry-multiple/src/main/resources/META-INF/dubbo/internal/org.apache.dubbo.registry.RegistryFactory b/dubbo-spi-registry/dubbo-registry-multiple/src/main/resources/META-INF/dubbo/internal/org.apache.dubbo.registry.RegistryFactory
deleted file mode 100644
index defb7a2..0000000
--- a/dubbo-spi-registry/dubbo-registry-multiple/src/main/resources/META-INF/dubbo/internal/org.apache.dubbo.registry.RegistryFactory
+++ /dev/null
@@ -1 +0,0 @@
-multiple=org.apache.dubbo.registry.multiple.MultipleRegistryFactory
diff --git a/dubbo-spi-registry/dubbo-registry-multiple/src/test/java/org/apache/dubbo/registry/multiple/MultipleRegistry2S2RTest.java b/dubbo-spi-registry/dubbo-registry-multiple/src/test/java/org/apache/dubbo/registry/multiple/MultipleRegistry2S2RTest.java
deleted file mode 100644
index 9243730..0000000
--- a/dubbo-spi-registry/dubbo-registry-multiple/src/test/java/org/apache/dubbo/registry/multiple/MultipleRegistry2S2RTest.java
+++ /dev/null
@@ -1,213 +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.registry.multiple;
-
-import org.apache.commons.lang3.SystemUtils;
-import org.apache.dubbo.common.URL;
-import org.apache.dubbo.common.utils.NetUtils;
-import org.apache.dubbo.registry.NotifyListener;
-import org.apache.dubbo.registry.Registry;
-import org.apache.dubbo.registry.redis.RedisRegistry;
-import org.apache.dubbo.registry.zookeeper.ZookeeperRegistry;
-import org.apache.dubbo.remoting.zookeeper.ZookeeperClient;
-import org.apache.dubbo.remoting.zookeeper.curator.CuratorZookeeperClient;
-
-import org.apache.curator.test.TestingServer;
-import org.junit.jupiter.api.AfterAll;
-import org.junit.jupiter.api.Assertions;
-import org.junit.jupiter.api.BeforeAll;
-import org.junit.jupiter.api.Test;
-import redis.embedded.RedisServer;
-import redis.embedded.RedisServerBuilder;
-
-import java.util.ArrayList;
-import java.util.List;
-
-/**
- * 2019-04-30
- */
-public class MultipleRegistry2S2RTest {
-
-    private static final String SERVICE_NAME = "org.apache.dubbo.registry.MultipleService2S2R";
-    private static final String SERVICE2_NAME = "org.apache.dubbo.registry.MultipleService2S2R2";
-
-    private static TestingServer zkServer;
-    private static RedisServer redisServer;
-    static int zkServerPort;
-    static int redisServerPort;
-
-    private static String zookeeperRegistryURLStr;
-    private static String redisRegistryURLStr;
-
-    private static MultipleRegistry multipleRegistry;
-    // for test content
-    private static ZookeeperClient zookeeperClient;
-
-    private static ZookeeperRegistry zookeeperRegistry;
-    private static RedisRegistry redisRegistry;
-
-
-    @BeforeAll
-    public static void setUp() throws Exception {
-        zkServerPort = NetUtils.getAvailablePort();
-        zkServer = new TestingServer(zkServerPort, true);
-        zookeeperRegistryURLStr = "zookeeper://127.0.0.1:" + zkServerPort;
-
-        redisServerPort = NetUtils.getAvailablePort();
-        RedisServerBuilder builder = RedisServer.builder().port(redisServerPort);
-        if (SystemUtils.IS_OS_WINDOWS) {
-            // set maxheap to fix Windows error 0x70 while starting redis
-            builder.setting("maxheap 128mb");
-        }
-        redisServer = builder.build();
-        redisServer.start();
-        redisRegistryURLStr = "redis://127.0.0.1:" + redisServerPort;
-
-
-        URL url = URL.valueOf("multiple://127.0.0.1?application=vic&" +
-                MultipleRegistry.REGISTRY_FOR_SERVICE + "=" + zookeeperRegistryURLStr + "," + redisRegistryURLStr + "&"
-                + MultipleRegistry.REGISTRY_FOR_REFERENCE + "=" + zookeeperRegistryURLStr + "," + redisRegistryURLStr);
-        multipleRegistry = (MultipleRegistry) new MultipleRegistryFactory().createRegistry(url);
-
-        // for test validation
-        zookeeperClient = new CuratorZookeeperClient(URL.valueOf(zookeeperRegistryURLStr));
-        zookeeperRegistry = MultipleRegistryTestUtil.getZookeeperRegistry(multipleRegistry.getServiceRegistries().values());
-        redisRegistry = MultipleRegistryTestUtil.getRedisRegistry(multipleRegistry.getServiceRegistries().values());
-    }
-
-    @AfterAll
-    public static void tearDown() throws Exception {
-        zkServer.stop();
-        redisServer.stop();
-    }
-
-    @Test
-    public void testParamConfig() {
-
-        Assertions.assertEquals(2, multipleRegistry.origReferenceRegistryURLs.size());
-        Assertions.assertTrue(multipleRegistry.origReferenceRegistryURLs.contains(zookeeperRegistryURLStr));
-        Assertions.assertTrue(multipleRegistry.origReferenceRegistryURLs.contains(redisRegistryURLStr));
-
-        Assertions.assertEquals(2, multipleRegistry.origServiceRegistryURLs.size());
-        Assertions.assertTrue(multipleRegistry.origServiceRegistryURLs.contains(zookeeperRegistryURLStr));
-        Assertions.assertTrue(multipleRegistry.origServiceRegistryURLs.contains(redisRegistryURLStr));
-
-        Assertions.assertEquals(2, multipleRegistry.effectReferenceRegistryURLs.size());
-        Assertions.assertTrue(multipleRegistry.effectReferenceRegistryURLs.contains(zookeeperRegistryURLStr));
-        Assertions.assertTrue(multipleRegistry.effectReferenceRegistryURLs.contains(redisRegistryURLStr));
-
-        Assertions.assertEquals(2, multipleRegistry.effectServiceRegistryURLs.size());
-        Assertions.assertTrue(multipleRegistry.effectServiceRegistryURLs.contains(zookeeperRegistryURLStr));
-        Assertions.assertTrue(multipleRegistry.effectServiceRegistryURLs.contains(redisRegistryURLStr));
-
-        Assertions.assertTrue(multipleRegistry.getServiceRegistries().containsKey(zookeeperRegistryURLStr));
-        Assertions.assertTrue(multipleRegistry.getServiceRegistries().containsKey(redisRegistryURLStr));
-        Assertions.assertEquals(2, multipleRegistry.getServiceRegistries().values().size());
-//        java.util.Iterator<Registry> registryIterable = multipleRegistry.getServiceRegistries().values().iterator();
-//        Registry firstRegistry = registryIterable.next();
-//        Registry secondRegistry = registryIterable.next();
-        Assertions.assertNotNull(MultipleRegistryTestUtil.getZookeeperRegistry(multipleRegistry.getServiceRegistries().values()));
-        Assertions.assertNotNull(MultipleRegistryTestUtil.getRedisRegistry(multipleRegistry.getServiceRegistries().values()));
-        Assertions.assertNotNull(MultipleRegistryTestUtil.getZookeeperRegistry(multipleRegistry.getReferenceRegistries().values()));
-        Assertions.assertNotNull(MultipleRegistryTestUtil.getRedisRegistry(multipleRegistry.getReferenceRegistries().values()));
-
-        Assertions.assertEquals(MultipleRegistryTestUtil.getZookeeperRegistry(multipleRegistry.getServiceRegistries().values()),
-                MultipleRegistryTestUtil.getZookeeperRegistry(multipleRegistry.getReferenceRegistries().values()));
-
-        Assertions.assertEquals(MultipleRegistryTestUtil.getRedisRegistry(multipleRegistry.getServiceRegistries().values()),
-                MultipleRegistryTestUtil.getRedisRegistry(multipleRegistry.getReferenceRegistries().values()));
-
-        Assertions.assertEquals(multipleRegistry.getApplicationName(), "vic");
-
-        Assertions.assertTrue(multipleRegistry.isAvailable());
-    }
-
-    @Test
-    public void testRegistryAndUnRegistry() throws InterruptedException {
-        URL serviceUrl = URL.valueOf("http2://multiple/" + SERVICE_NAME + "?notify=false&methods=test1,test2&category=providers");
-//        URL serviceUrl2 = URL.valueOf("http2://multiple2/" + SERVICE_NAME + "?notify=false&methods=test1,test2&category=providers");
-        multipleRegistry.register(serviceUrl);
-
-        String path = "/dubbo/" + SERVICE_NAME + "/providers";
-        List<String> providerList = zookeeperClient.getChildren(path);
-        Assertions.assertTrue(!providerList.isEmpty());
-        System.out.println(providerList.get(0));
-
-        Assertions.assertNotNull(MultipleRegistryTestUtil.getRedisHashContent(redisServerPort, path, serviceUrl.toFullString()));
-
-        final List<URL> list = new ArrayList<URL>();
-        multipleRegistry.subscribe(serviceUrl, new NotifyListener() {
-            @Override
-            public void notify(List<URL> urls) {
-                System.out.println("invoke notify: " + urls);
-                list.clear();
-                list.addAll(urls);
-            }
-        });
-        Thread.sleep(1500);
-        Assertions.assertEquals(2, list.size());
-
-        multipleRegistry.unregister(serviceUrl);
-        Thread.sleep(1500);
-        Assertions.assertEquals(1, list.size());
-        List<URL> urls = MultipleRegistryTestUtil.getProviderURLsFromNotifyURLS(list);
-        Assertions.assertEquals(1, list.size());
-        Assertions.assertEquals("empty", list.get(0).getProtocol());
-    }
-
-    @Test
-    public void testSubscription() throws InterruptedException {
-        URL serviceUrl = URL.valueOf("http2://multiple/" + SERVICE2_NAME + "?notify=false&methods=test1,test2&category=providers");
-//        URL serviceUrl2 = URL.valueOf("http2://multiple2/" + SERVICE_NAME + "?notify=false&methods=test1,test2&category=providers");
-        multipleRegistry.register(serviceUrl);
-
-        String path = "/dubbo/" + SERVICE2_NAME + "/providers";
-        List<String> providerList = zookeeperClient.getChildren(path);
-        Assertions.assertTrue(!providerList.isEmpty());
-        System.out.println(providerList.get(0));
-
-        Assertions.assertNotNull(MultipleRegistryTestUtil.getRedisHashContent(redisServerPort, path, serviceUrl.toFullString()));
-
-        final List<URL> list = new ArrayList<URL>();
-        multipleRegistry.subscribe(serviceUrl, new NotifyListener() {
-            @Override
-            public void notify(List<URL> urls) {
-                System.out.println("invoke notify: " + urls);
-                list.clear();
-                list.addAll(urls);
-            }
-        });
-        Thread.sleep(1500);
-        Assertions.assertEquals(2, list.size());
-
-        List<Registry> serviceRegistries = new ArrayList<Registry>(multipleRegistry.getServiceRegistries().values());
-        serviceRegistries.get(0).unregister(serviceUrl);
-        Thread.sleep(1500);
-        Assertions.assertEquals(1, list.size());
-        List<URL> urls = MultipleRegistryTestUtil.getProviderURLsFromNotifyURLS(list);
-        Assertions.assertEquals(1, list.size());
-        Assertions.assertTrue(!"empty".equals(list.get(0).getProtocol()));
-
-        serviceRegistries.get(1).unregister(serviceUrl);
-        Thread.sleep(1500);
-        Assertions.assertEquals(1, list.size());
-        urls = MultipleRegistryTestUtil.getProviderURLsFromNotifyURLS(list);
-        Assertions.assertEquals(1, list.size());
-        Assertions.assertEquals("empty", list.get(0).getProtocol());
-    }
-
-}
diff --git a/dubbo-spi-registry/dubbo-registry-multiple/src/test/java/org/apache/dubbo/registry/multiple/MultipleRegistryTestUtil.java b/dubbo-spi-registry/dubbo-registry-multiple/src/test/java/org/apache/dubbo/registry/multiple/MultipleRegistryTestUtil.java
deleted file mode 100644
index 9544ef8..0000000
--- a/dubbo-spi-registry/dubbo-registry-multiple/src/test/java/org/apache/dubbo/registry/multiple/MultipleRegistryTestUtil.java
+++ /dev/null
@@ -1,145 +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.registry.multiple;
-
-import org.apache.dubbo.common.URL;
-import org.apache.dubbo.common.utils.StringUtils;
-import org.apache.dubbo.common.utils.UrlUtils;
-import org.apache.dubbo.registry.ListenerRegistryWrapper;
-import org.apache.dubbo.registry.Registry;
-import org.apache.dubbo.registry.redis.RedisRegistry;
-import org.apache.dubbo.registry.zookeeper.ZookeeperRegistry;
-import org.apache.dubbo.rpc.RpcException;
-
-import redis.clients.jedis.Jedis;
-
-import java.util.Collection;
-import java.util.Collections;
-import java.util.List;
-import java.util.Map;
-import java.util.Objects;
-import java.util.stream.Collectors;
-
-import static org.apache.dubbo.common.constants.RegistryConstants.APP_DYNAMIC_CONFIGURATORS_CATEGORY;
-import static org.apache.dubbo.common.constants.RegistryConstants.CATEGORY_KEY;
-import static org.apache.dubbo.common.constants.RegistryConstants.COMPATIBLE_CONFIG_KEY;
-import static org.apache.dubbo.common.constants.RegistryConstants.CONFIGURATORS_CATEGORY;
-import static org.apache.dubbo.common.constants.RegistryConstants.DEFAULT_CATEGORY;
-import static org.apache.dubbo.common.constants.RegistryConstants.DYNAMIC_CONFIGURATORS_CATEGORY;
-import static org.apache.dubbo.common.constants.RegistryConstants.PROVIDERS_CATEGORY;
-import static org.apache.dubbo.common.constants.RegistryConstants.ROUTERS_CATEGORY;
-import static org.apache.dubbo.common.constants.RegistryConstants.ROUTE_PROTOCOL;
-
-/**
- * 2019-05-13
- */
-public class MultipleRegistryTestUtil {
-    public static ZookeeperRegistry getZookeeperRegistry(Collection<Registry> registryCollection) {
-        for (Registry registry : registryCollection) {
-            if (registry instanceof ListenerRegistryWrapper) {
-                registry = ((ListenerRegistryWrapper) registry).getRegistry();
-            }
-            if (registry instanceof ZookeeperRegistry) {
-                return (ZookeeperRegistry) registry;
-            }
-        }
-        return null;
-    }
-
-    public static RedisRegistry getRedisRegistry(Collection<Registry> registryCollection) {
-        for (Registry registry : registryCollection) {
-            if (registry instanceof ListenerRegistryWrapper) {
-                registry = ((ListenerRegistryWrapper) registry).getRegistry();
-            }
-            if (registry instanceof RedisRegistry) {
-                return (RedisRegistry) registry;
-            }
-        }
-        return null;
-    }
-
-    public static String getRedisContent(int port, String key) {
-        Jedis jedis = null;
-        try {
-            jedis = new Jedis("127.0.0.1", port);
-            return jedis.get(key);
-        } catch (Throwable e) {
-            throw new RpcException("Failed to put to redis . cause: " + e.getMessage(), e);
-        } finally {
-            if (jedis != null) {
-                jedis.close();
-            }
-        }
-    }
-
-    public static String getRedisHashContent(int port, String key, String field) {
-        Jedis jedis = null;
-        try {
-            jedis = new Jedis("127.0.0.1", port);
-            return jedis.hget(key, field);
-        } catch (Throwable e) {
-            throw new RpcException("Failed to put to redis . cause: " + e.getMessage(), e);
-        } finally {
-            if (jedis != null) {
-                jedis.close();
-            }
-        }
-    }
-
-    /**
-     * copy from @org.apache.dubbo.registry.integration.RegistryDirectory#notify(java.util.List)
-     *
-     * @param urls
-     * @return
-     */
-    public static List<URL> getProviderURLsFromNotifyURLS(List<URL> urls) {
-        Map<String, List<URL>> categoryUrls = urls.stream()
-                .filter(Objects::nonNull)
-                .filter(MultipleRegistryTestUtil::isValidCategory)
-                .filter(MultipleRegistryTestUtil::isNotCompatibleFor26x)
-                .collect(Collectors.groupingBy(url -> {
-                    if (UrlUtils.isConfigurator(url)) {
-                        return CONFIGURATORS_CATEGORY;
-                    } else if (UrlUtils.isRoute(url)) {
-                        return ROUTERS_CATEGORY;
-                    } else if (UrlUtils.isProvider(url)) {
-                        return PROVIDERS_CATEGORY;
-                    }
-                    return "";
-                }));
-
-        // providers
-        List<URL> providerURLs = categoryUrls.getOrDefault(PROVIDERS_CATEGORY, Collections.emptyList());
-        return providerURLs;
-
-    }
-
-    private static boolean isValidCategory(URL url) {
-        String category = url.getParameter(CATEGORY_KEY, DEFAULT_CATEGORY);
-        if ((ROUTERS_CATEGORY.equals(category) || ROUTE_PROTOCOL.equals(url.getProtocol())) ||
-                PROVIDERS_CATEGORY.equals(category) ||
-                CONFIGURATORS_CATEGORY.equals(category) || DYNAMIC_CONFIGURATORS_CATEGORY.equals(category) ||
-                APP_DYNAMIC_CONFIGURATORS_CATEGORY.equals(category)) {
-            return true;
-        }
-        return false;
-    }
-
-    private static boolean isNotCompatibleFor26x(URL url) {
-        return StringUtils.isEmpty(url.getParameter(COMPATIBLE_CONFIG_KEY));
-    }
-}
diff --git a/dubbo-spi-registry/dubbo-registry-nacos/pom.xml b/dubbo-spi-registry/dubbo-registry-nacos/pom.xml
deleted file mode 100644
index f381bba..0000000
--- a/dubbo-spi-registry/dubbo-registry-nacos/pom.xml
+++ /dev/null
@@ -1,83 +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.
-  -->
-<project xmlns="http://maven.apache.org/POM/4.0.0" xmlns:xsi="http://www.w3.org/2001/XMLSchema-instance" xsi:schemaLocation="http://maven.apache.org/POM/4.0.0 http://maven.apache.org/xsd/maven-4.0.0.xsd">
-    <parent>
-        <groupId>org.apache.dubbo</groupId>
-        <artifactId>dubbo-registry</artifactId>
-        <version>2.7.7-SNAPSHOT</version>
-    </parent>
-    <modelVersion>4.0.0</modelVersion>
-
-    <artifactId>dubbo-registry-nacos</artifactId>
-    <name>${project.artifactId}</name>
-    <description>The Nacos registry module of Dubbo project</description>
-
-    <dependencies>
-
-        <dependency>
-            <groupId>org.apache.dubbo</groupId>
-            <artifactId>dubbo-registry-api</artifactId>
-            <version>${project.version}</version>
-        </dependency>
-
-        <dependency>
-            <groupId>org.apache.dubbo</groupId>
-            <artifactId>dubbo-common</artifactId>
-            <version>${project.version}</version>
-        </dependency>
-
-        <dependency>
-            <groupId>com.alibaba.nacos</groupId>
-            <artifactId>nacos-client</artifactId>
-        </dependency>
-
-        <dependency>
-            <groupId>org.apache.dubbo</groupId>
-            <artifactId>dubbo-serialization-hessian2</artifactId>
-            <version>${project.version}</version>
-            <scope>test</scope>
-        </dependency>
-
-        <dependency>
-            <groupId>org.apache.dubbo</groupId>
-            <artifactId>dubbo-rpc-dubbo</artifactId>
-            <version>${project.version}</version>
-            <scope>test</scope>
-        </dependency>
-
-        <dependency>
-            <groupId>org.apache.dubbo</groupId>
-            <artifactId>dubbo-remoting-netty4</artifactId>
-            <version>${project.version}</version>
-            <scope>test</scope>
-        </dependency>
-
-        <dependency>
-            <groupId>ch.qos.logback</groupId>
-            <artifactId>logback-classic</artifactId>
-            <scope>test</scope>
-        </dependency>
-
-        <!-- REST support dependencies -->
-        <dependency>
-            <groupId>org.springframework</groupId>
-            <artifactId>spring-test</artifactId>
-            <scope>test</scope>
-        </dependency>
-
-    </dependencies>
-</project>
diff --git a/dubbo-spi-registry/dubbo-registry-nacos/src/main/java/org/apache/dubbo/registry/nacos/NacosRegistry.java b/dubbo-spi-registry/dubbo-registry-nacos/src/main/java/org/apache/dubbo/registry/nacos/NacosRegistry.java
deleted file mode 100644
index 187da71..0000000
--- a/dubbo-spi-registry/dubbo-registry-nacos/src/main/java/org/apache/dubbo/registry/nacos/NacosRegistry.java
+++ /dev/null
@@ -1,629 +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.registry.nacos;
-
-
-import com.alibaba.nacos.api.common.Constants;
-import com.google.common.collect.Lists;
-import org.apache.dubbo.common.URL;
-import org.apache.dubbo.common.URLBuilder;
-import org.apache.dubbo.common.logger.Logger;
-import org.apache.dubbo.common.logger.LoggerFactory;
-import org.apache.dubbo.common.utils.StringUtils;
-import org.apache.dubbo.common.utils.UrlUtils;
-import org.apache.dubbo.registry.NotifyListener;
-import org.apache.dubbo.registry.Registry;
-import org.apache.dubbo.registry.nacos.util.NacosInstanceManageUtil;
-import org.apache.dubbo.registry.support.FailbackRegistry;
-
-import com.alibaba.nacos.api.exception.NacosException;
-import com.alibaba.nacos.api.naming.NamingService;
-import com.alibaba.nacos.api.naming.listener.EventListener;
-import com.alibaba.nacos.api.naming.listener.NamingEvent;
-import com.alibaba.nacos.api.naming.pojo.Instance;
-import com.alibaba.nacos.api.naming.pojo.ListView;
-
-import java.util.ArrayList;
-import java.util.Arrays;
-import java.util.Collection;
-import java.util.HashMap;
-import java.util.LinkedHashSet;
-import java.util.LinkedList;
-import java.util.List;
-import java.util.Map;
-import java.util.Set;
-import java.util.concurrent.Executors;
-import java.util.concurrent.ScheduledExecutorService;
-import java.util.concurrent.TimeUnit;
-import java.util.stream.Collectors;
-
-import static org.apache.dubbo.common.constants.CommonConstants.ANY_VALUE;
-import static org.apache.dubbo.common.constants.CommonConstants.GROUP_KEY;
-import static org.apache.dubbo.common.constants.CommonConstants.INTERFACE_KEY;
-import static org.apache.dubbo.common.constants.CommonConstants.PATH_KEY;
-import static org.apache.dubbo.common.constants.CommonConstants.PROTOCOL_KEY;
-import static org.apache.dubbo.common.constants.CommonConstants.VERSION_KEY;
-import static org.apache.dubbo.common.constants.RegistryConstants.CATEGORY_KEY;
-import static org.apache.dubbo.common.constants.RegistryConstants.CONFIGURATORS_CATEGORY;
-import static org.apache.dubbo.common.constants.RegistryConstants.CONSUMERS_CATEGORY;
-import static org.apache.dubbo.common.constants.RegistryConstants.DEFAULT_CATEGORY;
-import static org.apache.dubbo.common.constants.RegistryConstants.EMPTY_PROTOCOL;
-import static org.apache.dubbo.common.constants.RegistryConstants.PROVIDERS_CATEGORY;
-import static org.apache.dubbo.common.constants.RegistryConstants.ROUTERS_CATEGORY;
-import static org.apache.dubbo.registry.Constants.ADMIN_PROTOCOL;
-import static org.apache.dubbo.registry.nacos.NacosServiceName.valueOf;
-
-/**
- * Nacos {@link Registry}
- *
- * @see #SERVICE_NAME_SEPARATOR
- * @see #PAGINATION_SIZE
- * @see #LOOKUP_INTERVAL
- * @since 2.6.5
- */
-public class NacosRegistry extends FailbackRegistry {
-
-    /**
-     * All supported categories
-     */
-    private static final List<String> ALL_SUPPORTED_CATEGORIES = Arrays.asList(
-            PROVIDERS_CATEGORY,
-            CONSUMERS_CATEGORY,
-            ROUTERS_CATEGORY,
-            CONFIGURATORS_CATEGORY
-    );
-
-    private static final int CATEGORY_INDEX = 0;
-
-    private static final int SERVICE_INTERFACE_INDEX = 1;
-
-    private static final int SERVICE_VERSION_INDEX = 2;
-
-    private static final int SERVICE_GROUP_INDEX = 3;
-
-    private static final String WILDCARD = "*";
-
-    /**
-     * The separator for service name
-     * Change a constant to be configurable, it's designed for Windows file name that is compatible with old
-     * Nacos binary release(< 0.6.1)
-     */
-    private static final String SERVICE_NAME_SEPARATOR = System.getProperty("nacos.service.name.separator", ":");
-
-    /**
-     * The pagination size of query for Nacos service names(only for Dubbo-OPS)
-     */
-    private static final int PAGINATION_SIZE = Integer.getInteger("nacos.service.names.pagination.size", 100);
-
-    /**
-     * The interval in second of lookup Nacos service names(only for Dubbo-OPS)
-     */
-    private static final long LOOKUP_INTERVAL = Long.getLong("nacos.service.names.lookup.interval", 30);
-
-    /**
-     * {@link ScheduledExecutorService} lookup Nacos service names(only for Dubbo-OPS)
-     */
-    private volatile ScheduledExecutorService scheduledExecutorService;
-
-    private final Logger logger = LoggerFactory.getLogger(getClass());
-
-    private final NamingService namingService;
-
-    public NacosRegistry(URL url, NamingService namingService) {
-        super(url);
-        this.namingService = namingService;
-    }
-
-    @Override
-    public boolean isAvailable() {
-        return "UP".equals(namingService.getServerStatus());
-    }
-
-    @Override
-    public List<URL> lookup(final URL url) {
-        final List<URL> urls = new LinkedList<>();
-        execute(namingService -> {
-            Set<String> serviceNames = getServiceNames(url, null);
-            for (String serviceName : serviceNames) {
-                List<Instance> instances = namingService.getAllInstances(serviceName,
-                        getUrl().getParameter(GROUP_KEY, Constants.DEFAULT_GROUP));
-                urls.addAll(buildURLs(url, instances));
-            }
-        });
-        return urls;
-    }
-
-    @Override
-    public void doRegister(URL url) {
-        final String serviceName = getServiceName(url);
-        final Instance instance = createInstance(url);
-        /**
-         *  namingService.registerInstance with {@link org.apache.dubbo.registry.support.AbstractRegistry#registryUrl}
-         *  default {@link DEFAULT_GROUP}
-         *
-         * in https://github.com/apache/dubbo/issues/5978
-         */
-        execute(namingService -> namingService.registerInstance(serviceName,
-                getUrl().getParameter(GROUP_KEY, Constants.DEFAULT_GROUP), instance));
-    }
-
-    @Override
-    public void doUnregister(final URL url) {
-        execute(namingService -> {
-            String serviceName = getServiceName(url);
-            Instance instance = createInstance(url);
-            namingService.deregisterInstance(serviceName,
-                    getUrl().getParameter(GROUP_KEY, Constants.DEFAULT_GROUP),
-                    instance.getIp()
-                    , instance.getPort());
-        });
-    }
-
-    @Override
-    public void doSubscribe(final URL url, final NotifyListener listener) {
-        Set<String> serviceNames = getServiceNames(url, listener);
-
-        //Set corresponding serviceNames for easy search later
-        if (isServiceNamesWithCompatibleMode(url)) {
-            for (String serviceName : serviceNames) {
-                NacosInstanceManageUtil.setCorrespondingServiceNames(serviceName, serviceNames);
-            }
-        }
-
-        doSubscribe(url, listener, serviceNames);
-    }
-
-    private void doSubscribe(final URL url, final NotifyListener listener, final Set<String> serviceNames) {
-        execute(namingService -> {
-            if (isServiceNamesWithCompatibleMode(url)) {
-                List<Instance> allCorrespondingInstanceList = Lists.newArrayList();
-
-                /**
-                 * Get all instances with serviceNames to avoid instance overwrite and but with empty instance mentioned
-                 * in https://github.com/apache/dubbo/issues/5885 and https://github.com/apache/dubbo/issues/5899
-                 *
-                 * namingService.getAllInstances with {@link org.apache.dubbo.registry.support.AbstractRegistry#registryUrl}
-                 * default {@link DEFAULT_GROUP}
-                 *
-                 * in https://github.com/apache/dubbo/issues/5978
-                 */
-                for (String serviceName : serviceNames) {
-                    List<Instance> instances = namingService.getAllInstances(serviceName,
-                            getUrl().getParameter(GROUP_KEY, Constants.DEFAULT_GROUP));
-                    NacosInstanceManageUtil.initOrRefreshServiceInstanceList(serviceName, instances);
-                    allCorrespondingInstanceList.addAll(instances);
-                }
-                notifySubscriber(url, listener, allCorrespondingInstanceList);
-                for (String serviceName : serviceNames) {
-                    subscribeEventListener(serviceName, url, listener);
-                }
-            } else {
-                List<Instance> instances = new LinkedList<>();
-                for (String serviceName : serviceNames) {
-                    instances.addAll(namingService.getAllInstances(serviceName
-                            , getUrl().getParameter(GROUP_KEY, Constants.DEFAULT_GROUP)));
-                    notifySubscriber(url, listener, instances);
-                    subscribeEventListener(serviceName, url, listener);
-                }
-            }
-
-        });
-    }
-
-    /**
-     * Since 2.7.6 the legacy service name will be added to serviceNames
-     * to fix bug with https://github.com/apache/dubbo/issues/5442
-     *
-     * @param url
-     * @return
-     */
-    private boolean isServiceNamesWithCompatibleMode(final URL url) {
-        if (!isAdminProtocol(url) && createServiceName(url).isConcrete()) {
-            return true;
-        } else {
-            return false;
-        }
-    }
-
-    @Override
-    public void doUnsubscribe(URL url, NotifyListener listener) {
-        if (isAdminProtocol(url)) {
-            shutdownServiceNamesLookup();
-        }
-    }
-
-    private void shutdownServiceNamesLookup() {
-        if (scheduledExecutorService != null) {
-            scheduledExecutorService.shutdown();
-        }
-    }
-
-    /**
-     * Get the service names from the specified {@link URL url}
-     *
-     * @param url      {@link URL}
-     * @param listener {@link NotifyListener}
-     * @return non-null
-     */
-    private Set<String> getServiceNames(URL url, NotifyListener listener) {
-        if (isAdminProtocol(url)) {
-            scheduleServiceNamesLookup(url, listener);
-            return getServiceNamesForOps(url);
-        } else {
-            return getServiceNames0(url);
-        }
-    }
-
-    private Set<String> getServiceNames0(URL url) {
-        NacosServiceName serviceName = createServiceName(url);
-
-        final Set<String> serviceNames;
-
-        if (serviceName.isConcrete()) { // is the concrete service name
-            serviceNames = new LinkedHashSet<>();
-            serviceNames.add(serviceName.toString());
-            // Add the legacy service name since 2.7.6
-            String legacySubscribedServiceName = getLegacySubscribedServiceName(url);
-            if (!serviceName.toString().equals(legacySubscribedServiceName)) {
-                //avoid duplicated service names
-                serviceNames.add(legacySubscribedServiceName);
-            }
-        } else {
-            serviceNames = filterServiceNames(serviceName);
-        }
-
-        return serviceNames;
-    }
-
-    private Set<String> filterServiceNames(NacosServiceName serviceName) {
-        Set<String> serviceNames = new LinkedHashSet<>();
-
-        execute(namingService -> {
-
-            serviceNames.addAll(namingService.getServicesOfServer(1, Integer.MAX_VALUE,
-                    getUrl().getParameter(GROUP_KEY, Constants.DEFAULT_GROUP)).getData()
-                    .stream()
-                    .map(NacosServiceName::new)
-                    .filter(serviceName::isCompatible)
-                    .map(NacosServiceName::toString)
-                    .collect(Collectors.toList()));
-
-        });
-
-        return serviceNames;
-    }
-
-    /**
-     * Get the legacy subscribed service name for compatible with Dubbo 2.7.3 and below
-     *
-     * @param url {@link URL}
-     * @return non-null
-     * @since 2.7.6
-     */
-    private String getLegacySubscribedServiceName(URL url) {
-        StringBuilder serviceNameBuilder = new StringBuilder(DEFAULT_CATEGORY);
-        appendIfPresent(serviceNameBuilder, url, INTERFACE_KEY);
-        appendIfPresent(serviceNameBuilder, url, VERSION_KEY);
-        appendIfPresent(serviceNameBuilder, url, GROUP_KEY);
-        return serviceNameBuilder.toString();
-    }
-
-    private void appendIfPresent(StringBuilder target, URL url, String parameterName) {
-        String parameterValue = url.getParameter(parameterName);
-        if (!org.apache.commons.lang3.StringUtils.isBlank(parameterValue)) {
-            target.append(SERVICE_NAME_SEPARATOR).append(parameterValue);
-        }
-    }
-
-
-    private boolean isAdminProtocol(URL url) {
-        return ADMIN_PROTOCOL.equals(url.getProtocol());
-    }
-
-    private void scheduleServiceNamesLookup(final URL url, final NotifyListener listener) {
-        if (scheduledExecutorService == null) {
-            scheduledExecutorService = Executors.newSingleThreadScheduledExecutor();
-            scheduledExecutorService.scheduleAtFixedRate(() -> {
-                Set<String> serviceNames = getAllServiceNames();
-                filterData(serviceNames, serviceName -> {
-                    boolean accepted = false;
-                    for (String category : ALL_SUPPORTED_CATEGORIES) {
-                        String prefix = category + SERVICE_NAME_SEPARATOR;
-                        if (serviceName != null && serviceName.startsWith(prefix)) {
-                            accepted = true;
-                            break;
-                        }
-                    }
-                    return accepted;
-                });
-                doSubscribe(url, listener, serviceNames);
-            }, LOOKUP_INTERVAL, LOOKUP_INTERVAL, TimeUnit.SECONDS);
-        }
-    }
-
-    /**
-     * Get the service names for Dubbo OPS
-     *
-     * @param url {@link URL}
-     * @return non-null
-     */
-    private Set<String> getServiceNamesForOps(URL url) {
-        Set<String> serviceNames = getAllServiceNames();
-        filterServiceNames(serviceNames, url);
-        return serviceNames;
-    }
-
-    private Set<String> getAllServiceNames() {
-
-        final Set<String> serviceNames = new LinkedHashSet<>();
-
-        execute(namingService -> {
-
-            int pageIndex = 1;
-            ListView<String> listView = namingService.getServicesOfServer(pageIndex, PAGINATION_SIZE,
-                    getUrl().getParameter(GROUP_KEY, Constants.DEFAULT_GROUP));
-            // First page data
-            List<String> firstPageData = listView.getData();
-            // Append first page into list
-            serviceNames.addAll(firstPageData);
-            // the total count
-            int count = listView.getCount();
-            // the number of pages
-            int pageNumbers = count / PAGINATION_SIZE;
-            int remainder = count % PAGINATION_SIZE;
-            // remain
-            if (remainder > 0) {
-                pageNumbers += 1;
-            }
-            // If more than 1 page
-            while (pageIndex < pageNumbers) {
-                listView = namingService.getServicesOfServer(++pageIndex, PAGINATION_SIZE,
-                        getUrl().getParameter(GROUP_KEY, Constants.DEFAULT_GROUP));
-                serviceNames.addAll(listView.getData());
-            }
-
-        });
-
-        return serviceNames;
-    }
-
-    private void filterServiceNames(Set<String> serviceNames, URL url) {
-
-        final List<String> categories = getCategories(url);
-
-        final String targetServiceInterface = url.getServiceInterface();
-
-        final String targetVersion = url.getParameter(VERSION_KEY, "");
-
-        final String targetGroup = url.getParameter(GROUP_KEY, "");
-
-        filterData(serviceNames, serviceName -> {
-            // split service name to segments
-            // (required) segments[0] = category
-            // (required) segments[1] = serviceInterface
-            // (optional) segments[2] = version
-            // (optional) segments[3] = group
-            String[] segments = serviceName.split(SERVICE_NAME_SEPARATOR, -1);
-            int length = segments.length;
-            if (length != 4) { // must present 4 segments
-                return false;
-            }
-
-            String category = segments[CATEGORY_INDEX];
-            if (!categories.contains(category)) { // no match category
-                return false;
-            }
-
-            String serviceInterface = segments[SERVICE_INTERFACE_INDEX];
-            // no match service interface
-            if (!WILDCARD.equals(targetServiceInterface) &&
-                    !StringUtils.isEquals(targetServiceInterface, serviceInterface)) {
-                return false;
-            }
-
-            // no match service version
-            String version = segments[SERVICE_VERSION_INDEX];
-            if (!WILDCARD.equals(targetVersion) && !StringUtils.isEquals(targetVersion, version)) {
-                return false;
-            }
-
-            String group = segments[SERVICE_GROUP_INDEX];
-            return group == null || WILDCARD.equals(targetGroup) || StringUtils.isEquals(targetGroup, group);
-        });
-    }
-
-    private <T> void filterData(Collection<T> collection, NacosDataFilter<T> filter) {
-        // remove if not accept
-        collection.removeIf(data -> !filter.accept(data));
-    }
-
-    @Deprecated
-    private List<String> doGetServiceNames(URL url) {
-        List<String> categories = getCategories(url);
-        List<String> serviceNames = new ArrayList<>(categories.size());
-        for (String category : categories) {
-            final String serviceName = getServiceName(url, category);
-            serviceNames.add(serviceName);
-        }
-        return serviceNames;
-    }
-
-    private List<URL> toUrlWithEmpty(URL consumerURL, Collection<Instance> instances) {
-        List<URL> urls = buildURLs(consumerURL, instances);
-        if (urls.size() == 0) {
-            URL empty = URLBuilder.from(consumerURL)
-                    .setProtocol(EMPTY_PROTOCOL)
-                    .addParameter(CATEGORY_KEY, DEFAULT_CATEGORY)
-                    .build();
-            urls.add(empty);
-        }
-        return urls;
-    }
-
-    private List<URL> buildURLs(URL consumerURL, Collection<Instance> instances) {
-        List<URL> urls = new LinkedList<>();
-        if (instances != null && !instances.isEmpty()) {
-            for (Instance instance : instances) {
-                URL url = buildURL(instance);
-                if (UrlUtils.isMatch(consumerURL, url)) {
-                    urls.add(url);
-                }
-            }
-        }
-        return urls;
-    }
-
-    private void subscribeEventListener(String serviceName, final URL url, final NotifyListener listener)
-            throws NacosException {
-        EventListener eventListener = event -> {
-            if (event instanceof NamingEvent) {
-                NamingEvent e = (NamingEvent) event;
-                List<Instance> instances = e.getInstances();
-
-
-                if (isServiceNamesWithCompatibleMode(url)) {
-                    /**
-                     * Get all instances with corresponding serviceNames to avoid instance overwrite and but with empty instance mentioned
-                     * in https://github.com/apache/dubbo/issues/5885 and https://github.com/apache/dubbo/issues/5899
-                     */
-                    NacosInstanceManageUtil.initOrRefreshServiceInstanceList(serviceName, instances);
-                    instances = NacosInstanceManageUtil.getAllCorrespondingServiceInstanceList(serviceName);
-                }
-
-                notifySubscriber(url, listener, instances);
-            }
-        };
-        namingService.subscribe(serviceName,
-                getUrl().getParameter(GROUP_KEY, Constants.DEFAULT_GROUP),
-                eventListener);
-    }
-
-    /**
-     * Notify the Healthy {@link Instance instances} to subscriber.
-     *
-     * @param url       {@link URL}
-     * @param listener  {@link NotifyListener}
-     * @param instances all {@link Instance instances}
-     */
-    private void notifySubscriber(URL url, NotifyListener listener, Collection<Instance> instances) {
-        List<Instance> healthyInstances = new LinkedList<>(instances);
-        if (healthyInstances.size() > 0) {
-            // Healthy Instances
-            filterHealthyInstances(healthyInstances);
-        }
-        List<URL> urls = toUrlWithEmpty(url, healthyInstances);
-        NacosRegistry.this.notify(url, listener, urls);
-    }
-
-    /**
-     * Get the categories from {@link URL}
-     *
-     * @param url {@link URL}
-     * @return non-null array
-     */
-    private List<String> getCategories(URL url) {
-        return ANY_VALUE.equals(url.getServiceInterface()) ?
-                ALL_SUPPORTED_CATEGORIES : Arrays.asList(DEFAULT_CATEGORY);
-    }
-
-    private URL buildURL(Instance instance) {
-        Map<String, String> metadata = instance.getMetadata();
-        String protocol = metadata.get(PROTOCOL_KEY);
-        String path = metadata.get(PATH_KEY);
-        return new URL(protocol,
-                instance.getIp(),
-                instance.getPort(),
-                path,
-                instance.getMetadata());
-    }
-
-    private Instance createInstance(URL url) {
-        // Append default category if absent
-        String category = url.getParameter(CATEGORY_KEY, DEFAULT_CATEGORY);
-        URL newURL = url.addParameter(CATEGORY_KEY, category);
-        newURL = newURL.addParameter(PROTOCOL_KEY, url.getProtocol());
-        newURL = newURL.addParameter(PATH_KEY, url.getPath());
-        String ip = url.getHost();
-        int port = url.getPort();
-        Instance instance = new Instance();
-        instance.setIp(ip);
-        instance.setPort(port);
-        instance.setMetadata(new HashMap<>(newURL.getParameters()));
-        return instance;
-    }
-
-    private NacosServiceName createServiceName(URL url) {
-        return valueOf(url);
-    }
-
-    private String getServiceName(URL url) {
-        return getServiceName(url, url.getParameter(CATEGORY_KEY, DEFAULT_CATEGORY));
-    }
-
-    private String getServiceName(URL url, String category) {
-        return category + SERVICE_NAME_SEPARATOR + url.getColonSeparatedKey();
-    }
-
-    private void execute(NamingServiceCallback callback) {
-        try {
-            callback.callback(namingService);
-        } catch (NacosException e) {
-            if (logger.isErrorEnabled()) {
-                logger.error(e.getErrMsg(), e);
-            }
-        }
-    }
-
-    private void filterHealthyInstances(Collection<Instance> instances) {
-        filterData(instances, Instance::isEnabled);
-    }
-
-    /**
-     * A filter for Nacos data
-     *
-     * @since 2.6.5
-     */
-    private interface NacosDataFilter<T> {
-
-        /**
-         * Tests whether or not the specified data should be accepted.
-         *
-         * @param data The data to be tested
-         * @return <code>true</code> if and only if <code>data</code>
-         * should be accepted
-         */
-        boolean accept(T data);
-
-    }
-
-    /**
-     * {@link NamingService} Callback
-     *
-     * @since 2.6.5
-     */
-    interface NamingServiceCallback {
-
-        /**
-         * Callback
-         *
-         * @param namingService {@link NamingService}
-         * @throws NacosException
-         */
-        void callback(NamingService namingService) throws NacosException;
-
-    }
-}
\ No newline at end of file
diff --git a/dubbo-spi-registry/dubbo-registry-nacos/src/main/java/org/apache/dubbo/registry/nacos/NacosRegistryFactory.java b/dubbo-spi-registry/dubbo-registry-nacos/src/main/java/org/apache/dubbo/registry/nacos/NacosRegistryFactory.java
deleted file mode 100644
index 380280e..0000000
--- a/dubbo-spi-registry/dubbo-registry-nacos/src/main/java/org/apache/dubbo/registry/nacos/NacosRegistryFactory.java
+++ /dev/null
@@ -1,42 +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.registry.nacos;
-
-import org.apache.dubbo.common.URL;
-import org.apache.dubbo.registry.Registry;
-import org.apache.dubbo.registry.RegistryFactory;
-import org.apache.dubbo.registry.support.AbstractRegistryFactory;
-
-import static org.apache.dubbo.registry.nacos.util.NacosNamingServiceUtils.createNamingService;
-
-/**
- * Nacos {@link RegistryFactory}
- *
- * @since 2.6.5
- */
-public class NacosRegistryFactory extends AbstractRegistryFactory {
-
-    @Override
-    protected String createRegistryCacheKey(URL url) {
-        return url.toFullString();
-    }
-
-    @Override
-    protected Registry createRegistry(URL url) {
-        return new NacosRegistry(url, createNamingService(url));
-    }
-}
diff --git a/dubbo-spi-registry/dubbo-registry-nacos/src/main/java/org/apache/dubbo/registry/nacos/NacosServiceDiscovery.java b/dubbo-spi-registry/dubbo-registry-nacos/src/main/java/org/apache/dubbo/registry/nacos/NacosServiceDiscovery.java
deleted file mode 100644
index f27a50d..0000000
--- a/dubbo-spi-registry/dubbo-registry-nacos/src/main/java/org/apache/dubbo/registry/nacos/NacosServiceDiscovery.java
+++ /dev/null
@@ -1,130 +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.registry.nacos;
-
-import org.apache.dubbo.common.URL;
-import org.apache.dubbo.common.function.ThrowableFunction;
-import org.apache.dubbo.common.logger.Logger;
-import org.apache.dubbo.common.logger.LoggerFactory;
-import org.apache.dubbo.registry.client.ServiceDiscovery;
-import org.apache.dubbo.registry.client.ServiceInstance;
-import org.apache.dubbo.registry.client.event.listener.ServiceInstancesChangedListener;
-import org.apache.dubbo.registry.nacos.util.NacosNamingServiceUtils;
-
-import com.alibaba.nacos.api.naming.NamingService;
-import com.alibaba.nacos.api.naming.listener.NamingEvent;
-import com.alibaba.nacos.api.naming.pojo.Instance;
-import com.alibaba.nacos.api.naming.pojo.ListView;
-
-import java.util.Collection;
-import java.util.LinkedHashSet;
-import java.util.List;
-import java.util.Set;
-import java.util.stream.Collectors;
-
-import static org.apache.dubbo.common.function.ThrowableConsumer.execute;
-import static org.apache.dubbo.registry.nacos.util.NacosNamingServiceUtils.createNamingService;
-import static org.apache.dubbo.registry.nacos.util.NacosNamingServiceUtils.getGroup;
-import static org.apache.dubbo.registry.nacos.util.NacosNamingServiceUtils.toInstance;
-
-/**
- * Nacos {@link ServiceDiscovery} implementation
- *
- * @see ServiceDiscovery
- * @since 2.7.5
- */
-public class NacosServiceDiscovery implements ServiceDiscovery {
-
-    private final Logger logger = LoggerFactory.getLogger(getClass());
-
-    private String group;
-
-    private NamingService namingService;
-
-    @Override
-    public void initialize(URL registryURL) throws Exception {
-        this.namingService = createNamingService(registryURL);
-        this.group = getGroup(registryURL);
-    }
-
-    @Override
-    public void destroy() {
-        this.namingService = null;
-    }
-
-    @Override
-    public void register(ServiceInstance serviceInstance) throws RuntimeException {
-        execute(namingService, service -> {
-            Instance instance = toInstance(serviceInstance);
-            service.registerInstance(instance.getServiceName(), group, instance);
-        });
-    }
-
-    @Override
-    public void update(ServiceInstance serviceInstance) throws RuntimeException {
-        // TODO: Nacos should support
-        unregister(serviceInstance);
-        register(serviceInstance);
-    }
-
-    @Override
-    public void unregister(ServiceInstance serviceInstance) throws RuntimeException {
-        execute(namingService, service -> {
-            Instance instance = toInstance(serviceInstance);
-            service.deregisterInstance(instance.getServiceName(), group, instance);
-        });
-    }
-
-    @Override
-    public Set<String> getServices() {
-        return ThrowableFunction.execute(namingService, service -> {
-            ListView<String> view = service.getServicesOfServer(0, Integer.MAX_VALUE, group);
-            return new LinkedHashSet<>(view.getData());
-        });
-    }
-
-    @Override
-    public List<ServiceInstance> getInstances(String serviceName) throws NullPointerException {
-        return ThrowableFunction.execute(namingService, service ->
-                service.selectInstances(serviceName, true)
-                        .stream().map(NacosNamingServiceUtils::toServiceInstance)
-                        .collect(Collectors.toList())
-        );
-    }
-
-    @Override
-    public void addServiceInstancesChangedListener(ServiceInstancesChangedListener listener)
-            throws NullPointerException, IllegalArgumentException {
-        execute(namingService, service -> {
-            service.subscribe(listener.getServiceName(), e -> { // Register Nacos EventListener
-                if (e instanceof NamingEvent) {
-                    NamingEvent event = (NamingEvent) e;
-                    handleEvent(event, listener);
-                }
-            });
-        });
-    }
-
-    private void handleEvent(NamingEvent event, ServiceInstancesChangedListener listener) {
-        String serviceName = event.getServiceName();
-        Collection<ServiceInstance> serviceInstances = event.getInstances()
-                .stream()
-                .map(NacosNamingServiceUtils::toServiceInstance)
-                .collect(Collectors.toList());
-        dispatchServiceInstancesChangedEvent(serviceName, serviceInstances);
-    }
-}
diff --git a/dubbo-spi-registry/dubbo-registry-nacos/src/main/java/org/apache/dubbo/registry/nacos/NacosServiceName.java b/dubbo-spi-registry/dubbo-registry-nacos/src/main/java/org/apache/dubbo/registry/nacos/NacosServiceName.java
deleted file mode 100644
index 27c45ee..0000000
--- a/dubbo-spi-registry/dubbo-registry-nacos/src/main/java/org/apache/dubbo/registry/nacos/NacosServiceName.java
+++ /dev/null
@@ -1,234 +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.registry.nacos;
-
-import org.apache.dubbo.common.URL;
-import org.apache.dubbo.common.utils.StringUtils;
-
-import java.util.Arrays;
-import java.util.Objects;
-
-import static org.apache.dubbo.common.constants.CommonConstants.GROUP_KEY;
-import static org.apache.dubbo.common.constants.CommonConstants.INTERFACE_KEY;
-import static org.apache.dubbo.common.constants.CommonConstants.VERSION_KEY;
-import static org.apache.dubbo.common.constants.RegistryConstants.CATEGORY_KEY;
-import static org.apache.dubbo.common.constants.RegistryConstants.DEFAULT_CATEGORY;
-import static org.apache.dubbo.common.utils.StringUtils.isBlank;
-
-/**
- * The service name of Nacos
- *
- * @since 2.7.3
- */
-public class NacosServiceName {
-
-    public static final String NAME_SEPARATOR = ":";
-
-    public static final String VALUE_SEPARATOR = ",";
-
-    public static final String WILDCARD = "*";
-
-    public static final String DEFAULT_PARAM_VALUE = "";
-
-    private static final int CATEGORY_INDEX = 0;
-
-    private static final int SERVICE_INTERFACE_INDEX = 1;
-
-    private static final int SERVICE_VERSION_INDEX = 2;
-
-    private static final int SERVICE_GROUP_INDEX = 3;
-
-    private String category;
-
-    private String serviceInterface;
-
-    private String version;
-
-    private String group;
-
-    private String value;
-
-    public NacosServiceName() {
-    }
-
-    public NacosServiceName(URL url) {
-        serviceInterface = url.getParameter(INTERFACE_KEY);
-        category = isConcrete(serviceInterface) ? DEFAULT_CATEGORY : url.getParameter(CATEGORY_KEY);
-        version = url.getParameter(VERSION_KEY, DEFAULT_PARAM_VALUE);
-        group = url.getParameter(GROUP_KEY, DEFAULT_PARAM_VALUE);
-        value = toValue();
-    }
-
-    public NacosServiceName(String value) {
-        this.value = value;
-        String[] segments = value.split(NAME_SEPARATOR, -1);
-        this.category = segments[CATEGORY_INDEX];
-        this.serviceInterface = segments[SERVICE_INTERFACE_INDEX];
-        this.version = segments[SERVICE_VERSION_INDEX];
-        this.group = segments[SERVICE_GROUP_INDEX];
-    }
-
-    /**
-     * Build an instance of {@link NacosServiceName}
-     *
-     * @param url
-     * @return
-     */
-    public static NacosServiceName valueOf(URL url) {
-        return new NacosServiceName(url);
-    }
-
-    /**
-     * Is the concrete service name or not
-     *
-     * @return if concrete , return <code>true</code>, or <code>false</code>
-     */
-    public boolean isConcrete() {
-        return isConcrete(serviceInterface) && isConcrete(version) && isConcrete(group);
-    }
-
-    public boolean isCompatible(NacosServiceName concreteServiceName) {
-
-        if (!concreteServiceName.isConcrete()) { // The argument must be the concrete NacosServiceName
-            return false;
-        }
-
-        // Not match comparison
-        if (!StringUtils.isEquals(this.category, concreteServiceName.category)
-                && !matchRange(this.category, concreteServiceName.category)) {
-            return false;
-        }
-
-        if (!StringUtils.isEquals(this.serviceInterface, concreteServiceName.serviceInterface)) {
-            return false;
-        }
-
-        // wildcard condition
-        if (isWildcard(this.version)) {
-            return true;
-        }
-
-        if (isWildcard(this.group)) {
-            return true;
-        }
-
-        // range condition
-        if (!StringUtils.isEquals(this.version, concreteServiceName.version)
-                && !matchRange(this.version, concreteServiceName.version)) {
-            return false;
-        }
-
-        if (!StringUtils.isEquals(this.group, concreteServiceName.group) &&
-                !matchRange(this.group, concreteServiceName.group)) {
-            return false;
-        }
-
-        return true;
-    }
-
-    private boolean matchRange(String range, String value) {
-        if (isBlank(range)) {
-            return true;
-        }
-        if (!isRange(range)) {
-            return false;
-        }
-        String[] values = range.split(VALUE_SEPARATOR);
-        return Arrays.asList(values).contains(value);
-    }
-
-    private boolean isConcrete(String value) {
-        return !isWildcard(value) && !isRange(value);
-    }
-
-    private boolean isWildcard(String value) {
-        return WILDCARD.equals(value);
-    }
-
-    private boolean isRange(String value) {
-        return value != null && value.indexOf(VALUE_SEPARATOR) > -1 && value.split(VALUE_SEPARATOR).length > 1;
-    }
-
-    public String getCategory() {
-        return category;
-    }
-
-    public void setCategory(String category) {
-        this.category = category;
-    }
-
-    public String getServiceInterface() {
-        return serviceInterface;
-    }
-
-    public void setServiceInterface(String serviceInterface) {
-        this.serviceInterface = serviceInterface;
-    }
-
-    public String getVersion() {
-        return version;
-    }
-
-    public void setVersion(String version) {
-        this.version = version;
-    }
-
-    public String getGroup() {
-        return group;
-    }
-
-    public void setGroup(String group) {
-        this.group = group;
-    }
-
-    public String getValue() {
-        if (value == null) {
-            value = toValue();
-        }
-        return value;
-    }
-
-    private String toValue() {
-        return new StringBuilder(category)
-                .append(NAME_SEPARATOR).append(serviceInterface)
-                .append(NAME_SEPARATOR).append(version)
-                .append(NAME_SEPARATOR).append(group)
-                .toString();
-    }
-
-    @Override
-    public boolean equals(Object o) {
-        if (this == o) {
-            return true;
-        }
-        if (!(o instanceof NacosServiceName)) {
-            return false;
-        }
-        NacosServiceName that = (NacosServiceName) o;
-        return Objects.equals(getValue(), that.getValue());
-    }
-
-    @Override
-    public int hashCode() {
-        return Objects.hash(getValue());
-    }
-
-    @Override
-    public String toString() {
-        return getValue();
-    }
-}
diff --git a/dubbo-spi-registry/dubbo-registry-nacos/src/main/java/org/apache/dubbo/registry/nacos/util/NacosInstanceManageUtil.java b/dubbo-spi-registry/dubbo-registry-nacos/src/main/java/org/apache/dubbo/registry/nacos/util/NacosInstanceManageUtil.java
deleted file mode 100644
index 190a5aa..0000000
--- a/dubbo-spi-registry/dubbo-registry-nacos/src/main/java/org/apache/dubbo/registry/nacos/util/NacosInstanceManageUtil.java
+++ /dev/null
@@ -1,67 +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.registry.nacos.util;
-
-import com.alibaba.nacos.api.naming.pojo.Instance;
-import com.google.common.collect.Lists;
-import com.google.common.collect.Maps;
-import org.apache.dubbo.common.utils.CollectionUtils;
-
-import java.util.List;
-import java.util.Map;
-import java.util.Set;
-
-/**
- * Instance manage util for multiple serviceNames
- * To resolve bug with https://github.com/apache/dubbo/issues/5885 and https://github.com/apache/dubbo/issues/5899
- *
- * @since 2.7.6
- */
-public class NacosInstanceManageUtil {
-
-    /**
-     * serviceName -> refreshed instance list
-     */
-    private static final Map<String, List<Instance>> SERVICE_INSTANCE_LIST_MAP = Maps.newConcurrentMap();
-
-    /**
-     * serviceName -> corresponding serviceName list
-     */
-    private static final Map<String, Set<String>> CORRESPONDING_SERVICE_NAMES_MAP = Maps.newConcurrentMap();
-
-    public static void setCorrespondingServiceNames(String serviceName, Set<String> serviceNames) {
-        CORRESPONDING_SERVICE_NAMES_MAP.put(serviceName, serviceNames);
-    }
-
-    public static void initOrRefreshServiceInstanceList(String serviceName, List<Instance> instanceList) {
-        SERVICE_INSTANCE_LIST_MAP.put(serviceName, instanceList);
-    }
-
-    public static List<Instance> getAllCorrespondingServiceInstanceList(String serviceName) {
-        if (!CORRESPONDING_SERVICE_NAMES_MAP.containsKey(serviceName)) {
-            return Lists.newArrayList();
-        }
-        List<Instance> allInstances = Lists.newArrayList();
-        for (String correspondingServiceName : CORRESPONDING_SERVICE_NAMES_MAP.get(serviceName)) {
-            if (SERVICE_INSTANCE_LIST_MAP.containsKey(correspondingServiceName) && CollectionUtils.isNotEmpty(SERVICE_INSTANCE_LIST_MAP.get(correspondingServiceName))) {
-                allInstances.addAll(SERVICE_INSTANCE_LIST_MAP.get(correspondingServiceName));
-            }
-        }
-        return allInstances;
-    }
-
-}
diff --git a/dubbo-spi-registry/dubbo-registry-nacos/src/main/java/org/apache/dubbo/registry/nacos/util/NacosNamingServiceUtils.java b/dubbo-spi-registry/dubbo-registry-nacos/src/main/java/org/apache/dubbo/registry/nacos/util/NacosNamingServiceUtils.java
deleted file mode 100644
index 5644474..0000000
--- a/dubbo-spi-registry/dubbo-registry-nacos/src/main/java/org/apache/dubbo/registry/nacos/util/NacosNamingServiceUtils.java
+++ /dev/null
@@ -1,192 +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.registry.nacos.util;
-
-import org.apache.dubbo.common.URL;
-import org.apache.dubbo.common.logger.Logger;
-import org.apache.dubbo.common.logger.LoggerFactory;
-import org.apache.dubbo.common.utils.StringUtils;
-import org.apache.dubbo.registry.client.DefaultServiceInstance;
-import org.apache.dubbo.registry.client.ServiceInstance;
-
-import com.alibaba.nacos.api.NacosFactory;
-import com.alibaba.nacos.api.exception.NacosException;
-import com.alibaba.nacos.api.naming.NamingService;
-import com.alibaba.nacos.api.naming.pojo.Instance;
-
-import java.util.Properties;
-
-import static com.alibaba.nacos.api.PropertyKeyConst.ACCESS_KEY;
-import static com.alibaba.nacos.api.PropertyKeyConst.CLUSTER_NAME;
-import static com.alibaba.nacos.api.PropertyKeyConst.CONFIG_LONG_POLL_TIMEOUT;
-import static com.alibaba.nacos.api.PropertyKeyConst.CONFIG_RETRY_TIME;
-import static com.alibaba.nacos.api.PropertyKeyConst.CONTEXT_PATH;
-import static com.alibaba.nacos.api.PropertyKeyConst.ENABLE_REMOTE_SYNC_CONFIG;
-import static com.alibaba.nacos.api.PropertyKeyConst.ENCODE;
-import static com.alibaba.nacos.api.PropertyKeyConst.ENDPOINT;
-import static com.alibaba.nacos.api.PropertyKeyConst.ENDPOINT_PORT;
-import static com.alibaba.nacos.api.PropertyKeyConst.IS_USE_CLOUD_NAMESPACE_PARSING;
-import static com.alibaba.nacos.api.PropertyKeyConst.IS_USE_ENDPOINT_PARSING_RULE;
-import static com.alibaba.nacos.api.PropertyKeyConst.MAX_RETRY;
-import static com.alibaba.nacos.api.PropertyKeyConst.NAMESPACE;
-import static com.alibaba.nacos.api.PropertyKeyConst.NAMING_CLIENT_BEAT_THREAD_COUNT;
-import static com.alibaba.nacos.api.PropertyKeyConst.NAMING_LOAD_CACHE_AT_START;
-import static com.alibaba.nacos.api.PropertyKeyConst.NAMING_POLLING_THREAD_COUNT;
-import static com.alibaba.nacos.api.PropertyKeyConst.RAM_ROLE_NAME;
-import static com.alibaba.nacos.api.PropertyKeyConst.SECRET_KEY;
-import static com.alibaba.nacos.api.PropertyKeyConst.SERVER_ADDR;
-import static com.alibaba.nacos.api.common.Constants.DEFAULT_GROUP;
-import static com.alibaba.nacos.client.naming.utils.UtilAndComs.NACOS_NAMING_LOG_NAME;
-import static org.apache.dubbo.common.constants.RemotingConstants.BACKUP_KEY;
-
-/**
- * The utilities class for {@link NamingService}
- *
- * @since 2.7.5
- */
-public class NacosNamingServiceUtils {
-
-    private static final Logger logger = LoggerFactory.getLogger(NacosNamingServiceUtils.class);
-
-    /**
-     * Convert the {@link ServiceInstance} to {@link Instance}
-     *
-     * @param serviceInstance {@link ServiceInstance}
-     * @return non-null
-     * @since 2.7.5
-     */
-    public static Instance toInstance(ServiceInstance serviceInstance) {
-        Instance instance = new Instance();
-        instance.setInstanceId(serviceInstance.getId());
-        instance.setServiceName(serviceInstance.getServiceName());
-        instance.setIp(serviceInstance.getHost());
-        instance.setPort(serviceInstance.getPort());
-        instance.setMetadata(serviceInstance.getMetadata());
-        instance.setEnabled(serviceInstance.isEnabled());
-        instance.setHealthy(serviceInstance.isHealthy());
-        return instance;
-    }
-
-    /**
-     * Convert the {@link Instance} to {@link ServiceInstance}
-     *
-     * @param instance {@link Instance}
-     * @return non-null
-     * @since 2.7.5
-     */
-    public static ServiceInstance toServiceInstance(Instance instance) {
-        DefaultServiceInstance serviceInstance = new DefaultServiceInstance(instance.getInstanceId(),
-                instance.getServiceName(), instance.getIp(), instance.getPort());
-        serviceInstance.setMetadata(instance.getMetadata());
-        serviceInstance.setEnabled(instance.isEnabled());
-        serviceInstance.setHealthy(instance.isHealthy());
-        return serviceInstance;
-    }
-
-    /**
-     * The group of {@link NamingService} to register
-     *
-     * @param connectionURL {@link URL connection url}
-     * @return non-null, "default" as default
-     * @since 2.7.5
-     */
-    public static String getGroup(URL connectionURL) {
-        return connectionURL.getParameter("nacos.group", DEFAULT_GROUP);
-    }
-
-    /**
-     * Create an instance of {@link NamingService} from specified {@link URL connection url}
-     *
-     * @param connectionURL {@link URL connection url}
-     * @return {@link NamingService}
-     * @since 2.7.5
-     */
-    public static NamingService createNamingService(URL connectionURL) {
-        Properties nacosProperties = buildNacosProperties(connectionURL);
-        NamingService namingService;
-        try {
-            namingService = NacosFactory.createNamingService(nacosProperties);
-        } catch (NacosException e) {
-            if (logger.isErrorEnabled()) {
-                logger.error(e.getErrMsg(), e);
-            }
-            throw new IllegalStateException(e);
-        }
-        return namingService;
-    }
-
-    private static Properties buildNacosProperties(URL url) {
-        Properties properties = new Properties();
-        setServerAddr(url, properties);
-        setProperties(url, properties);
-        return properties;
-    }
-
-    private static void setServerAddr(URL url, Properties properties) {
-        StringBuilder serverAddrBuilder =
-                new StringBuilder(url.getHost()) // Host
-                        .append(":")
-                        .append(url.getPort()); // Port
-
-        // Append backup parameter as other servers
-        String backup = url.getParameter(BACKUP_KEY);
-        if (backup != null) {
-            serverAddrBuilder.append(",").append(backup);
-        }
-
-        String serverAddr = serverAddrBuilder.toString();
-        properties.put(SERVER_ADDR, serverAddr);
-    }
-
-    private static void setProperties(URL url, Properties properties) {
-        putPropertyIfAbsent(url, properties, NACOS_NAMING_LOG_NAME);
-        putPropertyIfAbsent(url, properties, IS_USE_CLOUD_NAMESPACE_PARSING);
-        putPropertyIfAbsent(url, properties, IS_USE_ENDPOINT_PARSING_RULE);
-        putPropertyIfAbsent(url, properties, ENDPOINT);
-        putPropertyIfAbsent(url, properties, ENDPOINT_PORT);
-        putPropertyIfAbsent(url, properties, NAMESPACE);
-        putPropertyIfAbsent(url, properties, ACCESS_KEY);
-        putPropertyIfAbsent(url, properties, SECRET_KEY);
-        putPropertyIfAbsent(url, properties, RAM_ROLE_NAME);
-        putPropertyIfAbsent(url, properties, CONTEXT_PATH);
-        putPropertyIfAbsent(url, properties, CLUSTER_NAME);
-        putPropertyIfAbsent(url, properties, ENCODE);
-        putPropertyIfAbsent(url, properties, CONFIG_LONG_POLL_TIMEOUT);
-        putPropertyIfAbsent(url, properties, CONFIG_RETRY_TIME);
-        putPropertyIfAbsent(url, properties, MAX_RETRY);
-        putPropertyIfAbsent(url, properties, ENABLE_REMOTE_SYNC_CONFIG);
-        putPropertyIfAbsent(url, properties, NAMING_LOAD_CACHE_AT_START, "true");
-        putPropertyIfAbsent(url, properties, NAMING_CLIENT_BEAT_THREAD_COUNT);
-        putPropertyIfAbsent(url, properties, NAMING_POLLING_THREAD_COUNT);
-    }
-
-    private static void putPropertyIfAbsent(URL url, Properties properties, String propertyName) {
-        String propertyValue = url.getParameter(propertyName);
-        if (StringUtils.isNotEmpty(propertyValue)) {
-            properties.setProperty(propertyName, propertyValue);
-        }
-    }
-
-    private static void putPropertyIfAbsent(URL url, Properties properties, String propertyName, String defaultValue) {
-        String propertyValue = url.getParameter(propertyName);
-        if (StringUtils.isNotEmpty(propertyValue)) {
-            properties.setProperty(propertyName, propertyValue);
-        } else {
-            properties.setProperty(propertyName, defaultValue);
-        }
-    }
-}
diff --git a/dubbo-spi-registry/dubbo-registry-nacos/src/main/resources/META-INF/dubbo/internal/org.apache.dubbo.registry.RegistryFactory b/dubbo-spi-registry/dubbo-registry-nacos/src/main/resources/META-INF/dubbo/internal/org.apache.dubbo.registry.RegistryFactory
deleted file mode 100644
index bb75467..0000000
--- a/dubbo-spi-registry/dubbo-registry-nacos/src/main/resources/META-INF/dubbo/internal/org.apache.dubbo.registry.RegistryFactory
+++ /dev/null
@@ -1 +0,0 @@
-nacos=org.apache.dubbo.registry.nacos.NacosRegistryFactory
\ No newline at end of file
diff --git a/dubbo-spi-registry/dubbo-registry-nacos/src/main/resources/META-INF/dubbo/internal/org.apache.dubbo.registry.client.ServiceDiscovery b/dubbo-spi-registry/dubbo-registry-nacos/src/main/resources/META-INF/dubbo/internal/org.apache.dubbo.registry.client.ServiceDiscovery
deleted file mode 100644
index e3819e0..0000000
--- a/dubbo-spi-registry/dubbo-registry-nacos/src/main/resources/META-INF/dubbo/internal/org.apache.dubbo.registry.client.ServiceDiscovery
+++ /dev/null
@@ -1 +0,0 @@
-nacos=org.apache.dubbo.registry.nacos.NacosServiceDiscovery
\ No newline at end of file
diff --git a/dubbo-spi-registry/pom.xml b/dubbo-spi-registry/pom.xml
index d34c24b..c4e4ca7 100644
--- a/dubbo-spi-registry/pom.xml
+++ b/dubbo-spi-registry/pom.xml
@@ -33,8 +33,6 @@
         <module>dubbo-registry-redis</module>
         <module>dubbo-registry-consul</module>
         <module>dubbo-registry-etcd3</module>
-        <module>dubbo-registry-nacos</module>
-        <module>dubbo-registry-multiple</module>
         <module>dubbo-registry-sofa</module>
         <module>dubbo-registry-eureka</module>
     </modules>
diff --git a/dubbo-spi-remoting/dubbo-remoting-zookeeper/pom.xml b/dubbo-spi-remoting/dubbo-remoting-zookeeper/pom.xml
deleted file mode 100644
index d17713c..0000000
--- a/dubbo-spi-remoting/dubbo-remoting-zookeeper/pom.xml
+++ /dev/null
@@ -1,56 +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.
--->
-<project xmlns="http://maven.apache.org/POM/4.0.0" xmlns:xsi="http://www.w3.org/2001/XMLSchema-instance" xsi:schemaLocation="http://maven.apache.org/POM/4.0.0 http://maven.apache.org/maven-v4_0_0.xsd">
-    <modelVersion>4.0.0</modelVersion>
-    <parent>
-        <groupId>org.apache.dubbo</groupId>
-        <artifactId>dubbo-remoting</artifactId>
-        <version>2.7.7-SNAPSHOT</version>
-    </parent>
-    <artifactId>dubbo-remoting-zookeeper</artifactId>
-    <packaging>jar</packaging>
-    <name>${project.artifactId}</name>
-    <description>The zookeeper remoting module of dubbo project</description>
-    <properties>
-        <skip_maven_deploy>false</skip_maven_deploy>
-    </properties>
-    <dependencies>
-        <dependency>
-            <groupId>org.apache.dubbo</groupId>
-            <artifactId>dubbo-remoting-api</artifactId>
-            <version>${project.parent.version}</version>
-        </dependency>
-        <dependency>
-            <groupId>org.apache.dubbo</groupId>
-            <artifactId>dubbo-common</artifactId>
-            <version>${project.parent.version}</version>
-        </dependency>
-        <dependency>
-            <groupId>org.apache.curator</groupId>
-            <artifactId>curator-recipes</artifactId>
-        </dependency>
-        <dependency>
-            <groupId>org.apache.zookeeper</groupId>
-            <artifactId>zookeeper</artifactId>
-        </dependency>
-        <dependency>
-            <groupId>org.apache.curator</groupId>
-            <artifactId>curator-test</artifactId>
-            <scope>test</scope>
-        </dependency>
-    </dependencies>
-</project>
diff --git a/dubbo-spi-remoting/dubbo-remoting-zookeeper/src/main/java/org/apache/dubbo/remoting/zookeeper/ChildListener.java b/dubbo-spi-remoting/dubbo-remoting-zookeeper/src/main/java/org/apache/dubbo/remoting/zookeeper/ChildListener.java
deleted file mode 100644
index 0e876af..0000000
--- a/dubbo-spi-remoting/dubbo-remoting-zookeeper/src/main/java/org/apache/dubbo/remoting/zookeeper/ChildListener.java
+++ /dev/null
@@ -1,25 +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.remoting.zookeeper;
-
-import java.util.List;
-
-public interface ChildListener {
-
-    void childChanged(String path, List<String> children);
-
-}
diff --git a/dubbo-spi-remoting/dubbo-remoting-zookeeper/src/main/java/org/apache/dubbo/remoting/zookeeper/DataListener.java b/dubbo-spi-remoting/dubbo-remoting-zookeeper/src/main/java/org/apache/dubbo/remoting/zookeeper/DataListener.java
deleted file mode 100644
index 95b948a..0000000
--- a/dubbo-spi-remoting/dubbo-remoting-zookeeper/src/main/java/org/apache/dubbo/remoting/zookeeper/DataListener.java
+++ /dev/null
@@ -1,25 +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.remoting.zookeeper;
-
-/**
- * 2019-02-26
- */
-public interface DataListener {
-
-    void dataChanged(String path, Object value, EventType eventType);
-}
diff --git a/dubbo-spi-remoting/dubbo-remoting-zookeeper/src/main/java/org/apache/dubbo/remoting/zookeeper/EventType.java b/dubbo-spi-remoting/dubbo-remoting-zookeeper/src/main/java/org/apache/dubbo/remoting/zookeeper/EventType.java
deleted file mode 100644
index a1de037..0000000
--- a/dubbo-spi-remoting/dubbo-remoting-zookeeper/src/main/java/org/apache/dubbo/remoting/zookeeper/EventType.java
+++ /dev/null
@@ -1,65 +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.remoting.zookeeper;
-
-import org.apache.zookeeper.Watcher;
-
-/**
- * 2019-02-26
- */
-public enum EventType {
-    None(-1),
-    NodeCreated(1),
-    NodeDeleted(2),
-    NodeDataChanged(3),
-    NodeChildrenChanged(4),
-    CONNECTION_SUSPENDED(11),
-    CONNECTION_RECONNECTED(12),
-    CONNECTION_LOST(12),
-    INITIALIZED(10);
-
-
-
-    private final int intValue;     // Integer representation of value
-    // for sending over wire
-
-    EventType(int intValue) {
-        this.intValue = intValue;
-    }
-
-    public int getIntValue() {
-        return intValue;
-    }
-
-    public static Watcher.Event.EventType fromInt(int intValue) {
-        switch (intValue) {
-            case -1:
-                return Watcher.Event.EventType.None;
-            case 1:
-                return Watcher.Event.EventType.NodeCreated;
-            case 2:
-                return Watcher.Event.EventType.NodeDeleted;
-            case 3:
-                return Watcher.Event.EventType.NodeDataChanged;
-            case 4:
-                return Watcher.Event.EventType.NodeChildrenChanged;
-
-            default:
-                throw new RuntimeException("Invalid integer value for conversion to EventType");
-        }
-    }
-}
diff --git a/dubbo-spi-remoting/dubbo-remoting-zookeeper/src/main/java/org/apache/dubbo/remoting/zookeeper/StateListener.java b/dubbo-spi-remoting/dubbo-remoting-zookeeper/src/main/java/org/apache/dubbo/remoting/zookeeper/StateListener.java
deleted file mode 100644
index ca4dbe0..0000000
--- a/dubbo-spi-remoting/dubbo-remoting-zookeeper/src/main/java/org/apache/dubbo/remoting/zookeeper/StateListener.java
+++ /dev/null
@@ -1,33 +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.remoting.zookeeper;
-
-public interface StateListener {
-
-    int SESSION_LOST = 0;
-
-    int CONNECTED = 1;
-
-    int RECONNECTED = 2;
-
-    int SUSPENDED = 3;
-
-    int NEW_SESSION_CREATED = 4;
-
-    void stateChanged(int connected);
-
-}
diff --git a/dubbo-spi-remoting/dubbo-remoting-zookeeper/src/main/java/org/apache/dubbo/remoting/zookeeper/ZookeeperClient.java b/dubbo-spi-remoting/dubbo-remoting-zookeeper/src/main/java/org/apache/dubbo/remoting/zookeeper/ZookeeperClient.java
deleted file mode 100644
index cbb3747..0000000
--- a/dubbo-spi-remoting/dubbo-remoting-zookeeper/src/main/java/org/apache/dubbo/remoting/zookeeper/ZookeeperClient.java
+++ /dev/null
@@ -1,65 +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.remoting.zookeeper;
-
-import org.apache.dubbo.common.URL;
-
-import java.util.List;
-import java.util.concurrent.Executor;
-
-public interface ZookeeperClient {
-
-    void create(String path, boolean ephemeral);
-
-    void delete(String path);
-
-    List<String> getChildren(String path);
-
-    List<String> addChildListener(String path, ChildListener listener);
-
-    /**
-     * @param path:    directory. All of child of path will be listened.
-     * @param listener
-     */
-    void addDataListener(String path, DataListener listener);
-
-    /**
-     * @param path:    directory. All of child of path will be listened.
-     * @param listener
-     * @param executor another thread
-     */
-    void addDataListener(String path, DataListener listener, Executor executor);
-
-    void removeDataListener(String path, DataListener listener);
-
-    void removeChildListener(String path, ChildListener listener);
-
-    void addStateListener(StateListener listener);
-
-    void removeStateListener(StateListener listener);
-
-    boolean isConnected();
-
-    void close();
-
-    URL getUrl();
-
-    void create(String path, String content, boolean ephemeral);
-
-    String getContent(String path);
-
-}
diff --git a/dubbo-spi-remoting/dubbo-remoting-zookeeper/src/main/java/org/apache/dubbo/remoting/zookeeper/ZookeeperTransporter.java b/dubbo-spi-remoting/dubbo-remoting-zookeeper/src/main/java/org/apache/dubbo/remoting/zookeeper/ZookeeperTransporter.java
deleted file mode 100644
index 638f3ed..0000000
--- a/dubbo-spi-remoting/dubbo-remoting-zookeeper/src/main/java/org/apache/dubbo/remoting/zookeeper/ZookeeperTransporter.java
+++ /dev/null
@@ -1,30 +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.remoting.zookeeper;
-
-import org.apache.dubbo.common.URL;
-import org.apache.dubbo.common.extension.Adaptive;
-import org.apache.dubbo.common.extension.SPI;
-import org.apache.dubbo.remoting.Constants;
-
-@SPI("curator")
-public interface ZookeeperTransporter {
-
-    @Adaptive({Constants.CLIENT_KEY, Constants.TRANSPORTER_KEY})
-    ZookeeperClient connect(URL url);
-
-}
diff --git a/dubbo-spi-remoting/dubbo-remoting-zookeeper/src/main/java/org/apache/dubbo/remoting/zookeeper/curator/CuratorZookeeperClient.java b/dubbo-spi-remoting/dubbo-remoting-zookeeper/src/main/java/org/apache/dubbo/remoting/zookeeper/curator/CuratorZookeeperClient.java
deleted file mode 100644
index e830e11..0000000
--- a/dubbo-spi-remoting/dubbo-remoting-zookeeper/src/main/java/org/apache/dubbo/remoting/zookeeper/curator/CuratorZookeeperClient.java
+++ /dev/null
@@ -1,398 +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.remoting.zookeeper.curator;
-
-import org.apache.dubbo.common.URL;
-import org.apache.dubbo.common.logger.Logger;
-import org.apache.dubbo.common.logger.LoggerFactory;
-import org.apache.dubbo.remoting.zookeeper.ChildListener;
-import org.apache.dubbo.remoting.zookeeper.DataListener;
-import org.apache.dubbo.remoting.zookeeper.EventType;
-import org.apache.dubbo.remoting.zookeeper.StateListener;
-import org.apache.dubbo.remoting.zookeeper.support.AbstractZookeeperClient;
-
-import org.apache.curator.framework.CuratorFramework;
-import org.apache.curator.framework.CuratorFrameworkFactory;
-import org.apache.curator.framework.api.CuratorWatcher;
-import org.apache.curator.framework.recipes.cache.TreeCache;
-import org.apache.curator.framework.recipes.cache.TreeCacheEvent;
-import org.apache.curator.framework.recipes.cache.TreeCacheListener;
-import org.apache.curator.framework.state.ConnectionState;
-import org.apache.curator.framework.state.ConnectionStateListener;
-import org.apache.curator.retry.RetryNTimes;
-import org.apache.zookeeper.CreateMode;
-import org.apache.zookeeper.KeeperException.NoNodeException;
-import org.apache.zookeeper.KeeperException.NodeExistsException;
-import org.apache.zookeeper.WatchedEvent;
-import org.apache.zookeeper.Watcher;
-
-import java.nio.charset.Charset;
-import java.util.List;
-import java.util.Map;
-import java.util.concurrent.ConcurrentHashMap;
-import java.util.concurrent.Executor;
-import java.util.concurrent.TimeUnit;
-
-import static org.apache.dubbo.common.constants.CommonConstants.TIMEOUT_KEY;
-
-public class CuratorZookeeperClient extends AbstractZookeeperClient<CuratorZookeeperClient.CuratorWatcherImpl, CuratorZookeeperClient.CuratorWatcherImpl> {
-
-    protected static final Logger logger = LoggerFactory.getLogger(CuratorZookeeperClient.class);
-    private static final String ZK_SESSION_EXPIRE_KEY = "zk.session.expire";
-
-    static final Charset CHARSET = Charset.forName("UTF-8");
-    private final CuratorFramework client;
-    private Map<String, TreeCache> treeCacheMap = new ConcurrentHashMap<>();
-
-    public CuratorZookeeperClient(URL url) {
-        super(url);
-        try {
-            int timeout = url.getParameter(TIMEOUT_KEY, DEFAULT_CONNECTION_TIMEOUT_MS);
-            int sessionExpireMs = url.getParameter(ZK_SESSION_EXPIRE_KEY, DEFAULT_SESSION_TIMEOUT_MS);
-            CuratorFrameworkFactory.Builder builder = CuratorFrameworkFactory.builder()
-                    .connectString(url.getBackupAddress())
-                    .retryPolicy(new RetryNTimes(1, 1000))
-                    .connectionTimeoutMs(timeout)
-                    .sessionTimeoutMs(sessionExpireMs);
-            String authority = url.getAuthority();
-            if (authority != null && authority.length() > 0) {
-                builder = builder.authorization("digest", authority.getBytes());
-            }
-            client = builder.build();
-            client.getConnectionStateListenable().addListener(new CuratorConnectionStateListener(url));
-            client.start();
-            boolean connected = client.blockUntilConnected(timeout, TimeUnit.MILLISECONDS);
-            if (!connected) {
-                throw new IllegalStateException("zookeeper not connected");
-            }
-        } catch (Exception e) {
-            throw new IllegalStateException(e.getMessage(), e);
-        }
-    }
-
-    @Override
-    public void createPersistent(String path) {
-        try {
-            client.create().forPath(path);
-        } catch (NodeExistsException e) {
-            logger.warn("ZNode " + path + " already exists.", e);
-        } catch (Exception e) {
-            throw new IllegalStateException(e.getMessage(), e);
-        }
-    }
-
-    @Override
-    public void createEphemeral(String path) {
-        try {
-            client.create().withMode(CreateMode.EPHEMERAL).forPath(path);
-        } catch (NodeExistsException e) {
-            logger.warn("ZNode " + path + " already exists, since we will only try to recreate a node on a session expiration" +
-                    ", this duplication might be caused by a delete delay from the zk server, which means the old expired session" +
-                    " may still holds this ZNode and the server just hasn't got time to do the deletion. In this case, " +
-                    "we can just try to delete and create again.", e);
-            deletePath(path);
-            createEphemeral(path);
-        } catch (Exception e) {
-            throw new IllegalStateException(e.getMessage(), e);
-        }
-    }
-
-    @Override
-    protected void createPersistent(String path, String data) {
-        byte[] dataBytes = data.getBytes(CHARSET);
-        try {
-            client.create().forPath(path, dataBytes);
-        } catch (NodeExistsException e) {
-            try {
-                client.setData().forPath(path, dataBytes);
-            } catch (Exception e1) {
-                throw new IllegalStateException(e.getMessage(), e1);
-            }
-        } catch (Exception e) {
-            throw new IllegalStateException(e.getMessage(), e);
-        }
-    }
-
-    @Override
-    protected void createEphemeral(String path, String data) {
-        byte[] dataBytes = data.getBytes(CHARSET);
-        try {
-            client.create().withMode(CreateMode.EPHEMERAL).forPath(path, dataBytes);
-        } catch (NodeExistsException e) {
-            logger.warn("ZNode " + path + " already exists, since we will only try to recreate a node on a session expiration" +
-                    ", this duplication might be caused by a delete delay from the zk server, which means the old expired session" +
-                    " may still holds this ZNode and the server just hasn't got time to do the deletion. In this case, " +
-                    "we can just try to delete and create again.", e);
-            deletePath(path);
-            createEphemeral(path, data);
-        } catch (Exception e) {
-            throw new IllegalStateException(e.getMessage(), e);
-        }
-    }
-
-    @Override
-    protected void deletePath(String path) {
-        try {
-            client.delete().deletingChildrenIfNeeded().forPath(path);
-        } catch (NoNodeException e) {
-        } catch (Exception e) {
-            throw new IllegalStateException(e.getMessage(), e);
-        }
-    }
-
-    @Override
-    public List<String> getChildren(String path) {
-        try {
-            return client.getChildren().forPath(path);
-        } catch (NoNodeException e) {
-            return null;
-        } catch (Exception e) {
-            throw new IllegalStateException(e.getMessage(), e);
-        }
-    }
-
-    @Override
-    public boolean checkExists(String path) {
-        try {
-            if (client.checkExists().forPath(path) != null) {
-                return true;
-            }
-        } catch (Exception e) {
-        }
-        return false;
-    }
-
-    @Override
-    public boolean isConnected() {
-        return client.getZookeeperClient().isConnected();
-    }
-
-    @Override
-    public String doGetContent(String path) {
-        try {
-            byte[] dataBytes = client.getData().forPath(path);
-            return (dataBytes == null || dataBytes.length == 0) ? null : new String(dataBytes, CHARSET);
-        } catch (NoNodeException e) {
-            // ignore NoNode Exception.
-        } catch (Exception e) {
-            throw new IllegalStateException(e.getMessage(), e);
-        }
-        return null;
-    }
-
-    @Override
-    public void doClose() {
-        client.close();
-    }
-
-    @Override
-    public CuratorZookeeperClient.CuratorWatcherImpl createTargetChildListener(String path, ChildListener listener) {
-        return new CuratorZookeeperClient.CuratorWatcherImpl(client, listener, path);
-    }
-
-    @Override
-    public List<String> addTargetChildListener(String path, CuratorWatcherImpl listener) {
-        try {
-            return client.getChildren().usingWatcher(listener).forPath(path);
-        } catch (NoNodeException e) {
-            return null;
-        } catch (Exception e) {
-            throw new IllegalStateException(e.getMessage(), e);
-        }
-    }
-
-    @Override
-    protected CuratorZookeeperClient.CuratorWatcherImpl createTargetDataListener(String path, DataListener listener) {
-        return new CuratorWatcherImpl(client, listener);
-    }
-
-    @Override
-    protected void addTargetDataListener(String path, CuratorZookeeperClient.CuratorWatcherImpl treeCacheListener) {
-        this.addTargetDataListener(path, treeCacheListener, null);
-    }
-
-    @Override
-    protected void addTargetDataListener(String path, CuratorZookeeperClient.CuratorWatcherImpl treeCacheListener, Executor executor) {
-        try {
-            TreeCache treeCache = TreeCache.newBuilder(client, path).setCacheData(false).build();
-            treeCacheMap.putIfAbsent(path, treeCache);
-
-            if (executor == null) {
-                treeCache.getListenable().addListener(treeCacheListener);
-            } else {
-                treeCache.getListenable().addListener(treeCacheListener, executor);
-            }
-
-            treeCache.start();
-        } catch (Exception e) {
-            throw new IllegalStateException("Add treeCache listener for path:" + path, e);
-        }
-    }
-
-    @Override
-    protected void removeTargetDataListener(String path, CuratorZookeeperClient.CuratorWatcherImpl treeCacheListener) {
-        TreeCache treeCache = treeCacheMap.get(path);
-        if (treeCache != null) {
-            treeCache.getListenable().removeListener(treeCacheListener);
-        }
-        treeCacheListener.dataListener = null;
-    }
-
-    @Override
-    public void removeTargetChildListener(String path, CuratorWatcherImpl listener) {
-        listener.unwatch();
-    }
-
-    static class CuratorWatcherImpl implements CuratorWatcher, TreeCacheListener {
-
-        private CuratorFramework client;
-        private volatile ChildListener childListener;
-        private volatile DataListener dataListener;
-        private String path;
-
-        public CuratorWatcherImpl(CuratorFramework client, ChildListener listener, String path) {
-            this.client = client;
-            this.childListener = listener;
-            this.path = path;
-        }
-
-        public CuratorWatcherImpl(CuratorFramework client, DataListener dataListener) {
-            this.dataListener = dataListener;
-        }
-
-        protected CuratorWatcherImpl() {
-        }
-
-        public void unwatch() {
-            this.childListener = null;
-        }
-
-        @Override
-        public void process(WatchedEvent event) throws Exception {
-            // if client connect or disconnect to server, zookeeper will queue
-            // watched event(Watcher.Event.EventType.None, .., path = null).
-            if (event.getType() == Watcher.Event.EventType.None) {
-                return;
-            }
-
-            if (childListener != null) {
-                childListener.childChanged(path, client.getChildren().usingWatcher(this).forPath(path));
-            }
-        }
-
-        @Override
-        public void childEvent(CuratorFramework client, TreeCacheEvent event) throws Exception {
-            if (dataListener != null) {
-                if (logger.isDebugEnabled()) {
-                    logger.debug("listen the zookeeper changed. The changed data:" + event.getData());
-                }
-                TreeCacheEvent.Type type = event.getType();
-                EventType eventType = null;
-                String content = null;
-                String path = null;
-                switch (type) {
-                    case NODE_ADDED:
-                        eventType = EventType.NodeCreated;
-                        path = event.getData().getPath();
-                        content = event.getData().getData() == null ? "" : new String(event.getData().getData(), CHARSET);
-                        break;
-                    case NODE_UPDATED:
-                        eventType = EventType.NodeDataChanged;
-                        path = event.getData().getPath();
-                        content = event.getData().getData() == null ? "" : new String(event.getData().getData(), CHARSET);
-                        break;
-                    case NODE_REMOVED:
-                        path = event.getData().getPath();
-                        eventType = EventType.NodeDeleted;
-                        break;
-                    case INITIALIZED:
-                        eventType = EventType.INITIALIZED;
-                        break;
-                    case CONNECTION_LOST:
-                        eventType = EventType.CONNECTION_LOST;
-                        break;
-                    case CONNECTION_RECONNECTED:
-                        eventType = EventType.CONNECTION_RECONNECTED;
-                        break;
-                    case CONNECTION_SUSPENDED:
-                        eventType = EventType.CONNECTION_SUSPENDED;
-                        break;
-
-                }
-                dataListener.dataChanged(path, content, eventType);
-            }
-        }
-    }
-
-    private class CuratorConnectionStateListener implements ConnectionStateListener {
-        private final long UNKNOWN_SESSION_ID = -1L;
-
-        private long lastSessionId;
-        private URL url;
-
-        public CuratorConnectionStateListener(URL url) {
-            this.url = url;
-        }
-
-        @Override
-        public void stateChanged(CuratorFramework client, ConnectionState state) {
-            int timeout = url.getParameter(TIMEOUT_KEY, DEFAULT_CONNECTION_TIMEOUT_MS);
-            int sessionExpireMs = url.getParameter(ZK_SESSION_EXPIRE_KEY, DEFAULT_SESSION_TIMEOUT_MS);
-
-            long sessionId = UNKNOWN_SESSION_ID;
-            try {
-                sessionId = client.getZookeeperClient().getZooKeeper().getSessionId();
-            } catch (Exception e) {
-                logger.warn("Curator client state changed, but failed to get the related zk session instance.");
-            }
-
-            if (state == ConnectionState.LOST) {
-                logger.warn("Curator zookeeper session " + Long.toHexString(lastSessionId) + " expired.");
-                CuratorZookeeperClient.this.stateChanged(StateListener.SESSION_LOST);
-            } else if (state == ConnectionState.SUSPENDED) {
-                logger.warn("Curator zookeeper connection of session " + Long.toHexString(sessionId) + " timed out. " +
-                        "connection timeout value is " + timeout + ", session expire timeout value is " + sessionExpireMs);
-                CuratorZookeeperClient.this.stateChanged(StateListener.SUSPENDED);
-            } else if (state == ConnectionState.CONNECTED) {
-                lastSessionId = sessionId;
-                logger.info("Curator zookeeper client instance initiated successfully, session id is " + Long.toHexString(sessionId));
-                CuratorZookeeperClient.this.stateChanged(StateListener.CONNECTED);
-            } else if (state == ConnectionState.RECONNECTED) {
-                if (lastSessionId == sessionId && sessionId != UNKNOWN_SESSION_ID) {
-                    logger.warn("Curator zookeeper connection recovered from connection lose, " +
-                            "reuse the old session " + Long.toHexString(sessionId));
-                    CuratorZookeeperClient.this.stateChanged(StateListener.RECONNECTED);
-                } else {
-                    logger.warn("New session created after old session lost, " +
-                            "old session " + Long.toHexString(lastSessionId) + ", new session " + Long.toHexString(sessionId));
-                    lastSessionId = sessionId;
-                    CuratorZookeeperClient.this.stateChanged(StateListener.NEW_SESSION_CREATED);
-                }
-            }
-        }
-
-    }
-
-    /**
-     * just for unit test
-     *
-     * @return
-     */
-    CuratorFramework getClient() {
-        return client;
-    }
-}
diff --git a/dubbo-spi-remoting/dubbo-remoting-zookeeper/src/main/java/org/apache/dubbo/remoting/zookeeper/curator/CuratorZookeeperTransporter.java b/dubbo-spi-remoting/dubbo-remoting-zookeeper/src/main/java/org/apache/dubbo/remoting/zookeeper/curator/CuratorZookeeperTransporter.java
deleted file mode 100644
index 21a2e09..0000000
--- a/dubbo-spi-remoting/dubbo-remoting-zookeeper/src/main/java/org/apache/dubbo/remoting/zookeeper/curator/CuratorZookeeperTransporter.java
+++ /dev/null
@@ -1,30 +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.remoting.zookeeper.curator;
-
-import org.apache.dubbo.common.URL;
-import org.apache.dubbo.remoting.zookeeper.ZookeeperClient;
-import org.apache.dubbo.remoting.zookeeper.support.AbstractZookeeperTransporter;
-
-public class CuratorZookeeperTransporter extends AbstractZookeeperTransporter {
-    @Override
-    public ZookeeperClient createZookeeperClient(URL url) {
-        return new CuratorZookeeperClient(url);
-    }
-
-
-}
diff --git a/dubbo-spi-remoting/dubbo-remoting-zookeeper/src/main/java/org/apache/dubbo/remoting/zookeeper/support/AbstractZookeeperClient.java b/dubbo-spi-remoting/dubbo-remoting-zookeeper/src/main/java/org/apache/dubbo/remoting/zookeeper/support/AbstractZookeeperClient.java
deleted file mode 100644
index d17697c..0000000
--- a/dubbo-spi-remoting/dubbo-remoting-zookeeper/src/main/java/org/apache/dubbo/remoting/zookeeper/support/AbstractZookeeperClient.java
+++ /dev/null
@@ -1,226 +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.remoting.zookeeper.support;
-
-import org.apache.dubbo.common.URL;
-import org.apache.dubbo.common.logger.Logger;
-import org.apache.dubbo.common.logger.LoggerFactory;
-import org.apache.dubbo.common.utils.ConcurrentHashSet;
-import org.apache.dubbo.remoting.zookeeper.ChildListener;
-import org.apache.dubbo.remoting.zookeeper.DataListener;
-import org.apache.dubbo.remoting.zookeeper.StateListener;
-import org.apache.dubbo.remoting.zookeeper.ZookeeperClient;
-
-import java.util.List;
-import java.util.Set;
-import java.util.concurrent.ConcurrentHashMap;
-import java.util.concurrent.ConcurrentMap;
-import java.util.concurrent.CopyOnWriteArraySet;
-import java.util.concurrent.Executor;
-
-public abstract class AbstractZookeeperClient<TargetDataListener, TargetChildListener> implements ZookeeperClient {
-
-    protected static final Logger logger = LoggerFactory.getLogger(AbstractZookeeperClient.class);
-
-    protected int DEFAULT_CONNECTION_TIMEOUT_MS = 5 * 1000;
-    protected int DEFAULT_SESSION_TIMEOUT_MS = 60 * 1000;
-
-    private final URL url;
-
-    private final Set<StateListener> stateListeners = new CopyOnWriteArraySet<StateListener>();
-
-    private final ConcurrentMap<String, ConcurrentMap<ChildListener, TargetChildListener>> childListeners = new ConcurrentHashMap<String, ConcurrentMap<ChildListener, TargetChildListener>>();
-
-    private final ConcurrentMap<String, ConcurrentMap<DataListener, TargetDataListener>> listeners = new ConcurrentHashMap<String, ConcurrentMap<DataListener, TargetDataListener>>();
-
-    private volatile boolean closed = false;
-
-    private final Set<String>  persistentExistNodePath = new ConcurrentHashSet<>();
-
-    public AbstractZookeeperClient(URL url) {
-        this.url = url;
-    }
-
-    @Override
-    public URL getUrl() {
-        return url;
-    }
-
-    @Override
-    public void delete(String path){
-        //never mind if ephemeral
-        persistentExistNodePath.remove(path);
-        deletePath(path);
-    }
-
-
-    @Override
-    public void create(String path, boolean ephemeral) {
-        if (!ephemeral) {
-            if(persistentExistNodePath.contains(path)){
-                return;
-            }
-            if (checkExists(path)) {
-                persistentExistNodePath.add(path);
-                return;
-            }
-        }
-        int i = path.lastIndexOf('/');
-        if (i > 0) {
-            create(path.substring(0, i), false);
-        }
-        if (ephemeral) {
-            createEphemeral(path);
-        } else {
-            createPersistent(path);
-            persistentExistNodePath.add(path);
-        }
-    }
-
-    @Override
-    public void addStateListener(StateListener listener) {
-        stateListeners.add(listener);
-    }
-
-    @Override
-    public void removeStateListener(StateListener listener) {
-        stateListeners.remove(listener);
-    }
-
-    public Set<StateListener> getSessionListeners() {
-        return stateListeners;
-    }
-
-    @Override
-    public List<String> addChildListener(String path, final ChildListener listener) {
-        ConcurrentMap<ChildListener, TargetChildListener> listeners = childListeners.computeIfAbsent(path, k -> new ConcurrentHashMap<>());
-        TargetChildListener targetListener = listeners.computeIfAbsent(listener, k -> createTargetChildListener(path, k));
-        return addTargetChildListener(path, targetListener);
-    }
-
-    @Override
-    public void addDataListener(String path, DataListener listener) {
-        this.addDataListener(path, listener, null);
-    }
-
-    @Override
-    public void addDataListener(String path, DataListener listener, Executor executor) {
-        ConcurrentMap<DataListener, TargetDataListener> dataListenerMap = listeners.computeIfAbsent(path, k -> new ConcurrentHashMap<>());
-        TargetDataListener targetListener = dataListenerMap.computeIfAbsent(listener, k -> createTargetDataListener(path, k));
-        addTargetDataListener(path, targetListener, executor);
-    }
-
-    @Override
-    public void removeDataListener(String path, DataListener listener ){
-        ConcurrentMap<DataListener, TargetDataListener> dataListenerMap = listeners.get(path);
-        if (dataListenerMap != null) {
-            TargetDataListener targetListener = dataListenerMap.remove(listener);
-            if(targetListener != null){
-                removeTargetDataListener(path, targetListener);
-            }
-        }
-    }
-
-    @Override
-    public void removeChildListener(String path, ChildListener listener) {
-        ConcurrentMap<ChildListener, TargetChildListener> listeners = childListeners.get(path);
-        if (listeners != null) {
-            TargetChildListener targetListener = listeners.remove(listener);
-            if (targetListener != null) {
-                removeTargetChildListener(path, targetListener);
-            }
-        }
-    }
-
-    protected void stateChanged(int state) {
-        for (StateListener sessionListener : getSessionListeners()) {
-            sessionListener.stateChanged(state);
-        }
-    }
-
-    @Override
-    public void close() {
-        if (closed) {
-            return;
-        }
-        closed = true;
-        try {
-            doClose();
-        } catch (Throwable t) {
-            logger.warn(t.getMessage(), t);
-        }
-    }
-
-    @Override
-    public void create(String path, String content, boolean ephemeral) {
-        if (checkExists(path)) {
-            delete(path);
-        }
-        int i = path.lastIndexOf('/');
-        if (i > 0) {
-            create(path.substring(0, i), false);
-        }
-        if (ephemeral) {
-            createEphemeral(path, content);
-        } else {
-            createPersistent(path, content);
-        }
-    }
-
-    @Override
-    public String getContent(String path) {
-        if (!checkExists(path)) {
-            return null;
-        }
-        return doGetContent(path);
-    }
-
-    protected abstract void doClose();
-
-    protected abstract void createPersistent(String path);
-
-    protected abstract void createEphemeral(String path);
-
-    protected abstract void createPersistent(String path, String data);
-
-    protected abstract void createEphemeral(String path, String data);
-
-    protected abstract boolean checkExists(String path);
-
-    protected abstract TargetChildListener createTargetChildListener(String path, ChildListener listener);
-
-    protected abstract List<String> addTargetChildListener(String path, TargetChildListener listener);
-
-    protected abstract TargetDataListener createTargetDataListener(String path, DataListener listener);
-
-    protected abstract void addTargetDataListener(String path, TargetDataListener listener);
-
-    protected abstract void addTargetDataListener(String path, TargetDataListener listener, Executor executor);
-
-    protected abstract void removeTargetDataListener(String path, TargetDataListener listener);
-
-    protected abstract void removeTargetChildListener(String path, TargetChildListener listener);
-
-    protected abstract String doGetContent(String path);
-
-    /**
-     * we invoke the zookeeper client to delete the node
-     * @param path the node path
-     */
-    protected abstract void deletePath(String path);
-
-}
diff --git a/dubbo-spi-remoting/dubbo-remoting-zookeeper/src/main/java/org/apache/dubbo/remoting/zookeeper/support/AbstractZookeeperTransporter.java b/dubbo-spi-remoting/dubbo-remoting-zookeeper/src/main/java/org/apache/dubbo/remoting/zookeeper/support/AbstractZookeeperTransporter.java
deleted file mode 100644
index b861c15..0000000
--- a/dubbo-spi-remoting/dubbo-remoting-zookeeper/src/main/java/org/apache/dubbo/remoting/zookeeper/support/AbstractZookeeperTransporter.java
+++ /dev/null
@@ -1,182 +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.remoting.zookeeper.support;
-
-import org.apache.dubbo.common.URL;
-import org.apache.dubbo.common.constants.RemotingConstants;
-import org.apache.dubbo.common.logger.Logger;
-import org.apache.dubbo.common.logger.LoggerFactory;
-import org.apache.dubbo.common.utils.StringUtils;
-import org.apache.dubbo.remoting.zookeeper.ZookeeperClient;
-import org.apache.dubbo.remoting.zookeeper.ZookeeperTransporter;
-
-import java.util.ArrayList;
-import java.util.Collections;
-import java.util.HashMap;
-import java.util.List;
-import java.util.Map;
-import java.util.concurrent.ConcurrentHashMap;
-
-import static org.apache.dubbo.common.constants.CommonConstants.TIMEOUT_KEY;
-
-/**
- * AbstractZookeeperTransporter is abstract implements of ZookeeperTransporter.
- * <p>
- * If you want to extends this, implements createZookeeperClient.
- */
-public abstract class AbstractZookeeperTransporter implements ZookeeperTransporter {
-    private static final Logger logger = LoggerFactory.getLogger(ZookeeperTransporter.class);
-    private final Map<String, ZookeeperClient> zookeeperClientMap = new ConcurrentHashMap<>();
-
-    /**
-     * share connnect for registry, metadata, etc..
-     * <p>
-     * Make sure the connection is connected.
-     *
-     * @param url
-     * @return
-     */
-    @Override
-    public ZookeeperClient connect(URL url) {
-        ZookeeperClient zookeeperClient;
-        // address format: {[username:password@]address}
-        List<String> addressList = getURLBackupAddress(url);
-        // The field define the zookeeper server , including protocol, host, port, username, password
-        if ((zookeeperClient = fetchAndUpdateZookeeperClientCache(addressList)) != null && zookeeperClient.isConnected()) {
-            logger.info("find valid zookeeper client from the cache for address: " + url);
-            return zookeeperClient;
-        }
-        // avoid creating too many connections, so add lock
-        synchronized (zookeeperClientMap) {
-            if ((zookeeperClient = fetchAndUpdateZookeeperClientCache(addressList)) != null && zookeeperClient.isConnected()) {
-                logger.info("find valid zookeeper client from the cache for address: " + url);
-                return zookeeperClient;
-            }
-
-            zookeeperClient = createZookeeperClient(url);
-            logger.info("No valid zookeeper client found from cache, therefore create a new client for url. " + url);
-            writeToClientMap(addressList, zookeeperClient);
-        }
-        return zookeeperClient;
-    }
-
-    /**
-     * @param url the url that will create zookeeper connection .
-     *            The url in AbstractZookeeperTransporter#connect parameter is rewritten by this one.
-     *            such as: zookeeper://127.0.0.1:2181/org.apache.dubbo.remoting.zookeeper.ZookeeperTransporter
-     * @return
-     */
-    protected abstract ZookeeperClient createZookeeperClient(URL url);
-
-    /**
-     * get the ZookeeperClient from cache, the ZookeeperClient must be connected.
-     * <p>
-     * It is not private method for unit test.
-     *
-     * @param addressList
-     * @return
-     */
-    ZookeeperClient fetchAndUpdateZookeeperClientCache(List<String> addressList) {
-
-        ZookeeperClient zookeeperClient = null;
-        for (String address : addressList) {
-            if ((zookeeperClient = zookeeperClientMap.get(address)) != null && zookeeperClient.isConnected()) {
-                break;
-            }
-        }
-        if (zookeeperClient != null && zookeeperClient.isConnected()) {
-            writeToClientMap(addressList, zookeeperClient);
-        }
-        return zookeeperClient;
-    }
-
-    /**
-     * get all zookeeper urls (such as :zookeeper://127.0.0.1:2181?127.0.0.1:8989,127.0.0.1:9999)
-     *
-     * @param url such as:zookeeper://127.0.0.1:2181?127.0.0.1:8989,127.0.0.1:9999
-     * @return such as 127.0.0.1:2181,127.0.0.1:8989,127.0.0.1:9999
-     */
-    List<String> getURLBackupAddress(URL url) {
-        List<String> addressList = new ArrayList<String>();
-        addressList.add(url.getAddress());
-        addressList.addAll(url.getParameter(RemotingConstants.BACKUP_KEY, Collections.EMPTY_LIST));
-
-        String authPrefix = null;
-        if (StringUtils.isNotEmpty(url.getUsername())) {
-            StringBuilder buf = new StringBuilder();
-            buf.append(url.getUsername());
-            if (StringUtils.isNotEmpty(url.getPassword())) {
-                buf.append(":");
-                buf.append(url.getPassword());
-            }
-            buf.append("@");
-            authPrefix = buf.toString();
-        }
-
-        if (StringUtils.isNotEmpty(authPrefix)) {
-            List<String> authedAddressList = new ArrayList<>(addressList.size());
-            for (String addr : addressList) {
-                authedAddressList.add(authPrefix + addr);
-            }
-            return authedAddressList;
-        }
-
-
-        return addressList;
-    }
-
-    /**
-     * write address-ZookeeperClient relationship to Map
-     *
-     * @param addressList
-     * @param zookeeperClient
-     */
-    void writeToClientMap(List<String> addressList, ZookeeperClient zookeeperClient) {
-        for (String address : addressList) {
-            zookeeperClientMap.put(address, zookeeperClient);
-        }
-    }
-
-    /**
-     * redefine the url for zookeeper. just keep protocol, username, password, host, port, and individual parameter.
-     *
-     * @param url
-     * @return
-     */
-    URL toClientURL(URL url) {
-        Map<String, String> parameterMap = new HashMap<>();
-        // for CuratorZookeeperClient
-        if (url.getParameter(TIMEOUT_KEY) != null) {
-            parameterMap.put(TIMEOUT_KEY, url.getParameter(TIMEOUT_KEY));
-        }
-        if (url.getParameter(RemotingConstants.BACKUP_KEY) != null) {
-            parameterMap.put(RemotingConstants.BACKUP_KEY, url.getParameter(RemotingConstants.BACKUP_KEY));
-        }
-
-        return new URL(url.getProtocol(), url.getUsername(), url.getPassword(), url.getHost(), url.getPort(),
-                ZookeeperTransporter.class.getName(), parameterMap);
-    }
-
-    /**
-     * for unit test
-     *
-     * @return
-     */
-    Map<String, ZookeeperClient> getZookeeperClientMap() {
-        return zookeeperClientMap;
-    }
-}
diff --git a/dubbo-spi-remoting/dubbo-remoting-zookeeper/src/main/resources/META-INF/dubbo/internal/org.apache.dubbo.remoting.zookeeper.ZookeeperTransporter b/dubbo-spi-remoting/dubbo-remoting-zookeeper/src/main/resources/META-INF/dubbo/internal/org.apache.dubbo.remoting.zookeeper.ZookeeperTransporter
deleted file mode 100644
index 44f9374..0000000
--- a/dubbo-spi-remoting/dubbo-remoting-zookeeper/src/main/resources/META-INF/dubbo/internal/org.apache.dubbo.remoting.zookeeper.ZookeeperTransporter
+++ /dev/null
@@ -1 +0,0 @@
-curator=org.apache.dubbo.remoting.zookeeper.curator.CuratorZookeeperTransporter
diff --git a/dubbo-spi-remoting/dubbo-remoting-zookeeper/src/test/java/org/apache/dubbo/remoting/zookeeper/curator/CuratorZookeeperClientTest.java b/dubbo-spi-remoting/dubbo-remoting-zookeeper/src/test/java/org/apache/dubbo/remoting/zookeeper/curator/CuratorZookeeperClientTest.java
deleted file mode 100644
index 2f2b2f5..0000000
--- a/dubbo-spi-remoting/dubbo-remoting-zookeeper/src/test/java/org/apache/dubbo/remoting/zookeeper/curator/CuratorZookeeperClientTest.java
+++ /dev/null
@@ -1,195 +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.remoting.zookeeper.curator;
-
-import org.apache.dubbo.common.URL;
-import org.apache.dubbo.common.utils.NetUtils;
-import org.apache.dubbo.remoting.zookeeper.ChildListener;
-
-import org.apache.curator.framework.CuratorFramework;
-import org.apache.curator.framework.CuratorFrameworkFactory;
-import org.apache.curator.framework.recipes.cache.TreeCacheEvent;
-import org.apache.curator.retry.ExponentialBackoffRetry;
-import org.apache.curator.test.TestingServer;
-import org.apache.zookeeper.WatchedEvent;
-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 java.io.IOException;
-import java.util.List;
-import java.util.concurrent.CountDownLatch;
-import java.util.concurrent.atomic.AtomicInteger;
-
-import static org.hamcrest.MatcherAssert.assertThat;
-import static org.hamcrest.core.Is.is;
-import static org.junit.jupiter.api.Assertions.assertEquals;
-import static org.junit.jupiter.api.Assertions.assertNull;
-import static org.mockito.Mockito.mock;
-
-public class CuratorZookeeperClientTest {
-    private TestingServer zkServer;
-    private CuratorZookeeperClient curatorClient;
-    CuratorFramework client = null;
-
-    @BeforeEach
-    public void setUp() throws Exception {
-        int zkServerPort = NetUtils.getAvailablePort();
-        zkServer = new TestingServer(zkServerPort, true);
-        curatorClient = new CuratorZookeeperClient(URL.valueOf("zookeeper://127.0.0.1:" +
-                zkServerPort + "/org.apache.dubbo.registry.RegistryService"));
-        client = CuratorFrameworkFactory.newClient(zkServer.getConnectString(), new ExponentialBackoffRetry(1000, 3));
-        client.start();
-    }
-
-    @Test
-    public void testCheckExists() {
-        String path = "/dubbo/org.apache.dubbo.demo.DemoService/providers";
-        curatorClient.create(path, false);
-        assertThat(curatorClient.checkExists(path), is(true));
-        assertThat(curatorClient.checkExists(path + "/noneexits"), is(false));
-    }
-
-    @Test
-    public void testChildrenPath() {
-        String path = "/dubbo/org.apache.dubbo.demo.DemoService/providers";
-        curatorClient.create(path, false);
-        curatorClient.create(path + "/provider1", false);
-        curatorClient.create(path + "/provider2", false);
-
-        List<String> children = curatorClient.getChildren(path);
-        assertThat(children.size(), is(2));
-    }
-
-    @Test
-    public void testChildrenListener() throws InterruptedException {
-        String path = "/dubbo/org.apache.dubbo.demo.DemoService/providers";
-        curatorClient.create(path, false);
-        final CountDownLatch countDownLatch = new CountDownLatch(1);
-        curatorClient.addTargetChildListener(path, new CuratorZookeeperClient.CuratorWatcherImpl() {
-
-            @Override
-            public void process(WatchedEvent watchedEvent) throws Exception {
-                countDownLatch.countDown();
-            }
-        });
-        curatorClient.createPersistent(path + "/provider1");
-        countDownLatch.await();
-    }
-
-
-    @Test
-    public void testWithInvalidServer() {
-        Assertions.assertThrows(IllegalStateException.class, () -> {
-            curatorClient = new CuratorZookeeperClient(URL.valueOf("zookeeper://127.0.0.1:1/service"));
-            curatorClient.create("/testPath", true);
-        });
-    }
-
-    @Test
-    public void testWithStoppedServer() throws IOException {
-        Assertions.assertThrows(IllegalStateException.class, () -> {
-            curatorClient.create("/testPath", true);
-            zkServer.stop();
-            curatorClient.delete("/testPath");
-        });
-    }
-
-    @Test
-    public void testRemoveChildrenListener() {
-        ChildListener childListener = mock(ChildListener.class);
-        curatorClient.addChildListener("/children", childListener);
-        curatorClient.removeChildListener("/children", childListener);
-    }
-
-    @Test
-    public void testCreateExistingPath() {
-        curatorClient.create("/pathOne", false);
-        curatorClient.create("/pathOne", false);
-    }
-
-    @Test
-    public void testConnectedStatus() {
-        curatorClient.createEphemeral("/testPath");
-        boolean connected = curatorClient.isConnected();
-        assertThat(connected, is(true));
-    }
-
-    @Test
-    public void testCreateContent4Persistent() {
-        String path = "/curatorTest4CrContent/content.data";
-        String content = "createContentTest";
-        curatorClient.delete(path);
-        assertThat(curatorClient.checkExists(path), is(false));
-        assertNull(curatorClient.getContent(path));
-
-        curatorClient.create(path, content, false);
-        assertThat(curatorClient.checkExists(path), is(true));
-        assertEquals(curatorClient.getContent(path), content);
-    }
-
-    @Test
-    public void testCreateContent4Temp() {
-        String path = "/curatorTest4CrContent/content.data";
-        String content = "createContentTest";
-        curatorClient.delete(path);
-        assertThat(curatorClient.checkExists(path), is(false));
-        assertNull(curatorClient.getContent(path));
-
-        curatorClient.create(path, content, true);
-        assertThat(curatorClient.checkExists(path), is(true));
-        assertEquals(curatorClient.getContent(path), content);
-    }
-
-    @AfterEach
-    public void tearDown() throws Exception {
-        curatorClient.close();
-        zkServer.stop();
-    }
-
-    @Test
-    public void testAddTargetDataListener() throws Exception {
-        String listenerPath = "/dubbo/service.name/configuration";
-        String path = listenerPath + "/dat/data";
-        String value = "vav";
-
-        curatorClient.create(path + "/d.json", value, true);
-        String valueFromCache = curatorClient.getContent(path + "/d.json");
-        Assertions.assertEquals(value, valueFromCache);
-        final AtomicInteger atomicInteger = new AtomicInteger(0);
-        curatorClient.addTargetDataListener(listenerPath, new CuratorZookeeperClient.CuratorWatcherImpl() {
-            @Override
-            public void childEvent(CuratorFramework client, TreeCacheEvent event) throws Exception {
-                System.out.println("===" + event);
-                atomicInteger.incrementAndGet();
-            }
-        });
-
-        valueFromCache = curatorClient.getContent(path + "/d.json");
-        Assertions.assertNotNull(valueFromCache);
-        curatorClient.getClient().setData().forPath(path + "/d.json", "sdsdf".getBytes());
-        curatorClient.getClient().setData().forPath(path + "/d.json", "dfsasf".getBytes());
-        curatorClient.delete(path + "/d.json");
-        curatorClient.delete(path);
-        valueFromCache = curatorClient.getContent(path + "/d.json");
-        Assertions.assertNull(valueFromCache);
-        Thread.sleep(2000L);
-        Assertions.assertTrue(9L >= atomicInteger.get());
-        Assertions.assertTrue(2L <= atomicInteger.get());
-    }
-}
diff --git a/dubbo-spi-remoting/dubbo-remoting-zookeeper/src/test/java/org/apache/dubbo/remoting/zookeeper/curator/CuratorZookeeperTransporterTest.java b/dubbo-spi-remoting/dubbo-remoting-zookeeper/src/test/java/org/apache/dubbo/remoting/zookeeper/curator/CuratorZookeeperTransporterTest.java
deleted file mode 100644
index e051dc9..0000000
--- a/dubbo-spi-remoting/dubbo-remoting-zookeeper/src/test/java/org/apache/dubbo/remoting/zookeeper/curator/CuratorZookeeperTransporterTest.java
+++ /dev/null
@@ -1,57 +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.remoting.zookeeper.curator;
-
-import org.apache.dubbo.common.URL;
-import org.apache.dubbo.common.utils.NetUtils;
-import org.apache.dubbo.remoting.zookeeper.ZookeeperClient;
-
-import org.apache.curator.test.TestingServer;
-import org.junit.jupiter.api.AfterEach;
-import org.junit.jupiter.api.BeforeEach;
-import org.junit.jupiter.api.Test;
-
-import static org.hamcrest.MatcherAssert.assertThat;
-import static org.hamcrest.core.IsNot.not;
-import static org.hamcrest.core.IsNull.nullValue;
-
-public class CuratorZookeeperTransporterTest {
-    private TestingServer zkServer;
-    private ZookeeperClient zookeeperClient;
-    private CuratorZookeeperTransporter curatorZookeeperTransporter;
-    private int zkServerPort;
-
-    @BeforeEach
-    public void setUp() throws Exception {
-        zkServerPort = NetUtils.getAvailablePort();
-        zkServer = new TestingServer(zkServerPort, true);
-        zookeeperClient = new CuratorZookeeperTransporter().connect(URL.valueOf("zookeeper://127.0.0.1:" +
-                zkServerPort + "/service"));
-        curatorZookeeperTransporter = new CuratorZookeeperTransporter();
-    }
-
-    @Test
-    public void testZookeeperClient() {
-        assertThat(zookeeperClient, not(nullValue()));
-        zookeeperClient.close();
-    }
-
-    @AfterEach
-    public void tearDown() throws Exception {
-        zkServer.stop();
-    }
-}
diff --git a/dubbo-spi-remoting/dubbo-remoting-zookeeper/src/test/java/org/apache/dubbo/remoting/zookeeper/support/AbstractZookeeperTransporterTest.java b/dubbo-spi-remoting/dubbo-remoting-zookeeper/src/test/java/org/apache/dubbo/remoting/zookeeper/support/AbstractZookeeperTransporterTest.java
deleted file mode 100644
index 3662d8f..0000000
--- a/dubbo-spi-remoting/dubbo-remoting-zookeeper/src/test/java/org/apache/dubbo/remoting/zookeeper/support/AbstractZookeeperTransporterTest.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.remoting.zookeeper.support;
-
-import org.apache.dubbo.common.URL;
-import org.apache.dubbo.common.utils.NetUtils;
-import org.apache.dubbo.remoting.zookeeper.ZookeeperClient;
-import org.apache.dubbo.remoting.zookeeper.curator.CuratorZookeeperTransporter;
-
-import org.apache.curator.test.TestingServer;
-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 java.util.List;
-
-import static org.hamcrest.MatcherAssert.assertThat;
-import static org.hamcrest.core.IsNot.not;
-import static org.hamcrest.core.IsNull.nullValue;
-
-/**
- * AbstractZookeeperTransporterTest
- */
-public class AbstractZookeeperTransporterTest {
-    private TestingServer zkServer;
-    private ZookeeperClient zookeeperClient;
-    private AbstractZookeeperTransporter abstractZookeeperTransporter;
-    private int zkServerPort;
-
-    @BeforeEach
-    public void setUp() throws Exception {
-        zkServerPort = NetUtils.getAvailablePort();
-        zkServer = new TestingServer(zkServerPort, true);
-        zookeeperClient = new CuratorZookeeperTransporter().connect(URL.valueOf("zookeeper://127.0.0.1:" +
-                zkServerPort + "/service"));
-        abstractZookeeperTransporter = new CuratorZookeeperTransporter();
-    }
-
-
-    @AfterEach
-    public void tearDown() throws Exception {
-        zkServer.stop();
-    }
-
-    @Test
-    public void testZookeeperClient() {
-        assertThat(zookeeperClient, not(nullValue()));
-        zookeeperClient.close();
-    }
-
-    @Test
-    public void testGetURLBackupAddress() {
-        URL url = URL.valueOf("zookeeper://127.0.0.1:" + zkServerPort + "/org.apache.dubbo.registry.RegistryService?backup=127.0.0.1:" + 9099 + "&application=metadatareport-local-xml-provider2&dubbo=2.0.2&interface=org.apache.dubbo.registry.RegistryService&pid=47418&specVersion=2.7.0-SNAPSHOT&timestamp=1547102428828");
-        List<String> stringList = abstractZookeeperTransporter.getURLBackupAddress(url);
-        Assertions.assertEquals(stringList.size(), 2);
-        Assertions.assertEquals(stringList.get(0), "127.0.0.1:" + zkServerPort);
-        Assertions.assertEquals(stringList.get(1), "127.0.0.1:9099");
-    }
-
-    @Test
-    public void testGetURLBackupAddressNoBack() {
-        URL url = URL.valueOf("zookeeper://127.0.0.1:" + zkServerPort + "/org.apache.dubbo.registry.RegistryService?application=metadatareport-local-xml-provider2&dubbo=2.0.2&interface=org.apache.dubbo.registry.RegistryService&pid=47418&specVersion=2.7.0-SNAPSHOT&timestamp=1547102428828");
-        List<String> stringList = abstractZookeeperTransporter.getURLBackupAddress(url);
-        Assertions.assertEquals(stringList.size(), 1);
-        Assertions.assertEquals(stringList.get(0), "127.0.0.1:" + zkServerPort);
-    }
-
-    @Test
-    public void testFetchAndUpdateZookeeperClientCache() throws Exception {
-        int zkServerPort2 = NetUtils.getAvailablePort();
-        TestingServer zkServer2 = new TestingServer(zkServerPort2, true);
-
-        int zkServerPort3 = NetUtils.getAvailablePort();
-        TestingServer zkServer3 = new TestingServer(zkServerPort3, true);
-
-        URL url = URL.valueOf("zookeeper://127.0.0.1:" + zkServerPort + "/org.apache.dubbo.registry.RegistryService?backup=127.0.0.1:" + zkServerPort3 + ",127.0.0.1:" + zkServerPort2 + "&application=metadatareport-local-xml-provider2&dubbo=2.0.2&interface=org.apache.dubbo.registry.RegistryService&pid=47418&specVersion=2.7.0-SNAPSHOT&timestamp=1547102428828");
-        ZookeeperClient newZookeeperClient = abstractZookeeperTransporter.connect(url);
-        //just for connected
-        newZookeeperClient.getContent("/dubbo/test");
-        Assertions.assertEquals(abstractZookeeperTransporter.getZookeeperClientMap().size(), 3);
-        Assertions.assertEquals(abstractZookeeperTransporter.getZookeeperClientMap().get("127.0.0.1:" + zkServerPort), newZookeeperClient);
-
-        URL url2 = URL.valueOf("zookeeper://127.0.0.1:" + zkServerPort + "/org.apache.dubbo.metadata.store.MetadataReport?address=zookeeper://127.0.0.1:2181&application=metadatareport-local-xml-provider2&cycle-report=false&interface=org.apache.dubbo.metadata.store.MetadataReport&retry-period=4590&retry-times=23&sync-report=true");
-        checkFetchAndUpdateCacheNotNull(url2);
-        URL url3 = URL.valueOf("zookeeper://127.0.0.1:8778/org.apache.dubbo.metadata.store.MetadataReport?backup=127.0.0.1:" + zkServerPort3 + "&address=zookeeper://127.0.0.1:2181&application=metadatareport-local-xml-provider2&cycle-report=false&interface=org.apache.dubbo.metadata.store.MetadataReport&retry-period=4590&retry-times=23&sync-report=true");
-        checkFetchAndUpdateCacheNotNull(url3);
-
-        zkServer2.stop();
-        zkServer3.stop();
-    }
-
-    private void checkFetchAndUpdateCacheNotNull(URL url) {
-        List<String> addressList = abstractZookeeperTransporter.getURLBackupAddress(url);
-        ZookeeperClient zookeeperClient = abstractZookeeperTransporter.fetchAndUpdateZookeeperClientCache(addressList);
-        Assertions.assertNotNull(zookeeperClient);
-    }
-
-    @Test
-    public void testRepeatConnect() {
-        URL url = URL.valueOf("zookeeper://127.0.0.1:" + zkServerPort + "/org.apache.dubbo.registry.RegistryService?application=metadatareport-local-xml-provider2&dubbo=2.0.2&interface=org.apache.dubbo.registry.RegistryService&pid=47418&specVersion=2.7.0-SNAPSHOT&timestamp=1547102428828");
-        URL url2 = URL.valueOf("zookeeper://127.0.0.1:" + zkServerPort + "/org.apache.dubbo.metadata.store.MetadataReport?address=zookeeper://127.0.0.1:2181&application=metadatareport-local-xml-provider2&cycle-report=false&interface=org.apache.dubbo.metadata.store.MetadataReport&retry-period=4590&retry-times=23&sync-report=true");
-        ZookeeperClient newZookeeperClient = abstractZookeeperTransporter.connect(url);
-        //just for connected
-        newZookeeperClient.getContent("/dubbo/test");
-        Assertions.assertEquals(abstractZookeeperTransporter.getZookeeperClientMap().size(), 1);
-        Assertions.assertEquals(abstractZookeeperTransporter.getZookeeperClientMap().get("127.0.0.1:" + zkServerPort), newZookeeperClient);
-        Assertions.assertTrue(newZookeeperClient.isConnected());
-
-        ZookeeperClient newZookeeperClient2 = abstractZookeeperTransporter.connect(url2);
-        //just for connected
-        newZookeeperClient2.getContent("/dubbo/test");
-        Assertions.assertEquals(newZookeeperClient, newZookeeperClient2);
-        Assertions.assertEquals(abstractZookeeperTransporter.getZookeeperClientMap().size(), 1);
-        Assertions.assertEquals(abstractZookeeperTransporter.getZookeeperClientMap().get("127.0.0.1:" + zkServerPort), newZookeeperClient);
-    }
-
-    @Test
-    public void testNotRepeatConnect() throws Exception {
-        int zkServerPort2 = NetUtils.getAvailablePort();
-        TestingServer zkServer2 = new TestingServer(zkServerPort2, true);
-
-        URL url = URL.valueOf("zookeeper://127.0.0.1:" + zkServerPort + "/org.apache.dubbo.registry.RegistryService?application=metadatareport-local-xml-provider2&dubbo=2.0.2&interface=org.apache.dubbo.registry.RegistryService&pid=47418&specVersion=2.7.0-SNAPSHOT&timestamp=1547102428828");
-        URL url2 = URL.valueOf("zookeeper://127.0.0.1:" + zkServerPort2 + "/org.apache.dubbo.metadata.store.MetadataReport?address=zookeeper://127.0.0.1:2181&application=metadatareport-local-xml-provider2&cycle-report=false&interface=org.apache.dubbo.metadata.store.MetadataReport&retry-period=4590&retry-times=23&sync-report=true");
-        ZookeeperClient newZookeeperClient = abstractZookeeperTransporter.connect(url);
-        //just for connected
-        newZookeeperClient.getContent("/dubbo/test");
-        Assertions.assertEquals(abstractZookeeperTransporter.getZookeeperClientMap().size(), 1);
-        Assertions.assertEquals(abstractZookeeperTransporter.getZookeeperClientMap().get("127.0.0.1:" + zkServerPort), newZookeeperClient);
-
-        ZookeeperClient newZookeeperClient2 = abstractZookeeperTransporter.connect(url2);
-        //just for connected
-        newZookeeperClient2.getContent("/dubbo/test");
-        Assertions.assertNotEquals(newZookeeperClient, newZookeeperClient2);
-        Assertions.assertEquals(abstractZookeeperTransporter.getZookeeperClientMap().size(), 2);
-        Assertions.assertEquals(abstractZookeeperTransporter.getZookeeperClientMap().get("127.0.0.1:" + zkServerPort2), newZookeeperClient2);
-
-        zkServer2.stop();
-    }
-
-    @Test
-    public void testRepeatConnectForBackUpAdd() throws Exception {
-        int zkServerPort2 = NetUtils.getAvailablePort();
-        TestingServer zkServer2 = new TestingServer(zkServerPort2, true);
-
-        int zkServerPort3 = NetUtils.getAvailablePort();
-        TestingServer zkServer3 = new TestingServer(zkServerPort3, true);
-
-        URL url = URL.valueOf("zookeeper://127.0.0.1:" + zkServerPort + "/org.apache.dubbo.registry.RegistryService?backup=127.0.0.1:" + zkServerPort2 + "&application=metadatareport-local-xml-provider2&dubbo=2.0.2&interface=org.apache.dubbo.registry.RegistryService&pid=47418&specVersion=2.7.0-SNAPSHOT&timestamp=1547102428828");
-        URL url2 = URL.valueOf("zookeeper://127.0.0.1:" + zkServerPort2 + "/org.apache.dubbo.metadata.store.MetadataReport?backup=127.0.0.1:" + zkServerPort3 + "&address=zookeeper://127.0.0.1:2181&application=metadatareport-local-xml-provider2&cycle-report=false&interface=org.apache.dubbo.metadata.store.MetadataReport&retry-period=4590&retry-times=23&sync-report=true");
-        ZookeeperClient newZookeeperClient = abstractZookeeperTransporter.connect(url);
-        //just for connected
-        newZookeeperClient.getContent("/dubbo/test");
-        Assertions.assertEquals(abstractZookeeperTransporter.getZookeeperClientMap().size(), 2);
-        Assertions.assertEquals(abstractZookeeperTransporter.getZookeeperClientMap().get("127.0.0.1:" + zkServerPort), newZookeeperClient);
-
-        ZookeeperClient newZookeeperClient2 = abstractZookeeperTransporter.connect(url2);
-        //just for connected
-        newZookeeperClient2.getContent("/dubbo/test");
-        Assertions.assertEquals(newZookeeperClient, newZookeeperClient2);
-        Assertions.assertEquals(abstractZookeeperTransporter.getZookeeperClientMap().size(), 3);
-        Assertions.assertEquals(abstractZookeeperTransporter.getZookeeperClientMap().get("127.0.0.1:" + zkServerPort2), newZookeeperClient2);
-
-        zkServer2.stop();
-        zkServer3.stop();
-    }
-
-    @Test
-    public void testRepeatConnectForNoMatchBackUpAdd() throws Exception {
-        int zkServerPort2 = NetUtils.getAvailablePort();
-        TestingServer zkServer2 = new TestingServer(zkServerPort2, true);
-
-        int zkServerPort3 = NetUtils.getAvailablePort();
-        TestingServer zkServer3 = new TestingServer(zkServerPort3, true);
-
-        URL url = URL.valueOf("zookeeper://127.0.0.1:" + zkServerPort + "/org.apache.dubbo.registry.RegistryService?backup=127.0.0.1:" + zkServerPort3 + "&application=metadatareport-local-xml-provider2&dubbo=2.0.2&interface=org.apache.dubbo.registry.RegistryService&pid=47418&specVersion=2.7.0-SNAPSHOT&timestamp=1547102428828");
-        URL url2 = URL.valueOf("zookeeper://127.0.0.1:" + zkServerPort2 + "/org.apache.dubbo.metadata.store.MetadataReport?address=zookeeper://127.0.0.1:2181&application=metadatareport-local-xml-provider2&cycle-report=false&interface=org.apache.dubbo.metadata.store.MetadataReport&retry-period=4590&retry-times=23&sync-report=true");
-        ZookeeperClient newZookeeperClient = abstractZookeeperTransporter.connect(url);
-        //just for connected
-        newZookeeperClient.getContent("/dubbo/test");
-        Assertions.assertEquals(abstractZookeeperTransporter.getZookeeperClientMap().size(), 2);
-        Assertions.assertEquals(abstractZookeeperTransporter.getZookeeperClientMap().get("127.0.0.1:" + zkServerPort), newZookeeperClient);
-
-        ZookeeperClient newZookeeperClient2 = abstractZookeeperTransporter.connect(url2);
-        //just for connected
-        newZookeeperClient2.getContent("/dubbo/test");
-        Assertions.assertNotEquals(newZookeeperClient, newZookeeperClient2);
-        Assertions.assertEquals(abstractZookeeperTransporter.getZookeeperClientMap().size(), 3);
-        Assertions.assertEquals(abstractZookeeperTransporter.getZookeeperClientMap().get("127.0.0.1:" + zkServerPort2), newZookeeperClient2);
-
-        zkServer2.stop();
-        zkServer3.stop();
-    }
-
-    @Test
-    public void testSameHostWithDifferentUser() throws Exception {
-        int zkPort1 = NetUtils.getAvailablePort();
-        int zkPort2 = NetUtils.getAvailablePort();
-        try (TestingServer zkServer1 = new TestingServer(zkPort1, true)) {
-            try (TestingServer zkServer2 = new TestingServer(zkPort2, true)) {
-                URL url1 = URL.valueOf("zookeeper://us1:pw1@127.0.0.1:" + zkPort1 + "/path1");
-                URL url2 = URL.valueOf("zookeeper://us2:pw2@127.0.0.1:" + zkPort1 + "/path2");
-
-                ZookeeperClient client1 = abstractZookeeperTransporter.connect(url1);
-                ZookeeperClient client2 = abstractZookeeperTransporter.connect(url2);
-
-                assertThat(client1, not(client2));
-            }
-        }
-    }
-}
diff --git a/dubbo-spi-remoting/pom.xml b/dubbo-spi-remoting/pom.xml
index fe73221..152782f 100644
--- a/dubbo-spi-remoting/pom.xml
+++ b/dubbo-spi-remoting/pom.xml
@@ -34,7 +34,6 @@
         <module>dubbo-remoting-grizzly</module>
         <module>dubbo-remoting-p2p</module>
         <module>dubbo-remoting-http</module>
-        <module>dubbo-remoting-zookeeper</module>
         <module>dubbo-remoting-etcd3</module>
     </modules>
 </project>
\ No newline at end of file
diff --git a/dubbo-spi-serialization/dubbo-serialization-jdk/pom.xml b/dubbo-spi-serialization/dubbo-serialization-jdk/pom.xml
deleted file mode 100644
index 0b70869..0000000
--- a/dubbo-spi-serialization/dubbo-serialization-jdk/pom.xml
+++ /dev/null
@@ -1,43 +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.
--->
-
-<project xmlns="http://maven.apache.org/POM/4.0.0" xmlns:xsi="http://www.w3.org/2001/XMLSchema-instance" xsi:schemaLocation="http://maven.apache.org/POM/4.0.0 http://maven.apache.org/maven-v4_0_0.xsd">
-    <modelVersion>4.0.0</modelVersion>
-    <parent>
-        <groupId>org.apache.dubbo</groupId>
-        <artifactId>dubbo-serialization</artifactId>
-        <version>2.7.7-SNAPSHOT</version>
-    </parent>
-    <artifactId>dubbo-serialization-jdk</artifactId>
-    <packaging>jar</packaging>
-    <name>${project.artifactId}</name>
-    <description>The jdk serialization module of dubbo project</description>
-    <properties>
-        <skip_maven_deploy>false</skip_maven_deploy>
-    </properties>
-    <dependencies>
-        <dependency>
-            <groupId>org.apache.dubbo</groupId>
-            <artifactId>dubbo-serialization-api</artifactId>
-            <version>${project.parent.version}</version>
-        </dependency>
-        <dependency>
-            <groupId>com.alibaba</groupId>
-            <artifactId>hessian-lite</artifactId>
-        </dependency>
-    </dependencies>
-</project>
\ No newline at end of file
diff --git a/dubbo-spi-serialization/dubbo-serialization-jdk/src/main/java/org/apache/dubbo/common/serialize/java/CompactedJavaSerialization.java b/dubbo-spi-serialization/dubbo-serialization-jdk/src/main/java/org/apache/dubbo/common/serialize/java/CompactedJavaSerialization.java
deleted file mode 100644
index 2df9db1..0000000
--- a/dubbo-spi-serialization/dubbo-serialization-jdk/src/main/java/org/apache/dubbo/common/serialize/java/CompactedJavaSerialization.java
+++ /dev/null
@@ -1,59 +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.common.serialize.java;
-
-import org.apache.dubbo.common.URL;
-import org.apache.dubbo.common.serialize.ObjectInput;
-import org.apache.dubbo.common.serialize.ObjectOutput;
-import org.apache.dubbo.common.serialize.Serialization;
-
-import java.io.IOException;
-import java.io.InputStream;
-import java.io.OutputStream;
-
-import static org.apache.dubbo.common.serialize.Constants.COMPACTED_JAVA_SERIALIZATION_ID;
-
-/**
- * Compacted java serialization implementation
- *
- * <pre>
- *     e.g. &lt;dubbo:protocol serialization="compactedjava" /&gt;
- * </pre>
- */
-public class CompactedJavaSerialization implements Serialization {
-
-    @Override
-    public byte getContentTypeId() {
-        return COMPACTED_JAVA_SERIALIZATION_ID;
-    }
-
-    @Override
-    public String getContentType() {
-        return "x-application/compactedjava";
-    }
-
-    @Override
-    public ObjectOutput serialize(URL url, OutputStream out) throws IOException {
-        return new JavaObjectOutput(out, true);
-    }
-
-    @Override
-    public ObjectInput deserialize(URL url, InputStream is) throws IOException {
-        return new JavaObjectInput(is, true);
-    }
-
-}
diff --git a/dubbo-spi-serialization/dubbo-serialization-jdk/src/main/java/org/apache/dubbo/common/serialize/java/CompactedObjectInputStream.java b/dubbo-spi-serialization/dubbo-serialization-jdk/src/main/java/org/apache/dubbo/common/serialize/java/CompactedObjectInputStream.java
deleted file mode 100644
index e881774..0000000
--- a/dubbo-spi-serialization/dubbo-serialization-jdk/src/main/java/org/apache/dubbo/common/serialize/java/CompactedObjectInputStream.java
+++ /dev/null
@@ -1,64 +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.common.serialize.java;
-
-
-import org.apache.dubbo.common.utils.ClassUtils;
-
-import java.io.EOFException;
-import java.io.IOException;
-import java.io.InputStream;
-import java.io.ObjectInputStream;
-import java.io.ObjectStreamClass;
-import java.io.StreamCorruptedException;
-
-/**
- * Compacted java object input implementation
- */
-public class CompactedObjectInputStream extends ObjectInputStream {
-    private ClassLoader mClassLoader;
-
-    public CompactedObjectInputStream(InputStream in) throws IOException {
-        this(in, Thread.currentThread().getContextClassLoader());
-    }
-
-    public CompactedObjectInputStream(InputStream in, ClassLoader cl) throws IOException {
-        super(in);
-        mClassLoader = cl == null ? ClassUtils.getClassLoader() : cl;
-    }
-
-    @Override
-    protected ObjectStreamClass readClassDescriptor() throws IOException, ClassNotFoundException {
-        int type = read();
-        if (type < 0) {
-            throw new EOFException();
-        }
-        switch (type) {
-            case 0:
-                return super.readClassDescriptor();
-            case 1:
-                Class<?> clazz = loadClass(readUTF());
-                return ObjectStreamClass.lookup(clazz);
-            default:
-                throw new StreamCorruptedException("Unexpected class descriptor type: " + type);
-        }
-    }
-
-    private Class<?> loadClass(String className) throws ClassNotFoundException {
-        return mClassLoader.loadClass(className);
-    }
-}
\ No newline at end of file
diff --git a/dubbo-spi-serialization/dubbo-serialization-jdk/src/main/java/org/apache/dubbo/common/serialize/java/CompactedObjectOutputStream.java b/dubbo-spi-serialization/dubbo-serialization-jdk/src/main/java/org/apache/dubbo/common/serialize/java/CompactedObjectOutputStream.java
deleted file mode 100644
index 56847e5..0000000
--- a/dubbo-spi-serialization/dubbo-serialization-jdk/src/main/java/org/apache/dubbo/common/serialize/java/CompactedObjectOutputStream.java
+++ /dev/null
@@ -1,43 +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.common.serialize.java;
-
-import java.io.IOException;
-import java.io.ObjectOutputStream;
-import java.io.ObjectStreamClass;
-import java.io.OutputStream;
-
-/**
- * Compacted java object output implementation
- */
-public class CompactedObjectOutputStream extends ObjectOutputStream {
-    public CompactedObjectOutputStream(OutputStream out) throws IOException {
-        super(out);
-    }
-
-    @Override
-    protected void writeClassDescriptor(ObjectStreamClass desc) throws IOException {
-        Class<?> clazz = desc.forClass();
-        if (clazz.isPrimitive() || clazz.isArray()) {
-            write(0);
-            super.writeClassDescriptor(desc);
-        } else {
-            write(1);
-            writeUTF(desc.getName());
-        }
-    }
-}
\ No newline at end of file
diff --git a/dubbo-spi-serialization/dubbo-serialization-jdk/src/main/java/org/apache/dubbo/common/serialize/java/JavaObjectInput.java b/dubbo-spi-serialization/dubbo-serialization-jdk/src/main/java/org/apache/dubbo/common/serialize/java/JavaObjectInput.java
deleted file mode 100644
index 936ab26..0000000
--- a/dubbo-spi-serialization/dubbo-serialization-jdk/src/main/java/org/apache/dubbo/common/serialize/java/JavaObjectInput.java
+++ /dev/null
@@ -1,91 +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.common.serialize.java;
-
-import org.apache.dubbo.common.serialize.nativejava.NativeJavaObjectInput;
-
-import java.io.IOException;
-import java.io.InputStream;
-import java.io.ObjectInputStream;
-import java.lang.reflect.Type;
-
-/**
- * Java object input implementation
- */
-public class JavaObjectInput extends NativeJavaObjectInput {
-    public final static int MAX_BYTE_ARRAY_LENGTH = 8 * 1024 * 1024;
-
-    public JavaObjectInput(InputStream is) throws IOException {
-        super(new ObjectInputStream(is));
-    }
-
-    public JavaObjectInput(InputStream is, boolean compacted) throws IOException {
-        super(compacted ? new CompactedObjectInputStream(is) : new ObjectInputStream(is));
-    }
-
-    @Override
-    public byte[] readBytes() throws IOException {
-        int len = getObjectInputStream().readInt();
-        if (len < 0) {
-            return null;
-        }
-        if (len == 0) {
-            return new byte[0];
-        }
-        if (len > MAX_BYTE_ARRAY_LENGTH) {
-            throw new IOException("Byte array length too large. " + len);
-        }
-
-        byte[] b = new byte[len];
-        getObjectInputStream().readFully(b);
-        return b;
-    }
-
-    @Override
-    public String readUTF() throws IOException {
-        int len = getObjectInputStream().readInt();
-        if (len < 0) {
-            return null;
-        }
-
-        return getObjectInputStream().readUTF();
-    }
-
-    @Override
-    public Object readObject() throws IOException, ClassNotFoundException {
-        byte b = getObjectInputStream().readByte();
-        if (b == 0) {
-            return null;
-        }
-
-        return getObjectInputStream().readObject();
-    }
-
-    @Override
-    @SuppressWarnings("unchecked")
-    public <T> T readObject(Class<T> cls) throws IOException,
-            ClassNotFoundException {
-        return (T) readObject();
-    }
-
-    @Override
-    @SuppressWarnings("unchecked")
-    public <T> T readObject(Class<T> cls, Type type) throws IOException, ClassNotFoundException {
-        return (T) readObject();
-    }
-
-}
diff --git a/dubbo-spi-serialization/dubbo-serialization-jdk/src/main/java/org/apache/dubbo/common/serialize/java/JavaObjectOutput.java b/dubbo-spi-serialization/dubbo-serialization-jdk/src/main/java/org/apache/dubbo/common/serialize/java/JavaObjectOutput.java
deleted file mode 100644
index 0e78747..0000000
--- a/dubbo-spi-serialization/dubbo-serialization-jdk/src/main/java/org/apache/dubbo/common/serialize/java/JavaObjectOutput.java
+++ /dev/null
@@ -1,61 +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.common.serialize.java;
-
-import org.apache.dubbo.common.serialize.nativejava.NativeJavaObjectOutput;
-
-import java.io.IOException;
-import java.io.ObjectOutputStream;
-import java.io.OutputStream;
-
-/**
- * Java object output implementation
- */
-public class JavaObjectOutput extends NativeJavaObjectOutput {
-    public JavaObjectOutput(OutputStream os) throws IOException {
-        super(new ObjectOutputStream(os));
-    }
-
-    public JavaObjectOutput(OutputStream os, boolean compact) throws IOException {
-        super(compact ? new CompactedObjectOutputStream(os) : new ObjectOutputStream(os));
-    }
-
-    @Override
-    public void writeUTF(String v) throws IOException {
-        if (v == null) {
-            getObjectOutputStream().writeInt(-1);
-        } else {
-            getObjectOutputStream().writeInt(v.length());
-            getObjectOutputStream().writeUTF(v);
-        }
-    }
-
-    @Override
-    public void writeObject(Object obj) throws IOException {
-        if (obj == null) {
-            getObjectOutputStream().writeByte(0);
-        } else {
-            getObjectOutputStream().writeByte(1);
-            getObjectOutputStream().writeObject(obj);
-        }
-    }
-
-    @Override
-    public void flushBuffer() throws IOException {
-        getObjectOutputStream().flush();
-    }
-}
diff --git a/dubbo-spi-serialization/dubbo-serialization-jdk/src/main/java/org/apache/dubbo/common/serialize/java/JavaSerialization.java b/dubbo-spi-serialization/dubbo-serialization-jdk/src/main/java/org/apache/dubbo/common/serialize/java/JavaSerialization.java
deleted file mode 100644
index 2045e4e..0000000
--- a/dubbo-spi-serialization/dubbo-serialization-jdk/src/main/java/org/apache/dubbo/common/serialize/java/JavaSerialization.java
+++ /dev/null
@@ -1,59 +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.common.serialize.java;
-
-import org.apache.dubbo.common.URL;
-import org.apache.dubbo.common.serialize.ObjectInput;
-import org.apache.dubbo.common.serialize.ObjectOutput;
-import org.apache.dubbo.common.serialize.Serialization;
-
-import java.io.IOException;
-import java.io.InputStream;
-import java.io.OutputStream;
-
-import static org.apache.dubbo.common.serialize.Constants.JAVA_SERIALIZATION_ID;
-
-/**
- * Java serialization implementation
- *
- * <pre>
- *     e.g. &lt;dubbo:protocol serialization="java" /&gt;
- * </pre>
- */
-public class JavaSerialization implements Serialization {
-
-    @Override
-    public byte getContentTypeId() {
-        return JAVA_SERIALIZATION_ID;
-    }
-
-    @Override
-    public String getContentType() {
-        return "x-application/java";
-    }
-
-    @Override
-    public ObjectOutput serialize(URL url, OutputStream out) throws IOException {
-        return new JavaObjectOutput(out);
-    }
-
-    @Override
-    public ObjectInput deserialize(URL url, InputStream is) throws IOException {
-        return new JavaObjectInput(is);
-    }
-
-}
diff --git a/dubbo-spi-serialization/dubbo-serialization-jdk/src/main/java/org/apache/dubbo/common/serialize/nativejava/NativeJavaObjectInput.java b/dubbo-spi-serialization/dubbo-serialization-jdk/src/main/java/org/apache/dubbo/common/serialize/nativejava/NativeJavaObjectInput.java
deleted file mode 100644
index c791250..0000000
--- a/dubbo-spi-serialization/dubbo-serialization-jdk/src/main/java/org/apache/dubbo/common/serialize/nativejava/NativeJavaObjectInput.java
+++ /dev/null
@@ -1,118 +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.common.serialize.nativejava;
-
-import org.apache.dubbo.common.serialize.ObjectInput;
-import org.apache.dubbo.common.utils.Assert;
-
-import java.io.IOException;
-import java.io.InputStream;
-import java.io.ObjectInputStream;
-import java.lang.reflect.Type;
-
-/**
- * Native java object input implementation
- */
-public class NativeJavaObjectInput implements ObjectInput {
-
-    private final ObjectInputStream inputStream;
-
-    public NativeJavaObjectInput(InputStream is) throws IOException {
-        this(new ObjectInputStream(is));
-    }
-
-    protected NativeJavaObjectInput(ObjectInputStream is) {
-        Assert.notNull(is, "input == null");
-        inputStream = is;
-    }
-
-    protected ObjectInputStream getObjectInputStream() {
-        return inputStream;
-    }
-
-    @Override
-    public Object readObject() throws IOException, ClassNotFoundException {
-        return inputStream.readObject();
-    }
-
-    @Override
-    @SuppressWarnings("unchecked")
-    public <T> T readObject(Class<T> cls) throws IOException, ClassNotFoundException {
-        return (T) readObject();
-    }
-
-    @Override
-    @SuppressWarnings("unchecked")
-    public <T> T readObject(Class<T> cls, Type type) throws IOException, ClassNotFoundException {
-        return (T) readObject();
-    }
-
-    @Override
-    public boolean readBool() throws IOException {
-        return inputStream.readBoolean();
-    }
-
-    @Override
-    public byte readByte() throws IOException {
-        return inputStream.readByte();
-    }
-
-    @Override
-    public short readShort() throws IOException {
-        return inputStream.readShort();
-    }
-
-    @Override
-    public int readInt() throws IOException {
-        return inputStream.readInt();
-    }
-
-    @Override
-    public long readLong() throws IOException {
-        return inputStream.readLong();
-    }
-
-    @Override
-    public float readFloat() throws IOException {
-        return inputStream.readFloat();
-    }
-
-    @Override
-    public double readDouble() throws IOException {
-        return inputStream.readDouble();
-    }
-
-    @Override
-    public String readUTF() throws IOException {
-        return inputStream.readUTF();
-    }
-
-    @Override
-    public byte[] readBytes() throws IOException {
-        int len = inputStream.readInt();
-        if (len < 0) {
-            return null;
-        } else if (len == 0) {
-            return new byte[]{};
-        } else {
-            byte[] result = new byte[len];
-            inputStream.readFully(result);
-            return result;
-        }
-    }
-}
diff --git a/dubbo-spi-serialization/dubbo-serialization-jdk/src/main/java/org/apache/dubbo/common/serialize/nativejava/NativeJavaObjectOutput.java b/dubbo-spi-serialization/dubbo-serialization-jdk/src/main/java/org/apache/dubbo/common/serialize/nativejava/NativeJavaObjectOutput.java
deleted file mode 100644
index 2ff82f7..0000000
--- a/dubbo-spi-serialization/dubbo-serialization-jdk/src/main/java/org/apache/dubbo/common/serialize/nativejava/NativeJavaObjectOutput.java
+++ /dev/null
@@ -1,115 +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.common.serialize.nativejava;
-
-import org.apache.dubbo.common.serialize.ObjectOutput;
-import org.apache.dubbo.common.utils.Assert;
-
-import java.io.IOException;
-import java.io.ObjectOutputStream;
-import java.io.OutputStream;
-
-/**
- * Native java object output implementation
- */
-public class NativeJavaObjectOutput implements ObjectOutput {
-
-    private final ObjectOutputStream outputStream;
-
-    public NativeJavaObjectOutput(OutputStream os) throws IOException {
-        this(new ObjectOutputStream(os));
-    }
-
-    protected NativeJavaObjectOutput(ObjectOutputStream out) {
-        Assert.notNull(out, "output == null");
-        this.outputStream = out;
-    }
-
-    protected ObjectOutputStream getObjectOutputStream() {
-        return outputStream;
-    }
-
-    @Override
-    public void writeObject(Object obj) throws IOException {
-        outputStream.writeObject(obj);
-    }
-
-    @Override
-    public void writeBool(boolean v) throws IOException {
-        outputStream.writeBoolean(v);
-    }
-
-    @Override
-    public void writeByte(byte v) throws IOException {
-        outputStream.writeByte(v);
-    }
-
-    @Override
-    public void writeShort(short v) throws IOException {
-        outputStream.writeShort(v);
-    }
-
-    @Override
-    public void writeInt(int v) throws IOException {
-        outputStream.writeInt(v);
-    }
-
-    @Override
-    public void writeLong(long v) throws IOException {
-        outputStream.writeLong(v);
-    }
-
-    @Override
-    public void writeFloat(float v) throws IOException {
-        outputStream.writeFloat(v);
-    }
-
-    @Override
-    public void writeDouble(double v) throws IOException {
-        outputStream.writeDouble(v);
-    }
-
-    @Override
-    public void writeUTF(String v) throws IOException {
-        outputStream.writeUTF(v);
-    }
-
-    @Override
-    public void writeBytes(byte[] v) throws IOException {
-        if (v == null) {
-            outputStream.writeInt(-1);
-        } else {
-            writeBytes(v, 0, v.length);
-        }
-    }
-
-    @Override
-    public void writeBytes(byte[] v, int off, int len) throws IOException {
-        if (v == null) {
-            outputStream.writeInt(-1);
-        } else {
-            outputStream.writeInt(len);
-            outputStream.write(v, off, len);
-        }
-    }
-
-    @Override
-    public void flushBuffer() throws IOException {
-        outputStream.flush();
-    }
-}
diff --git a/dubbo-spi-serialization/dubbo-serialization-jdk/src/main/java/org/apache/dubbo/common/serialize/nativejava/NativeJavaSerialization.java b/dubbo-spi-serialization/dubbo-serialization-jdk/src/main/java/org/apache/dubbo/common/serialize/nativejava/NativeJavaSerialization.java
deleted file mode 100644
index 6617d29..0000000
--- a/dubbo-spi-serialization/dubbo-serialization-jdk/src/main/java/org/apache/dubbo/common/serialize/nativejava/NativeJavaSerialization.java
+++ /dev/null
@@ -1,60 +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.common.serialize.nativejava;
-
-import org.apache.dubbo.common.URL;
-import org.apache.dubbo.common.serialize.ObjectInput;
-import org.apache.dubbo.common.serialize.ObjectOutput;
-import org.apache.dubbo.common.serialize.Serialization;
-
-import java.io.IOException;
-import java.io.InputStream;
-import java.io.OutputStream;
-
-import static org.apache.dubbo.common.serialize.Constants.NATIVE_JAVA_SERIALIZATION_ID;
-
-/**
- * Native java serialization implementation
- *
- * <pre>
- *     e.g. &lt;dubbo:protocol serialization="nativejava" /&gt;
- * </pre>
- */
-public class NativeJavaSerialization implements Serialization {
-
-
-    @Override
-    public byte getContentTypeId() {
-        return NATIVE_JAVA_SERIALIZATION_ID;
-    }
-
-    @Override
-    public String getContentType() {
-        return "x-application/nativejava";
-    }
-
-    @Override
-    public ObjectOutput serialize(URL url, OutputStream output) throws IOException {
-        return new NativeJavaObjectOutput(output);
-    }
-
-    @Override
-    public ObjectInput deserialize(URL url, InputStream input) throws IOException {
-        return new NativeJavaObjectInput(input);
-    }
-}
diff --git a/dubbo-spi-serialization/dubbo-serialization-jdk/src/main/resources/META-INF/dubbo/internal/org.apache.dubbo.common.serialize.Serialization b/dubbo-spi-serialization/dubbo-serialization-jdk/src/main/resources/META-INF/dubbo/internal/org.apache.dubbo.common.serialize.Serialization
deleted file mode 100644
index bc1e4ef..0000000
--- a/dubbo-spi-serialization/dubbo-serialization-jdk/src/main/resources/META-INF/dubbo/internal/org.apache.dubbo.common.serialize.Serialization
+++ /dev/null
@@ -1,3 +0,0 @@
-java=org.apache.dubbo.common.serialize.java.JavaSerialization
-compactedjava=org.apache.dubbo.common.serialize.java.CompactedJavaSerialization
-nativejava=org.apache.dubbo.common.serialize.nativejava.NativeJavaSerialization
\ No newline at end of file
diff --git a/dubbo-spi-serialization/pom.xml b/dubbo-spi-serialization/pom.xml
index a978639..3536885 100644
--- a/dubbo-spi-serialization/pom.xml
+++ b/dubbo-spi-serialization/pom.xml
@@ -32,7 +32,6 @@
         <module>dubbo-serialization-fastjson</module>
         <module>dubbo-serialization-kryo</module>
         <module>dubbo-serialization-fst</module>
-        <module>dubbo-serialization-jdk</module>
         <module>dubbo-serialization-protostuff</module>
         <module>dubbo-serialization-avro</module>
         <module>dubbo-serialization-test</module>


[dubbo-spi-extensions] 39/39: Merge pull request #12 from KeRan213539/api-docs-20210120

Posted by li...@apache.org.
This is an automated email from the ASF dual-hosted git repository.

liujun pushed a commit to branch 2.7.x
in repository https://gitbox.apache.org/repos/asf/dubbo-spi-extensions.git

commit f6d4d2dec24d7ad78031ab8e5aeef2319cd61757
Merge: ce6bc20 1d0cb55
Author: ken.lj <ke...@gmail.com>
AuthorDate: Sat Jan 30 19:28:06 2021 +0800

    Merge pull request #12 from KeRan213539/api-docs-20210120
    
    fix #7, fix #9, fix #10

 dubbo-api-docs/codestyle/checkstyle.xml            |  25 ++++
 .../codestyle/dubbo_codestyle_for_idea.xml         |  33 +++++
 .../apache/dubbo/apidocs/annotations/ApiDoc.java   |   1 +
 .../dubbo/apidocs/annotations/ApiModule.java       |   1 +
 .../core/DubboApiDocsAnnotationScanner.java        | 139 +++++++++++++++++----
 .../apidocs/core/beans/ApiParamsCacheItem.java     |  13 ++
 .../dubbo/apidocs/core/beans/HtmlTypeEnum.java     |  10 ++
 .../core/providers/DubboDocProviderImpl.java       |   4 -
 .../apache/dubbo/apidocs/utils/ClassTypeUtil.java  |  81 ++++++++----
 .../apidocs/examples/api/IQuickStartDemo.java      |  29 ++++-
 ...RequestBean.java => QuickStartRequestBase.java} |  58 +++++----
 .../examples/params/QuickStartRequestBean.java     |   4 +-
 ...equestBean.java => QuickStartRequestBean2.java} |  39 +++---
 .../examples/params/QuickStartRespBean.java        |   4 +-
 .../src/main/resources/application.yml             |  17 +++
 .../src/main/resources/bootstrap.yml               |  17 +++
 .../examples-provider/pom.xml                      |   5 -
 .../examples/api/impl/QuickStartDemoImpl.java      |  36 +++++-
 .../examples/spi/DubboDocExporterListener.java}    |  44 +++----
 .../examples/spi/TestConfigInitializer.java}       |  26 ++--
 .../examples/spi/TestConfigPostProcessor.java}     |  40 +++---
 .../org.apache.dubbo.config.ConfigInitializer      |   1 +
 .../org.apache.dubbo.config.ConfigPostProcessor    |   1 +
 .../dubbo/org.apache.dubbo.rpc.ExporterListener    |   1 +
 .../src/main/resources/application.yml             |  22 +++-
 dubbo-api-docs/pom.xml                             |  84 ++++++++++++-
 26 files changed, 559 insertions(+), 176 deletions(-)


[dubbo-spi-extensions] 26/39: 修改说明文档

Posted by li...@apache.org.
This is an automated email from the ASF dual-hosted git repository.

liujun pushed a commit to branch 2.7.x
in repository https://gitbox.apache.org/repos/asf/dubbo-spi-extensions.git

commit 4d371e9a4ef1e8709061f19e737502f45574decc
Author: qq213539 <21...@qq.com>
AuthorDate: Tue Dec 22 15:22:31 2020 +0800

    修改说明文档
---
 dubbo-api-docs/README.md    | 54 +++++++++++++++++++++++++++++++--------------
 dubbo-api-docs/README_ch.md | 43 ++++++++++++++++++++++--------------
 2 files changed, 64 insertions(+), 33 deletions(-)

diff --git a/dubbo-api-docs/README.md b/dubbo-api-docs/README.md
index 3ed8aed..baebc8d 100644
--- a/dubbo-api-docs/README.md
+++ b/dubbo-api-docs/README.md
@@ -6,12 +6,27 @@ Dubbo api documents, test tools, generate documents according to annotations, an
 
 Adding some annotations can generate a swagger like document without turning a non web Dubbo project into a web project
 
+## Involving repositorys
+* [dubbo-spi-extensions](https://github.com/apache/dubbo-spi-extensions)
+  [\branch: 2.7.x\dubbo-api-docs](https://github.com/apache/dubbo-spi-extensions/tree/2.7.x/dubbo-api-docs):
+  Dubbo-Api-Docs related annotation ,annotation parsing
+* [dubbo-admin](https://github.com/KeRan213539/dubbo-admin): Dubbo-Api-Docs document display, test function
+
 ## How to use?
+
 1. Dubbo api docs annotation added to method parameters of Dubbo project
-   * Dubbo provider project introduces dubbo-api-docs-core
-   * If Dubbo's interface and parameters are a separate jar package project, introduce dubbo-api-docs-annotations
+    * Dubbo provider project introduces dubbo-api-docs-core
+    * If Dubbo's interface and parameters are a separate jar package project, introduce dubbo-api-docs-annotations
+    * Add the annotation @EnableDubboApiDocs to the project startup class (marked with @SpringBootApplication) 
+      or configuration class (marked with @Configuration) of the provider project to enable the Dubbo API Docs
+       * In order to avoid increasing the resource consumption in the production environment, it is recommended
+         to create a configuration class to enable Dubbo API Docs, and use it with the @Profile("dev") annotation
+       * Of course, Dubbo API Docs consumed a little CPU resources when the project starting and used a little 
+         memory for caching. In the future, it will consider putting the contents of the cache into the metadata 
+         center
 
 ### Current Version: Same as Dubbo version
+
 ```
 <dependency>
     <groupId>org.apache.dubbo</groupId>
@@ -25,7 +40,9 @@ Adding some annotations can generate a swagger like document without turning a n
     <version>${dubbo-version}</version>
 </dependency>
 ```
-2. Download [dubbo-admin](https://github.com/apache/dubbo-admin) [Download](https://github.com/apache/dubbo-admin/releases)
+
+2.
+Download [dubbo-admin](https://github.com/apache/dubbo-admin) [Download](https://github.com/apache/dubbo-admin/releases)
 
 3. Start dubbo-admin
 
@@ -34,16 +51,18 @@ Adding some annotations can generate a swagger like document without turning a n
 5. Enter the "API Doc" module
 
 ### Annotation use
-* @ApiModule class annotation: dubbo API module information, used to mark the purpose of an interface class module
+
+* @EnableDubboApiDocs: 配制注解, 启用 dubbo api docs 功能
+* @ApiModule: class annotation, dubbo API module information, used to mark the purpose of an interface class module
     * value: module name
     * apiInterface: Provider implemented interface
     * version: module version
-* @ApiDoc method annotation: dubbo API information, used to mark the purpose of an dubbo API
+* @ApiDoc: method annotation, dubbo API information, used to mark the purpose of an dubbo API
     * value: API name
     * description: API description(HTML tags available)
     * version: API version
     * responseClassDescription: response class description
-* @RequestParam class property/method Parameter annotation: mark request parameters
+* @RequestParam: class property/method Parameter annotation, mark request parameters
     * value: parameter name
     * required: true/false required parameter
     * description: parameter description
@@ -51,33 +70,34 @@ Adding some annotations can generate a swagger like document without turning a n
     * defaultValue: parameter default value
     * allowableValues: Allowed values. After setting this property, a drop-down list will be generated for the parameter
         * Note: a drop-down selection box will be generated after using this property
-        * Parameters of boolean type do not need to be set with this property. A drop-down list of true / false will be generated by default
-        * Parameters of enumeration type will automatically generate a drop-down list. If you do not want to open all enumeration values, you can set this property separately.
-* @ResponseProperty Class attribute annotation: mark response parameters
+        * Parameters of boolean type do not need to be set with this property. A drop-down list of true / false will be
+          generated by default
+        * Parameters of enumeration type will automatically generate a drop-down list. If you do not want to open all
+          enumeration values, you can set this property separately.
+* @ResponseProperty: Class attribute annotation, mark response parameters
     * value: parameter name
     * example: example
 
 ### Use note
+
 * Get API list direct connection:
+
 > Because Dubbo services with different functions may be registered in the same registration center,
-> but the name of the interface used by Dubbo doc is the same, so the interface of Dubbo doc uses direct
-connection to obtain the list of different interfaces of different functions.
+> but the name of the interface used by Dubbo doc is the same, so the interface of Dubbo doc uses direct connection to obtain the list of different interfaces of different functions.
 > The test can be connected directly or through the registration center
 
 * The response bean (the return type of the interface) supports custom generics, but only one generic placeholder.
-* About the use of Map: the key of map can only use the basic data type. If the key of map is not the basic data type, the generated key is not in the standard JSON format, and an exception will occur
+* About the use of Map: the key of map can only use the basic data type. If the key of map is not the basic data type,
+  the generated key is not in the standard JSON format, and an exception will occur
 * The API's synchronous / asynchronous is from org.apache.dubbo.config.annotation.Service.async
 
 ## Project structure
+
 * dubbo-api-docs-annotations: Document generation annotation project
 * dubbo-api-docs-core: Responsible for annotation analysis and document information acquisition interface (Dubbo API)
 * dubbo-api-docs-examples: Use example
 * readmeImgs: Pictures used by README.md
 
-## Major dependent version
-* spring-boot: 2.3.4.RELEASE
-* dubbo: apache dubbo 2.7.8
-* icework in front(iceworks 4.0)
-
 ## Screenshot
+
 ![Screenshot](./readmeImgs/dubbo_docs_en.png)
diff --git a/dubbo-api-docs/README_ch.md b/dubbo-api-docs/README_ch.md
index 89c231d..4633a4d 100644
--- a/dubbo-api-docs/README_ch.md
+++ b/dubbo-api-docs/README_ch.md
@@ -6,11 +6,22 @@ dubbo 接口文档、测试工具,根据注解生成文档,并提供测试功能
 
 增加一些注解就能生成类似swagger的文档, 不会把非web的dubbo项目变为web项目.
 
+## 相关项目
+* [dubbo-spi-extensions](https://github.com/apache/dubbo-spi-extensions)
+  [\分支: 2.7.x\dubbo-api-docs](https://github.com/apache/dubbo-spi-extensions/tree/2.7.x/dubbo-api-docs):
+  Dubbo-Api-Docs 相关注解,解析注解
+* [dubbo-admin](https://github.com/KeRan213539/dubbo-admin): Dubbo-Api-Docs 文档展示,测试功能
+
 ## 如何使用?
-1. dubbo项目的方法参数中加上 dubbo api docs注解
-   * dubbo提供者项目引入 dubbo-api-docs-core
-   * 如果dubbo的接口和参数是一个单独的jar包项目,引入dubbo-api-docs-annotations
-   
+
+1. dubbo项目的方法参数中加上 dubbo api docs 注解
+    * dubbo提供者项目引入 dubbo-api-docs-core
+    * 如果dubbo的接口和参数是一个单独的jar包项目,引入dubbo-api-docs-annotations
+    * 在提供者项目的项目启动类(标注了@SpringBootApplication的类)或者配制类(标注了@Configuration的类)中增加注解 
+      @EnableDubboApiDocs 以启用Dubbo Api Docs功能
+        * 为避免增加生产环境中的资源占用, 建议单独创建一个配制类用于启用Dubbo Api Docs, 并配合 @Profile("dev") 注解使用
+        * 当然, Dubbo Api Docs 仅在项目启动时多消耗了点CPU资源, 并使用了一点点内存用于缓存, 将来会考虑将缓存中的内容放到元数据中心.
+
 ### 当前版本: 同Dubbo版本号
 
 ```
@@ -36,16 +47,18 @@ dubbo 接口文档、测试工具,根据注解生成文档,并提供测试功能
 5. 进入"接口文档"模块
 
 ### 注解使用
-* @ApiModule 类注解: dubbo接口模块信息,用于标注一个接口类模块的用途
+
+* @EnableDubboApiDocs: 配制注解, 启用 dubbo api docs 功能
+* @ApiModule: 类注解, dubbo接口模块信息,用于标注一个接口类模块的用途
     * value: 模块名称
     * apiInterface: 提供者实现的接口
     * version: 模块版本
-* @ApiDoc 方法注解: dubbo 接口信息,用于标注一个接口的用途
+* @ApiDoc: 方法注解, dubbo 接口信息,用于标注一个接口的用途
     * value: 接口名称
     * description: 接口描述(可使用html标签)
     * version: 接口版本
     * responseClassDescription: 响应的数据的描述
-* @RequestParam 类属性/方法参数注解:标注请求参数
+* @RequestParam: 类属性/方法参数注解,标注请求参数
     * value: 参数名
     * required: 是否必传参数
     * description: 参数描述
@@ -55,31 +68,29 @@ dubbo 接口文档、测试工具,根据注解生成文档,并提供测试功能
         * 注:使用该属性后将生成下拉选择框
         * boolean 类型的参数不用设置该属性,将默认生成 true/false 的下拉列表
         * 枚举类型的参数会自动生成下拉列表,如果不想开放全部的枚举值,可以单独设置此属性.
-* @ResponseProperty 类属性注解: 标注响应参数
+* @ResponseProperty: 类属性注解, 标注响应参数
     * value: 参数名
     * example: 示例
-    
+
 ### 使用注意
+
 * 获取接口列表直连:
+
 > 由于可能不同功能的dubbo服务都会注册到同一个注册中心,但是dubbo doc
 > 使用的接口名是一样的,所以dubbo doc的接口采用直连方式以获取到不同功能服务的不同接口列表
 > 测试可以直连或者走注册中心
 
 * 响应bean(接口的返回类型)支持自定义泛型, 但只支持一个泛型占位符
-* 关于Map的使用:Map的key只能用基本数据类型.如果Map的key不是基础数据类型,生成的
-就不是标准json格式,会出异常
+* 关于Map的使用:Map的key只能用基本数据类型.如果Map的key不是基础数据类型,生成的 就不是标准json格式,会出异常
 * 接口的同步/异步取自 org.apache.dubbo.config.annotation.Service.async
 
 ## 项目结构
+
 * dubbo-api-docs-annotations: 文档生成辅助注解项目
 * dubbo-api-docs-core: 负责注解解析,文档信息获取接口(dubbo接口)
 * dubbo-api-docs-examples: 使用示例
 * readmeImgs: README.md 用到的图片
 
-## 主要依赖版本
-* spring-boot: 2.3.4.RELEASE
-* dubbo: apache dubbo 2.7.8
-* 前端使用飞冰(iceworks 4.0)
-
 ## 页面截图
+
 ![页面截图](./readmeImgs/dubbo_docs_zh.png)
\ No newline at end of file


[dubbo-spi-extensions] 02/39: init project:move some sub-modules from apache/dubbo to here

Posted by li...@apache.org.
This is an automated email from the ASF dual-hosted git repository.

liujun pushed a commit to branch 2.7.x
in repository https://gitbox.apache.org/repos/asf/dubbo-spi-extensions.git

commit 193bdaa36c0038c71422653013cf20439cc3032d
Author: ken.lj <ke...@gmail.com>
AuthorDate: Mon May 18 13:53:13 2020 +0800

    init project:move some sub-modules from apache/dubbo to here
---
 .gitignore                                         |   43 +
 .mvn/wrapper/maven-wrapper.jar                     |  Bin 0 -> 47774 bytes
 .mvn/wrapper/maven-wrapper.properties              |    1 +
 CODE_OF_CONDUCT.md                                 |   46 +
 CONTRIBUTING.md                                    |   76 +
 LICENSE                                            |  202 +
 NOTICE                                             |    6 +
 PULL_REQUEST_TEMPLATE.md                           |   20 +
 SECURITY.md                                        |   31 +
 codestyle/checkstyle-suppressions.xml              |    8 +
 codestyle/checkstyle.xml                           |   38 +
 codestyle/dubbo_codestyle_for_idea.xml             |   16 +
 codestyle/manage_profiles.png                      |  Bin 0 -> 430 bytes
 compiler/pom.xml                                   |  237 +
 .../org/apache/dubbo/gen/AbstractGenerator.java    |  293 ++
 .../org/apache/dubbo/gen/dubbo/DubboGenerator.java |   42 +
 .../apache/dubbo/gen/grpc/DubboGrpcGenerator.java  |   41 +
 .../grpc/reactive/ReactorDubboGrpcGenerator.java   |   42 +
 .../gen/grpc/reactive/RxDubboGrpcGenerator.java    |   41 +
 compiler/src/main/resources/DubboGrpcStub.mustache |  312 ++
 compiler/src/main/resources/DubboStub.mustache     |   53 +
 .../main/resources/ReactorDubboGrpcStub.mustache   |  212 +
 .../src/main/resources/RxDubboGrpcStub.mustache    |  246 +
 .../dubbo-configcenter-apollo/pom.xml              |   52 +
 .../support/apollo/ApolloDynamicConfiguration.java |  258 +
 .../apollo/ApolloDynamicConfigurationFactory.java  |   31 +
 ...config.configcenter.DynamicConfigurationFactory |    1 +
 .../apollo/ApolloDynamicConfigurationTest.java     |  191 +
 .../src/test/resources/META-INF/app.properties     |    1 +
 .../src/test/resources/mockdata-dubbo.properties   |    2 +
 .../dubbo-configcenter-consul/pom.xml              |   47 +
 .../consul/ConsulDynamicConfiguration.java         |  218 +
 .../consul/ConsulDynamicConfigurationFactory.java  |   32 +
 ...config.configcenter.DynamicConfigurationFactory |    1 +
 .../consul/ConsulDynamicConfigurationTest.java     |  109 +
 .../dubbo-configcenter-etcd/pom.xml                |   74 +
 .../support/etcd/EtcdDynamicConfiguration.java     |  197 +
 .../etcd/EtcdDynamicConfigurationFactory.java      |   33 +
 ...config.configcenter.DynamicConfigurationFactory |    1 +
 .../support/etcd/EtcdDynamicConfigurationTest.java |  154 +
 .../dubbo-configcenter-nacos/pom.xml               |   45 +
 .../support/nacos/NacosDynamicConfiguration.java   |  381 ++
 .../nacos/NacosDynamicConfigurationFactory.java    |   41 +
 ...config.configcenter.DynamicConfigurationFactory |    1 +
 .../nacos/NacosDynamicConfigurationTest.java       |  188 +
 dubbo-spi-configcenter/pom.xml                     |   38 +
 dubbo-spi-container/dubbo-container-log4j/pom.xml  |   38 +
 .../dubbo/container/log4j/Log4jContainer.java      |  103 +
 .../internal/org.apache.dubbo.container.Container  |    1 +
 .../dubbo/container/log4j/Log4jContainerTest.java  |   36 +
 .../dubbo-container-logback/pom.xml                |   42 +
 .../dubbo/container/logback/LogbackContainer.java  |  108 +
 .../internal/org.apache.dubbo.container.Container  |    1 +
 .../container/logback/LogbackContainerTest.java    |   47 +
 dubbo-spi-container/pom.xml                        |   35 +
 dubbo-spi-filter/dubbo-filter-cache/pom.xml        |   48 +
 .../main/java/org/apache/dubbo/cache/Cache.java    |   43 +
 .../java/org/apache/dubbo/cache/CacheFactory.java  |   43 +
 .../org/apache/dubbo/cache/filter/CacheFilter.java |  133 +
 .../dubbo/cache/support/AbstractCacheFactory.java  |   72 +
 .../cache/support/expiring/ExpiringCache.java      |   77 +
 .../support/expiring/ExpiringCacheFactory.java     |   44 +
 .../dubbo/cache/support/expiring/ExpiringMap.java  |  374 ++
 .../apache/dubbo/cache/support/jcache/JCache.java  |   87 +
 .../dubbo/cache/support/jcache/JCacheFactory.java  |   48 +
 .../apache/dubbo/cache/support/lfu/LfuCache.java   |   80 +
 .../dubbo/cache/support/lfu/LfuCacheFactory.java   |   43 +
 .../apache/dubbo/cache/support/lru/LruCache.java   |   80 +
 .../dubbo/cache/support/lru/LruCacheFactory.java   |   43 +
 .../support/threadlocal/ThreadLocalCache.java      |   77 +
 .../threadlocal/ThreadLocalCacheFactory.java       |   43 +
 .../internal/org.apache.dubbo.cache.CacheFactory   |    4 +
 .../dubbo/internal/org.apache.dubbo.rpc.Filter     |    1 +
 .../apache/dubbo/cache/filter/CacheFilterTest.java |  137 +
 .../cache/support/AbstractCacheFactoryTest.java    |   33 +
 .../support/expiring/ExpiringCacheFactoryTest.java |   38 +
 .../cache/support/jcache/JCacheFactoryTest.java    |   55 +
 .../cache/support/lru/LruCacheFactoryTest.java     |   38 +
 .../threadlocal/ThreadLocalCacheFactoryTest.java   |   38 +
 dubbo-spi-filter/dubbo-filter-validation/pom.xml   |   72 +
 .../apache/dubbo/validation/MethodValidated.java   |   40 +
 .../org/apache/dubbo/validation/Validation.java    |   39 +
 .../org/apache/dubbo/validation/Validator.java     |   27 +
 .../dubbo/validation/filter/ValidationFilter.java  |  104 +
 .../validation/support/AbstractValidation.java     |   51 +
 .../support/jvalidation/JValidation.java           |   40 +
 .../validation/support/jvalidation/JValidator.java |  330 ++
 .../dubbo/internal/org.apache.dubbo.rpc.Filter     |    1 +
 .../org.apache.dubbo.validation.Validation         |    1 +
 .../validation/filter/ValidationFilterTest.java    |  137 +
 .../support/jvalidation/JValidationTest.java       |   50 +
 .../support/jvalidation/JValidatorTest.java        |   86 +
 .../jvalidation/mock/JValidatorTestTarget.java     |   41 +
 .../jvalidation/mock/ValidationParameter.java      |   31 +
 dubbo-spi-filter/pom.xml                           |   35 +
 .../dubbo-metadata-report-consul/pom.xml           |   41 +
 .../store/consul/ConsulMetadataReport.java         |  135 +
 .../store/consul/ConsulMetadataReportFactory.java  |   32 +
 ...che.dubbo.metadata.report.MetadataReportFactory |    1 +
 .../dubbo-metadata-report-etcd/pom.xml             |   69 +
 .../metadata/store/etcd/EtcdMetadataReport.java    |  150 +
 .../store/etcd/EtcdMetadataReportFactory.java      |   50 +
 ...che.dubbo.metadata.report.MetadataReportFactory |    1 +
 .../store/etcd/EtcdMetadata4TstService.java        |   28 +
 .../store/etcd/EtcdMetadataReportTest.java         |  259 +
 .../dubbo-metadata-report-nacos/pom.xml            |   41 +
 .../metadata/store/nacos/NacosMetadataReport.java  |  234 +
 .../store/nacos/NacosMetadataReportFactory.java    |   32 +
 ...che.dubbo.metadata.report.MetadataReportFactory |    1 +
 .../store/nacos/NacosMetadata4TstService.java      |   28 +
 .../store/nacos/NacosMetadataReportTest.java       |  247 +
 .../dubbo-metadata-report-redis/pom.xml            |   57 +
 .../metadata/store/redis/RedisMetadataReport.java  |  201 +
 .../store/redis/RedisMetadataReportFactory.java    |   34 +
 ...che.dubbo.metadata.report.MetadataReportFactory |    1 +
 .../store/redis/RedisMetadata4TstService.java      |   28 +
 .../store/redis/RedisMetadataReportTest.java       |  220 +
 dubbo-spi-metadata/pom.xml                         |   41 +
 dubbo-spi-registry/dubbo-registry-consul/pom.xml   |   62 +
 .../registry/consul/AbstractConsulRegistry.java    |   39 +
 .../dubbo/registry/consul/ConsulRegistry.java      |  360 ++
 .../registry/consul/ConsulRegistryFactory.java     |   32 +
 .../registry/consul/ConsulServiceDiscovery.java    |  394 ++
 .../org.apache.dubbo.registry.RegistryFactory      |    1 +
 ...g.apache.dubbo.registry.client.ServiceDiscovery |    1 +
 .../dubbo/registry/consul/ConsulRegistryTest.java  |  135 +
 .../consul/ConsulServiceDiscoveryTest.java         |  108 +
 dubbo-spi-registry/dubbo-registry-default/pom.xml  |   68 +
 .../apache/dubbo/registry/dubbo/DubboRegistry.java |  161 +
 .../dubbo/registry/dubbo/DubboRegistryFactory.java |  118 +
 .../org.apache.dubbo.registry.RegistryFactory      |    1 +
 .../registry/dubbo/AbstractRegistryService.java    |  237 +
 .../apache/dubbo/registry/dubbo/DemoService.java   |   27 +
 .../dubbo/registry/dubbo/DemoServiceImpl.java      |   32 +
 .../dubbo/registry/dubbo/DubboRegistryTest.java    |  155 +
 .../apache/dubbo/registry/dubbo/MockChannel.java   |  141 +
 .../apache/dubbo/registry/dubbo/MockedClient.java  |  298 ++
 .../registry/dubbo/RegistryDirectoryTest.java      | 1143 +++++
 .../dubbo/registry/dubbo/RegistryProtocolTest.java |  233 +
 .../registry/dubbo/RegistryStatusCheckerTest.java  |   69 +
 .../registry/dubbo/SimpleRegistryExporter.java     |   87 +
 .../registry/dubbo/SimpleRegistryService.java      |  146 +
 .../src/test/resources/log4j.xml                   |   38 +
 dubbo-spi-registry/dubbo-registry-etcd3/pom.xml    |   51 +
 .../apache/dubbo/registry/etcd/EtcdRegistry.java   |  359 ++
 .../dubbo/registry/etcd/EtcdRegistryFactory.java   |   36 +
 .../dubbo/registry/etcd/EtcdServiceDiscovery.java  |  208 +
 .../org.apache.dubbo.registry.RegistryFactory      |    1 +
 ...g.apache.dubbo.registry.client.ServiceDiscovery |    1 +
 .../dubbo/registry/etcd/EtcdRegistryTest.java      |  327 ++
 .../registry/etcd/EtcdServiceDiscoveryTest.java    |  124 +
 dubbo-spi-registry/dubbo-registry-eureka/pom.xml   |   85 +
 .../eureka/ConfigurableEurekaInstanceConfig.java   |  369 ++
 .../registry/eureka/EurekaServiceDiscovery.java    |  279 ++
 .../apache/dubbo/registry/eureka/package-info.java |   22 +
 ...g.apache.dubbo.registry.client.ServiceDiscovery |    1 +
 .../eureka/EurekaServiceDiscoveryTest.java         |   67 +
 dubbo-spi-registry/dubbo-registry-multiple/pom.xml |   65 +
 .../dubbo/registry/multiple/MultipleRegistry.java  |  337 ++
 .../registry/multiple/MultipleRegistryFactory.java |   33 +
 .../org.apache.dubbo.registry.RegistryFactory      |    1 +
 .../multiple/MultipleRegistry2S2RTest.java         |  213 +
 .../multiple/MultipleRegistryTestUtil.java         |  145 +
 dubbo-spi-registry/dubbo-registry-nacos/pom.xml    |   83 +
 .../apache/dubbo/registry/nacos/NacosRegistry.java |  629 +++
 .../dubbo/registry/nacos/NacosRegistryFactory.java |   42 +
 .../registry/nacos/NacosServiceDiscovery.java      |  130 +
 .../dubbo/registry/nacos/NacosServiceName.java     |  234 +
 .../nacos/util/NacosInstanceManageUtil.java        |   67 +
 .../nacos/util/NacosNamingServiceUtils.java        |  192 +
 .../org.apache.dubbo.registry.RegistryFactory      |    1 +
 ...g.apache.dubbo.registry.client.ServiceDiscovery |    1 +
 dubbo-spi-registry/dubbo-registry-redis/pom.xml    |   52 +
 .../apache/dubbo/registry/redis/RedisRegistry.java |  661 +++
 .../dubbo/registry/redis/RedisRegistryFactory.java |   34 +
 .../org.apache.dubbo.registry.RegistryFactory      |    1 +
 .../dubbo/registry/redis/RedisRegistryTest.java    |  130 +
 dubbo-spi-registry/dubbo-registry-sofa/pom.xml     |  133 +
 .../apache/dubbo/registry/sofa/SofaRegistry.java   |  300 ++
 .../dubbo/registry/sofa/SofaRegistryConstants.java |   43 +
 .../dubbo/registry/sofa/SofaRegistryFactory.java   |   41 +
 .../org.apache.dubbo.registry.RegistryFactory      |    1 +
 .../apache/dubbo/registry/sofa/HelloService.java   |   24 +
 .../dubbo/registry/sofa/HelloServiceImpl.java      |   44 +
 .../src/test/resources/log4j.properties            |    7 +
 dubbo-spi-registry/pom.xml                         |   41 +
 dubbo-spi-remoting/dubbo-remoting-etcd3/pom.xml    |  106 +
 .../dubbo/remoting/etcd/AbstractRetryPolicy.java   |   45 +
 .../apache/dubbo/remoting/etcd/ChildListener.java  |   25 +
 .../org/apache/dubbo/remoting/etcd/Constants.java  |   55 +
 .../org/apache/dubbo/remoting/etcd/EtcdClient.java |  191 +
 .../dubbo/remoting/etcd/EtcdTransporter.java       |   47 +
 .../apache/dubbo/remoting/etcd/RetryPolicy.java    |   31 +
 .../apache/dubbo/remoting/etcd/StateListener.java  |   27 +
 .../etcd/jetcd/ConnectionStateListener.java        |   31 +
 .../dubbo/remoting/etcd/jetcd/JEtcdClient.java     |  473 ++
 .../remoting/etcd/jetcd/JEtcdClientWrapper.java    |  754 +++
 .../remoting/etcd/jetcd/JEtcdTransporter.java      |   30 +
 .../dubbo/remoting/etcd/jetcd/RetryLoops.java      |   99 +
 .../dubbo/remoting/etcd/jetcd/RetryNTimes.java     |   36 +
 .../dubbo/remoting/etcd/option/OptionUtil.java     |   78 +
 .../remoting/etcd/support/AbstractEtcdClient.java  |  194 +
 .../org.apache.dubbo.remoting.etcd.EtcdTransporter |    1 +
 .../dubbo/remoting/etcd/jetcd/JEtcdClientTest.java |  427 ++
 .../etcd/jetcd/JEtcdClientWrapperTest.java         |  187 +
 .../dubbo/remoting/etcd/jetcd/LeaseTest.java       |  154 +
 dubbo-spi-remoting/dubbo-remoting-grizzly/pom.xml  |   42 +
 .../remoting/transport/grizzly/GrizzlyChannel.java |  198 +
 .../remoting/transport/grizzly/GrizzlyClient.java  |  112 +
 .../transport/grizzly/GrizzlyCodecAdapter.java     |  145 +
 .../remoting/transport/grizzly/GrizzlyHandler.java |  118 +
 .../remoting/transport/grizzly/GrizzlyServer.java  |  127 +
 .../transport/grizzly/GrizzlyTransporter.java      |   43 +
 .../internal/org.apache.dubbo.remoting.Transporter |    1 +
 .../transport/grizzly/GrizzlyTransporterTest.java  |   41 +
 dubbo-spi-remoting/dubbo-remoting-http/pom.xml     |   61 +
 .../org/apache/dubbo/remoting/http/HttpBinder.java |   39 +
 .../apache/dubbo/remoting/http/HttpHandler.java    |   39 +
 .../org/apache/dubbo/remoting/http/HttpServer.java |   72 +
 .../dubbo/remoting/http/jetty/JettyHttpBinder.java |   34 +
 .../dubbo/remoting/http/jetty/JettyHttpServer.java |  112 +
 .../remoting/http/servlet/BootstrapListener.java   |   37 +
 .../remoting/http/servlet/DispatcherServlet.java   |   65 +
 .../remoting/http/servlet/ServletHttpBinder.java   |   34 +
 .../remoting/http/servlet/ServletHttpServer.java   |   31 +
 .../remoting/http/servlet/ServletManager.java      |   50 +
 .../remoting/http/support/AbstractHttpServer.java  |  134 +
 .../remoting/http/tomcat/TomcatHttpBinder.java     |   31 +
 .../remoting/http/tomcat/TomcatHttpServer.java     |   93 +
 .../org.apache.dubbo.remoting.http.HttpBinder      |    3 +
 .../remoting/http/jetty/JettyHttpBinderTest.java   |   53 +
 .../remoting/http/tomcat/TomcatHttpBinderTest.java |   55 +
 dubbo-spi-remoting/dubbo-remoting-mina/pom.xml     |   52 +
 .../dubbo/remoting/transport/mina/MinaChannel.java |  191 +
 .../dubbo/remoting/transport/mina/MinaClient.java  |  174 +
 .../remoting/transport/mina/MinaCodecAdapter.java  |  167 +
 .../dubbo/remoting/transport/mina/MinaHandler.java |   95 +
 .../dubbo/remoting/transport/mina/MinaServer.java  |  112 +
 .../remoting/transport/mina/MinaTransporter.java   |   40 +
 .../internal/org.apache.dubbo.remoting.Transporter |    1 +
 .../transport/mina/ClientToServerTest.java         |   92 +
 .../remoting/transport/mina/ClientsTest.java       |   65 +
 .../org/apache/remoting/transport/mina/Hello.java  |   45 +
 .../transport/mina/MinaClientToServerTest.java     |   41 +
 .../org/apache/remoting/transport/mina/World.java  |   45 +
 .../remoting/transport/mina/WorldHandler.java      |   36 +
 dubbo-spi-remoting/dubbo-remoting-p2p/pom.xml      |   44 +
 .../java/org/apache/dubbo/remoting/p2p/Group.java  |   57 +
 .../org/apache/dubbo/remoting/p2p/Networker.java   |   39 +
 .../org/apache/dubbo/remoting/p2p/Networkers.java  |   47 +
 .../java/org/apache/dubbo/remoting/p2p/Peer.java   |   36 +
 .../dubbo/remoting/p2p/exchange/ExchangeGroup.java |   36 +
 .../remoting/p2p/exchange/ExchangeNetworker.java   |   35 +
 .../remoting/p2p/exchange/ExchangeNetworkers.java  |   45 +
 .../dubbo/remoting/p2p/exchange/ExchangePeer.java  |   26 +
 .../exchange/support/AbstractExchangeGroup.java    |  128 +
 .../p2p/exchange/support/ExchangeServerPeer.java   |  137 +
 .../p2p/exchange/support/FileExchangeGroup.java    |  135 +
 .../exchange/support/FileExchangeNetworker.java    |   34 +
 .../exchange/support/MulticastExchangeGroup.java   |  108 +
 .../support/MulticastExchangeNetworker.java        |   34 +
 .../dubbo/remoting/p2p/support/AbstractGroup.java  |  119 +
 .../dubbo/remoting/p2p/support/FileGroup.java      |  133 +
 .../dubbo/remoting/p2p/support/FileNetworker.java  |   34 +
 .../dubbo/remoting/p2p/support/MulticastGroup.java |  108 +
 .../remoting/p2p/support/MulticastNetworker.java   |   34 +
 .../dubbo/remoting/p2p/support/ServerPeer.java     |  124 +
 .../org.apache.dubbo.remoting.p2p.Networker        |    2 +
 .../support/MulticastExchangeNetworkerTest.java    |   81 +
 .../remoting/p2p/support/FileNetworkerTest.java    |   83 +
 .../p2p/support/MulticastNetworkerTest.java        |   70 +
 .../dubbo-remoting-zookeeper/pom.xml               |   56 +
 .../dubbo/remoting/zookeeper/ChildListener.java    |   25 +
 .../dubbo/remoting/zookeeper/DataListener.java     |   25 +
 .../apache/dubbo/remoting/zookeeper/EventType.java |   65 +
 .../dubbo/remoting/zookeeper/StateListener.java    |   33 +
 .../dubbo/remoting/zookeeper/ZookeeperClient.java  |   65 +
 .../remoting/zookeeper/ZookeeperTransporter.java   |   30 +
 .../zookeeper/curator/CuratorZookeeperClient.java  |  398 ++
 .../curator/CuratorZookeeperTransporter.java       |   30 +
 .../zookeeper/support/AbstractZookeeperClient.java |  226 +
 .../support/AbstractZookeeperTransporter.java      |  182 +
 ...e.dubbo.remoting.zookeeper.ZookeeperTransporter |    1 +
 .../curator/CuratorZookeeperClientTest.java        |  195 +
 .../curator/CuratorZookeeperTransporterTest.java   |   57 +
 .../support/AbstractZookeeperTransporterTest.java  |  225 +
 dubbo-spi-remoting/pom.xml                         |   40 +
 dubbo-spi-rpc/dubbo-rpc-grpc/pom.xml               |   68 +
 .../rpc/protocol/grpc/DubboHandlerRegistry.java    |   70 +
 .../apache/dubbo/rpc/protocol/grpc/GrpcConfig.java |   21 +
 .../dubbo/rpc/protocol/grpc/GrpcConstants.java     |   41 +
 .../dubbo/rpc/protocol/grpc/GrpcInvoker.java       |  118 +
 .../dubbo/rpc/protocol/grpc/GrpcOptionsUtils.java  |  225 +
 .../dubbo/rpc/protocol/grpc/GrpcProtocol.java      |  239 +
 .../grpc/ReferenceCountManagedChannel.java         |   85 +
 .../grpc/interceptors/ClientInterceptor.java       |   26 +
 .../grpc/interceptors/GrpcConfigurator.java        |   41 +
 .../grpc/interceptors/RpcContextInterceptor.java   |  100 +
 .../grpc/interceptors/ServerInterceptor.java       |   26 +
 .../grpc/interceptors/ServerTransportFilter.java   |   27 +
 .../dubbo/internal/org.apache.dubbo.rpc.Protocol   |    1 +
 ...pc.protocol.grpc.interceptors.ClientInterceptor |    1 +
 ...pc.protocol.grpc.interceptors.ServerInterceptor |    1 +
 dubbo-spi-rpc/dubbo-rpc-hessian/pom.xml            |   62 +
 .../dubbo/rpc/protocol/hessian/Constants.java      |   35 +
 .../hessian/DubboHessianURLConnectionFactory.java  |   41 +
 .../rpc/protocol/hessian/HessianProtocol.java      |  202 +
 .../rpc/protocol/hessian/HttpClientConnection.java |   99 +
 .../hessian/HttpClientConnectionFactory.java       |   58 +
 .../dubbo/internal/org.apache.dubbo.rpc.Protocol   |    1 +
 .../rpc/protocol/hessian/HessianProtocolTest.java  |  250 +
 .../dubbo/rpc/protocol/hessian/HessianService.java |   37 +
 .../rpc/protocol/hessian/HessianServiceImpl.java   |   75 +
 dubbo-spi-rpc/dubbo-rpc-http/pom.xml               |   61 +
 .../dubbo/rpc/protocol/http/HttpProtocol.java      |  191 +
 .../rpc/protocol/http/HttpProtocolErrorCode.java   |   29 +
 .../rpc/protocol/http/JsonRemoteInvocation.java    |   61 +
 .../rpc/protocol/http/JsonRpcProxyFactoryBean.java |   86 +
 .../dubbo/internal/org.apache.dubbo.rpc.Protocol   |    1 +
 .../dubbo/rpc/protocol/http/HttpProtocolTest.java  |   92 +
 .../dubbo/rpc/protocol/http/HttpService.java       |   27 +
 .../dubbo/rpc/protocol/http/HttpServiceImpl.java   |   58 +
 dubbo-spi-rpc/dubbo-rpc-injvm/pom.xml              |   38 +
 .../dubbo/rpc/protocol/injvm/InjvmExporter.java    |   47 +
 .../dubbo/rpc/protocol/injvm/InjvmInvoker.java     |   65 +
 .../dubbo/rpc/protocol/injvm/InjvmProtocol.java    |  120 +
 .../dubbo/internal/org.apache.dubbo.rpc.Protocol   |    1 +
 .../dubbo/rpc/protocol/injvm/DemoRequest.java      |   58 +
 .../dubbo/rpc/protocol/injvm/DemoService.java      |   44 +
 .../dubbo/rpc/protocol/injvm/DemoServiceImpl.java  |   78 +
 .../org/apache/dubbo/rpc/protocol/injvm/IEcho.java |   21 +
 .../rpc/protocol/injvm/InjvmProtocolTest.java      |  126 +
 .../dubbo/rpc/protocol/injvm/ProtocolTest.java     |   72 +
 .../org/apache/dubbo/rpc/protocol/injvm/Type.java  |   21 +
 dubbo-spi-rpc/dubbo-rpc-memcached/pom.xml          |   42 +
 .../rpc/protocol/memcached/MemcachedProtocol.java  |  122 +
 .../dubbo/internal/org.apache.dubbo.rpc.Protocol   |    1 +
 .../protocol/memcached/MemcachedProtocolTest.java  |   21 +
 dubbo-spi-rpc/dubbo-rpc-native-thrift/pom.xml      |   49 +
 .../rpc/protocol/nativethrift/ThriftProtocol.java  |  189 +
 .../dubbo/internal/org.apache.dubbo.rpc.Protocol   |    1 +
 .../src/test/idls/DemoService.thrift               |   17 +
 .../src/test/idls/UserService.thrift               |    6 +
 .../rpc/protocol/nativethrift/DemoService.java     | 5141 ++++++++++++++++++++
 .../rpc/protocol/nativethrift/DemoServiceImpl.java |   78 +
 .../protocol/nativethrift/ThriftProtocolTest.java  |   84 +
 .../rpc/protocol/nativethrift/UserService.java     |  952 ++++
 .../rpc/protocol/nativethrift/UserServiceImpl.java |   24 +
 dubbo-spi-rpc/dubbo-rpc-redis/pom.xml              |   58 +
 .../dubbo/rpc/protocol/redis/RedisProtocol.java    |  187 +
 .../dubbo/internal/org.apache.dubbo.rpc.Protocol   |    1 +
 .../dubbo/rpc/protocol/redis/IDemoService.java     |   29 +
 .../rpc/protocol/redis/RedisProtocolTest.java      |  230 +
 ...org.apache.dubbo.common.serialize.Serialization |    1 +
 dubbo-spi-rpc/dubbo-rpc-rest/pom.xml               |  115 +
 .../rpc/protocol/rest/BaseRestProtocolServer.java  |   80 +
 .../apache/dubbo/rpc/protocol/rest/Constants.java  |   29 +
 .../rpc/protocol/rest/DubboHttpProtocolServer.java |  131 +
 .../rpc/protocol/rest/DubboResourceFactory.java    |   76 +
 .../rpc/protocol/rest/NettyRestProtocolServer.java |   73 +
 .../rpc/protocol/rest/RestConstraintViolation.java |   66 +
 .../dubbo/rpc/protocol/rest/RestProtocol.java      |  295 ++
 .../rpc/protocol/rest/RestProtocolServer.java      |   33 +
 .../dubbo/rpc/protocol/rest/RestServerFactory.java |   44 +
 .../dubbo/rpc/protocol/rest/RpcContextFilter.java  |  106 +
 .../rpc/protocol/rest/RpcExceptionMapper.java      |   51 +
 .../dubbo/rpc/protocol/rest/ViolationReport.java   |   48 +
 .../swagger/DubboSwaggerApiListingResource.java    |   48 +
 .../integration/swagger/DubboSwaggerService.java   |   43 +
 .../rpc/protocol/rest/support/ContentType.java     |   26 +
 .../rpc/protocol/rest/support/LoggingFilter.java   |  148 +
 .../dubbo/internal/org.apache.dubbo.rpc.Protocol   |    1 +
 .../dubbo/rpc/protocol/rest/DemoService.java       |   45 +
 .../dubbo/rpc/protocol/rest/DemoServiceImpl.java   |   57 +
 .../dubbo/rpc/protocol/rest/RestProtocolTest.java  |  282 ++
 .../rpc/protocol/rest/RpcExceptionMapperTest.java  |   67 +
 .../DubboSwaggerApiListingResourceTest.java        |   62 +
 .../rest/integration/swagger/SwaggerService.java   |   34 +
 dubbo-spi-rpc/dubbo-rpc-rmi/pom.xml                |   42 +
 .../rpc/protocol/rmi/RmiRemoteInvocation.java      |   39 +
 .../apache/dubbo/rpc/protocol/rmi/RmiProtocol.java |  154 +
 .../rpc/protocol/rmi/RmiRemoteInvocation.java      |   64 +
 .../dubbo/internal/org.apache.dubbo.rpc.Protocol   |    1 +
 .../apache/dubbo/rpc/protocol/rmi/DemoService.java |   47 +
 .../dubbo/rpc/protocol/rmi/DemoServiceImpl.java    |   89 +
 .../dubbo/rpc/protocol/rmi/RemoteService.java      |   26 +
 .../dubbo/rpc/protocol/rmi/RemoteServiceImpl.java  |   32 +
 .../dubbo/rpc/protocol/rmi/RmiProtocolTest.java    |  227 +
 .../org/apache/dubbo/rpc/protocol/rmi/Type.java    |   21 +
 dubbo-spi-rpc/dubbo-rpc-thrift/pom.xml             |   73 +
 .../rpc/protocol/thrift/ClassNameGenerator.java    |   31 +
 .../protocol/thrift/DubboClassNameGenerator.java   |   36 +
 .../protocol/thrift/ThriftClassNameGenerator.java  |   36 +
 .../dubbo/rpc/protocol/thrift/ThriftCodec.java     |  697 +++
 .../dubbo/rpc/protocol/thrift/ThriftConstants.java |   32 +
 .../dubbo/rpc/protocol/thrift/ThriftInvoker.java   |  171 +
 .../rpc/protocol/thrift/ThriftNativeCodec.java     |   96 +
 .../dubbo/rpc/protocol/thrift/ThriftProtocol.java  |  272 ++
 .../dubbo/rpc/protocol/thrift/ThriftType.java      |   51 +
 .../dubbo/rpc/protocol/thrift/ThriftUtils.java     |  135 +
 .../protocol/thrift/ext/MultiServiceProcessor.java |  121 +
 .../rpc/protocol/thrift/io/InputStreamWrapper.java |   88 +
 .../io/RandomAccessByteArrayOutputStream.java      |  117 +
 .../internal/org.apache.dubbo.remoting.Codec2      |    1 +
 .../dubbo/internal/org.apache.dubbo.rpc.Protocol   |    1 +
 ...he.dubbo.rpc.protocol.thrift.ClassNameGenerator |    2 +
 .../src/test/java/$__ClassNameTestDubboStub.java   |  681 +++
 .../src/test/java/ClassNameTest.java               |   45 +
 .../src/test/java/ClassNameTestDubbo.java          |   29 +
 .../src/test/java/ClassNameTestThrift.java         |  767 +++
 .../apache/dubbo/rpc/gen/dubbo/$__DemoStub.java    | 4347 +++++++++++++++++
 .../java/org/apache/dubbo/rpc/gen/dubbo/Demo.java  |   42 +
 .../java/org/apache/dubbo/rpc/gen/thrift/Demo.java | 4753 ++++++++++++++++++
 .../dubbo/rpc/protocol/thrift/AbstractTest.java    |  150 +
 .../apache/dubbo/rpc/protocol/thrift/DemoImpl.java |   56 +
 .../dubbo/rpc/protocol/thrift/DubboDemoImpl.java   |   23 +
 .../protocol/thrift/FramedTransportFactory.java    |   30 +
 .../dubbo/rpc/protocol/thrift/MockedChannel.java   |  116 +
 .../rpc/protocol/thrift/ServerExceptionTest.java   |  100 +
 .../protocol/thrift/ServiceMethodNotFoundTest.java |  146 +
 .../dubbo/rpc/protocol/thrift/ThriftCodecTest.java |  477 ++
 .../dubbo/rpc/protocol/thrift/ThriftDemoImpl.java  |   22 +
 .../rpc/protocol/thrift/ThriftProtocolTest.java    |   87 +
 .../dubbo/rpc/protocol/thrift/ThriftUtilsTest.java |   88 +
 .../thrift/examples/DubboDemoConsumer.java         |   36 +
 .../thrift/examples/DubboDemoProvider.java         |   31 +
 .../src/test/resources/dubbo-demo-consumer.xml     |   32 +
 .../src/test/resources/dubbo-demo-provider.xml     |   34 +
 .../src/test/thrift/ClassNameTestDubbo.thrift      |    3 +
 .../src/test/thrift/ClassNameTestThrift.thrift     |    3 +
 .../dubbo-rpc-thrift/src/test/thrift/Demo.thrift   |   16 +
 dubbo-spi-rpc/dubbo-rpc-webservice/pom.xml         |   76 +
 .../protocol/webservice/WebServiceProtocol.java    |  204 +
 .../dubbo/internal/org.apache.dubbo.rpc.Protocol   |    1 +
 .../dubbo/rpc/protocol/webservice/DemoService.java |   43 +
 .../rpc/protocol/webservice/DemoServiceImpl.java   |   80 +
 .../apache/dubbo/rpc/protocol/webservice/User.java |   38 +
 .../webservice/WebserviceProtocolTest.java         |   77 +
 dubbo-spi-rpc/dubbo-rpc-xml/README.md              |   88 +
 dubbo-spi-rpc/dubbo-rpc-xml/pom.xml                |   66 +
 .../xml/rpc/protocol/xmlrpc/XmlRpcProtocol.java    |  196 +
 .../protocol/xmlrpc/XmlRpcProxyFactoryBean.java    |  142 +
 .../org.apache.dubbo.remoting.http.HttpBinder      |    1 +
 .../dubbo/internal/org.apache.dubbo.rpc.Protocol   |    1 +
 .../rpc/protocol/xmlrpc/XmlRpcProtocolTest.java    |   90 +
 .../xml/rpc/protocol/xmlrpc/XmlRpcService.java     |   25 +
 .../xml/rpc/protocol/xmlrpc/XmlRpcServiceImpl.java |   51 +
 dubbo-spi-rpc/pom.xml                              |   45 +
 .../dubbo-serialization-avro/pom.xml               |   44 +
 .../common/serialize/avro/AvroObjectInput.java     |  118 +
 .../common/serialize/avro/AvroObjectOutput.java    |  106 +
 .../common/serialize/avro/AvroSerialization.java   |   52 +
 ...org.apache.dubbo.common.serialize.Serialization |    1 +
 .../dubbo-serialization-fastjson/pom.xml           |   43 +
 .../serialize/fastjson/FastJsonObjectInput.java    |  121 +
 .../serialize/fastjson/FastJsonObjectOutput.java   |  113 +
 .../serialize/fastjson/FastJsonSerialization.java  |   59 +
 ...org.apache.dubbo.common.serialize.Serialization |    1 +
 .../dubbo-serialization-fst/pom.xml                |   42 +
 .../dubbo/common/serialize/fst/FstFactory.java     |   53 +
 .../dubbo/common/serialize/fst/FstObjectInput.java |  117 +
 .../common/serialize/fst/FstObjectOutput.java      |  106 +
 .../common/serialize/fst/FstSerialization.java     |   58 +
 ...org.apache.dubbo.common.serialize.Serialization |    1 +
 .../dubbo-serialization-gson/pom.xml               |   42 +
 .../common/serialize/gson/GsonJsonObjectInput.java |  121 +
 .../serialize/gson/GsonJsonObjectOutput.java       |  108 +
 .../common/serialize/gson/GsonSerialization.java   |   53 +
 ...org.apache.dubbo.common.serialize.Serialization |    1 +
 .../serialize/gson/GsonJsonObjectOutputTest.java   |  143 +
 .../serialize/gson/GsonJsonSerializationTest.java  |   64 +
 .../apache/dubbo/common/serialize/gson/Image.java  |  120 +
 .../dubbo-serialization-jdk/pom.xml                |   43 +
 .../serialize/java/CompactedJavaSerialization.java |   59 +
 .../serialize/java/CompactedObjectInputStream.java |   64 +
 .../java/CompactedObjectOutputStream.java          |   43 +
 .../common/serialize/java/JavaObjectInput.java     |   91 +
 .../common/serialize/java/JavaObjectOutput.java    |   61 +
 .../common/serialize/java/JavaSerialization.java   |   59 +
 .../nativejava/NativeJavaObjectInput.java          |  118 +
 .../nativejava/NativeJavaObjectOutput.java         |  115 +
 .../nativejava/NativeJavaSerialization.java        |   60 +
 ...org.apache.dubbo.common.serialize.Serialization |    3 +
 .../dubbo-serialization-kryo/pom.xml               |   47 +
 .../common/serialize/kryo/CompatibleKryo.java      |   54 +
 .../common/serialize/kryo/KryoObjectInput.java     |  162 +
 .../common/serialize/kryo/KryoObjectOutput.java    |  118 +
 .../common/serialize/kryo/KryoSerialization.java   |   58 +
 .../serialize/kryo/optimized/KryoObjectInput2.java |  168 +
 .../kryo/optimized/KryoObjectOutput2.java          |  122 +
 .../kryo/optimized/KryoSerialization2.java         |   57 +
 .../serialize/kryo/utils/AbstractKryoFactory.java  |  158 +
 .../common/serialize/kryo/utils/KryoUtils.java     |   44 +
 .../serialize/kryo/utils/PooledKryoFactory.java    |   40 +
 .../serialize/kryo/utils/PrototypeKryoFactory.java |   32 +
 .../serialize/kryo/utils/ReflectionUtils.java      |   33 +
 .../kryo/utils/ThreadLocalKryoFactory.java         |   39 +
 ...org.apache.dubbo.common.serialize.Serialization |    2 +
 .../dubbo-serialization-native-hession/pom.xml     |   42 +
 .../serialize/hessian/Hessian2ObjectInput.java     |   98 +
 .../serialize/hessian/Hessian2ObjectOutput.java    |   95 +
 .../serialize/hessian/Hessian2Serialization.java   |   53 +
 .../hessian/Hessian2SerializerFactory.java         |   42 +
 .../serialize/hessian/Java8SerializerFactory.java  |   88 +
 .../hessian/serializer/java8/DurationHandle.java   |   53 +
 .../hessian/serializer/java8/InstantHandle.java    |   54 +
 .../serializer/java8/Java8TimeSerializer.java      |   57 +
 .../hessian/serializer/java8/LocalDateHandle.java  |   55 +
 .../serializer/java8/LocalDateTimeHandle.java      |   55 +
 .../hessian/serializer/java8/LocalTimeHandle.java  |   57 +
 .../hessian/serializer/java8/MonthDayHandle.java   |   53 +
 .../serializer/java8/OffsetDateTimeHandle.java     |   55 +
 .../hessian/serializer/java8/OffsetTimeHandle.java |   55 +
 .../hessian/serializer/java8/PeriodHandle.java     |   56 +
 .../hessian/serializer/java8/YearHandle.java       |   52 +
 .../hessian/serializer/java8/YearMonthHandle.java  |   53 +
 .../hessian/serializer/java8/ZoneIdHandle.java     |   52 +
 .../hessian/serializer/java8/ZoneIdSerializer.java |   43 +
 .../hessian/serializer/java8/ZoneOffsetHandle.java |   51 +
 .../serializer/java8/ZonedDateTimeHandle.java      |   62 +
 ...org.apache.dubbo.common.serialize.Serialization |    1 +
 .../serialize/hessian/Java8TimeSerializerTest.java |  150 +
 .../protobuf/support/wrapper/MapValue.java         |  793 +++
 .../protobuf/support/wrapper/ThrowablePB.java      | 2662 ++++++++++
 .../dubbo-serialization-protobuf/pom.xml           |   96 +
 .../support/GenericProtobufJsonObjectInput.java    |  164 +
 .../support/GenericProtobufJsonObjectOutput.java   |  161 +
 .../support/GenericProtobufJsonSerialization.java  |   54 +
 .../support/GenericProtobufObjectInput.java        |  146 +
 .../support/GenericProtobufObjectOutput.java       |  157 +
 .../support/GenericProtobufSerialization.java      |   63 +
 .../serialize/protobuf/support/ProtobufUtils.java  |  206 +
 .../protobuf/support/ProtobufWrappedException.java |   68 +
 .../src/main/proto/MapValue.proto                  |   27 +
 .../src/main/proto/ThrowablePB.proto               |   64 +
 ...org.apache.dubbo.common.serialize.Serialization |    2 +
 .../dubbo-serialization-protostuff/pom.xml         |   53 +
 .../protostuff/ProtostuffObjectInput.java          |  136 +
 .../protostuff/ProtostuffObjectOutput.java         |  130 +
 .../protostuff/ProtostuffSerialization.java        |   58 +
 .../dubbo/common/serialize/protostuff/Wrapper.java |   33 +
 .../protostuff/delegate/SqlDateDelegate.java       |   55 +
 .../protostuff/delegate/TimeDelegate.java          |   57 +
 .../protostuff/delegate/TimestampDelegate.java     |   57 +
 .../serialize/protostuff/utils/WrapperUtils.java   |  115 +
 ...org.apache.dubbo.common.serialize.Serialization |    1 +
 .../dubbo-serialization-test/pom.xml               |   86 +
 .../serialize/avro/AvroObjectInputOutputTest.java  |  196 +
 .../serialize/avro/AvroSerializationTest.java      |   64 +
 .../base/AbstractSerializationPersonFailTest.java  |  141 +
 .../base/AbstractSerializationPersonOkTest.java    |   92 +
 .../serialize/base/AbstractSerializationTest.java  | 1212 +++++
 .../fastjson/FastJsonObjectInputTest.java          |  199 +
 .../fastjson/FastJsonObjectOutputTest.java         |  142 +
 .../fastjson/FastJsonSerializationTest.java        |   62 +
 .../dubbo/common/serialize/fst/FstFactoryTest.java |   32 +
 .../common/serialize/fst/FstObjectInputTest.java   |   51 +
 .../common/serialize/fst/FstObjectOutputTest.java  |  186 +
 .../common/serialize/fst/FstSerializationTest.java |   63 +
 .../serialize/hessian2/Hessian2PersonOkTest.java   |  212 +
 .../hessian2/Hessian2SerializationTest.java        |  210 +
 .../jdk/CompactedJavaSerializationTest.java        |   27 +
 .../serialize/jdk/JavaSerializationTest.java       |   27 +
 .../common/serialize/jdk/JdkPersonOkTest.java      |   30 +
 .../serialize/jdk/NativeJavaSerializationTest.java |   26 +
 .../common/serialize/kryo/KryoPersonOkTest.java    |   29 +
 .../serialize/kryo/KyroSerializationTest.java      |   26 +
 .../common/serialize/kryo/ReflectionUtilsTest.java |   46 +
 .../dubbo/common/serialize/model/AnimalEnum.java   |   21 +
 .../dubbo/common/serialize/model/BizException.java |   29 +
 .../model/BizExceptionNoDefaultConstructor.java    |   26 +
 .../dubbo/common/serialize/model/Organization.java |   30 +
 .../dubbo/common/serialize/model/Person.java       |   95 +
 .../common/serialize/model/SerializablePerson.java |   97 +
 .../dubbo/common/serialize/model/media/Image.java  |  120 +
 .../dubbo/common/serialize/model/media/Media.java  |  205 +
 .../common/serialize/model/media/MediaContent.java |   78 +
 .../common/serialize/model/person/BigPerson.java   |  151 +
 .../common/serialize/model/person/FullAddress.java |  202 +
 .../common/serialize/model/person/PersonInfo.java  |  206 +
 .../serialize/model/person/PersonStatus.java       |   22 +
 .../dubbo/common/serialize/model/person/Phone.java |  139 +
 .../support/AbstractProtobufSerializationTest.java |  372 ++
 .../GenericProtobufJsonObjectOutputTest.java       |  206 +
 .../GenericProtobufJsonSerializationTest.java      |   23 +
 .../support/GenericProtobufSerializationTest.java  |   23 +
 .../serialize/protobuf/support/model/GooglePB.java | 3431 +++++++++++++
 .../protobuf/support/model/ServiceInterface.java   |   21 +
 .../protostuff/ProtostuffObjectOutputTest.java     |  242 +
 .../protostuff/ProtostuffSerializationTest.java    |   27 +
 .../support/SerializableClassRegistryTest.java     |   38 +
 .../src/test/proto/GooglePB.proto                  |   51 +
 .../src/test/resources/log4j.xml                   |   31 +
 .../SimpleDO.fc                                    |    2 +
 dubbo-spi-serialization/pom.xml                    |   43 +
 mvnw                                               |  227 +
 mvnw.cmd                                           |  143 +
 pom.xml                                            |   40 +
 598 files changed, 76515 insertions(+)

diff --git a/.gitignore b/.gitignore
new file mode 100644
index 0000000..15002c4
--- /dev/null
+++ b/.gitignore
@@ -0,0 +1,43 @@
+# maven ignore
+target/
+*.jar
+!.mvn/wrapper/*
+*.war
+*.zip
+*.tar
+*.tar.gz
+.flattened-pom.xml
+
+# eclipse ignore
+.settings/
+.project
+.classpath
+
+# idea ignore
+.idea/
+*.ipr
+*.iml
+*.iws
+
+# temp ignore
+*.log
+*.cache
+*.diff
+*.patch
+*.tmp
+
+# system ignore
+.DS_Store
+Thumbs.db
+*.orig
+
+# license check result
+license-list
+
+# grpc compiler
+compiler/gradle.properties
+compiler/build/*
+compiler/.gradle/*
+
+# protobuf
+dubbo-serialization/dubbo-serialization-protobuf/build/*
diff --git a/.mvn/wrapper/maven-wrapper.jar b/.mvn/wrapper/maven-wrapper.jar
new file mode 100755
index 0000000..41c70a7
Binary files /dev/null and b/.mvn/wrapper/maven-wrapper.jar differ
diff --git a/.mvn/wrapper/maven-wrapper.properties b/.mvn/wrapper/maven-wrapper.properties
new file mode 100755
index 0000000..a3ba20e
--- /dev/null
+++ b/.mvn/wrapper/maven-wrapper.properties
@@ -0,0 +1 @@
+distributionUrl=https://repo1.maven.org/maven2/org/apache/maven/apache-maven/3.6.1/apache-maven-3.6.1-bin.zip
diff --git a/CODE_OF_CONDUCT.md b/CODE_OF_CONDUCT.md
new file mode 100644
index 0000000..b7c31c2
--- /dev/null
+++ b/CODE_OF_CONDUCT.md
@@ -0,0 +1,46 @@
+# Contributor Covenant Code of Conduct
+
+## Our Pledge
+
+In the interest of fostering an open and welcoming environment, we as contributors and maintainers pledge to making participation in our project and our community a harassment-free experience for everyone, regardless of age, body size, disability, ethnicity, gender identity and expression, level of experience, nationality, personal appearance, race, religion, or sexual identity and orientation.
+
+## Our Standards
+
+Examples of behavior that contributes to creating a positive environment include:
+
+* Using welcoming and inclusive language
+* Being respectful of differing viewpoints and experiences
+* Gracefully accepting constructive criticism
+* Focusing on what is best for the community
+* Showing empathy towards other community members
+
+Examples of unacceptable behavior by participants include:
+
+* The use of sexualized language or imagery and unwelcome sexual attention or advances
+* Trolling, insulting/derogatory comments, and personal or political attacks
+* Public or private harassment
+* Publishing others' private information, such as a physical or electronic address, without explicit permission
+* Other conduct which could reasonably be considered inappropriate in a professional setting
+
+## Our Responsibilities
+
+Project maintainers are responsible for clarifying the standards of acceptable behavior and are expected to take appropriate and fair corrective action in response to any instances of unacceptable behavior.
+
+Project maintainers have the right and responsibility to remove, edit, or reject comments, commits, code, wiki edits, issues, and other contributions that are not aligned to this Code of Conduct, or to ban temporarily or permanently any contributor for other behaviors that they deem inappropriate, threatening, offensive, or harmful.
+
+## Scope
+
+This Code of Conduct applies both within project spaces and in public spaces when an individual is representing the project or its community. Examples of representing a project or community include using an official project e-mail address, posting via an official social media account, or acting as an appointed representative at an online or offline event. Representation of a project may be further defined and clarified by project maintainers.
+
+## Enforcement
+
+Instances of abusive, harassing, or otherwise unacceptable behavior may be reported by contacting the project team at dev@dubbo.apache.org. The project team will review and investigate all complaints, and will respond in a way that it deems appropriate to the circumstances. The project team is obligated to maintain confidentiality with regard to the reporter of an incident. Further details of specific enforcement policies may be posted separately.
+
+Project maintainers who do not follow or enforce the Code of Conduct in good faith may face temporary or permanent repercussions as determined by other members of the project's leadership.
+
+## Attribution
+
+This Code of Conduct is adapted from the [Contributor Covenant][homepage], version 1.4, available at [http://contributor-covenant.org/version/1/4][version]
+
+[homepage]: http://contributor-covenant.org
+[version]: http://contributor-covenant.org/version/1/4/
diff --git a/CONTRIBUTING.md b/CONTRIBUTING.md
new file mode 100644
index 0000000..c92e4a1
--- /dev/null
+++ b/CONTRIBUTING.md
@@ -0,0 +1,76 @@
+
+## Contributing to dubbo
+Dubbo is released under the non-restrictive Apache 2.0 license, and follows a very standard Github development process, using Github tracker for issues and merging pull requests into master. If you want to contribute even something trivial please do not hesitate, but follow the guidelines below.
+
+### Sign the Contributor License Agreement
+Before we accept a non-trivial patch or pull request we will need you to sign the Contributor License Agreement. Signing the contributor’s agreement does not grant anyone commit rights to the main repository, but it does mean that we can accept your contributions, and you will get an author credit if we do. Active contributors might be asked to join the core team, and given the ability to merge pull requests.
+
+### Contact
+
+#### Mailing list
+
+The mailing list is the recommended way for discussing almost anything that related to Dubbo. Please refer to this [guide](https://github.com/apache/dubbo/wiki/Mailing-list-subscription-guide) for detailed documentation on how to subscribe.
+
+- [dev@dubbo.apache.org](mailto:dev-subscribe@dubbo.apache.org): the develop mailing list, you can ask question here if you have encountered any problem when using or developing Dubbo.
+- [commits@dubbo.apache.org](mailto:commits-subscribe@dubbo.apache.org): all the commits will be sent to this mailing list. You can subscribe to it if you are interested in Dubbo's development.
+- [notifications@dubbo.apache.org](mailto:notifications-subscribe@dubbo.apache.org): all the Github [issue](https://github.com/apache/dubbo/issues) updates and [pull request](https://github.com/apache/dubbo/pulls) updates will be sent to this mailing list.
+
+### Reporting issue
+
+Please follow the [template](https://github.com/apache/dubbo/issues/new?template=dubbo-issue-report-template.md) for reporting any issues.
+
+### Code Conventions
+Our code style is almost in line with the standard java conventions (Popular IDE's default setting satisfy this), with the following additional restricts:  
+* If there are more than 120 characters in current line, start a new line.
+
+* Make sure all new .java files to have a simple Javadoc class comment with at least a @date tag identifying birth, and preferably at least a paragraph on what the class is for.
+
+* Add the ASF license header comment to all new .java files (copy from existing files in the project)
+
+* Make sure no @author tag added to the file you contribute since @author tag is not used at Apache, other ways such as cvs will record all your contributions fairly.
+
+* Add some Javadocs and, if you change the namespace, some XSD doc elements.
+
+* A few unit tests should be added for a new feature or an important bugfix.
+
+* If no-one else is using your branch, please rebase it against the current master (or other target branch in the main project).
+
+* When writing a commit message please follow these conventions, if you are fixing an existing issue please add Fixes #XXX at the end of the commit message (where XXX is the issue number).
+
+### Contribution flow
+
+This is a rough outline of what a contributor's workflow looks like:
+
+* Fork the current repository
+* Create a topic branch from where to base the contribution. This is usually master.
+* Make commits of logical units.
+* Make sure commit messages are in the proper format (see below).
+* Push changes in a topic branch to your forked repository.
+* Follow the checklist in the [pull request template](https://github.com/apache/dubbo/blob/master/PULL_REQUEST_TEMPLATE.md)
+* Before you sending out the pull request, please sync your forked repository with remote repository, this will make your pull request simple and clear. See guide below:
+```
+git remote add upstream git@github.com:apache/dubbo.git
+git fetch upstream
+git rebase upstream/master
+git checkout -b your_awesome_patch
+... add some work
+git push origin your_awesome_patch
+```
+* Submit a pull request to apache/dubbo and wait for the reply.
+
+Thanks for contributing!
+
+### Code style
+
+We provide a template file [dubbo_codestyle_for_idea.xml](https://github.com/apache/dubbo/tree/master/codestyle/dubbo_codestyle_for_idea.xml) for IntelliJ idea, you can import it to you IDE. 
+If you use Eclipse you can config manually by referencing the same file.
+
+**NOTICE**
+
+It is very important to set the dubbo_codestyle_for_idea.xml, otherwise you will fail to pass the Travis CI. Steps to set the code style are as below:
+
+1. Enter `Editor > Code Style`
+2. To manage a code style scheme, in the Code Style page, select the desired scheme from the drop-down list, and click ![manage profiles](codestyle/manage_profiles.png).
+From the drop-down list, select `Import Scheme`, then select this option `IntelliJ IDEA code style XML` to import scheme
+3. In the Scheme field, type the name of the new scheme and press ⏎ to save the changes.
+
diff --git a/LICENSE b/LICENSE
new file mode 100644
index 0000000..7a4a3ea
--- /dev/null
+++ b/LICENSE
@@ -0,0 +1,202 @@
+
+                                 Apache License
+                           Version 2.0, January 2004
+                        http://www.apache.org/licenses/
+
+   TERMS AND CONDITIONS FOR USE, REPRODUCTION, AND DISTRIBUTION
+
+   1. Definitions.
+
+      "License" shall mean the terms and conditions for use, reproduction,
+      and distribution as defined by Sections 1 through 9 of this document.
+
+      "Licensor" shall mean the copyright owner or entity authorized by
+      the copyright owner that is granting the License.
+
+      "Legal Entity" shall mean the union of the acting entity and all
+      other entities that control, are controlled by, or are under common
+      control with that entity. For the purposes of this definition,
+      "control" means (i) the power, direct or indirect, to cause the
+      direction or management of such entity, whether by contract or
+      otherwise, or (ii) ownership of fifty percent (50%) or more of the
+      outstanding shares, or (iii) beneficial ownership of such entity.
+
+      "You" (or "Your") shall mean an individual or Legal Entity
+      exercising permissions granted by this License.
+
+      "Source" form shall mean the preferred form for making modifications,
+      including but not limited to software source code, documentation
+      source, and configuration files.
+
+      "Object" form shall mean any form resulting from mechanical
+      transformation or translation of a Source form, including but
+      not limited to compiled object code, generated documentation,
+      and conversions to other media types.
+
+      "Work" shall mean the work of authorship, whether in Source or
+      Object form, made available under the License, as indicated by a
+      copyright notice that is included in or attached to the work
+      (an example is provided in the Appendix below).
+
+      "Derivative Works" shall mean any work, whether in Source or Object
+      form, that is based on (or derived from) the Work and for which the
+      editorial revisions, annotations, elaborations, or other modifications
+      represent, as a whole, an original work of authorship. For the purposes
+      of this License, Derivative Works shall not include works that remain
+      separable from, or merely link (or bind by name) to the interfaces of,
+      the Work and Derivative Works thereof.
+
+      "Contribution" shall mean any work of authorship, including
+      the original version of the Work and any modifications or additions
+      to that Work or Derivative Works thereof, that is intentionally
+      submitted to Licensor for inclusion in the Work by the copyright owner
+      or by an individual or Legal Entity authorized to submit on behalf of
+      the copyright owner. For the purposes of this definition, "submitted"
+      means any form of electronic, verbal, or written communication sent
+      to the Licensor or its representatives, including but not limited to
+      communication on electronic mailing lists, source code control systems,
+      and issue tracking systems that are managed by, or on behalf of, the
+      Licensor for the purpose of discussing and improving the Work, but
+      excluding communication that is conspicuously marked or otherwise
+      designated in writing by the copyright owner as "Not a Contribution."
+
+      "Contributor" shall mean Licensor and any individual or Legal Entity
+      on behalf of whom a Contribution has been received by Licensor and
+      subsequently incorporated within the Work.
+
+   2. Grant of Copyright License. Subject to the terms and conditions of
+      this License, each Contributor hereby grants to You a perpetual,
+      worldwide, non-exclusive, no-charge, royalty-free, irrevocable
+      copyright license to reproduce, prepare Derivative Works of,
+      publicly display, publicly perform, sublicense, and distribute the
+      Work and such Derivative Works in Source or Object form.
+
+   3. Grant of Patent License. Subject to the terms and conditions of
+      this License, each Contributor hereby grants to You a perpetual,
+      worldwide, non-exclusive, no-charge, royalty-free, irrevocable
+      (except as stated in this section) patent license to make, have made,
+      use, offer to sell, sell, import, and otherwise transfer the Work,
+      where such license applies only to those patent claims licensable
+      by such Contributor that are necessarily infringed by their
+      Contribution(s) alone or by combination of their Contribution(s)
+      with the Work to which such Contribution(s) was submitted. If You
+      institute patent litigation against any entity (including a
+      cross-claim or counterclaim in a lawsuit) alleging that the Work
+      or a Contribution incorporated within the Work constitutes direct
+      or contributory patent infringement, then any patent licenses
+      granted to You under this License for that Work shall terminate
+      as of the date such litigation is filed.
+
+   4. Redistribution. You may reproduce and distribute copies of the
+      Work or Derivative Works thereof in any medium, with or without
+      modifications, and in Source or Object form, provided that You
+      meet the following conditions:
+
+      (a) You must give any other recipients of the Work or
+          Derivative Works a copy of this License; and
+
+      (b) You must cause any modified files to carry prominent notices
+          stating that You changed the files; and
+
+      (c) You must retain, in the Source form of any Derivative Works
+          that You distribute, all copyright, patent, trademark, and
+          attribution notices from the Source form of the Work,
+          excluding those notices that do not pertain to any part of
+          the Derivative Works; and
+
+      (d) If the Work includes a "NOTICE" text file as part of its
+          distribution, then any Derivative Works that You distribute must
+          include a readable copy of the attribution notices contained
+          within such NOTICE file, excluding those notices that do not
+          pertain to any part of the Derivative Works, in at least one
+          of the following places: within a NOTICE text file distributed
+          as part of the Derivative Works; within the Source form or
+          documentation, if provided along with the Derivative Works; or,
+          within a display generated by the Derivative Works, if and
+          wherever such third-party notices normally appear. The contents
+          of the NOTICE file are for informational purposes only and
+          do not modify the License. You may add Your own attribution
+          notices within Derivative Works that You distribute, alongside
+          or as an addendum to the NOTICE text from the Work, provided
+          that such additional attribution notices cannot be construed
+          as modifying the License.
+
+      You may add Your own copyright statement to Your modifications and
+      may provide additional or different license terms and conditions
+      for use, reproduction, or distribution of Your modifications, or
+      for any such Derivative Works as a whole, provided Your use,
+      reproduction, and distribution of the Work otherwise complies with
+      the conditions stated in this License.
+
+   5. Submission of Contributions. Unless You explicitly state otherwise,
+      any Contribution intentionally submitted for inclusion in the Work
+      by You to the Licensor shall be under the terms and conditions of
+      this License, without any additional terms or conditions.
+      Notwithstanding the above, nothing herein shall supersede or modify
+      the terms of any separate license agreement you may have executed
+      with Licensor regarding such Contributions.
+
+   6. Trademarks. This License does not grant permission to use the trade
+      names, trademarks, service marks, or product names of the Licensor,
+      except as required for reasonable and customary use in describing the
+      origin of the Work and reproducing the content of the NOTICE file.
+
+   7. Disclaimer of Warranty. Unless required by applicable law or
+      agreed to in writing, Licensor provides the Work (and each
+      Contributor provides its Contributions) on an "AS IS" BASIS,
+      WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or
+      implied, including, without limitation, any warranties or conditions
+      of TITLE, NON-INFRINGEMENT, MERCHANTABILITY, or FITNESS FOR A
+      PARTICULAR PURPOSE. You are solely responsible for determining the
+      appropriateness of using or redistributing the Work and assume any
+      risks associated with Your exercise of permissions under this License.
+
+   8. Limitation of Liability. In no event and under no legal theory,
+      whether in tort (including negligence), contract, or otherwise,
+      unless required by applicable law (such as deliberate and grossly
+      negligent acts) or agreed to in writing, shall any Contributor be
+      liable to You for damages, including any direct, indirect, special,
+      incidental, or consequential damages of any character arising as a
+      result of this License or out of the use or inability to use the
+      Work (including but not limited to damages for loss of goodwill,
+      work stoppage, computer failure or malfunction, or any and all
+      other commercial damages or losses), even if such Contributor
+      has been advised of the possibility of such damages.
+
+   9. Accepting Warranty or Additional Liability. While redistributing
+      the Work or Derivative Works thereof, You may choose to offer,
+      and charge a fee for, acceptance of support, warranty, indemnity,
+      or other liability obligations and/or rights consistent with this
+      License. However, in accepting such obligations, You may act only
+      on Your own behalf and on Your sole responsibility, not on behalf
+      of any other Contributor, and only if You agree to indemnify,
+      defend, and hold each Contributor harmless for any liability
+      incurred by, or claims asserted against, such Contributor by reason
+      of your accepting any such warranty or additional liability.
+
+   END OF TERMS AND CONDITIONS
+
+   APPENDIX: How to apply the Apache License to your work.
+
+      To apply the Apache License to your work, attach the following
+      boilerplate notice, with the fields enclosed by brackets "[]"
+      replaced with your own identifying information. (Don't include
+      the brackets!)  The text should be enclosed in the appropriate
+      comment syntax for the file format. We also recommend that a
+      file or class name and description of purpose be included on the
+      same "printed page" as the copyright notice for easier
+      identification within third-party archives.
+
+   Copyright [yyyy] [name of copyright owner]
+
+   Licensed 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.
\ No newline at end of file
diff --git a/NOTICE b/NOTICE
new file mode 100644
index 0000000..7a95db5
--- /dev/null
+++ b/NOTICE
@@ -0,0 +1,6 @@
+Apache Dubbo
+Copyright 2018-2020 The Apache Software Foundation
+
+This product includes software developed at
+The Apache Software Foundation (http://www.apache.org/).
+
diff --git a/PULL_REQUEST_TEMPLATE.md b/PULL_REQUEST_TEMPLATE.md
new file mode 100644
index 0000000..20c5854
--- /dev/null
+++ b/PULL_REQUEST_TEMPLATE.md
@@ -0,0 +1,20 @@
+## What is the purpose of the change
+
+XXXXX
+
+## Brief changelog
+
+XXXXX
+
+## Verifying this change
+
+XXXXX
+
+Follow this checklist to help us incorporate your contribution quickly and easily:
+
+- [x] Make sure there is a [GITHUB_issue](https://github.com/apache/dubbo/issues) field for the change (usually before you start working on it). Trivial changes like typos do not require a GITHUB issue. Your pull request should address just this issue, without pulling in other changes - one PR resolves one issue.
+- [ ] Format the pull request title like `[Dubbo-XXX] Fix UnknownException when host config not exist #XXX`. Each commit in the pull request should have a meaningful subject line and body.
+- [ ] Write a pull request description that is detailed enough to understand what the pull request does, how, and why.
+- [ ] Write necessary unit-test to verify your logic correction, more mock a little better when cross module dependency exist. If the new feature or significant change is committed, please remember to add sample in [dubbo samples](https://github.com/apache/dubbo-samples) project.
+- [ ] Run `mvn clean install -DskipTests=false` & `mvn clean test-compile failsafe:integration-test` to make sure unit-test and integration-test pass.
+- [ ] If this contribution is large, please follow the [Software Donation Guide](https://github.com/apache/dubbo/wiki/Software-donation-guide).
diff --git a/SECURITY.md b/SECURITY.md
new file mode 100644
index 0000000..ac0c2ad
--- /dev/null
+++ b/SECURITY.md
@@ -0,0 +1,31 @@
+# Security Policy
+
+## Supported Versions
+
+Below is a table that shows versions that accept security fix.
+
+| Version | Supported          |
+| ------- | ------------------ |
+| 2.7.x   | :white_check_mark: |
+| 2.6.x   | :white_check_mark: |
+| 2.5.x   | :x: |
+
+
+## Reporting a Vulnerability
+
+The Apache Software Foundation takes a rigorous standpoint in annihilating the security issues in its software projects. Apache Dubbo is highly sensitive and forthcoming to issues pertaining to its features and functionality.
+
+If you have apprehensions regarding Dubbo's security or you discover vulnerability or potential threat, don’t hesitate to get in touch with the Apache Dubbo Security Team by dropping a mail at security@dubbo.apache.org. In the mail, specify the description of the issue or potential threat. You are also urged to recommend the way to reproduce and replicate the issue. The Dubbo community will get back to you after assessing and analysing the findings.
+
+PLEASE PAY ATTENTION to report the security issue on the security email before disclosing it on public domain.
+
+## VULNERABILITY HANDLING
+
+An overview of the vulnerability handling process is:
+
+* The reporter reports the vulnerability privately to Apache.
+* The appropriate project's security team works privately with the reporter to resolve the vulnerability.
+* A new release of the Apache product concerned is made that includes the fix.
+* The vulnerability is publicly announced.
+
+A more detailed description of the process can be found [here](https://www.apache.org/security/committers.html).
diff --git a/codestyle/checkstyle-suppressions.xml b/codestyle/checkstyle-suppressions.xml
new file mode 100644
index 0000000..1817cf7
--- /dev/null
+++ b/codestyle/checkstyle-suppressions.xml
@@ -0,0 +1,8 @@
+<?xml version="1.0"?>
+<!DOCTYPE suppressions PUBLIC
+        "-//Puppy Crawl//DTD Suppressions 1.1//EN"
+        "http://www.puppycrawl.com/dtds/suppressions_1_1.dtd">
+<suppressions>
+    <suppress files="[\\/]src[\\/]main[\\/]java[\\/]com[\\/]alibaba[\\/]com[\\/]caucho[\\/]hessian" checks=".*"/>
+    <suppress files="Yylex\.java" checks="AvoidEscapedUnicodeCharacters"/>
+</suppressions>
\ No newline at end of file
diff --git a/codestyle/checkstyle.xml b/codestyle/checkstyle.xml
new file mode 100644
index 0000000..050fbed
--- /dev/null
+++ b/codestyle/checkstyle.xml
@@ -0,0 +1,38 @@
+<?xml version="1.0"?>
+<!DOCTYPE module PUBLIC
+        "-//Puppy Crawl//DTD Check Configuration 1.3//EN"
+        "http://checkstyle.sourceforge.net/dtds/configuration_1_3.dtd">
+
+<module name="Checker">
+    <property name="charset" value="UTF-8"/>
+    <property name="fileExtensions" value="java"/>
+
+    <module name="Header">
+        <property name="headerFile" value="/checkstyle-header.txt"/>
+        <property name="fileExtensions" value="java"/>
+    </module>
+
+    <!-- TreeWalker Checks -->
+    <module name="TreeWalker">
+        <module name="SuppressWarningsHolder"/>
+
+        <module name="AvoidStarImport"/>
+        <module name="AvoidEscapedUnicodeCharacters">
+            <property name="allowEscapesForControlCharacters" value="true"/>
+            <property name="allowByTailComment" value="true"/>
+            <property name="allowNonPrintableEscapes" value="true"/>
+        </module>
+        <module name="NoLineWrap"/>
+        <module name="OuterTypeFilename"/>
+        <module name="UnusedImports"/>
+        <module name="RedundantImport"/>
+
+        <module name="EqualsHashCode"/>
+
+        <!--<module name="CustomImportOrder">-->
+        <!--<property name="specialImportsRegExp" value="org.apache.dubbo.*"/>-->
+        <!--<property name="sortImportsInGroupAlphabetically" value="false"/>-->
+        <!--<property name="customImportOrderRules" value="SPECIAL_IMPORTS###THIRD_PARTY_PACKAGE###STANDARD_JAVA_PACKAGE###STATIC"/>-->
+        <!--</module>-->
+    </module>
+</module>
diff --git a/codestyle/dubbo_codestyle_for_idea.xml b/codestyle/dubbo_codestyle_for_idea.xml
new file mode 100644
index 0000000..1f87caa
--- /dev/null
+++ b/codestyle/dubbo_codestyle_for_idea.xml
@@ -0,0 +1,16 @@
+<code_scheme name="dubbo_codestyle">
+    <option name="CLASS_COUNT_TO_USE_IMPORT_ON_DEMAND" value="99"/>
+    <option name="NAMES_COUNT_TO_USE_IMPORT_ON_DEMAND" value="99"/>
+    <option name="IMPORT_LAYOUT_TABLE">
+        <value>
+            <package name="org.apache.dubbo" withSubpackages="true" static="false"/>
+            <emptyLine/>
+            <package name="" withSubpackages="true" static="false"/>
+            <emptyLine/>
+            <package name="javax" withSubpackages="true" static="false"/>
+            <package name="java" withSubpackages="true" static="false"/>
+            <emptyLine/>
+            <package name="" withSubpackages="true" static="true"/>
+        </value>
+    </option>
+</code_scheme>
\ No newline at end of file
diff --git a/codestyle/manage_profiles.png b/codestyle/manage_profiles.png
new file mode 100644
index 0000000..1664d67
Binary files /dev/null and b/codestyle/manage_profiles.png differ
diff --git a/compiler/pom.xml b/compiler/pom.xml
new file mode 100644
index 0000000..c3d4201
--- /dev/null
+++ b/compiler/pom.xml
@@ -0,0 +1,237 @@
+<!--
+  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.
+  -->
+
+<project xmlns="http://maven.apache.org/POM/4.0.0" xmlns:xsi="http://www.w3.org/2001/XMLSchema-instance"
+         xsi:schemaLocation="http://maven.apache.org/POM/4.0.0 http://maven.apache.org/maven-v4_0_0.xsd">
+    <modelVersion>4.0.0</modelVersion>
+    <parent>
+        <groupId>org.apache</groupId>
+        <artifactId>apache</artifactId>
+        <version>21</version>
+    </parent>
+
+    <groupId>org.apache.dubbo</groupId>
+    <artifactId>dubbo-compiler</artifactId>
+    <version>0.0.1</version>
+
+    <packaging>jar</packaging>
+
+    <properties>
+        <maven_compiler_version>3.6.0</maven_compiler_version>
+        <maven_jar_version>3.0.2</maven_jar_version>
+        <maven_source_version>3.0.1</maven_source_version>
+        <maven_javadoc_version>3.0.1</maven_javadoc_version>
+        <java_source_version>1.8</java_source_version>
+        <java_target_version>1.8</java_target_version>
+        <file_encoding>UTF-8</file_encoding>
+    </properties>
+
+    <dependencies>
+        <dependency>
+            <groupId>com.salesforce.servicelibs</groupId>
+            <artifactId>grpc-contrib</artifactId>
+            <version>0.8.1</version>
+        </dependency>
+        <dependency>
+            <groupId>com.salesforce.servicelibs</groupId>
+            <artifactId>jprotoc</artifactId>
+            <version>0.9.1</version>
+        </dependency>
+    </dependencies>
+
+    <build>
+        <plugins>
+            <plugin>
+                <groupId>org.apache.maven.plugins</groupId>
+                <artifactId>maven-compiler-plugin</artifactId>
+                <version>${maven_compiler_version}</version>
+                <configuration>
+                    <compilerArgument>-proc:none</compilerArgument>
+                    <fork>true</fork>
+                    <source>${java_source_version}</source>
+                    <target>${java_target_version}</target>
+                    <encoding>${file_encoding}</encoding>
+                </configuration>
+            </plugin>
+
+            <plugin>
+                <groupId>org.apache.maven.plugins</groupId>
+                <artifactId>maven-jar-plugin</artifactId>
+                <version>${maven_jar_version}</version>
+                <configuration>
+                    <archive>
+                        <manifest>
+                            <addClasspath>true</addClasspath>
+                            <mainClass>org.apache.dubbo.gen.grpc.DubboGrpcGenerator</mainClass>
+                        </manifest>
+                    </archive>
+                </configuration>
+            </plugin>
+
+            <!-- Optional, used to build directly executable packages (without using 'java -jar'),
+            for example 'artifactId-1.0.0-osx-x86_64.exe', 'artifactId-1.0.0-osx-x86_64.exe' -->
+            <plugin>
+                <groupId>com.salesforce.servicelibs</groupId>
+                <artifactId>canteen-maven-plugin</artifactId>
+                <version>1.0.0</version>
+                <executions>
+                    <execution>
+                        <goals>
+                            <goal>bootstrap</goal>
+                        </goals>
+                    </execution>
+                </executions>
+            </plugin>
+        </plugins>
+    </build>
+
+    <profiles>
+        <profile>
+            <id>release</id>
+            <properties>
+                <log4j2_version>2.11.1</log4j2_version>
+            </properties>
+            <build>
+                <plugins>
+                    <plugin>
+                        <artifactId>maven-source-plugin</artifactId>
+                        <version>${maven_source_version}</version>
+                        <executions>
+                            <execution>
+                                <id>attach-sources</id>
+                                <goals>
+                                    <goal>jar</goal>
+                                </goals>
+                            </execution>
+                        </executions>
+                    </plugin>
+                    <plugin>
+                        <artifactId>maven-javadoc-plugin</artifactId>
+                        <version>${maven_javadoc_version}</version>
+                        <executions>
+                            <execution>
+                                <id>attach-javadoc</id>
+                                <goals>
+                                    <goal>jar</goal>
+                                    <goal>aggregate</goal>
+                                </goals>
+                                <configuration>
+                                    <additionalDependencies>
+                                        <additionalDependency>
+                                            <groupId>org.apache.logging.log4j</groupId>
+                                            <artifactId>log4j-api</artifactId>
+                                            <version>${log4j2_version}</version>
+                                        </additionalDependency>
+                                        <additionalDependency>
+                                            <groupId>org.apache.logging.log4j</groupId>
+                                            <artifactId>log4j-core</artifactId>
+                                            <version>${log4j2_version}</version>
+                                        </additionalDependency>
+                                    </additionalDependencies>
+                                </configuration>
+                            </execution>
+                        </executions>
+                        <configuration>
+                            <show>public</show>
+                            <charset>UTF-8</charset>
+                            <encoding>UTF-8</encoding>
+                            <docencoding>UTF-8</docencoding>
+                            <links>
+                                <link>http://docs.oracle.com/javase/8/docs/api</link>
+                            </links>
+                            <doclint>none</doclint>
+                            <excludePackageNames>
+                                org.apache.dubbo.demo,org.apache.dubbo.demo.*
+                            </excludePackageNames>
+                            <doctitle>Apache Dubbo ${project.version} API</doctitle>
+                            <windowtitle>Apache Dubbo ${project.version} API</windowtitle>
+                        </configuration>
+                    </plugin>
+                    <plugin>
+                        <groupId>org.apache.maven.plugins</groupId>
+                        <artifactId>maven-gpg-plugin</artifactId>
+                        <executions>
+                            <execution>
+                                <phase>verify</phase>
+                                <goals>
+                                    <goal>sign</goal>
+                                </goals>
+                            </execution>
+                        </executions>
+                    </plugin>
+                </plugins>
+            </build>
+        </profile>
+    </profiles>
+
+    <name>dubbo-compiler</name>
+    <description>Dubbo customized RPC stub compiler.</description>
+    <url>https://github.com/apache/dubbo</url>
+    <inceptionYear>2011</inceptionYear>
+    <licenses>
+        <license>
+            <name>Apache License, Version 2.0</name>
+            <url>http://www.apache.org/licenses/LICENSE-2.0</url>
+            <distribution>repo</distribution>
+        </license>
+    </licenses>
+
+    <scm>
+        <url>https://github.com/apache/dubbo</url>
+        <connection>scm:git:https://github.com/apache/dubbo.git</connection>
+        <developerConnection>scm:git:https://github.com/apache/dubbo.git</developerConnection>
+        <tag>HEAD</tag>
+    </scm>
+    <mailingLists>
+        <mailingList>
+            <name>Development List</name>
+            <subscribe>dev-subscribe@dubbo.apache.org</subscribe>
+            <unsubscribe>dev-unsubscribe@dubbo.apache.org</unsubscribe>
+            <post>dev@dubbo.apache.org</post>
+        </mailingList>
+        <mailingList>
+            <name>Commits List</name>
+            <subscribe>commits-subscribe@dubbo.apache.org</subscribe>
+            <unsubscribe>commits-unsubscribe@dubbo.apache.org</unsubscribe>
+            <post>commits@dubbo.apache.org</post>
+        </mailingList>
+        <mailingList>
+            <name>Issues List</name>
+            <subscribe>issues-subscribe@dubbo.apache.org</subscribe>
+            <unsubscribe>issues-unsubscribe@dubbo.apache.org</unsubscribe>
+            <post>issues@dubbo.apache.org</post>
+        </mailingList>
+    </mailingLists>
+    <developers>
+        <developer>
+            <id>dubbo.io</id>
+            <name>The Dubbo Project Contributors</name>
+            <email>dev-subscribe@dubbo.apache.org</email>
+            <url>http://dubbo.apache.org/</url>
+        </developer>
+    </developers>
+
+    <organization>
+        <name>The Apache Software Foundation</name>
+        <url>http://www.apache.org/</url>
+    </organization>
+
+    <issueManagement>
+        <system>Github Issues</system>
+        <url>https://github.com/apache/dubbo/issues</url>
+    </issueManagement>
+</project>
\ No newline at end of file
diff --git a/compiler/src/main/java/org/apache/dubbo/gen/AbstractGenerator.java b/compiler/src/main/java/org/apache/dubbo/gen/AbstractGenerator.java
new file mode 100644
index 0000000..3e8dee1
--- /dev/null
+++ b/compiler/src/main/java/org/apache/dubbo/gen/AbstractGenerator.java
@@ -0,0 +1,293 @@
+/*
+ * 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.gen;
+
+import com.google.common.base.Strings;
+import com.google.common.html.HtmlEscapers;
+import com.google.protobuf.DescriptorProtos.FileDescriptorProto;
+import com.google.protobuf.DescriptorProtos.FileOptions;
+import com.google.protobuf.DescriptorProtos.MethodDescriptorProto;
+import com.google.protobuf.DescriptorProtos.ServiceDescriptorProto;
+import com.google.protobuf.DescriptorProtos.SourceCodeInfo.Location;
+import com.google.protobuf.compiler.PluginProtos;
+import com.salesforce.jprotoc.Generator;
+import com.salesforce.jprotoc.GeneratorException;
+import com.salesforce.jprotoc.ProtoTypeMap;
+
+import java.util.ArrayList;
+import java.util.Arrays;
+import java.util.HashSet;
+import java.util.List;
+import java.util.Set;
+import java.util.stream.Collectors;
+
+public abstract class AbstractGenerator extends Generator {
+
+    private static final int SERVICE_NUMBER_OF_PATHS = 2;
+    private static final int METHOD_NUMBER_OF_PATHS = 4;
+
+    protected abstract String getClassPrefix();
+
+    protected abstract String getClassSuffix();
+
+    private String getServiceJavaDocPrefix() {
+        return "    ";
+    }
+
+    private String getMethodJavaDocPrefix() {
+        return "        ";
+    }
+
+    @Override
+    public List<PluginProtos.CodeGeneratorResponse.File> generateFiles(PluginProtos.CodeGeneratorRequest request) throws GeneratorException {
+        final ProtoTypeMap typeMap = ProtoTypeMap.of(request.getProtoFileList());
+
+        List<FileDescriptorProto> protosToGenerate = request.getProtoFileList().stream()
+                .filter(protoFile -> request.getFileToGenerateList().contains(protoFile.getName()))
+                .collect(Collectors.toList());
+
+        List<ServiceContext> services = findServices(protosToGenerate, typeMap);
+        return generateFiles(services);
+    }
+
+    private List<ServiceContext> findServices(List<FileDescriptorProto> protos, ProtoTypeMap typeMap) {
+        List<ServiceContext> contexts = new ArrayList<>();
+
+        protos.forEach(fileProto -> {
+            for (int serviceNumber = 0; serviceNumber < fileProto.getServiceCount(); serviceNumber++) {
+                ServiceContext serviceContext = buildServiceContext(
+                    fileProto.getService(serviceNumber),
+                    typeMap,
+                    fileProto.getSourceCodeInfo().getLocationList(),
+                    serviceNumber
+                );
+                serviceContext.protoName = fileProto.getName();
+                serviceContext.packageName = extractPackageName(fileProto);
+                contexts.add(serviceContext);
+            }
+        });
+
+        return contexts;
+    }
+
+    private String extractPackageName(FileDescriptorProto proto) {
+        FileOptions options = proto.getOptions();
+        if (options != null) {
+            String javaPackage = options.getJavaPackage();
+            if (!Strings.isNullOrEmpty(javaPackage)) {
+                return javaPackage;
+            }
+        }
+
+        return Strings.nullToEmpty(proto.getPackage());
+    }
+
+    private ServiceContext buildServiceContext(ServiceDescriptorProto serviceProto, ProtoTypeMap typeMap, List<Location> locations, int serviceNumber) {
+        ServiceContext serviceContext = new ServiceContext();
+        serviceContext.fileName = getClassPrefix() + serviceProto.getName() + getClassSuffix() + ".java";
+        serviceContext.className = getClassPrefix() + serviceProto.getName() + getClassSuffix();
+        serviceContext.serviceName = serviceProto.getName();
+        serviceContext.deprecated = serviceProto.getOptions() != null && serviceProto.getOptions().getDeprecated();
+
+        List<Location> allLocationsForService = locations.stream()
+                .filter(location ->
+                    location.getPathCount() >= 2 &&
+                       location.getPath(0) == FileDescriptorProto.SERVICE_FIELD_NUMBER &&
+                       location.getPath(1) == serviceNumber
+                )
+                .collect(Collectors.toList());
+
+        Location serviceLocation = allLocationsForService.stream()
+                .filter(location -> location.getPathCount() == SERVICE_NUMBER_OF_PATHS)
+                .findFirst()
+                .orElseGet(Location::getDefaultInstance);
+        serviceContext.javaDoc = getJavaDoc(getComments(serviceLocation), getServiceJavaDocPrefix());
+
+        for (int methodNumber = 0; methodNumber < serviceProto.getMethodCount(); methodNumber++) {
+            MethodContext methodContext = buildMethodContext(
+                serviceProto.getMethod(methodNumber),
+                typeMap,
+                locations,
+                methodNumber
+            );
+
+            serviceContext.methods.add(methodContext);
+            serviceContext.methodTypes.add(methodContext.inputType);
+            serviceContext.methodTypes.add(methodContext.outputType);
+        }
+        return serviceContext;
+    }
+
+    private MethodContext buildMethodContext(MethodDescriptorProto methodProto, ProtoTypeMap typeMap, List<Location> locations, int methodNumber) {
+        MethodContext methodContext = new MethodContext();
+        methodContext.methodName = lowerCaseFirst(methodProto.getName());
+        methodContext.inputType = typeMap.toJavaTypeName(methodProto.getInputType());
+        methodContext.outputType = typeMap.toJavaTypeName(methodProto.getOutputType());
+        methodContext.deprecated = methodProto.getOptions() != null && methodProto.getOptions().getDeprecated();
+        methodContext.isManyInput = methodProto.getClientStreaming();
+        methodContext.isManyOutput = methodProto.getServerStreaming();
+        methodContext.methodNumber = methodNumber;
+
+        Location methodLocation = locations.stream()
+                .filter(location ->
+                    location.getPathCount() == METHOD_NUMBER_OF_PATHS &&
+                        location.getPath(METHOD_NUMBER_OF_PATHS - 1) == methodNumber
+                )
+                .findFirst()
+                .orElseGet(Location::getDefaultInstance);
+        methodContext.javaDoc = getJavaDoc(getComments(methodLocation), getMethodJavaDocPrefix());
+
+        if (!methodProto.getClientStreaming() && !methodProto.getServerStreaming()) {
+            methodContext.reactiveCallsMethodName = "oneToOne";
+            methodContext.grpcCallsMethodName = "asyncUnaryCall";
+        }
+        if (!methodProto.getClientStreaming() && methodProto.getServerStreaming()) {
+            methodContext.reactiveCallsMethodName = "oneToMany";
+            methodContext.grpcCallsMethodName = "asyncServerStreamingCall";
+        }
+        if (methodProto.getClientStreaming() && !methodProto.getServerStreaming()) {
+            methodContext.reactiveCallsMethodName = "manyToOne";
+            methodContext.grpcCallsMethodName = "asyncClientStreamingCall";
+        }
+        if (methodProto.getClientStreaming() && methodProto.getServerStreaming()) {
+            methodContext.reactiveCallsMethodName = "manyToMany";
+            methodContext.grpcCallsMethodName = "asyncBidiStreamingCall";
+        }
+        return methodContext;
+    }
+
+    private String lowerCaseFirst(String s) {
+        return Character.toLowerCase(s.charAt(0)) + s.substring(1);
+    }
+
+    private List<PluginProtos.CodeGeneratorResponse.File> generateFiles(List<ServiceContext> services) {
+        return services.stream()
+                .map(this::buildFile)
+                .collect(Collectors.toList());
+    }
+
+    private PluginProtos.CodeGeneratorResponse.File buildFile(ServiceContext context) {
+        String content = applyTemplate(getClassPrefix() + getClassSuffix() + "Stub.mustache", context);
+        return PluginProtos.CodeGeneratorResponse.File
+                .newBuilder()
+                .setName(absoluteFileName(context))
+                .setContent(content)
+                .build();
+    }
+
+    private String absoluteFileName(ServiceContext ctx) {
+        String dir = ctx.packageName.replace('.', '/');
+        if (Strings.isNullOrEmpty(dir)) {
+            return ctx.fileName;
+        } else {
+            return dir + "/" + ctx.fileName;
+        }
+    }
+
+    private String getComments(Location location) {
+        return location.getLeadingComments().isEmpty() ? location.getTrailingComments() : location.getLeadingComments();
+    }
+
+    private String getJavaDoc(String comments, String prefix) {
+        if (!comments.isEmpty()) {
+            StringBuilder builder = new StringBuilder("/**\n")
+                    .append(prefix).append(" * <pre>\n");
+            Arrays.stream(HtmlEscapers.htmlEscaper().escape(comments).split("\n"))
+                    .map(line -> line.replace("*/", "&#42;&#47;").replace("*", "&#42;"))
+                    .forEach(line -> builder.append(prefix).append(" * ").append(line).append("\n"));
+            builder
+                    .append(prefix).append(" * </pre>\n")
+                    .append(prefix).append(" */");
+            return builder.toString();
+        }
+        return null;
+    }
+
+    /**
+     * Template class for proto Service objects.
+     */
+    private class ServiceContext {
+        // CHECKSTYLE DISABLE VisibilityModifier FOR 8 LINES
+        public String fileName;
+        public String protoName;
+        public String packageName;
+        public String className;
+        public String serviceName;
+        public boolean deprecated;
+        public String javaDoc;
+        public List<MethodContext> methods = new ArrayList<>();
+
+        public Set<String> methodTypes = new HashSet<>();
+
+        public List<MethodContext> unaryRequestMethods() {
+            return methods.stream().filter(m -> !m.isManyInput).collect(Collectors.toList());
+        }
+
+        public List<MethodContext> unaryMethods() {
+            return methods.stream().filter(m -> (!m.isManyInput && !m.isManyOutput)).collect(Collectors.toList());
+        }
+
+        public List<MethodContext> serverStreamingMethods() {
+            return methods.stream().filter(m -> !m.isManyInput && m.isManyOutput).collect(Collectors.toList());
+        }
+
+        public List<MethodContext> biStreamingMethods() {
+            return methods.stream().filter(m -> m.isManyInput).collect(Collectors.toList());
+        }
+    }
+
+    /**
+     * Template class for proto RPC objects.
+     */
+    private class MethodContext {
+        // CHECKSTYLE DISABLE VisibilityModifier FOR 10 LINES
+        public String methodName;
+        public String inputType;
+        public String outputType;
+        public boolean deprecated;
+        public boolean isManyInput;
+        public boolean isManyOutput;
+        public String reactiveCallsMethodName;
+        public String grpcCallsMethodName;
+        public int methodNumber;
+        public String javaDoc;
+
+        // This method mimics the upper-casing method ogf gRPC to ensure compatibility
+        // See https://github.com/grpc/grpc-java/blob/v1.8.0/compiler/src/java_plugin/cpp/java_generator.cpp#L58
+        public String methodNameUpperUnderscore() {
+            StringBuilder s = new StringBuilder();
+            for (int i = 0; i < methodName.length(); i++) {
+                char c = methodName.charAt(i);
+                s.append(Character.toUpperCase(c));
+                if ((i < methodName.length() - 1) && Character.isLowerCase(c) && Character.isUpperCase(methodName.charAt(i + 1))) {
+                    s.append('_');
+                }
+            }
+            return s.toString();
+        }
+
+        public String methodNamePascalCase() {
+            String mn = methodName.replace("_", "");
+            return String.valueOf(Character.toUpperCase(mn.charAt(0))) + mn.substring(1);
+        }
+
+        public String methodNameCamelCase() {
+            String mn = methodName.replace("_", "");
+            return String.valueOf(Character.toLowerCase(mn.charAt(0))) + mn.substring(1);
+        }
+    }
+}
diff --git a/compiler/src/main/java/org/apache/dubbo/gen/dubbo/DubboGenerator.java b/compiler/src/main/java/org/apache/dubbo/gen/dubbo/DubboGenerator.java
new file mode 100644
index 0000000..1c35f0a
--- /dev/null
+++ b/compiler/src/main/java/org/apache/dubbo/gen/dubbo/DubboGenerator.java
@@ -0,0 +1,42 @@
+/*
+ * 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.gen.dubbo;
+
+import org.apache.dubbo.gen.AbstractGenerator;
+
+import com.salesforce.jprotoc.ProtocPlugin;
+
+public class DubboGenerator extends AbstractGenerator {
+
+    public static void main(String[] args) {
+        if (args.length == 0) {
+            ProtocPlugin.generate(new DubboGenerator());
+        } else {
+            ProtocPlugin.debug(new DubboGenerator(), args[0]);
+        }
+    }
+
+    @Override
+    protected String getClassPrefix() {
+        return "";
+    }
+
+    @Override
+    protected String getClassSuffix() {
+        return "Dubbo";
+    }
+}
\ No newline at end of file
diff --git a/compiler/src/main/java/org/apache/dubbo/gen/grpc/DubboGrpcGenerator.java b/compiler/src/main/java/org/apache/dubbo/gen/grpc/DubboGrpcGenerator.java
new file mode 100644
index 0000000..dafdd5a
--- /dev/null
+++ b/compiler/src/main/java/org/apache/dubbo/gen/grpc/DubboGrpcGenerator.java
@@ -0,0 +1,41 @@
+/*
+ * 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.gen.grpc;
+
+import org.apache.dubbo.gen.AbstractGenerator;
+
+import com.salesforce.jprotoc.ProtocPlugin;
+
+public class DubboGrpcGenerator extends AbstractGenerator {
+
+    public static void main(String[] args) {
+        if (args.length == 0) {
+            ProtocPlugin.generate(new DubboGrpcGenerator());
+        } else {
+            ProtocPlugin.debug(new DubboGrpcGenerator(), args[0]);
+        }
+    }
+
+    @Override
+    protected String getClassPrefix() {
+        return "Dubbo";
+    }
+
+    protected String getClassSuffix() {
+        return "Grpc";
+    }
+}
diff --git a/compiler/src/main/java/org/apache/dubbo/gen/grpc/reactive/ReactorDubboGrpcGenerator.java b/compiler/src/main/java/org/apache/dubbo/gen/grpc/reactive/ReactorDubboGrpcGenerator.java
new file mode 100644
index 0000000..dd9520b
--- /dev/null
+++ b/compiler/src/main/java/org/apache/dubbo/gen/grpc/reactive/ReactorDubboGrpcGenerator.java
@@ -0,0 +1,42 @@
+/*
+ * 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.gen.grpc.reactive;
+
+import org.apache.dubbo.gen.AbstractGenerator;
+
+import com.salesforce.jprotoc.ProtocPlugin;
+
+public class ReactorDubboGrpcGenerator extends AbstractGenerator {
+
+    @Override
+    protected String getClassPrefix() {
+        return "ReactorDubbo";
+    }
+
+    @Override
+    protected String getClassSuffix() {
+        return "Grpc";
+    }
+
+    public static void main(String[] args) {
+        if (args.length == 0) {
+            ProtocPlugin.generate(new ReactorDubboGrpcGenerator());
+        } else {
+            ProtocPlugin.debug(new ReactorDubboGrpcGenerator(), args[0]);
+        }
+    }
+}
diff --git a/compiler/src/main/java/org/apache/dubbo/gen/grpc/reactive/RxDubboGrpcGenerator.java b/compiler/src/main/java/org/apache/dubbo/gen/grpc/reactive/RxDubboGrpcGenerator.java
new file mode 100644
index 0000000..028332a
--- /dev/null
+++ b/compiler/src/main/java/org/apache/dubbo/gen/grpc/reactive/RxDubboGrpcGenerator.java
@@ -0,0 +1,41 @@
+/*
+ * 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.gen.grpc.reactive;
+
+import org.apache.dubbo.gen.AbstractGenerator;
+
+import com.salesforce.jprotoc.ProtocPlugin;
+
+public class RxDubboGrpcGenerator extends AbstractGenerator {
+    @Override
+    protected String getClassPrefix() {
+        return "RxDubbo";
+    }
+
+    @Override
+    protected String getClassSuffix() {
+        return "Grpc";
+    }
+
+    public static void main(String[] args) {
+        if (args.length == 0) {
+            ProtocPlugin.generate(new RxDubboGrpcGenerator());
+        } else {
+            ProtocPlugin.debug(new RxDubboGrpcGenerator(), args[0]);
+        }
+    }
+}
diff --git a/compiler/src/main/resources/DubboGrpcStub.mustache b/compiler/src/main/resources/DubboGrpcStub.mustache
new file mode 100644
index 0000000..a02d0c4
--- /dev/null
+++ b/compiler/src/main/resources/DubboGrpcStub.mustache
@@ -0,0 +1,312 @@
+{{#packageName}}
+    package {{packageName}};
+{{/packageName}}
+
+import org.apache.dubbo.common.URL;
+import org.apache.dubbo.config.ReferenceConfigBase;
+
+import java.util.concurrent.TimeUnit;
+
+import static org.apache.dubbo.common.constants.CommonConstants.DEFAULT_TIMEOUT;
+import static org.apache.dubbo.common.constants.CommonConstants.TIMEOUT_KEY;
+
+import static {{packageName}}.{{serviceName}}Grpc.getServiceDescriptor;
+import static io.grpc.stub.ServerCalls.asyncUnaryCall;
+import static io.grpc.stub.ServerCalls.asyncServerStreamingCall;
+import static io.grpc.stub.ServerCalls.asyncClientStreamingCall;
+import static io.grpc.stub.ServerCalls.asyncBidiStreamingCall;
+import static io.grpc.stub.ServerCalls.asyncUnimplementedStreamingCall;
+import static io.grpc.stub.ServerCalls.asyncUnimplementedUnaryCall;
+
+{{#deprecated}}
+    @java.lang.Deprecated
+{{/deprecated}}
+@javax.annotation.Generated(
+value = "by DubboGrpc generator",
+comments = "Source: {{protoName}}")
+public final class {{className}} {
+private {{className}}() {}
+
+public static class Dubbo{{serviceName}}Stub implements I{{serviceName}} {
+
+protected URL url;
+protected ReferenceConfigBase<?> referenceConfig;
+
+protected {{serviceName}}Grpc.{{serviceName}}BlockingStub blockingStub;
+protected {{serviceName}}Grpc.{{serviceName}}FutureStub futureStub;
+protected {{serviceName}}Grpc.{{serviceName}}Stub stub;
+
+public Dubbo{{serviceName}}Stub(io.grpc.Channel channel, io.grpc.CallOptions callOptions, URL url, ReferenceConfigBase<?> referenceConfig) {
+this.url = url;
+this.referenceConfig = referenceConfig;
+
+blockingStub = {{serviceName}}Grpc.newBlockingStub(channel).build(channel, callOptions);
+futureStub = {{serviceName}}Grpc.newFutureStub(channel).build(channel, callOptions);
+stub = {{serviceName}}Grpc.newStub(channel).build(channel, callOptions);
+}
+
+{{#unaryMethods}}
+    {{#javaDoc}}
+        {{{javaDoc}}}
+    {{/javaDoc}}
+    {{#deprecated}}
+        @java.lang.Deprecated
+    {{/deprecated}}
+    public {{outputType}} {{methodName}}({{inputType}} request) {
+    return blockingStub
+    .withDeadlineAfter(url.getParameter(TIMEOUT_KEY, DEFAULT_TIMEOUT), TimeUnit.MILLISECONDS)
+    .{{methodName}}(request);
+    }
+
+    public com.google.common.util.concurrent.ListenableFuture<{{outputType}}> {{methodName}}Async({{inputType}} request) {
+    return futureStub
+    .withDeadlineAfter(url.getParameter(TIMEOUT_KEY, DEFAULT_TIMEOUT), TimeUnit.MILLISECONDS)
+    .{{methodName}}(request);
+    }
+
+    public void {{methodName}}({{inputType}} request, io.grpc.stub.StreamObserver<{{outputType}}> responseObserver){
+    stub
+    .withDeadlineAfter(url.getParameter(TIMEOUT_KEY, DEFAULT_TIMEOUT), TimeUnit.MILLISECONDS)
+    .{{methodName}}(request, responseObserver);
+    }
+
+{{/unaryMethods}}
+{{#serverStreamingMethods}}
+    {{#javaDoc}}
+        {{{javaDoc}}}
+    {{/javaDoc}}
+    {{#deprecated}}
+        @java.lang.Deprecated
+    {{/deprecated}}
+    public java.util.Iterator<{{outputType}}> {{methodName}}({{inputType}} request) {
+    return blockingStub
+    .withDeadlineAfter(url.getParameter(TIMEOUT_KEY, DEFAULT_TIMEOUT), TimeUnit.MILLISECONDS)
+    .{{methodName}}(request);
+    }
+
+    public void {{methodName}}({{inputType}} request, io.grpc.stub.StreamObserver<{{outputType}}> responseObserver) {
+    stub
+    .withDeadlineAfter(url.getParameter(TIMEOUT_KEY, DEFAULT_TIMEOUT), TimeUnit.MILLISECONDS)
+    .{{methodName}}(request, responseObserver);
+    }
+
+{{/serverStreamingMethods}}
+{{#biStreamingMethods}}
+    {{#javaDoc}}
+        {{{javaDoc}}}
+    {{/javaDoc}}
+    {{#deprecated}}
+        @java.lang.Deprecated
+    {{/deprecated}}
+    public io.grpc.stub.StreamObserver<{{inputType}}> {{methodName}}(io.grpc.stub.StreamObserver<{{outputType}}> responseObserver) {
+    return stub
+    .withDeadlineAfter(url.getParameter(TIMEOUT_KEY, DEFAULT_TIMEOUT), TimeUnit.MILLISECONDS)
+    .{{methodName}}(responseObserver);
+    }
+{{/biStreamingMethods}}
+}
+
+public static Dubbo{{serviceName}}Stub getDubboStub(io.grpc.Channel channel, io.grpc.CallOptions callOptions, URL url, ReferenceConfigBase<?> referenceConfig) {
+return new Dubbo{{serviceName}}Stub(channel, callOptions, url, referenceConfig);
+}
+
+public interface I{{serviceName}} {
+{{#unaryMethods}}
+    {{#javaDoc}}
+        {{{javaDoc}}}
+    {{/javaDoc}}
+    {{#deprecated}}
+        @java.lang.Deprecated
+    {{/deprecated}}
+    default public {{outputType}} {{methodName}}({{inputType}} request) {
+    throw new UnsupportedOperationException("No need to override this method, extend XxxImplBase and override all methods it allows.");
+    }
+
+    {{#javaDoc}}
+        {{{javaDoc}}}
+    {{/javaDoc}}
+    {{#deprecated}}
+        @java.lang.Deprecated
+    {{/deprecated}}
+    default public com.google.common.util.concurrent.ListenableFuture<{{outputType}}> {{methodName}}Async({{inputType}} request) {
+    throw new UnsupportedOperationException("No need to override this method, extend XxxImplBase and override all methods it allows.");
+    }
+
+    {{#javaDoc}}
+        {{{javaDoc}}}
+    {{/javaDoc}}
+    {{#deprecated}}
+        @java.lang.Deprecated
+    {{/deprecated}}
+    public void {{methodName}}({{inputType}} request, io.grpc.stub.StreamObserver<{{outputType}}> responseObserver);
+
+{{/unaryMethods}}
+{{#serverStreamingMethods}}
+    {{#javaDoc}}
+        {{{javaDoc}}}
+    {{/javaDoc}}
+    {{#deprecated}}
+        @java.lang.Deprecated
+    {{/deprecated}}
+    default public java.util.Iterator<{{outputType}}> {{methodName}}({{inputType}} request) {
+    throw new UnsupportedOperationException("No need to override this method, extend XxxImplBase and override all methods it allows.");
+    }
+
+    {{#javaDoc}}
+        {{{javaDoc}}}
+    {{/javaDoc}}
+    {{#deprecated}}
+        @java.lang.Deprecated
+    {{/deprecated}}
+    public void {{methodName}}({{inputType}} request, io.grpc.stub.StreamObserver<{{outputType}}> responseObserver);
+
+{{/serverStreamingMethods}}
+{{#biStreamingMethods}}
+    {{#javaDoc}}
+        {{{javaDoc}}}
+    {{/javaDoc}}
+    {{#deprecated}}
+        @java.lang.Deprecated
+    {{/deprecated}}
+    public io.grpc.stub.StreamObserver<{{inputType}}> {{methodName}}(io.grpc.stub.StreamObserver<{{outputType}}> responseObserver);
+
+{{/biStreamingMethods}}
+}
+
+{{#javaDoc}}
+    {{{javaDoc}}}
+{{/javaDoc}}
+public static abstract class {{serviceName}}ImplBase implements io.grpc.BindableService, I{{serviceName}} {
+
+private I{{serviceName}} proxiedImpl;
+
+public final void setProxiedImpl(I{{serviceName}} proxiedImpl) {
+this.proxiedImpl = proxiedImpl;
+}
+
+{{#unaryMethods}}
+    {{#javaDoc}}
+        {{{javaDoc}}}
+    {{/javaDoc}}
+    {{#deprecated}}
+        @java.lang.Deprecated
+    {{/deprecated}}
+    @java.lang.Override
+    public final {{outputType}} {{methodName}}({{inputType}} request) {
+    throw new UnsupportedOperationException("No need to override this method, extend XxxImplBase and override all methods it allows.");
+    }
+
+    {{#javaDoc}}
+        {{{javaDoc}}}
+    {{/javaDoc}}
+    {{#deprecated}}
+        @java.lang.Deprecated
+    {{/deprecated}}
+    @java.lang.Override
+    public final com.google.common.util.concurrent.ListenableFuture<{{outputType}}> {{methodName}}Async({{inputType}} request) {
+    throw new UnsupportedOperationException("No need to override this method, extend XxxImplBase and override all methods it allows.");
+    }
+
+{{/unaryMethods}}
+{{#serverStreamingMethods}}
+    {{#javaDoc}}
+        {{{javaDoc}}}
+    {{/javaDoc}}
+    {{#deprecated}}
+        @java.lang.Deprecated
+    {{/deprecated}}
+    @java.lang.Override
+    public final java.util.Iterator<{{outputType}}> {{methodName}}({{inputType}} request) {
+    throw new UnsupportedOperationException("No need to override this method, extend XxxImplBase and override all methods it allows.");
+    }
+
+{{/serverStreamingMethods}}
+{{#methods}}
+    {{#isManyInput}}
+        public io.grpc.stub.StreamObserver<{{inputType}}> {{methodName}}(
+        io.grpc.stub.StreamObserver<{{outputType}}> responseObserver) {
+        return asyncUnimplementedStreamingCall({{packageName}}.{{serviceName}}Grpc.get{{methodNamePascalCase}}Method(), responseObserver);
+        }
+    {{/isManyInput}}{{^isManyInput}}
+        public void {{methodName}}({{inputType}} request,
+        io.grpc.stub.StreamObserver<{{outputType}}> responseObserver) {
+        asyncUnimplementedUnaryCall({{packageName}}.{{serviceName}}Grpc.get{{methodNamePascalCase}}Method(), responseObserver);
+        }
+    {{/isManyInput}}
+{{/methods}}
+
+@java.lang.Override public final io.grpc.ServerServiceDefinition bindService() {
+return io.grpc.ServerServiceDefinition.builder(getServiceDescriptor())
+{{#methods}}
+    .addMethod(
+    {{packageName}}.{{serviceName}}Grpc.get{{methodNamePascalCase}}Method(),
+    {{grpcCallsMethodName}}(
+    new MethodHandlers<
+    {{inputType}},
+    {{outputType}}>(
+    proxiedImpl, METHODID_{{methodNameUpperUnderscore}})))
+{{/methods}}
+.build();
+}
+}
+{{#methods}}
+    private static final int METHODID_{{methodNameUpperUnderscore}} = {{methodNumber}};
+{{/methods}}
+
+private static final class MethodHandlers
+<Req, Resp> implements
+io.grpc.stub.ServerCalls.UnaryMethod
+<Req, Resp>,
+io.grpc.stub.ServerCalls.ServerStreamingMethod
+<Req, Resp>,
+io.grpc.stub.ServerCalls.ClientStreamingMethod
+<Req, Resp>,
+io.grpc.stub.ServerCalls.BidiStreamingMethod
+<Req, Resp> {
+private final I{{serviceName}} serviceImpl;
+private final int methodId;
+
+MethodHandlers(I{{serviceName}} serviceImpl, int methodId) {
+this.serviceImpl = serviceImpl;
+this.methodId = methodId;
+}
+
+@java.lang.Override
+@java.lang.SuppressWarnings("unchecked")
+public void invoke(Req request, io.grpc.stub.StreamObserver
+<Resp> responseObserver) {
+    switch (methodId) {
+    {{#methods}}
+        {{^isManyInput}}
+            case METHODID_{{methodNameUpperUnderscore}}:
+            serviceImpl.{{methodName}}(({{inputType}}) request,
+            (io.grpc.stub.StreamObserver<{{outputType}}>) responseObserver);
+            break;
+        {{/isManyInput}}
+    {{/methods}}
+    default:
+    throw new java.lang.AssertionError();
+    }
+    }
+
+    @java.lang.Override
+    @java.lang.SuppressWarnings("unchecked")
+    public io.grpc.stub.StreamObserver
+    <Req> invoke(io.grpc.stub.StreamObserver
+        <Resp> responseObserver) {
+            switch (methodId) {
+            {{#methods}}
+                {{#isManyInput}}
+                    case METHODID_{{methodNameUpperUnderscore}}:
+                    return (io.grpc.stub.StreamObserver
+                <Req>) serviceImpl.{{methodName}}(
+                    (io.grpc.stub.StreamObserver<{{outputType}}>) responseObserver);
+                {{/isManyInput}}
+            {{/methods}}
+            default:
+            throw new java.lang.AssertionError();
+            }
+            }
+            }
+
+            }
diff --git a/compiler/src/main/resources/DubboStub.mustache b/compiler/src/main/resources/DubboStub.mustache
new file mode 100644
index 0000000..06bd7b4
--- /dev/null
+++ b/compiler/src/main/resources/DubboStub.mustache
@@ -0,0 +1,53 @@
+{{#packageName}}
+    package {{packageName}};
+{{/packageName}}
+
+import java.util.concurrent.CompletableFuture;
+import java.util.concurrent.atomic.AtomicBoolean;
+
+{{#deprecated}}
+    @java.lang.Deprecated
+{{/deprecated}}
+@javax.annotation.Generated(
+value = "by Dubbo generator",
+comments = "Source: {{protoName}}")
+public final class {{className}} {
+private static final AtomicBoolean registered = new AtomicBoolean();
+
+private static Class<?> init() {
+Class<?> clazz = null;
+try {
+clazz = Class.forName({{serviceName}}Dubbo.class.getName());
+if (registered.compareAndSet(false, true)) {
+{{#methodTypes}}
+    org.apache.dubbo.common.serialize.protobuf.support.ProtobufUtils.marshaller(
+    {{.}}.getDefaultInstance());
+{{/methodTypes}}
+}
+} catch (ClassNotFoundException e) {
+// ignore
+}
+return clazz;
+}
+
+private {{serviceName}}Dubbo() {}
+
+public static final String SERVICE_NAME = "{{packageName}}.{{serviceName}}";
+
+/**
+* Code generated for Dubbo
+*/
+public interface I{{serviceName}} {
+
+static Class<?> clazz = init();
+
+{{#methods}}
+    {{outputType}} {{methodName}}({{inputType}} request);
+
+    CompletableFuture<{{outputType}}> {{methodName}}Async({{inputType}} request);
+
+{{/methods}}
+
+}
+
+}
diff --git a/compiler/src/main/resources/ReactorDubboGrpcStub.mustache b/compiler/src/main/resources/ReactorDubboGrpcStub.mustache
new file mode 100644
index 0000000..2cf1471
--- /dev/null
+++ b/compiler/src/main/resources/ReactorDubboGrpcStub.mustache
@@ -0,0 +1,212 @@
+{{#packageName}}
+    package {{packageName}};
+{{/packageName}}
+
+import org.apache.dubbo.common.URL;
+import org.apache.dubbo.config.ReferenceConfigBase;
+
+import java.util.concurrent.TimeUnit;
+
+import static org.apache.dubbo.common.constants.CommonConstants.DEFAULT_TIMEOUT;
+import static org.apache.dubbo.common.constants.CommonConstants.TIMEOUT_KEY;
+
+import static {{packageName}}.{{serviceName}}Grpc.getServiceDescriptor;
+import static io.grpc.stub.ServerCalls.asyncUnaryCall;
+import static io.grpc.stub.ServerCalls.asyncServerStreamingCall;
+import static io.grpc.stub.ServerCalls.asyncClientStreamingCall;
+import static io.grpc.stub.ServerCalls.asyncBidiStreamingCall;
+
+
+{{#deprecated}}
+    @java.lang.Deprecated
+{{/deprecated}}
+@javax.annotation.Generated(
+value = "by ReactorDubboGrpc generator",
+comments = "Source: {{protoName}}")
+public final class {{className}} {
+private {{className}}() {}
+
+public static ReactorDubbo{{serviceName}}Stub getDubboStub(io.grpc.Channel channel, io.grpc.CallOptions callOptions, URL url, ReferenceConfigBase<?> referenceConfig) {
+return new ReactorDubbo{{serviceName}}Stub(channel, callOptions, url, referenceConfig);
+}
+
+{{#javaDoc}}
+    {{{javaDoc}}}
+{{/javaDoc}}
+public static final class ReactorDubbo{{serviceName}}Stub implements IReactor{{serviceName}} {
+
+protected URL url;
+protected ReferenceConfigBase<?> referenceConfig;
+
+protected {{serviceName}}Grpc.{{serviceName}}Stub stub;
+
+public ReactorDubbo{{serviceName}}Stub(io.grpc.Channel channel, io.grpc.CallOptions callOptions, URL url, ReferenceConfigBase<?> referenceConfig) {
+this.url = url;
+this.referenceConfig = referenceConfig;
+stub = {{serviceName}}Grpc.newStub(channel).build(channel, callOptions);
+}
+
+{{#methods}}
+    {{#javaDoc}}
+        {{{javaDoc}}}
+    {{/javaDoc}}
+    {{#deprecated}}
+        @java.lang.Deprecated
+    {{/deprecated}}
+    public {{#isManyOutput}}reactor.core.publisher.Flux{{/isManyOutput}}{{^isManyOutput}}reactor.core.publisher.Mono{{/isManyOutput}}<{{outputType}}> {{methodName}}({{#isManyInput}}reactor.core.publisher.Flux{{/isManyInput}}{{^isManyInput}}reactor.core.publisher.Mono{{/isManyInput}}<{{inputType}}> reactorRequest) {
+    {{serviceName}}Grpc.{{serviceName}}Stub localStub = stub.withDeadlineAfter(url.getParameter(TIMEOUT_KEY, DEFAULT_TIMEOUT), TimeUnit.MILLISECONDS);
+    return com.salesforce.reactorgrpc.stub.ClientCalls.{{reactiveCallsMethodName}}(reactorRequest, localStub::{{methodName}});
+    }
+
+{{/methods}}
+{{#unaryRequestMethods}}
+    {{#javaDoc}}
+        {{{javaDoc}}}
+    {{/javaDoc}}
+    {{#deprecated}}
+        @java.lang.Deprecated
+    {{/deprecated}}
+    public {{#isManyOutput}}reactor.core.publisher.Flux{{/isManyOutput}}{{^isManyOutput}}reactor.core.publisher.Mono{{/isManyOutput}}<{{outputType}}> {{methodName}}({{inputType}} reactorRequest) {
+    {{serviceName}}Grpc.{{serviceName}}Stub localStub = stub.withDeadlineAfter(url.getParameter(TIMEOUT_KEY, DEFAULT_TIMEOUT), TimeUnit.MILLISECONDS);
+    return com.salesforce.reactorgrpc.stub.ClientCalls.{{reactiveCallsMethodName}}(reactor.core.publisher.Mono.just(reactorRequest), localStub::{{methodName}});
+    }
+
+{{/unaryRequestMethods}}
+}
+
+public interface IReactor{{serviceName}} {
+{{#methods}}
+    {{#javaDoc}}
+        {{{javaDoc}}}
+    {{/javaDoc}}
+    {{#deprecated}}
+        @java.lang.Deprecated
+    {{/deprecated}}
+    public {{#isManyOutput}}reactor.core.publisher.Flux{{/isManyOutput}}{{^isManyOutput}}reactor.core.publisher.Mono{{/isManyOutput}}<{{outputType}}> {{methodName}}({{#isManyInput}}reactor.core.publisher.Flux{{/isManyInput}}{{^isManyInput}}reactor.core.publisher.Mono{{/isManyInput}}<{{inputType}}> reactorRequest);
+
+{{/methods}}
+{{#unaryRequestMethods}}
+    {{#javaDoc}}
+        {{{javaDoc}}}
+    {{/javaDoc}}
+    {{#deprecated}}
+        @java.lang.Deprecated
+    {{/deprecated}}
+    public {{#isManyOutput}}reactor.core.publisher.Flux{{/isManyOutput}}{{^isManyOutput}}reactor.core.publisher.Mono{{/isManyOutput}}<{{outputType}}> {{methodName}}({{inputType}} reactorRequest);
+
+{{/unaryRequestMethods}}
+}
+
+{{#javaDoc}}
+    {{{javaDoc}}}
+{{/javaDoc}}
+public static abstract class {{serviceName}}ImplBase implements IReactor{{serviceName}}, io.grpc.BindableService {
+
+private IReactor{{serviceName}} proxiedImpl;
+
+public final void setProxiedImpl(IReactor{{serviceName}} proxiedImpl) {
+this.proxiedImpl = proxiedImpl;
+}
+
+{{#unaryRequestMethods}}
+    {{#javaDoc}}
+        {{{javaDoc}}}
+    {{/javaDoc}}
+    {{#deprecated}}
+        @java.lang.Deprecated
+    {{/deprecated}}
+    public final {{#isManyOutput}}reactor.core.publisher.Flux{{/isManyOutput}}{{^isManyOutput}}reactor.core.publisher.Mono{{/isManyOutput}}<{{outputType}}> {{methodName}}({{inputType}} reactorRequest) {
+    throw new UnsupportedOperationException("No need to override this method, extend XxxImplBase and override all methods it allows.");
+    }
+
+{{/unaryRequestMethods}}
+{{#methods}}
+    {{#javaDoc}}
+        {{{javaDoc}}}
+    {{/javaDoc}}
+    {{#deprecated}}
+        @java.lang.Deprecated
+    {{/deprecated}}
+    public {{#isManyOutput}}reactor.core.publisher.Flux{{/isManyOutput}}{{^isManyOutput}}reactor.core.publisher.Mono{{/isManyOutput}}<{{outputType}}> {{methodName}}({{#isManyInput}}reactor.core.publisher.Flux{{/isManyInput}}{{^isManyInput}}reactor.core.publisher.Mono{{/isManyInput}}<{{inputType}}> request) {
+    throw new io.grpc.StatusRuntimeException(io.grpc.Status.UNIMPLEMENTED);
+    }
+
+{{/methods}}
+@java.lang.Override public final io.grpc.ServerServiceDefinition bindService() {
+return io.grpc.ServerServiceDefinition.builder(getServiceDescriptor())
+{{#methods}}
+    .addMethod(
+    {{packageName}}.{{serviceName}}Grpc.get{{methodNamePascalCase}}Method(),
+    {{grpcCallsMethodName}}(
+    new MethodHandlers<
+    {{inputType}},
+    {{outputType}}>(
+    proxiedImpl, METHODID_{{methodNameUpperUnderscore}})))
+{{/methods}}
+.build();
+}
+}
+
+{{#methods}}
+    private static final int METHODID_{{methodNameUpperUnderscore}} = {{methodNumber}};
+{{/methods}}
+
+private static final class MethodHandlers
+<Req, Resp> implements
+io.grpc.stub.ServerCalls.UnaryMethod
+<Req, Resp>,
+io.grpc.stub.ServerCalls.ServerStreamingMethod
+<Req, Resp>,
+io.grpc.stub.ServerCalls.ClientStreamingMethod
+<Req, Resp>,
+io.grpc.stub.ServerCalls.BidiStreamingMethod
+<Req, Resp> {
+private final IReactor{{serviceName}} serviceImpl;
+private final int methodId;
+
+MethodHandlers(IReactor{{serviceName}} serviceImpl, int methodId) {
+this.serviceImpl = serviceImpl;
+this.methodId = methodId;
+}
+
+@java.lang.Override
+@java.lang.SuppressWarnings("unchecked")
+public void invoke(Req request, io.grpc.stub.StreamObserver
+<Resp> responseObserver) {
+    switch (methodId) {
+    {{#methods}}
+        {{^isManyInput}}
+            case METHODID_{{methodNameUpperUnderscore}}:
+            com.salesforce.reactorgrpc.stub.ServerCalls.{{reactiveCallsMethodName}}(({{inputType}}) request,
+            (io.grpc.stub.StreamObserver<{{outputType}}>) responseObserver,
+            serviceImpl::{{methodName}});
+            break;
+        {{/isManyInput}}
+    {{/methods}}
+    default:
+    throw new java.lang.AssertionError();
+    }
+    }
+
+    @java.lang.Override
+    @java.lang.SuppressWarnings("unchecked")
+    public io.grpc.stub.StreamObserver
+    <Req> invoke(io.grpc.stub.StreamObserver
+        <Resp> responseObserver) {
+            switch (methodId) {
+            {{#methods}}
+                {{#isManyInput}}
+                    case METHODID_{{methodNameUpperUnderscore}}:
+                    return (io.grpc.stub.StreamObserver
+                <Req>) com.salesforce.reactorgrpc.stub.ServerCalls.{{reactiveCallsMethodName}}(
+                    (io.grpc.stub.StreamObserver<{{outputType}}>) responseObserver,
+                    serviceImpl::{{methodName}});
+                {{/isManyInput}}
+            {{/methods}}
+            default:
+            throw new java.lang.AssertionError();
+            }
+            }
+            }
+
+            }
diff --git a/compiler/src/main/resources/RxDubboGrpcStub.mustache b/compiler/src/main/resources/RxDubboGrpcStub.mustache
new file mode 100644
index 0000000..22c06b0
--- /dev/null
+++ b/compiler/src/main/resources/RxDubboGrpcStub.mustache
@@ -0,0 +1,246 @@
+{{#packageName}}
+    package {{packageName}};
+{{/packageName}}
+
+import org.apache.dubbo.common.URL;
+import org.apache.dubbo.config.ReferenceConfigBase;
+
+import java.util.concurrent.TimeUnit;
+
+import static org.apache.dubbo.common.constants.CommonConstants.DEFAULT_TIMEOUT;
+import static org.apache.dubbo.common.constants.CommonConstants.TIMEOUT_KEY;
+
+import static {{packageName}}.{{serviceName}}Grpc.getServiceDescriptor;
+import static io.grpc.stub.ServerCalls.asyncUnaryCall;
+import static io.grpc.stub.ServerCalls.asyncServerStreamingCall;
+import static io.grpc.stub.ServerCalls.asyncClientStreamingCall;
+import static io.grpc.stub.ServerCalls.asyncBidiStreamingCall;
+
+
+{{#deprecated}}
+    @java.lang.Deprecated
+{{/deprecated}}
+@javax.annotation.Generated(
+value = "by RxDubboGrpc generator",
+comments = "Source: {{protoName}}")
+public final class {{className}} {
+private {{className}}() {}
+
+public static RxDubbo{{serviceName}}Stub getDubboStub(io.grpc.Channel channel, io.grpc.CallOptions callOptions, URL url, ReferenceConfigBase<?> referenceConfig) {
+return new RxDubbo{{serviceName}}Stub(channel, callOptions, url, referenceConfig);
+}
+
+{{#javaDoc}}
+    {{{javaDoc}}}
+{{/javaDoc}}
+public static final class RxDubbo{{serviceName}}Stub implements IRx{{serviceName}} {
+
+protected URL url;
+protected ReferenceConfigBase<?> referenceConfig;
+
+protected {{serviceName}}Grpc.{{serviceName}}Stub stub;
+
+public RxDubbo{{serviceName}}Stub(io.grpc.Channel channel, io.grpc.CallOptions callOptions, URL url, ReferenceConfigBase<?> referenceConfig) {
+this.url = url;
+this.referenceConfig = referenceConfig;
+stub = {{serviceName}}Grpc.newStub(channel).build(channel, callOptions);
+}
+
+{{#methods}}
+    {{#javaDoc}}
+        {{{javaDoc}}}
+    {{/javaDoc}}
+    {{#deprecated}}
+        @java.lang.Deprecated
+    {{/deprecated}}
+    public {{#isManyOutput}}io.reactivex.Flowable{{/isManyOutput}}{{^isManyOutput}}io.reactivex.Single{{/isManyOutput}}<{{outputType}}> {{methodName}}({{#isManyInput}}io.reactivex.Flowable{{/isManyInput}}{{^isManyInput}}io.reactivex.Single{{/isManyInput}}<{{inputType}}> rxRequest) {
+    return com.salesforce.rxgrpc.stub.ClientCalls.{{reactiveCallsMethodName}}(rxRequest,
+    {{^isManyInput}}
+        new com.salesforce.reactivegrpc.common.BiConsumer<{{inputType}}, io.grpc.stub.StreamObserver<{{outputType}}>>() {
+        @java.lang.Override
+        public void accept({{inputType}} request, io.grpc.stub.StreamObserver<{{outputType}}> observer) {
+        stub.withDeadlineAfter(url.getParameter(TIMEOUT_KEY, DEFAULT_TIMEOUT), TimeUnit.MILLISECONDS).{{methodNameCamelCase}}(request, observer);
+        }
+        });
+    {{/isManyInput}}
+    {{#isManyInput}}
+        new com.salesforce.reactivegrpc.common.Function
+        <io.grpc.stub.StreamObserver<{{outputType}}>, io.grpc.stub.StreamObserver<{{inputType}}>>() {
+        @java.lang.Override
+        public io.grpc.stub.StreamObserver<{{inputType}}> apply(io.grpc.stub.StreamObserver<{{outputType}}> observer) {
+        return stub.withDeadlineAfter(url.getParameter(TIMEOUT_KEY, DEFAULT_TIMEOUT), TimeUnit.MILLISECONDS).{{methodNameCamelCase}}(observer);
+        }
+        });
+    {{/isManyInput}}
+    }
+
+{{/methods}}
+{{#unaryRequestMethods}}
+    {{#javaDoc}}
+        {{{javaDoc}}}
+    {{/javaDoc}}
+    {{#deprecated}}
+        @java.lang.Deprecated
+    {{/deprecated}}
+    public {{#isManyOutput}}io.reactivex.Flowable{{/isManyOutput}}{{^isManyOutput}}io.reactivex.Single{{/isManyOutput}}<{{outputType}}> {{methodName}}({{inputType}} rxRequest) {
+    return com.salesforce.rxgrpc.stub.ClientCalls.{{reactiveCallsMethodName}}(io.reactivex.Single.just(rxRequest),
+    new com.salesforce.reactivegrpc.common.BiConsumer<{{inputType}}, io.grpc.stub.StreamObserver<{{outputType}}>>() {
+    @java.lang.Override
+    public void accept({{inputType}} request, io.grpc.stub.StreamObserver<{{outputType}}> observer) {
+    stub.withDeadlineAfter(url.getParameter(TIMEOUT_KEY, DEFAULT_TIMEOUT), TimeUnit.MILLISECONDS).{{methodNameCamelCase}}(request, observer);
+    }
+    });
+    }
+
+{{/unaryRequestMethods}}
+}
+
+public interface IRx{{serviceName}} {
+{{#methods}}
+    {{#javaDoc}}
+        {{{javaDoc}}}
+    {{/javaDoc}}
+    {{#deprecated}}
+        @java.lang.Deprecated
+    {{/deprecated}}
+    public {{#isManyOutput}}io.reactivex.Flowable{{/isManyOutput}}{{^isManyOutput}}io.reactivex.Single{{/isManyOutput}}<{{outputType}}> {{methodName}}({{#isManyInput}}io.reactivex.Flowable{{/isManyInput}}{{^isManyInput}}io.reactivex.Single{{/isManyInput}}<{{inputType}}> rxRequest);
+
+{{/methods}}
+{{#unaryRequestMethods}}
+    {{#javaDoc}}
+        {{{javaDoc}}}
+    {{/javaDoc}}
+    {{#deprecated}}
+        @java.lang.Deprecated
+    {{/deprecated}}
+    public {{#isManyOutput}}io.reactivex.Flowable{{/isManyOutput}}{{^isManyOutput}}io.reactivex.Single{{/isManyOutput}}<{{outputType}}> {{methodName}}({{inputType}} rxRequest);
+
+{{/unaryRequestMethods}}
+}
+
+
+{{#javaDoc}}
+    {{{javaDoc}}}
+{{/javaDoc}}
+public static abstract class {{serviceName}}ImplBase implements IRx{{serviceName}}, io.grpc.BindableService {
+
+private IRx{{serviceName}} proxiedImpl;
+
+public final void setProxiedImpl(IRx{{serviceName}} proxiedImpl) {
+this.proxiedImpl = proxiedImpl;
+}
+{{#unaryRequestMethods}}
+    {{#javaDoc}}
+        {{{javaDoc}}}
+    {{/javaDoc}}
+    {{#deprecated}}
+        @java.lang.Deprecated
+    {{/deprecated}}
+    public final {{#isManyOutput}}io.reactivex.Flowable{{/isManyOutput}}{{^isManyOutput}}io.reactivex.Single{{/isManyOutput}}<{{outputType}}> {{methodName}}({{inputType}} rxRequest) {
+    throw new UnsupportedOperationException("No need to override this method, extend XxxImplBase and override all methods it allows.");
+    }
+
+{{/unaryRequestMethods}}
+{{#methods}}
+    {{#javaDoc}}
+        {{{javaDoc}}}
+    {{/javaDoc}}
+    {{#deprecated}}
+        @java.lang.Deprecated
+    {{/deprecated}}
+    public {{#isManyOutput}}io.reactivex.Flowable{{/isManyOutput}}{{^isManyOutput}}io.reactivex.Single{{/isManyOutput}}<{{outputType}}> {{methodNameCamelCase}}({{#isManyInput}}io.reactivex.Flowable{{/isManyInput}}{{^isManyInput}}io.reactivex.Single{{/isManyInput}}<{{inputType}}> request) {
+    throw new io.grpc.StatusRuntimeException(io.grpc.Status.UNIMPLEMENTED);
+    }
+
+{{/methods}}
+@java.lang.Override public final io.grpc.ServerServiceDefinition bindService() {
+return io.grpc.ServerServiceDefinition.builder(getServiceDescriptor())
+{{#methods}}
+    .addMethod(
+    {{packageName}}.{{serviceName}}Grpc.get{{methodNamePascalCase}}Method(),
+    {{grpcCallsMethodName}}(
+    new MethodHandlers<
+    {{inputType}},
+    {{outputType}}>(
+    proxiedImpl, METHODID_{{methodNameUpperUnderscore}})))
+{{/methods}}
+.build();
+}
+}
+
+{{#methods}}
+    private static final int METHODID_{{methodNameUpperUnderscore}} = {{methodNumber}};
+{{/methods}}
+
+private static final class MethodHandlers
+<Req, Resp> implements
+io.grpc.stub.ServerCalls.UnaryMethod
+<Req, Resp>,
+io.grpc.stub.ServerCalls.ServerStreamingMethod
+<Req, Resp>,
+io.grpc.stub.ServerCalls.ClientStreamingMethod
+<Req, Resp>,
+io.grpc.stub.ServerCalls.BidiStreamingMethod
+<Req, Resp> {
+private final IRx{{serviceName}} serviceImpl;
+private final int methodId;
+
+MethodHandlers(IRx{{serviceName}} serviceImpl, int methodId) {
+this.serviceImpl = serviceImpl;
+this.methodId = methodId;
+}
+
+@java.lang.Override
+@java.lang.SuppressWarnings("unchecked")
+public void invoke(Req request, io.grpc.stub.StreamObserver
+<Resp> responseObserver) {
+    switch (methodId) {
+    {{#methods}}
+        {{^isManyInput}}
+            case METHODID_{{methodNameUpperUnderscore}}:
+            com.salesforce.rxgrpc.stub.ServerCalls.{{reactiveCallsMethodName}}(({{inputType}}) request,
+            (io.grpc.stub.StreamObserver<{{outputType}}>) responseObserver,
+            new com.salesforce.reactivegrpc.common.Function
+                <{{#isManyInput}}io.reactivex.Flowable{{/isManyInput}}{{^isManyInput}}io.reactivex.Single{{/isManyInput}}
+            <{{inputType}}>, {{#isManyOutput}}
+            io.reactivex.Flowable{{/isManyOutput}}{{^isManyOutput}}
+            io.reactivex.Single{{/isManyOutput}}<{{outputType}}>>() {
+            @java.lang.Override
+            public {{#isManyOutput}}
+            io.reactivex.Flowable{{/isManyOutput}}{{^isManyOutput}}
+            io.reactivex.Single{{/isManyOutput}}<{{outputType}}> apply({{#isManyInput}}
+            io.reactivex.Flowable{{/isManyInput}}{{^isManyInput}}
+            io.reactivex.Single{{/isManyInput}}<{{inputType}}> single) {
+            return serviceImpl.{{methodNameCamelCase}}(single);
+            }
+            });
+            break;
+        {{/isManyInput}}
+    {{/methods}}
+    default:
+    throw new java.lang.AssertionError();
+    }
+    }
+
+    @java.lang.Override
+    @java.lang.SuppressWarnings("unchecked")
+    public io.grpc.stub.StreamObserver
+    <Req> invoke(io.grpc.stub.StreamObserver
+        <Resp> responseObserver) {
+            switch (methodId) {
+            {{#methods}}
+                {{#isManyInput}}
+                    case METHODID_{{methodNameUpperUnderscore}}:
+                    return (io.grpc.stub.StreamObserver
+                <Req>) com.salesforce.rxgrpc.stub.ServerCalls.{{reactiveCallsMethodName}}(
+                    (io.grpc.stub.StreamObserver<{{outputType}}>) responseObserver,
+                    serviceImpl::{{methodNameCamelCase}});
+                {{/isManyInput}}
+            {{/methods}}
+            default:
+            throw new java.lang.AssertionError();
+            }
+            }
+            }
+
+            }
diff --git a/dubbo-spi-configcenter/dubbo-configcenter-apollo/pom.xml b/dubbo-spi-configcenter/dubbo-configcenter-apollo/pom.xml
new file mode 100644
index 0000000..8d3dc0e
--- /dev/null
+++ b/dubbo-spi-configcenter/dubbo-configcenter-apollo/pom.xml
@@ -0,0 +1,52 @@
+<!--
+  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.
+  -->
+<project xmlns="http://maven.apache.org/POM/4.0.0" xmlns:xsi="http://www.w3.org/2001/XMLSchema-instance" xsi:schemaLocation="http://maven.apache.org/POM/4.0.0 http://maven.apache.org/maven-v4_0_0.xsd">
+    <modelVersion>4.0.0</modelVersion>
+
+    <parent>
+        <groupId>org.apache.dubbo</groupId>
+        <artifactId>dubbo-configcenter</artifactId>
+        <version>2.7.7-SNAPSHOT</version>
+    </parent>
+
+    <artifactId>dubbo-configcenter-apollo</artifactId>
+    <packaging>jar</packaging>
+    <name>${project.artifactId}</name>
+    <description>The Apollo implementation of the configcenter api</description>
+    <properties>
+        <skip_maven_deploy>false</skip_maven_deploy>
+        <apollo_mock_server_version>1.1.1</apollo_mock_server_version>
+    </properties>
+
+    <dependencies>
+        <dependency>
+            <groupId>org.apache.dubbo</groupId>
+            <artifactId>dubbo-common</artifactId>
+            <version>${project.parent.version}</version>
+        </dependency>
+        <dependency>
+            <groupId>com.ctrip.framework.apollo</groupId>
+            <artifactId>apollo-client</artifactId>
+        </dependency>
+        <dependency>
+            <groupId>com.ctrip.framework.apollo</groupId>
+            <artifactId>apollo-mockserver</artifactId>
+            <version>${apollo_mock_server_version}</version>
+            <scope>test</scope>
+        </dependency>
+    </dependencies>
+</project>
\ No newline at end of file
diff --git a/dubbo-spi-configcenter/dubbo-configcenter-apollo/src/main/java/org/apache/dubbo/configcenter/support/apollo/ApolloDynamicConfiguration.java b/dubbo-spi-configcenter/dubbo-configcenter-apollo/src/main/java/org/apache/dubbo/configcenter/support/apollo/ApolloDynamicConfiguration.java
new file mode 100644
index 0000000..f191178
--- /dev/null
+++ b/dubbo-spi-configcenter/dubbo-configcenter-apollo/src/main/java/org/apache/dubbo/configcenter/support/apollo/ApolloDynamicConfiguration.java
@@ -0,0 +1,258 @@
+/*
+ * 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.configcenter.support.apollo;
+
+import org.apache.dubbo.common.URL;
+import org.apache.dubbo.common.config.configcenter.ConfigChangeType;
+import org.apache.dubbo.common.config.configcenter.ConfigChangedEvent;
+import org.apache.dubbo.common.config.configcenter.ConfigurationListener;
+import org.apache.dubbo.common.config.configcenter.DynamicConfiguration;
+import org.apache.dubbo.common.logger.Logger;
+import org.apache.dubbo.common.logger.LoggerFactory;
+import org.apache.dubbo.common.utils.StringUtils;
+
+import com.ctrip.framework.apollo.Config;
+import com.ctrip.framework.apollo.ConfigChangeListener;
+import com.ctrip.framework.apollo.ConfigFile;
+import com.ctrip.framework.apollo.ConfigService;
+import com.ctrip.framework.apollo.core.enums.ConfigFileFormat;
+import com.ctrip.framework.apollo.enums.ConfigSourceType;
+import com.ctrip.framework.apollo.enums.PropertyChangeType;
+import com.ctrip.framework.apollo.model.ConfigChange;
+
+import java.util.Arrays;
+import java.util.Collections;
+import java.util.Set;
+import java.util.concurrent.ConcurrentHashMap;
+import java.util.concurrent.ConcurrentMap;
+import java.util.concurrent.CopyOnWriteArraySet;
+import java.util.stream.Collectors;
+
+import static org.apache.dubbo.common.config.configcenter.Constants.CONFIG_NAMESPACE_KEY;
+import static org.apache.dubbo.common.constants.CommonConstants.ANYHOST_VALUE;
+import static org.apache.dubbo.common.constants.CommonConstants.APPLICATION_KEY;
+import static org.apache.dubbo.common.constants.CommonConstants.CHECK_KEY;
+import static org.apache.dubbo.common.constants.CommonConstants.CLUSTER_KEY;
+import static org.apache.dubbo.common.constants.CommonConstants.COMMA_SPLIT_PATTERN;
+import static org.apache.dubbo.common.constants.CommonConstants.GROUP_KEY;
+
+/**
+ * Apollo implementation, https://github.com/ctripcorp/apollo
+ *
+ * Apollo will be used for management of both governance rules and .properties files, by default, these two different
+ * kinds of data share the same namespace 'dubbo'. To gain better performance, we recommend separate them by giving
+ * namespace and group different values, for example:
+ *
+ * <dubbo:config-center namespace="governance" group="dubbo" />, 'dubbo=governance' is for governance rules while
+ * 'group=dubbo' is for properties files.
+ *
+ * Please see http://dubbo.apache.org/zh-cn/docs/user/configuration/config-center.html for details.
+ */
+public class ApolloDynamicConfiguration implements DynamicConfiguration {
+    private static final Logger logger = LoggerFactory.getLogger(ApolloDynamicConfiguration.class);
+    private static final String APOLLO_ENV_KEY = "env";
+    private static final String APOLLO_ADDR_KEY = "apollo.meta";
+    private static final String APOLLO_CLUSTER_KEY = "apollo.cluster";
+    private static final String APOLLO_PROTOCOL_PREFIX = "http://";
+    private static final String APOLLO_APPLICATION_KEY = "application";
+    private static final String APOLLO_APPID_KEY = "app.id";
+
+    private URL url;
+    private Config dubboConfig;
+    private ConfigFile dubboConfigFile;
+    private ConcurrentMap<String, ApolloListener> listeners = new ConcurrentHashMap<>();
+
+    ApolloDynamicConfiguration(URL url) {
+        this.url = url;
+        // Instead of using Dubbo's configuration, I would suggest use the original configuration method Apollo provides.
+        String configEnv = url.getParameter(APOLLO_ENV_KEY);
+        String configAddr = getAddressWithProtocolPrefix(url);
+        String configCluster = url.getParameter(CLUSTER_KEY);
+        String configAppId = url.getParameter(APOLLO_APPID_KEY);
+        if (StringUtils.isEmpty(System.getProperty(APOLLO_ENV_KEY)) && configEnv != null) {
+            System.setProperty(APOLLO_ENV_KEY, configEnv);
+        }
+        if (StringUtils.isEmpty(System.getProperty(APOLLO_ADDR_KEY)) && !ANYHOST_VALUE.equals(url.getHost())) {
+            System.setProperty(APOLLO_ADDR_KEY, configAddr);
+        }
+        if (StringUtils.isEmpty(System.getProperty(APOLLO_CLUSTER_KEY)) && configCluster != null) {
+            System.setProperty(APOLLO_CLUSTER_KEY, configCluster);
+        }
+        if (StringUtils.isEmpty(System.getProperty(APOLLO_APPID_KEY)) && configAppId != null) {
+            System.setProperty(APOLLO_APPID_KEY, configAppId);
+        }
+
+        String namespace = url.getParameter(CONFIG_NAMESPACE_KEY, DEFAULT_GROUP);
+        String apolloNamespace = StringUtils.isEmpty(namespace) ? url.getParameter(GROUP_KEY, DEFAULT_GROUP) : namespace;
+        dubboConfig = ConfigService.getConfig(apolloNamespace);
+        dubboConfigFile = ConfigService.getConfigFile(apolloNamespace, ConfigFileFormat.Properties);
+
+        // Decide to fail or to continue when failed to connect to remote server.
+        boolean check = url.getParameter(CHECK_KEY, true);
+        if (dubboConfig.getSourceType() != ConfigSourceType.REMOTE) {
+            if (check) {
+                throw new IllegalStateException("Failed to connect to config center, the config center is Apollo, " +
+                        "the address is: " + (StringUtils.isNotEmpty(configAddr) ? configAddr : configEnv));
+            } else {
+                logger.warn("Failed to connect to config center, the config center is Apollo, " +
+                        "the address is: " + (StringUtils.isNotEmpty(configAddr) ? configAddr : configEnv) +
+                        ", will use the local cache value instead before eventually the connection is established.");
+            }
+        }
+    }
+
+    private String getAddressWithProtocolPrefix(URL url) {
+        String address = url.getBackupAddress();
+        if (StringUtils.isNotEmpty(address)) {
+            address = Arrays.stream(COMMA_SPLIT_PATTERN.split(address))
+                    .map(addr -> {
+                        if (addr.startsWith(APOLLO_PROTOCOL_PREFIX)) {
+                            return addr;
+                        }
+                        return APOLLO_PROTOCOL_PREFIX + addr;
+                    })
+                    .collect(Collectors.joining(","));
+        }
+        return address;
+    }
+
+    /**
+     * Since all governance rules will lay under dubbo group, this method now always uses the default dubboConfig and
+     * ignores the group parameter.
+     */
+    @Override
+    public void addListener(String key, String group, ConfigurationListener listener) {
+        ApolloListener apolloListener = listeners.computeIfAbsent(group + key, k -> createTargetListener(key, group));
+        apolloListener.addListener(listener);
+        dubboConfig.addChangeListener(apolloListener, Collections.singleton(key));
+    }
+
+    @Override
+    public void removeListener(String key, String group, ConfigurationListener listener) {
+        ApolloListener apolloListener = listeners.get(group + key);
+        if (apolloListener != null) {
+            apolloListener.removeListener(listener);
+            if (!apolloListener.hasInternalListener()) {
+                dubboConfig.removeChangeListener(apolloListener);
+            }
+        }
+    }
+
+    @Override
+    public String getConfig(String key, String group, long timeout) throws IllegalStateException {
+        if (StringUtils.isNotEmpty(group)) {
+            if (group.equals(url.getParameter(APPLICATION_KEY))) {
+                return ConfigService.getAppConfig().getProperty(key, null);
+            } else {
+                return ConfigService.getConfig(group).getProperty(key, null);
+            }
+        }
+        return dubboConfig.getProperty(key, null);
+    }
+
+    /**
+     * Recommend specify namespace and group when using Apollo.
+     * <p>
+     * <dubbo:config-center namespace="governance" group="dubbo" />, 'dubbo=governance' is for governance rules while
+     * 'group=dubbo' is for properties files.
+     *
+     * @param key     default value is 'dubbo.properties', currently useless for Apollo.
+     * @param group
+     * @param timeout
+     * @return
+     * @throws IllegalStateException
+     */
+    @Override
+    public String getProperties(String key, String group, long timeout) throws IllegalStateException {
+        if (StringUtils.isEmpty(group)) {
+            return dubboConfigFile.getContent();
+        }
+        if (group.equals(url.getParameter(APPLICATION_KEY))) {
+            return ConfigService.getConfigFile(APOLLO_APPLICATION_KEY, ConfigFileFormat.Properties).getContent();
+        }
+
+        ConfigFile configFile = ConfigService.getConfigFile(group, ConfigFileFormat.Properties);
+        if (configFile == null) {
+            throw new IllegalStateException("There is no namespace named " + group + " in Apollo.");
+        }
+        return configFile.getContent();
+    }
+
+    /**
+     * This method will be used by Configuration to get valid value at runtime.
+     * The group is expected to be 'app level', which can be fetched from the 'config.appnamespace' in url if necessary.
+     * But I think Apollo's inheritance feature of namespace can solve the problem .
+     */
+    @Override
+    public String getInternalProperty(String key) {
+        return dubboConfig.getProperty(key, null);
+    }
+
+    /**
+     * Ignores the group parameter.
+     *
+     * @param key   property key the native listener will listen on
+     * @param group to distinguish different set of properties
+     * @return
+     */
+    private ApolloListener createTargetListener(String key, String group) {
+        return new ApolloListener();
+    }
+
+    public class ApolloListener implements ConfigChangeListener {
+
+        private Set<ConfigurationListener> listeners = new CopyOnWriteArraySet<>();
+
+        ApolloListener() {
+        }
+
+        @Override
+        public void onChange(com.ctrip.framework.apollo.model.ConfigChangeEvent changeEvent) {
+            for (String key : changeEvent.changedKeys()) {
+                ConfigChange change = changeEvent.getChange(key);
+                if ("".equals(change.getNewValue())) {
+                    logger.warn("an empty rule is received for " + key + ", the current working rule is " +
+                            change.getOldValue() + ", the empty rule will not take effect.");
+                    return;
+                }
+
+                ConfigChangedEvent event = new ConfigChangedEvent(key, change.getNamespace(), change.getNewValue(), getChangeType(change));
+                listeners.forEach(listener -> listener.process(event));
+            }
+        }
+
+        private ConfigChangeType getChangeType(ConfigChange change) {
+            if (change.getChangeType() == PropertyChangeType.DELETED) {
+                return ConfigChangeType.DELETED;
+            }
+            return ConfigChangeType.MODIFIED;
+        }
+
+        void addListener(ConfigurationListener configurationListener) {
+            this.listeners.add(configurationListener);
+        }
+
+        void removeListener(ConfigurationListener configurationListener) {
+            this.listeners.remove(configurationListener);
+        }
+
+        boolean hasInternalListener() {
+            return listeners != null && listeners.size() > 0;
+        }
+    }
+
+}
diff --git a/dubbo-spi-configcenter/dubbo-configcenter-apollo/src/main/java/org/apache/dubbo/configcenter/support/apollo/ApolloDynamicConfigurationFactory.java b/dubbo-spi-configcenter/dubbo-configcenter-apollo/src/main/java/org/apache/dubbo/configcenter/support/apollo/ApolloDynamicConfigurationFactory.java
new file mode 100644
index 0000000..6a8ce30
--- /dev/null
+++ b/dubbo-spi-configcenter/dubbo-configcenter-apollo/src/main/java/org/apache/dubbo/configcenter/support/apollo/ApolloDynamicConfigurationFactory.java
@@ -0,0 +1,31 @@
+/*
+ * 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.configcenter.support.apollo;
+
+import org.apache.dubbo.common.URL;
+import org.apache.dubbo.common.config.configcenter.AbstractDynamicConfigurationFactory;
+import org.apache.dubbo.common.config.configcenter.DynamicConfiguration;
+
+/**
+ *
+ */
+public class ApolloDynamicConfigurationFactory extends AbstractDynamicConfigurationFactory {
+    @Override
+    protected DynamicConfiguration createDynamicConfiguration(URL url) {
+        return new ApolloDynamicConfiguration(url);
+    }
+}
diff --git a/dubbo-spi-configcenter/dubbo-configcenter-apollo/src/main/resources/META-INF/dubbo/internal/org.apache.dubbo.common.config.configcenter.DynamicConfigurationFactory b/dubbo-spi-configcenter/dubbo-configcenter-apollo/src/main/resources/META-INF/dubbo/internal/org.apache.dubbo.common.config.configcenter.DynamicConfigurationFactory
new file mode 100644
index 0000000..0ea08c5
--- /dev/null
+++ b/dubbo-spi-configcenter/dubbo-configcenter-apollo/src/main/resources/META-INF/dubbo/internal/org.apache.dubbo.common.config.configcenter.DynamicConfigurationFactory
@@ -0,0 +1 @@
+apollo=org.apache.dubbo.configcenter.support.apollo.ApolloDynamicConfigurationFactory
\ No newline at end of file
diff --git a/dubbo-spi-configcenter/dubbo-configcenter-apollo/src/test/java/org/apache/dubbo/configcenter/support/apollo/ApolloDynamicConfigurationTest.java b/dubbo-spi-configcenter/dubbo-configcenter-apollo/src/test/java/org/apache/dubbo/configcenter/support/apollo/ApolloDynamicConfigurationTest.java
new file mode 100644
index 0000000..ca48bd6
--- /dev/null
+++ b/dubbo-spi-configcenter/dubbo-configcenter-apollo/src/test/java/org/apache/dubbo/configcenter/support/apollo/ApolloDynamicConfigurationTest.java
@@ -0,0 +1,191 @@
+/*
+ * 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.configcenter.support.apollo;
+
+import org.apache.dubbo.common.URL;
+import org.apache.dubbo.common.config.configcenter.ConfigChangeType;
+import org.apache.dubbo.common.config.configcenter.ConfigurationListener;
+
+import com.ctrip.framework.apollo.mockserver.EmbeddedApollo;
+import com.google.common.util.concurrent.SettableFuture;
+import org.junit.After;
+import org.junit.Before;
+import org.junit.ClassRule;
+import org.junit.Test;
+
+import java.io.FileOutputStream;
+import java.io.IOException;
+import java.util.Properties;
+import java.util.Random;
+import java.util.concurrent.TimeUnit;
+
+import static org.junit.jupiter.api.Assertions.assertEquals;
+import static org.junit.jupiter.api.Assertions.assertNull;
+import static org.junit.jupiter.api.Assertions.fail;
+
+/**
+ * Apollo dynamic configuration mock test.
+ * Notice: EmbeddedApollo(apollo mock server) only support < junit5, please not upgrade the junit version in this UT,
+ * the junit version in this UT is junit4, and the dependency comes from apollo-mockserver.
+ */
+public class ApolloDynamicConfigurationTest {
+    private static final String SESSION_TIMEOUT_KEY = "session";
+    private static final String DEFAULT_NAMESPACE = "dubbo";
+    private static ApolloDynamicConfiguration apolloDynamicConfiguration;
+    private static URL url;
+
+    /**
+     * The constant embeddedApollo.
+     */
+    @ClassRule
+    public static EmbeddedApollo embeddedApollo = new EmbeddedApollo();
+
+    /**
+     * Sets up.
+     */
+    @Before
+    public void setUp() {
+        String apolloUrl = System.getProperty("apollo.configService");
+        String urlForDubbo = "apollo://" + apolloUrl.substring(apolloUrl.lastIndexOf("/") + 1) + "/org.apache.dubbo.apollo.testService?namespace=dubbo&check=true";
+        url = URL.valueOf(urlForDubbo).addParameter(SESSION_TIMEOUT_KEY, 15000);
+    }
+
+//    /**
+//     * Embedded Apollo does not work as expected.
+//     */
+//    @Test
+//    public void testProperties() {
+//        URL url = this.url.addParameter(GROUP_KEY, "dubbo")
+//                .addParameter("namespace", "governance");
+//
+//        apolloDynamicConfiguration = new ApolloDynamicConfiguration(url);
+//        putData("dubbo", "dubbo.registry.address", "zookeeper://127.0.0.1:2181");
+//        assertEquals("zookeeper://127.0.0.1:2181", apolloDynamicConfiguration.getProperties(null, "dubbo"));
+//
+//        putData("governance", "router.tag", "router tag rule");
+//        assertEquals("router tag rule", apolloDynamicConfiguration.getConfig("router.tag", "governance"));
+//
+//    }
+
+    /**
+     * Test get rule.
+     */
+    @Test
+    public void testGetRule() {
+        String mockKey = "mockKey1";
+        String mockValue = String.valueOf(new Random().nextInt());
+        putMockRuleData(mockKey, mockValue, DEFAULT_NAMESPACE);
+        apolloDynamicConfiguration = new ApolloDynamicConfiguration(url);
+        assertEquals(mockValue, apolloDynamicConfiguration.getConfig(mockKey, DEFAULT_NAMESPACE, 3000L));
+
+        mockKey = "notExistKey";
+        assertNull(apolloDynamicConfiguration.getConfig(mockKey, DEFAULT_NAMESPACE, 3000L));
+    }
+
+    /**
+     * Test get internal property.
+     *
+     * @throws InterruptedException the interrupted exception
+     */
+    @Test
+    public void testGetInternalProperty() throws InterruptedException {
+        String mockKey = "mockKey2";
+        String mockValue = String.valueOf(new Random().nextInt());
+        putMockRuleData(mockKey, mockValue, DEFAULT_NAMESPACE);
+        TimeUnit.MILLISECONDS.sleep(1000);
+        apolloDynamicConfiguration = new ApolloDynamicConfiguration(url);
+        assertEquals(mockValue, apolloDynamicConfiguration.getInternalProperty(mockKey));
+
+        mockValue = "mockValue2";
+        System.setProperty(mockKey, mockValue);
+        assertEquals(mockValue, apolloDynamicConfiguration.getInternalProperty(mockKey));
+
+        mockKey = "notExistKey";
+        assertNull(apolloDynamicConfiguration.getInternalProperty(mockKey));
+    }
+
+    /**
+     * Test add listener.
+     *
+     * @throws Exception the exception
+     */
+    @Test
+    public void testAddListener() throws Exception {
+        String mockKey = "mockKey3";
+        String mockValue = String.valueOf(new Random().nextInt());
+
+        final SettableFuture<org.apache.dubbo.common.config.configcenter.ConfigChangedEvent> future = SettableFuture.create();
+
+        apolloDynamicConfiguration = new ApolloDynamicConfiguration(url);
+
+        apolloDynamicConfiguration.addListener(mockKey, DEFAULT_NAMESPACE, new ConfigurationListener() {
+            @Override
+            public void process(org.apache.dubbo.common.config.configcenter.ConfigChangedEvent event) {
+                future.set(event);
+            }
+        });
+
+        putData(mockKey, mockValue);
+        org.apache.dubbo.common.config.configcenter.ConfigChangedEvent result = future.get(3000, TimeUnit.MILLISECONDS);
+        assertEquals(mockValue, result.getContent());
+        assertEquals(mockKey, result.getKey());
+        assertEquals(ConfigChangeType.MODIFIED, result.getChangeType());
+    }
+
+    private static void putData(String namespace, String key, String value) {
+        embeddedApollo.addOrModifyProperty(namespace, key, value);
+    }
+
+    private static void putData(String key, String value) {
+        embeddedApollo.addOrModifyProperty(DEFAULT_NAMESPACE, key, value);
+    }
+
+    private static void putMockRuleData(String key, String value, String group) {
+        String fileName = ApolloDynamicConfigurationTest.class.getResource("/").getPath() + "mockdata-" + group + ".properties";
+        putMockData(key, value, fileName);
+    }
+
+    private static void putMockData(String key, String value, String fileName) {
+        Properties pro = new Properties();
+        FileOutputStream oFile = null;
+        try {
+            oFile = new FileOutputStream(fileName);
+            pro.setProperty(key, value);
+            pro.store(oFile, "put mock data");
+        } catch (IOException exx) {
+            fail(exx.getMessage());
+
+        } finally {
+            if (null != oFile) {
+                try {
+                    oFile.close();
+                } catch (IOException e) {
+                    fail(e.getMessage());
+                }
+            }
+        }
+    }
+
+    /**
+     * Tear down.
+     */
+    @After
+    public void tearDown() {
+
+    }
+
+}
\ No newline at end of file
diff --git a/dubbo-spi-configcenter/dubbo-configcenter-apollo/src/test/resources/META-INF/app.properties b/dubbo-spi-configcenter/dubbo-configcenter-apollo/src/test/resources/META-INF/app.properties
new file mode 100644
index 0000000..4d963e2
--- /dev/null
+++ b/dubbo-spi-configcenter/dubbo-configcenter-apollo/src/test/resources/META-INF/app.properties
@@ -0,0 +1 @@
+app.id=someAppId
\ No newline at end of file
diff --git a/dubbo-spi-configcenter/dubbo-configcenter-apollo/src/test/resources/mockdata-dubbo.properties b/dubbo-spi-configcenter/dubbo-configcenter-apollo/src/test/resources/mockdata-dubbo.properties
new file mode 100644
index 0000000..f995a3b
--- /dev/null
+++ b/dubbo-spi-configcenter/dubbo-configcenter-apollo/src/test/resources/mockdata-dubbo.properties
@@ -0,0 +1,2 @@
+key1=value1
+key2=value2
\ No newline at end of file
diff --git a/dubbo-spi-configcenter/dubbo-configcenter-consul/pom.xml b/dubbo-spi-configcenter/dubbo-configcenter-consul/pom.xml
new file mode 100644
index 0000000..bdabca7
--- /dev/null
+++ b/dubbo-spi-configcenter/dubbo-configcenter-consul/pom.xml
@@ -0,0 +1,47 @@
+<?xml version="1.0" encoding="UTF-8"?>
+<!--
+  ~ 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.
+  -->
+
+<project xmlns="http://maven.apache.org/POM/4.0.0" xmlns:xsi="http://www.w3.org/2001/XMLSchema-instance" xsi:schemaLocation="http://maven.apache.org/POM/4.0.0 http://maven.apache.org/xsd/maven-4.0.0.xsd">
+    <modelVersion>4.0.0</modelVersion>
+
+    <parent>
+        <groupId>org.apache.dubbo</groupId>
+        <artifactId>dubbo-configcenter</artifactId>
+        <version>2.7.7-SNAPSHOT</version>
+    </parent>
+
+    <artifactId>dubbo-configcenter-consul</artifactId>
+
+    <dependencies>
+        <dependency>
+            <groupId>org.apache.dubbo</groupId>
+            <artifactId>dubbo-common</artifactId>
+            <version>${project.version}</version>
+        </dependency>
+        <dependency>
+            <groupId>com.orbitz.consul</groupId>
+            <artifactId>consul-client</artifactId>
+        </dependency>
+        <dependency>
+            <groupId>com.pszymczyk.consul</groupId>
+            <artifactId>embedded-consul</artifactId>
+        </dependency>
+    </dependencies>
+
+
+</project>
diff --git a/dubbo-spi-configcenter/dubbo-configcenter-consul/src/main/java/org/apache/dubbo/configcenter/consul/ConsulDynamicConfiguration.java b/dubbo-spi-configcenter/dubbo-configcenter-consul/src/main/java/org/apache/dubbo/configcenter/consul/ConsulDynamicConfiguration.java
new file mode 100644
index 0000000..282bdef
--- /dev/null
+++ b/dubbo-spi-configcenter/dubbo-configcenter-consul/src/main/java/org/apache/dubbo/configcenter/consul/ConsulDynamicConfiguration.java
@@ -0,0 +1,218 @@
+/*
+ * 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.configcenter.consul;
+
+import org.apache.dubbo.common.URL;
+import org.apache.dubbo.common.config.configcenter.ConfigChangeType;
+import org.apache.dubbo.common.config.configcenter.ConfigChangedEvent;
+import org.apache.dubbo.common.config.configcenter.ConfigurationListener;
+import org.apache.dubbo.common.config.configcenter.DynamicConfiguration;
+import org.apache.dubbo.common.logger.Logger;
+import org.apache.dubbo.common.logger.LoggerFactory;
+import org.apache.dubbo.common.utils.CollectionUtils;
+import org.apache.dubbo.common.utils.StringUtils;
+
+import com.google.common.base.Charsets;
+import com.google.common.net.HostAndPort;
+import com.orbitz.consul.Consul;
+import com.orbitz.consul.KeyValueClient;
+import com.orbitz.consul.cache.KVCache;
+import com.orbitz.consul.model.kv.Value;
+
+import java.util.LinkedHashSet;
+import java.util.List;
+import java.util.Map;
+import java.util.Optional;
+import java.util.Set;
+import java.util.SortedSet;
+import java.util.TreeSet;
+import java.util.concurrent.ConcurrentHashMap;
+import java.util.concurrent.ConcurrentMap;
+
+import static org.apache.dubbo.common.config.configcenter.Constants.CONFIG_NAMESPACE_KEY;
+import static org.apache.dubbo.common.constants.CommonConstants.PATH_SEPARATOR;
+import static org.apache.dubbo.common.utils.StringUtils.EMPTY_STRING;
+
+/**
+ * config center implementation for consul
+ */
+public class ConsulDynamicConfiguration implements DynamicConfiguration {
+    private static final Logger logger = LoggerFactory.getLogger(ConsulDynamicConfiguration.class);
+
+    private static final int DEFAULT_PORT = 8500;
+    private static final int DEFAULT_WATCH_TIMEOUT = 60 * 1000;
+    private static final String WATCH_TIMEOUT = "consul-watch-timeout";
+
+    private URL url;
+    private String rootPath;
+    private Consul client;
+    private KeyValueClient kvClient;
+    private ConcurrentMap<String, ConsulListener> watchers = new ConcurrentHashMap<>();
+
+    public ConsulDynamicConfiguration(URL url) {
+        this.url = url;
+        this.rootPath = PATH_SEPARATOR + url.getParameter(CONFIG_NAMESPACE_KEY, DEFAULT_GROUP) + PATH_SEPARATOR + "config";
+        String host = url.getHost();
+        int port = url.getPort() != 0 ? url.getPort() : DEFAULT_PORT;
+        client = Consul.builder().withHostAndPort(HostAndPort.fromParts(host, port)).build();
+        this.kvClient = client.keyValueClient();
+    }
+
+    @Override
+    public void addListener(String key, String group, ConfigurationListener listener) {
+        logger.info("register listener " + listener.getClass() + " for config with key: " + key + ", group: " + group);
+        String normalizedKey = convertKey(group, key);
+        ConsulListener watcher = watchers.computeIfAbsent(normalizedKey, k -> new ConsulListener(key, group));
+        watcher.addListener(listener);
+    }
+
+    @Override
+    public void removeListener(String key, String group, ConfigurationListener listener) {
+        logger.info("unregister listener " + listener.getClass() + " for config with key: " + key + ", group: " + group);
+        ConsulListener watcher = watchers.get(convertKey(group, key));
+        if (watcher != null) {
+            watcher.removeListener(listener);
+        }
+    }
+
+    @Override
+    public String getConfig(String key, String group, long timeout) throws IllegalStateException {
+        return (String) getInternalProperty(convertKey(group, key));
+    }
+
+    @Override
+    public SortedSet<String> getConfigKeys(String group) throws UnsupportedOperationException {
+        SortedSet<String> configKeys = new TreeSet<>();
+        String normalizedKey = convertKey(group, EMPTY_STRING);
+        List<String> keys = kvClient.getKeys(normalizedKey);
+        if (CollectionUtils.isNotEmpty(keys)) {
+            keys.stream()
+                    .filter(k -> !k.equals(normalizedKey))
+                    .map(k -> k.substring(k.lastIndexOf(PATH_SEPARATOR) + 1))
+                    .forEach(configKeys::add);
+        }
+        return configKeys;
+//        SortedSet<String> configKeys = new TreeSet<>();
+//        String normalizedKey = convertKey(group, key);
+//        kvClient.getValueAsString(normalizedKey).ifPresent(v -> {
+//            Collections.addAll(configKeys, v.split(","));
+//        });
+//        return configKeys;
+    }
+
+    /**
+     * @param key     the key to represent a configuration
+     * @param group   the group where the key belongs to
+     * @param content the content of configuration
+     * @return
+     * @throws UnsupportedOperationException
+     */
+    @Override
+    public boolean publishConfig(String key, String group, String content) throws UnsupportedOperationException {
+//        String normalizedKey = convertKey(group, key);
+//        Value value = kvClient.getValue(normalizedKey).orElseThrow(() -> new IllegalArgumentException(normalizedKey + " does not exit."));
+//        Optional<String> old = value.getValueAsString();
+//        if (old.isPresent()) {
+//            content = old.get() + "," + content;
+//        }
+//
+//        while (!kvClient.putValue(key, content, value.getModifyIndex())) {
+//            value = kvClient.getValue(normalizedKey).orElseThrow(() -> new IllegalArgumentException(normalizedKey + " does not exit."));
+//            old = value.getValueAsString();
+//            if (old.isPresent()) {
+//                content = old.get() + "," + content;
+//            }
+//            try {
+//                Thread.sleep(10);
+//            } catch (InterruptedException e) {
+//                e.printStackTrace();
+//            }
+//        }
+//        return true;
+        String normalizedKey = convertKey(group, key);
+        return kvClient.putValue(normalizedKey + PATH_SEPARATOR + content);
+    }
+
+    @Override
+    public Object getInternalProperty(String key) {
+        logger.info("getting config from: " + key);
+        return kvClient.getValueAsString(key, Charsets.UTF_8).orElse(null);
+    }
+
+    @Override
+    public void close() throws Exception {
+        client.destroy();
+    }
+
+    private String buildPath(String group) {
+        String actualGroup = StringUtils.isEmpty(group) ? DEFAULT_GROUP : group;
+        return rootPath + PATH_SEPARATOR + actualGroup;
+    }
+
+    private String convertKey(String group, String key) {
+        return buildPath(group) + PATH_SEPARATOR + key;
+    }
+
+    private class ConsulListener implements KVCache.Listener<String, Value> {
+
+        private KVCache kvCache;
+        private Set<ConfigurationListener> listeners = new LinkedHashSet<>();
+        private String key;
+        private String group;
+        private String normalizedKey;
+
+        public ConsulListener(String key, String group) {
+            this.key = key;
+            this.group = group;
+            this.normalizedKey = convertKey(group, key);
+            initKVCache();
+        }
+
+        private void initKVCache() {
+            this.kvCache = KVCache.newCache(kvClient, normalizedKey);
+            kvCache.addListener(this);
+            kvCache.start();
+        }
+
+        @Override
+        public void notify(Map<String, Value> newValues) {
+            // Cache notifies all paths with "foo" the root path
+            // If you want to watch only "foo" value, you must filter other paths
+            Optional<Value> newValue = newValues.values().stream()
+                    .filter(value -> value.getKey().equals(normalizedKey))
+                    .findAny();
+
+            newValue.ifPresent(value -> {
+                // Values are encoded in key/value store, decode it if needed
+                Optional<String> decodedValue = newValue.get().getValueAsString();
+                decodedValue.ifPresent(v -> listeners.forEach(l -> {
+                    ConfigChangedEvent event = new ConfigChangedEvent(key, group, v, ConfigChangeType.MODIFIED);
+                    l.process(event);
+                }));
+            });
+        }
+
+        private void addListener(ConfigurationListener listener) {
+            this.listeners.add(listener);
+        }
+
+        private void removeListener(ConfigurationListener listener) {
+            this.listeners.remove(listener);
+        }
+    }
+}
diff --git a/dubbo-spi-configcenter/dubbo-configcenter-consul/src/main/java/org/apache/dubbo/configcenter/consul/ConsulDynamicConfigurationFactory.java b/dubbo-spi-configcenter/dubbo-configcenter-consul/src/main/java/org/apache/dubbo/configcenter/consul/ConsulDynamicConfigurationFactory.java
new file mode 100644
index 0000000..980a156
--- /dev/null
+++ b/dubbo-spi-configcenter/dubbo-configcenter-consul/src/main/java/org/apache/dubbo/configcenter/consul/ConsulDynamicConfigurationFactory.java
@@ -0,0 +1,32 @@
+/*
+ * 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.configcenter.consul;
+
+import org.apache.dubbo.common.URL;
+import org.apache.dubbo.common.config.configcenter.AbstractDynamicConfigurationFactory;
+import org.apache.dubbo.common.config.configcenter.DynamicConfiguration;
+
+/**
+ * Config center factory for consul
+ */
+public class ConsulDynamicConfigurationFactory extends AbstractDynamicConfigurationFactory {
+    @Override
+    protected DynamicConfiguration createDynamicConfiguration(URL url) {
+        return new ConsulDynamicConfiguration(url);
+    }
+}
diff --git a/dubbo-spi-configcenter/dubbo-configcenter-consul/src/main/resources/META-INF/dubbo/internal/org.apache.dubbo.common.config.configcenter.DynamicConfigurationFactory b/dubbo-spi-configcenter/dubbo-configcenter-consul/src/main/resources/META-INF/dubbo/internal/org.apache.dubbo.common.config.configcenter.DynamicConfigurationFactory
new file mode 100644
index 0000000..b7a5091
--- /dev/null
+++ b/dubbo-spi-configcenter/dubbo-configcenter-consul/src/main/resources/META-INF/dubbo/internal/org.apache.dubbo.common.config.configcenter.DynamicConfigurationFactory
@@ -0,0 +1 @@
+consul=org.apache.dubbo.configcenter.consul.ConsulDynamicConfigurationFactory
diff --git a/dubbo-spi-configcenter/dubbo-configcenter-consul/src/test/java/org/apache/dubbo/configcenter/consul/ConsulDynamicConfigurationTest.java b/dubbo-spi-configcenter/dubbo-configcenter-consul/src/test/java/org/apache/dubbo/configcenter/consul/ConsulDynamicConfigurationTest.java
new file mode 100644
index 0000000..8ada5fb
--- /dev/null
+++ b/dubbo-spi-configcenter/dubbo-configcenter-consul/src/test/java/org/apache/dubbo/configcenter/consul/ConsulDynamicConfigurationTest.java
@@ -0,0 +1,109 @@
+/*
+ * 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.configcenter.consul;
+
+import org.apache.dubbo.common.URL;
+
+import com.google.common.net.HostAndPort;
+import com.orbitz.consul.Consul;
+import com.orbitz.consul.KeyValueClient;
+import com.orbitz.consul.cache.KVCache;
+import com.orbitz.consul.model.kv.Value;
+import com.pszymczyk.consul.ConsulProcess;
+import com.pszymczyk.consul.ConsulStarterBuilder;
+import org.junit.jupiter.api.AfterAll;
+import org.junit.jupiter.api.Assertions;
+import org.junit.jupiter.api.BeforeAll;
+import org.junit.jupiter.api.Test;
+
+import java.util.Optional;
+
+import static org.junit.jupiter.api.Assertions.assertEquals;
+
+/**
+ *
+ */
+public class ConsulDynamicConfigurationTest {
+
+    private static ConsulProcess consul;
+    private static URL configCenterUrl;
+    private static ConsulDynamicConfiguration configuration;
+
+    private static Consul client;
+    private static KeyValueClient kvClient;
+
+    @BeforeAll
+    public static void setUp() throws Exception {
+        consul = ConsulStarterBuilder.consulStarter()
+                .build()
+                .start();
+        configCenterUrl = URL.valueOf("consul://localhost:" + consul.getHttpPort());
+
+        configuration = new ConsulDynamicConfiguration(configCenterUrl);
+        client = Consul.builder().withHostAndPort(HostAndPort.fromParts("localhost", consul.getHttpPort())).build();
+        kvClient = client.keyValueClient();
+    }
+
+    @AfterAll
+    public static void tearDown() throws Exception {
+        consul.close();
+        configuration.close();
+    }
+
+    @Test
+    public void testGetConfig() {
+        kvClient.putValue("/dubbo/config/dubbo/foo", "bar");
+        // test equals
+        assertEquals("bar", configuration.getConfig("foo", "dubbo"));
+        // test does not block
+        assertEquals("bar", configuration.getConfig("foo", "dubbo"));
+        Assertions.assertNull(configuration.getConfig("not-exist", "dubbo"));
+    }
+
+    @Test
+    public void testAddListener() {
+        KVCache cache = KVCache.newCache(kvClient, "/dubbo/config/dubbo/foo");
+        cache.addListener(newValues -> {
+            // Cache notifies all paths with "foo" the root path
+            // If you want to watch only "foo" value, you must filter other paths
+            Optional<Value> newValue = newValues.values().stream()
+                    .filter(value -> value.getKey().equals("foo"))
+                    .findAny();
+
+            newValue.ifPresent(value -> {
+                // Values are encoded in key/value store, decode it if needed
+                Optional<String> decodedValue = newValue.get().getValueAsString();
+                decodedValue.ifPresent(v -> System.out.println(String.format("Value is: %s", v))); //prints "bar"
+            });
+        });
+        cache.start();
+
+        kvClient.putValue("/dubbo/config/dubbo/foo", "new-value");
+        kvClient.putValue("/dubbo/config/dubbo/foo/sub", "sub-value");
+        kvClient.putValue("/dubbo/config/dubbo/foo/sub2", "sub-value2");
+        kvClient.putValue("/dubbo/config/foo", "parent-value");
+
+        System.out.println(kvClient.getKeys("/dubbo/config/dubbo/foo"));
+        System.out.println(kvClient.getKeys("/dubbo/config"));
+        System.out.println(kvClient.getValues("/dubbo/config/dubbo/foo"));
+    }
+
+    @Test
+    public void testGetConfigKeys() {
+
+    }
+}
diff --git a/dubbo-spi-configcenter/dubbo-configcenter-etcd/pom.xml b/dubbo-spi-configcenter/dubbo-configcenter-etcd/pom.xml
new file mode 100644
index 0000000..570ec92
--- /dev/null
+++ b/dubbo-spi-configcenter/dubbo-configcenter-etcd/pom.xml
@@ -0,0 +1,74 @@
+<?xml version="1.0" encoding="UTF-8"?>
+<!--
+  ~ 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.
+  -->
+
+<project xmlns="http://maven.apache.org/POM/4.0.0"
+         xmlns:xsi="http://www.w3.org/2001/XMLSchema-instance"
+         xsi:schemaLocation="http://maven.apache.org/POM/4.0.0 http://maven.apache.org/xsd/maven-4.0.0.xsd">
+    <modelVersion>4.0.0</modelVersion>
+
+    <parent>
+        <groupId>org.apache.dubbo</groupId>
+        <artifactId>dubbo-configcenter</artifactId>
+        <version>2.7.7-SNAPSHOT</version>
+    </parent>
+
+    <artifactId>dubbo-configcenter-etcd</artifactId>
+    <packaging>jar</packaging>
+    <name>${project.artifactId}</name>
+    <description>The etcd implementation of the config-center api</description>
+
+    <properties>
+        <skipIntegrationTests>true</skipIntegrationTests>
+    </properties>
+
+    <dependencies>
+        <dependency>
+            <groupId>io.etcd</groupId>
+            <artifactId>jetcd-launcher</artifactId>
+            <scope>test</scope>
+        </dependency>
+        <dependency>
+            <groupId>org.testcontainers</groupId>
+            <artifactId>testcontainers</artifactId>
+            <scope>test</scope>
+        </dependency>
+
+        <dependency>
+            <groupId>org.apache.dubbo</groupId>
+            <artifactId>dubbo-common</artifactId>
+            <version>${project.parent.version}</version>
+        </dependency>
+        <dependency>
+            <groupId>org.apache.dubbo</groupId>
+            <artifactId>dubbo-remoting-etcd3</artifactId>
+            <version>${project.parent.version}</version>
+        </dependency>
+    </dependencies>
+
+    <build>
+        <plugins>
+            <plugin>
+                <groupId>org.apache.maven.plugins</groupId>
+                <artifactId>maven-surefire-plugin</artifactId>
+                <configuration>
+                    <skipTests>${skipIntegrationTests}</skipTests>
+                </configuration>
+            </plugin>
+        </plugins>
+    </build>
+</project>
diff --git a/dubbo-spi-configcenter/dubbo-configcenter-etcd/src/main/java/org/apache/dubbo/configcenter/support/etcd/EtcdDynamicConfiguration.java b/dubbo-spi-configcenter/dubbo-configcenter-etcd/src/main/java/org/apache/dubbo/configcenter/support/etcd/EtcdDynamicConfiguration.java
new file mode 100644
index 0000000..f686e86
--- /dev/null
+++ b/dubbo-spi-configcenter/dubbo-configcenter-etcd/src/main/java/org/apache/dubbo/configcenter/support/etcd/EtcdDynamicConfiguration.java
@@ -0,0 +1,197 @@
+/*
+ * 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.configcenter.support.etcd;
+
+import org.apache.dubbo.common.URL;
+import org.apache.dubbo.common.config.configcenter.ConfigChangeType;
+import org.apache.dubbo.common.config.configcenter.ConfigChangedEvent;
+import org.apache.dubbo.common.config.configcenter.ConfigurationListener;
+import org.apache.dubbo.common.config.configcenter.DynamicConfiguration;
+import org.apache.dubbo.common.utils.StringUtils;
+import org.apache.dubbo.remoting.etcd.StateListener;
+import org.apache.dubbo.remoting.etcd.jetcd.JEtcdClient;
+
+import com.google.protobuf.ByteString;
+import io.etcd.jetcd.api.Event;
+import io.etcd.jetcd.api.WatchCancelRequest;
+import io.etcd.jetcd.api.WatchCreateRequest;
+import io.etcd.jetcd.api.WatchGrpc;
+import io.etcd.jetcd.api.WatchRequest;
+import io.etcd.jetcd.api.WatchResponse;
+import io.grpc.ManagedChannel;
+import io.grpc.stub.StreamObserver;
+
+import java.util.concurrent.ConcurrentHashMap;
+import java.util.concurrent.ConcurrentMap;
+
+import static java.nio.charset.StandardCharsets.UTF_8;
+import static org.apache.dubbo.common.config.configcenter.Constants.CONFIG_NAMESPACE_KEY;
+import static org.apache.dubbo.common.constants.CommonConstants.PATH_SEPARATOR;
+
+/**
+ * The etcd implementation of {@link DynamicConfiguration}
+ */
+public class EtcdDynamicConfiguration implements DynamicConfiguration {
+
+    /**
+     * The final root path would be: /$NAME_SPACE/config
+     */
+    private String rootPath;
+
+    /**
+     * The etcd client
+     */
+    private final JEtcdClient etcdClient;
+
+    /**
+     * The map store the key to {@link EtcdConfigWatcher} mapping
+     */
+    private final ConcurrentMap<ConfigurationListener, EtcdConfigWatcher> watchListenerMap;
+
+    EtcdDynamicConfiguration(URL url) {
+        rootPath = PATH_SEPARATOR + url.getParameter(CONFIG_NAMESPACE_KEY, DEFAULT_GROUP) + "/config";
+        etcdClient = new JEtcdClient(url);
+        etcdClient.addStateListener(state -> {
+            if (state == StateListener.CONNECTED) {
+                try {
+                    recover();
+                } catch (Exception e) {
+                    // ignore
+                }
+            }
+        });
+        watchListenerMap = new ConcurrentHashMap<>();
+    }
+
+    @Override
+    public void addListener(String key, String group, ConfigurationListener listener) {
+        if (watchListenerMap.get(listener) == null) {
+            EtcdConfigWatcher watcher = new EtcdConfigWatcher(key, group, listener);
+            watchListenerMap.put(listener, watcher);
+            watcher.watch();
+        }
+    }
+
+    @Override
+    public void removeListener(String key, String group, ConfigurationListener listener) {
+        EtcdConfigWatcher watcher = watchListenerMap.get(listener);
+        watcher.cancelWatch();
+    }
+
+    @Override
+    public String getConfig(String key, String group, long timeout) throws IllegalStateException {
+        return (String) getInternalProperty(convertKey(group, key));
+    }
+
+//    @Override
+//    public String getConfigs(String key, String group, long timeout) throws IllegalStateException {
+//        if (StringUtils.isEmpty(group)) {
+//            group = DEFAULT_GROUP;
+//        }
+//        return (String) getInternalProperty(convertKey(group, key));
+//    }
+
+    @Override
+    public Object getInternalProperty(String key) {
+        return etcdClient.getKVValue(key);
+    }
+
+    private String buildPath(String group) {
+        String actualGroup = StringUtils.isEmpty(group) ? DEFAULT_GROUP : group;
+        return rootPath + PATH_SEPARATOR + actualGroup;
+    }
+
+    private String convertKey(String group, String key) {
+        return buildPath(group) + PATH_SEPARATOR + key;
+    }
+
+    private void recover() {
+        for (EtcdConfigWatcher watcher : watchListenerMap.values()) {
+            watcher.watch();
+        }
+    }
+
+    public class EtcdConfigWatcher implements StreamObserver<WatchResponse> {
+
+        private ConfigurationListener listener;
+        protected WatchGrpc.WatchStub watchStub;
+        private StreamObserver<WatchRequest> observer;
+        protected long watchId;
+        private ManagedChannel channel;
+
+        private final String key;
+
+        private final String group;
+
+        private String normalizedKey;
+
+        public EtcdConfigWatcher(String key, String group, ConfigurationListener listener) {
+            this.key = key;
+            this.group = group;
+            this.normalizedKey = convertKey(group, key);
+            this.listener = listener;
+            this.channel = etcdClient.getChannel();
+        }
+
+        @Override
+        public void onNext(WatchResponse watchResponse) {
+            this.watchId = watchResponse.getWatchId();
+            for (Event etcdEvent : watchResponse.getEventsList()) {
+                ConfigChangeType type = ConfigChangeType.MODIFIED;
+                if (etcdEvent.getType() == Event.EventType.DELETE) {
+                    type = ConfigChangeType.DELETED;
+                }
+                ConfigChangedEvent event = new ConfigChangedEvent(key, group,
+                        etcdEvent.getKv().getValue().toString(UTF_8), type);
+                listener.process(event);
+            }
+        }
+
+        @Override
+        public void onError(Throwable throwable) {
+            // ignore
+        }
+
+        @Override
+        public void onCompleted() {
+            // ignore
+        }
+
+        public long getWatchId() {
+            return watchId;
+        }
+
+        private void watch() {
+            watchStub = WatchGrpc.newStub(channel);
+            observer = watchStub.watch(this);
+            WatchCreateRequest.Builder builder = WatchCreateRequest.newBuilder()
+                    .setKey(ByteString.copyFromUtf8(normalizedKey))
+                    .setProgressNotify(true);
+            WatchRequest req = WatchRequest.newBuilder().setCreateRequest(builder).build();
+            observer.onNext(req);
+        }
+
+        private void cancelWatch() {
+            WatchCancelRequest watchCancelRequest =
+                    WatchCancelRequest.newBuilder().setWatchId(watchId).build();
+            WatchRequest cancelRequest = WatchRequest.newBuilder()
+                    .setCancelRequest(watchCancelRequest).build();
+            observer.onNext(cancelRequest);
+        }
+    }
+}
diff --git a/dubbo-spi-configcenter/dubbo-configcenter-etcd/src/main/java/org/apache/dubbo/configcenter/support/etcd/EtcdDynamicConfigurationFactory.java b/dubbo-spi-configcenter/dubbo-configcenter-etcd/src/main/java/org/apache/dubbo/configcenter/support/etcd/EtcdDynamicConfigurationFactory.java
new file mode 100644
index 0000000..269cee6
--- /dev/null
+++ b/dubbo-spi-configcenter/dubbo-configcenter-etcd/src/main/java/org/apache/dubbo/configcenter/support/etcd/EtcdDynamicConfigurationFactory.java
@@ -0,0 +1,33 @@
+/*
+ * 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.configcenter.support.etcd;
+
+import org.apache.dubbo.common.URL;
+import org.apache.dubbo.common.config.configcenter.AbstractDynamicConfigurationFactory;
+import org.apache.dubbo.common.config.configcenter.DynamicConfiguration;
+
+/**
+ * The etcd implementation of {@link AbstractDynamicConfigurationFactory}
+ */
+public class EtcdDynamicConfigurationFactory extends AbstractDynamicConfigurationFactory {
+
+    @Override
+    protected DynamicConfiguration createDynamicConfiguration(URL url) {
+        return new EtcdDynamicConfiguration(url);
+    }
+}
diff --git a/dubbo-spi-configcenter/dubbo-configcenter-etcd/src/main/resources/META-INF/dubbo/internal/org.apache.dubbo.common.config.configcenter.DynamicConfigurationFactory b/dubbo-spi-configcenter/dubbo-configcenter-etcd/src/main/resources/META-INF/dubbo/internal/org.apache.dubbo.common.config.configcenter.DynamicConfigurationFactory
new file mode 100644
index 0000000..d84b1ae
--- /dev/null
+++ b/dubbo-spi-configcenter/dubbo-configcenter-etcd/src/main/resources/META-INF/dubbo/internal/org.apache.dubbo.common.config.configcenter.DynamicConfigurationFactory
@@ -0,0 +1 @@
+etcd=org.apache.dubbo.configcenter.support.etcd.EtcdDynamicConfigurationFactory
\ No newline at end of file
diff --git a/dubbo-spi-configcenter/dubbo-configcenter-etcd/src/test/java/org/apache/dubbo/configcenter/support/etcd/EtcdDynamicConfigurationTest.java b/dubbo-spi-configcenter/dubbo-configcenter-etcd/src/test/java/org/apache/dubbo/configcenter/support/etcd/EtcdDynamicConfigurationTest.java
new file mode 100644
index 0000000..86dd306
--- /dev/null
+++ b/dubbo-spi-configcenter/dubbo-configcenter-etcd/src/test/java/org/apache/dubbo/configcenter/support/etcd/EtcdDynamicConfigurationTest.java
@@ -0,0 +1,154 @@
+/*
+ * 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.configcenter.support.etcd;
+
+import org.apache.dubbo.common.URL;
+import org.apache.dubbo.common.config.configcenter.ConfigChangedEvent;
+import org.apache.dubbo.common.config.configcenter.ConfigurationListener;
+import org.apache.dubbo.common.config.configcenter.DynamicConfiguration;
+
+import io.etcd.jetcd.ByteSequence;
+import io.etcd.jetcd.Client;
+import io.etcd.jetcd.launcher.EtcdCluster;
+import io.etcd.jetcd.launcher.EtcdClusterFactory;
+import org.junit.After;
+import org.junit.Assert;
+import org.junit.Before;
+import org.junit.Test;
+
+import java.net.URI;
+import java.util.HashMap;
+import java.util.List;
+import java.util.Map;
+import java.util.concurrent.CountDownLatch;
+import java.util.concurrent.TimeUnit;
+
+import static java.nio.charset.StandardCharsets.UTF_8;
+import static org.apache.dubbo.remoting.etcd.Constants.SESSION_TIMEOUT_KEY;
+
+/**
+ * Unit test for etcd config center support
+ * Integrate with https://github.com/etcd-io/jetcd#launcher
+ */
+public class EtcdDynamicConfigurationTest {
+
+    private static EtcdDynamicConfiguration config;
+
+    public EtcdCluster etcdCluster = EtcdClusterFactory.buildCluster(getClass().getSimpleName(), 3, false, false);
+
+    private static Client client;
+
+    @Test
+    public void testGetConfig() {
+
+        put("/dubbo/config/org.apache.dubbo.etcd.testService/configurators", "hello");
+        put("/dubbo/config/test/dubbo.properties", "aaa=bbb");
+        Assert.assertEquals("hello", config.getConfig("org.apache.dubbo.etcd.testService.configurators", DynamicConfiguration.DEFAULT_GROUP));
+        Assert.assertEquals("aaa=bbb", config.getConfig("dubbo.properties", "test"));
+    }
+
+    @Test
+    public void testAddListener() throws Exception {
+        CountDownLatch latch = new CountDownLatch(4);
+        TestListener listener1 = new TestListener(latch);
+        TestListener listener2 = new TestListener(latch);
+        TestListener listener3 = new TestListener(latch);
+        TestListener listener4 = new TestListener(latch);
+        config.addListener("AService.configurators", listener1);
+        config.addListener("AService.configurators", listener2);
+        config.addListener("testapp.tagrouters", listener3);
+        config.addListener("testapp.tagrouters", listener4);
+
+        put("/dubbo/config/AService/configurators", "new value1");
+        Thread.sleep(200);
+        put("/dubbo/config/testapp/tagrouters", "new value2");
+        Thread.sleep(200);
+        put("/dubbo/config/testapp", "new value3");
+
+        Thread.sleep(1000);
+
+        Assert.assertTrue(latch.await(5, TimeUnit.SECONDS));
+        Assert.assertEquals(1, listener1.getCount("/dubbo/config/AService/configurators"));
+        Assert.assertEquals(1, listener2.getCount("/dubbo/config/AService/configurators"));
+        Assert.assertEquals(1, listener3.getCount("/dubbo/config/testapp/tagrouters"));
+        Assert.assertEquals(1, listener4.getCount("/dubbo/config/testapp/tagrouters"));
+
+        Assert.assertEquals("new value1", listener1.getValue());
+        Assert.assertEquals("new value1", listener2.getValue());
+        Assert.assertEquals("new value2", listener3.getValue());
+        Assert.assertEquals("new value2", listener4.getValue());
+    }
+
+    private class TestListener implements ConfigurationListener {
+        private CountDownLatch latch;
+        private String value;
+        private Map<String, Integer> countMap = new HashMap<>();
+
+        public TestListener(CountDownLatch latch) {
+            this.latch = latch;
+        }
+
+        @Override
+        public void process(ConfigChangedEvent event) {
+            Integer count = countMap.computeIfAbsent(event.getKey(), k -> 0);
+            countMap.put(event.getKey(), ++count);
+            value = event.getContent();
+            latch.countDown();
+        }
+
+        public int getCount(String key) {
+            return countMap.get(key);
+        }
+
+        public String getValue() {
+            return value;
+        }
+    }
+
+    private void put(String key, String value) {
+        try {
+            client.getKVClient().put(ByteSequence.from(key, UTF_8), ByteSequence.from(value, UTF_8)).get();
+        } catch (Exception e) {
+            System.out.println("Error put value to etcd.");
+        }
+    }
+
+    @Before
+    public void setUp() {
+
+        etcdCluster.start();
+
+        client = Client.builder().endpoints(etcdCluster.getClientEndpoints()).build();
+
+        List<URI> clientEndPoints = etcdCluster.getClientEndpoints();
+
+        String ipAddress = clientEndPoints.get(0).getHost() + ":" + clientEndPoints.get(0).getPort();
+        String urlForDubbo = "etcd3://" + ipAddress + "/org.apache.dubbo.etcd.testService";
+
+        // timeout in 15 seconds.
+        URL url = URL.valueOf(urlForDubbo)
+                .addParameter(SESSION_TIMEOUT_KEY, 15000);
+        config = new EtcdDynamicConfiguration(url);
+    }
+
+    @After
+    public void tearDown() {
+        etcdCluster.close();
+    }
+
+}
diff --git a/dubbo-spi-configcenter/dubbo-configcenter-nacos/pom.xml b/dubbo-spi-configcenter/dubbo-configcenter-nacos/pom.xml
new file mode 100644
index 0000000..42dcc69
--- /dev/null
+++ b/dubbo-spi-configcenter/dubbo-configcenter-nacos/pom.xml
@@ -0,0 +1,45 @@
+<?xml version="1.0" encoding="UTF-8"?>
+<!--
+  ~ 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.
+  -->
+
+<project xmlns="http://maven.apache.org/POM/4.0.0"
+         xmlns:xsi="http://www.w3.org/2001/XMLSchema-instance"
+         xsi:schemaLocation="http://maven.apache.org/POM/4.0.0 http://maven.apache.org/xsd/maven-4.0.0.xsd">
+    <parent>
+        <groupId>org.apache.dubbo</groupId>
+        <artifactId>dubbo-configcenter</artifactId>
+        <version>2.7.7-SNAPSHOT</version>
+    </parent>
+    <modelVersion>4.0.0</modelVersion>
+
+    <artifactId>dubbo-configcenter-nacos</artifactId>
+    <packaging>jar</packaging>
+    <name>${project.artifactId}</name>
+    <description>The nacos implementation of the config-center api</description>
+
+    <dependencies>
+        <dependency>
+            <groupId>org.apache.dubbo</groupId>
+            <artifactId>dubbo-common</artifactId>
+            <version>${project.parent.version}</version>
+        </dependency>
+        <dependency>
+            <groupId>com.alibaba.nacos</groupId>
+            <artifactId>nacos-client</artifactId>
+        </dependency>
+    </dependencies>
+</project>
diff --git a/dubbo-spi-configcenter/dubbo-configcenter-nacos/src/main/java/org/apache/dubbo/configcenter/support/nacos/NacosDynamicConfiguration.java b/dubbo-spi-configcenter/dubbo-configcenter-nacos/src/main/java/org/apache/dubbo/configcenter/support/nacos/NacosDynamicConfiguration.java
new file mode 100644
index 0000000..2227015
--- /dev/null
+++ b/dubbo-spi-configcenter/dubbo-configcenter-nacos/src/main/java/org/apache/dubbo/configcenter/support/nacos/NacosDynamicConfiguration.java
@@ -0,0 +1,381 @@
+/*
+ * 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.configcenter.support.nacos;
+
+import org.apache.dubbo.common.URL;
+import org.apache.dubbo.common.config.configcenter.ConfigChangeType;
+import org.apache.dubbo.common.config.configcenter.ConfigChangedEvent;
+import org.apache.dubbo.common.config.configcenter.ConfigurationListener;
+import org.apache.dubbo.common.config.configcenter.DynamicConfiguration;
+import org.apache.dubbo.common.logger.Logger;
+import org.apache.dubbo.common.logger.LoggerFactory;
+import org.apache.dubbo.common.utils.StringUtils;
+
+import com.alibaba.fastjson.JSON;
+import com.alibaba.fastjson.JSONArray;
+import com.alibaba.fastjson.JSONObject;
+import com.alibaba.nacos.api.NacosFactory;
+import com.alibaba.nacos.api.config.ConfigService;
+import com.alibaba.nacos.api.config.listener.AbstractSharedListener;
+import com.alibaba.nacos.api.exception.NacosException;
+import com.alibaba.nacos.client.config.http.HttpAgent;
+import com.alibaba.nacos.client.config.impl.HttpSimpleClient;
+
+import java.io.IOException;
+import java.lang.reflect.Field;
+import java.util.List;
+import java.util.Map;
+import java.util.Properties;
+import java.util.Set;
+import java.util.SortedSet;
+import java.util.TreeSet;
+import java.util.concurrent.ConcurrentHashMap;
+import java.util.concurrent.ConcurrentMap;
+import java.util.concurrent.CopyOnWriteArraySet;
+import java.util.concurrent.Executor;
+import java.util.stream.Stream;
+
+import static com.alibaba.nacos.api.PropertyKeyConst.ACCESS_KEY;
+import static com.alibaba.nacos.api.PropertyKeyConst.CLUSTER_NAME;
+import static com.alibaba.nacos.api.PropertyKeyConst.CONFIG_LONG_POLL_TIMEOUT;
+import static com.alibaba.nacos.api.PropertyKeyConst.CONFIG_RETRY_TIME;
+import static com.alibaba.nacos.api.PropertyKeyConst.CONTEXT_PATH;
+import static com.alibaba.nacos.api.PropertyKeyConst.ENABLE_REMOTE_SYNC_CONFIG;
+import static com.alibaba.nacos.api.PropertyKeyConst.ENCODE;
+import static com.alibaba.nacos.api.PropertyKeyConst.ENDPOINT;
+import static com.alibaba.nacos.api.PropertyKeyConst.ENDPOINT_PORT;
+import static com.alibaba.nacos.api.PropertyKeyConst.IS_USE_CLOUD_NAMESPACE_PARSING;
+import static com.alibaba.nacos.api.PropertyKeyConst.IS_USE_ENDPOINT_PARSING_RULE;
+import static com.alibaba.nacos.api.PropertyKeyConst.MAX_RETRY;
+import static com.alibaba.nacos.api.PropertyKeyConst.NAMESPACE;
+import static com.alibaba.nacos.api.PropertyKeyConst.NAMING_CLIENT_BEAT_THREAD_COUNT;
+import static com.alibaba.nacos.api.PropertyKeyConst.NAMING_LOAD_CACHE_AT_START;
+import static com.alibaba.nacos.api.PropertyKeyConst.NAMING_POLLING_THREAD_COUNT;
+import static com.alibaba.nacos.api.PropertyKeyConst.RAM_ROLE_NAME;
+import static com.alibaba.nacos.api.PropertyKeyConst.SECRET_KEY;
+import static com.alibaba.nacos.api.PropertyKeyConst.SERVER_ADDR;
+import static com.alibaba.nacos.client.naming.utils.UtilAndComs.NACOS_NAMING_LOG_NAME;
+import static java.util.Arrays.asList;
+import static java.util.Collections.emptyList;
+import static org.apache.dubbo.common.constants.RemotingConstants.BACKUP_KEY;
+import static org.apache.dubbo.common.utils.StringUtils.HYPHEN_CHAR;
+import static org.apache.dubbo.common.utils.StringUtils.SLASH_CHAR;
+
+/**
+ * The nacos implementation of {@link DynamicConfiguration}
+ */
+public class NacosDynamicConfiguration implements DynamicConfiguration {
+
+    private static final String GET_CONFIG_KEYS_PATH = "/v1/cs/configs";
+
+    private final Logger logger = LoggerFactory.getLogger(getClass());
+    /**
+     * the default timeout in millis to get config from nacos
+     */
+    private static final long DEFAULT_TIMEOUT = 5000L;
+
+    private Properties nacosProperties;
+
+    /**
+     * The nacos configService
+     */
+    private final ConfigService configService;
+
+    private HttpAgent httpAgent;
+
+    /**
+     * The map store the key to {@link NacosConfigListener} mapping
+     */
+    private final ConcurrentMap<String, NacosConfigListener> watchListenerMap;
+
+    NacosDynamicConfiguration(URL url) {
+        this.nacosProperties = buildNacosProperties(url);
+        this.configService = buildConfigService(url);
+        this.httpAgent = getHttpAgent(configService);
+        watchListenerMap = new ConcurrentHashMap<>();
+    }
+
+    private ConfigService buildConfigService(URL url) {
+        ConfigService configService = null;
+        try {
+            configService = NacosFactory.createConfigService(nacosProperties);
+        } catch (NacosException e) {
+            if (logger.isErrorEnabled()) {
+                logger.error(e.getErrMsg(), e);
+            }
+            throw new IllegalStateException(e);
+        }
+        return configService;
+    }
+
+    private HttpAgent getHttpAgent(ConfigService configService) {
+        HttpAgent agent = null;
+        try {
+            Field field = configService.getClass().getDeclaredField("agent");
+            field.setAccessible(true);
+            agent = (HttpAgent) field.get(configService);
+        } catch (Exception e) {
+            throw new IllegalStateException(e);
+        }
+        return agent;
+    }
+
+    private Properties buildNacosProperties(URL url) {
+        Properties properties = new Properties();
+        setServerAddr(url, properties);
+        setProperties(url, properties);
+        return properties;
+    }
+
+    private void setServerAddr(URL url, Properties properties) {
+        StringBuilder serverAddrBuilder =
+                new StringBuilder(url.getHost()) // Host
+                        .append(":")
+                        .append(url.getPort()); // Port
+
+        // Append backup parameter as other servers
+        String backup = url.getParameter(BACKUP_KEY);
+        if (backup != null) {
+            serverAddrBuilder.append(",").append(backup);
+        }
+        String serverAddr = serverAddrBuilder.toString();
+        properties.put(SERVER_ADDR, serverAddr);
+    }
+
+    private static void setProperties(URL url, Properties properties) {
+        putPropertyIfAbsent(url, properties, NACOS_NAMING_LOG_NAME);
+        putPropertyIfAbsent(url, properties, IS_USE_CLOUD_NAMESPACE_PARSING);
+        putPropertyIfAbsent(url, properties, IS_USE_ENDPOINT_PARSING_RULE);
+        putPropertyIfAbsent(url, properties, ENDPOINT);
+        putPropertyIfAbsent(url, properties, ENDPOINT_PORT);
+        putPropertyIfAbsent(url, properties, NAMESPACE);
+        putPropertyIfAbsent(url, properties, ACCESS_KEY);
+        putPropertyIfAbsent(url, properties, SECRET_KEY);
+        putPropertyIfAbsent(url, properties, RAM_ROLE_NAME);
+        putPropertyIfAbsent(url, properties, CONTEXT_PATH);
+        putPropertyIfAbsent(url, properties, CLUSTER_NAME);
+        putPropertyIfAbsent(url, properties, ENCODE);
+        putPropertyIfAbsent(url, properties, CONFIG_LONG_POLL_TIMEOUT);
+        putPropertyIfAbsent(url, properties, CONFIG_RETRY_TIME);
+        putPropertyIfAbsent(url, properties, MAX_RETRY);
+        putPropertyIfAbsent(url, properties, ENABLE_REMOTE_SYNC_CONFIG);
+        putPropertyIfAbsent(url, properties, NAMING_LOAD_CACHE_AT_START, "true");
+        putPropertyIfAbsent(url, properties, NAMING_CLIENT_BEAT_THREAD_COUNT);
+        putPropertyIfAbsent(url, properties, NAMING_POLLING_THREAD_COUNT);
+    }
+
+    private static void putPropertyIfAbsent(URL url, Properties properties, String propertyName) {
+        String propertyValue = url.getParameter(propertyName);
+        if (StringUtils.isNotEmpty(propertyValue)) {
+            properties.setProperty(propertyName, propertyValue);
+        }
+    }
+
+    private static void putPropertyIfAbsent(URL url, Properties properties, String propertyName, String defaultValue) {
+        String propertyValue = url.getParameter(propertyName);
+        if (StringUtils.isNotEmpty(propertyValue)) {
+            properties.setProperty(propertyName, propertyValue);
+        } else {
+            properties.setProperty(propertyName, defaultValue);
+        }
+    }
+
+    /**
+     * Ignores the group parameter.
+     *
+     * @param key   property key the native listener will listen on
+     * @param group to distinguish different set of properties
+     * @return
+     */
+    private NacosConfigListener createTargetListener(String key, String group) {
+        NacosConfigListener configListener = new NacosConfigListener();
+        configListener.fillContext(key, group);
+        return configListener;
+    }
+
+    @Override
+    public void addListener(String key, String group, ConfigurationListener listener) {
+        String resolvedGroup = resolveGroup(group);
+        String listenerKey = buildListenerKey(key, group);
+        NacosConfigListener nacosConfigListener = watchListenerMap.computeIfAbsent(listenerKey, k -> createTargetListener(key, resolvedGroup));
+        nacosConfigListener.addListener(listener);
+        try {
+            configService.addListener(key, resolvedGroup, nacosConfigListener);
+        } catch (NacosException e) {
+            logger.error(e.getMessage());
+        }
+    }
+
+    @Override
+    public void removeListener(String key, String group, ConfigurationListener listener) {
+        String listenerKey = buildListenerKey(key, group);
+        NacosConfigListener eventListener = watchListenerMap.get(listenerKey);
+        if (eventListener != null) {
+            eventListener.removeListener(listener);
+        }
+    }
+
+    @Override
+    public String getConfig(String key, String group, long timeout) throws IllegalStateException {
+        String resolvedGroup = resolveGroup(group);
+        try {
+            long nacosTimeout = timeout < 0 ? getDefaultTimeout() : timeout;
+            if (StringUtils.isEmpty(resolvedGroup)) {
+                resolvedGroup = DEFAULT_GROUP;
+            }
+            return configService.getConfig(key, resolvedGroup, nacosTimeout);
+        } catch (NacosException e) {
+            logger.error(e.getMessage());
+        }
+        return null;
+    }
+
+    @Override
+    public Object getInternalProperty(String key) {
+        try {
+            return configService.getConfig(key, DEFAULT_GROUP, getDefaultTimeout());
+        } catch (NacosException e) {
+            logger.error(e.getMessage());
+        }
+        return null;
+    }
+
+    @Override
+    public boolean publishConfig(String key, String group, String content) {
+        boolean published = false;
+        String resolvedGroup = resolveGroup(group);
+        try {
+            String value = configService.getConfig(key, resolvedGroup, getDefaultTimeout());
+            if (StringUtils.isNotEmpty(value)) {
+                content = value + "," + content;
+            }
+            published = configService.publishConfig(key, resolvedGroup, content);
+        } catch (NacosException e) {
+            logger.error(e.getErrMsg());
+        }
+        return published;
+    }
+
+    @Override
+    public long getDefaultTimeout() {
+        return DEFAULT_TIMEOUT;
+    }
+
+    /**
+     * TODO Nacos does not support atomic update of the value mapped to a key.
+     *
+     * @param key
+     * @param group the specified group
+     * @return
+     */
+    @Override
+    public SortedSet<String> getConfigKeys(String group) {
+        // TODO use Nacos Client API to replace HTTP Open API
+        SortedSet<String> keys = new TreeSet<>();
+        try {
+            List<String> paramsValues = asList(
+                    "search", "accurate",
+                    "dataId", "",
+                    "group", resolveGroup(group),
+                    "pageNo", "1",
+                    "pageSize", String.valueOf(Integer.MAX_VALUE)
+            );
+            String encoding = getProperty(ENCODE, "UTF-8");
+            HttpSimpleClient.HttpResult result = httpAgent.httpGet(GET_CONFIG_KEYS_PATH, emptyList(), paramsValues, encoding, 5 * 1000);
+            Stream<String> keysStream = toKeysStream(result.content);
+            keysStream.forEach(keys::add);
+        } catch (IOException e) {
+            if (logger.isErrorEnabled()) {
+                logger.error(e.getMessage(), e);
+            }
+        }
+        return keys;
+    }
+
+    private Stream<String> toKeysStream(String content) {
+        JSONObject jsonObject = JSON.parseObject(content);
+        JSONArray pageItems = jsonObject.getJSONArray("pageItems");
+        return pageItems.stream()
+                .map(object -> (JSONObject) object)
+                .map(json -> json.getString("dataId"));
+    }
+
+    private String getProperty(String name, String defaultValue) {
+        return nacosProperties.getProperty(name, defaultValue);
+    }
+
+    public class NacosConfigListener extends AbstractSharedListener {
+
+        private Set<ConfigurationListener> listeners = new CopyOnWriteArraySet<>();
+        /**
+         * cache data to store old value
+         */
+        private Map<String, String> cacheData = new ConcurrentHashMap<>();
+
+        @Override
+        public Executor getExecutor() {
+            return null;
+        }
+
+        /**
+         * receive
+         *
+         * @param dataId     data ID
+         * @param group      group
+         * @param configInfo content
+         */
+        @Override
+        public void innerReceive(String dataId, String group, String configInfo) {
+            String oldValue = cacheData.get(dataId);
+            ConfigChangedEvent event = new ConfigChangedEvent(dataId, group, configInfo, getChangeType(configInfo, oldValue));
+            if (configInfo == null) {
+                cacheData.remove(dataId);
+            } else {
+                cacheData.put(dataId, configInfo);
+            }
+            listeners.forEach(listener -> listener.process(event));
+        }
+
+        void addListener(ConfigurationListener configurationListener) {
+
+            this.listeners.add(configurationListener);
+        }
+
+        void removeListener(ConfigurationListener configurationListener) {
+            this.listeners.remove(configurationListener);
+        }
+
+        private ConfigChangeType getChangeType(String configInfo, String oldValue) {
+            if (StringUtils.isBlank(configInfo)) {
+                return ConfigChangeType.DELETED;
+            }
+            if (StringUtils.isBlank(oldValue)) {
+                return ConfigChangeType.ADDED;
+            }
+            return ConfigChangeType.MODIFIED;
+        }
+    }
+
+    protected String buildListenerKey(String key, String group) {
+        return key + HYPHEN_CHAR + resolveGroup(group);
+    }
+
+    protected String resolveGroup(String group) {
+        return group.replace(SLASH_CHAR, HYPHEN_CHAR);
+    }
+}
diff --git a/dubbo-spi-configcenter/dubbo-configcenter-nacos/src/main/java/org/apache/dubbo/configcenter/support/nacos/NacosDynamicConfigurationFactory.java b/dubbo-spi-configcenter/dubbo-configcenter-nacos/src/main/java/org/apache/dubbo/configcenter/support/nacos/NacosDynamicConfigurationFactory.java
new file mode 100644
index 0000000..61c02b4
--- /dev/null
+++ b/dubbo-spi-configcenter/dubbo-configcenter-nacos/src/main/java/org/apache/dubbo/configcenter/support/nacos/NacosDynamicConfigurationFactory.java
@@ -0,0 +1,41 @@
+/*
+ * 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.configcenter.support.nacos;
+
+import org.apache.dubbo.common.URL;
+import org.apache.dubbo.common.config.configcenter.AbstractDynamicConfigurationFactory;
+import org.apache.dubbo.common.config.configcenter.DynamicConfiguration;
+import org.apache.dubbo.common.constants.CommonConstants;
+
+import com.alibaba.nacos.api.PropertyKeyConst;
+
+/**
+ * The nacos implementation of {@link AbstractDynamicConfigurationFactory}
+ */
+public class NacosDynamicConfigurationFactory extends AbstractDynamicConfigurationFactory {
+
+    @Override
+    protected DynamicConfiguration createDynamicConfiguration(URL url) {
+        URL nacosURL = url;
+        if (CommonConstants.DUBBO.equals(url.getParameter(PropertyKeyConst.NAMESPACE))) {
+            // Nacos use empty string as default name space, replace default namespace "dubbo" to ""
+            nacosURL = url.removeParameter(PropertyKeyConst.NAMESPACE);
+        }
+        return new NacosDynamicConfiguration(nacosURL);
+    }
+}
diff --git a/dubbo-spi-configcenter/dubbo-configcenter-nacos/src/main/resources/META-INF/dubbo/internal/org.apache.dubbo.common.config.configcenter.DynamicConfigurationFactory b/dubbo-spi-configcenter/dubbo-configcenter-nacos/src/main/resources/META-INF/dubbo/internal/org.apache.dubbo.common.config.configcenter.DynamicConfigurationFactory
new file mode 100644
index 0000000..b9c75a4
--- /dev/null
+++ b/dubbo-spi-configcenter/dubbo-configcenter-nacos/src/main/resources/META-INF/dubbo/internal/org.apache.dubbo.common.config.configcenter.DynamicConfigurationFactory
@@ -0,0 +1 @@
+nacos=org.apache.dubbo.configcenter.support.nacos.NacosDynamicConfigurationFactory
\ No newline at end of file
diff --git a/dubbo-spi-configcenter/dubbo-configcenter-nacos/src/test/java/org/apache/dubbo/configcenter/support/nacos/NacosDynamicConfigurationTest.java b/dubbo-spi-configcenter/dubbo-configcenter-nacos/src/test/java/org/apache/dubbo/configcenter/support/nacos/NacosDynamicConfigurationTest.java
new file mode 100644
index 0000000..afafc1c
--- /dev/null
+++ b/dubbo-spi-configcenter/dubbo-configcenter-nacos/src/test/java/org/apache/dubbo/configcenter/support/nacos/NacosDynamicConfigurationTest.java
@@ -0,0 +1,188 @@
+/*
+ * 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.configcenter.support.nacos;
+
+import org.apache.dubbo.common.URL;
+import org.apache.dubbo.common.config.configcenter.ConfigChangedEvent;
+import org.apache.dubbo.common.config.configcenter.ConfigurationListener;
+import org.apache.dubbo.common.config.configcenter.DynamicConfiguration;
+
+import com.alibaba.nacos.api.NacosFactory;
+import com.alibaba.nacos.api.config.ConfigService;
+import com.alibaba.nacos.api.exception.NacosException;
+import org.junit.jupiter.api.AfterAll;
+import org.junit.jupiter.api.Assertions;
+import org.junit.jupiter.api.BeforeAll;
+import org.junit.jupiter.api.Disabled;
+import org.junit.jupiter.api.Test;
+
+import java.util.HashMap;
+import java.util.Map;
+import java.util.SortedSet;
+import java.util.concurrent.CountDownLatch;
+
+import static org.junit.jupiter.api.Assertions.assertEquals;
+import static org.junit.jupiter.api.Assertions.assertTrue;
+
+
+/**
+ * Unit test for nacos config center support
+ */
+//FIXME: waiting for embedded Nacos suport, then we can open the switch.
+@Disabled("https://github.com/alibaba/nacos/issues/1188")
+public class NacosDynamicConfigurationTest {
+    private static final String SESSION_TIMEOUT_KEY = "session";
+
+    private static NacosDynamicConfiguration config;
+
+    /**
+     * A test client to put data to Nacos server for testing purpose
+     */
+    private static ConfigService nacosClient;
+
+    @Test
+    public void testGetConfig() throws Exception {
+        put("org.apache.dubbo.nacos.testService.configurators", "hello");
+        Thread.sleep(200);
+        put("dubbo.properties", "test", "aaa=bbb");
+        Thread.sleep(200);
+        put("org.apache.dubbo.demo.DemoService:1.0.0.test:xxxx.configurators", "helloworld");
+        Thread.sleep(200);
+        Assertions.assertEquals("hello", config.getConfig("org.apache.dubbo.nacos.testService.configurators", DynamicConfiguration.DEFAULT_GROUP));
+        Assertions.assertEquals("aaa=bbb", config.getConfig("dubbo.properties", "test"));
+        Assertions.assertEquals("helloworld", config.getConfig("org.apache.dubbo.demo.DemoService:1.0.0.test:xxxx.configurators", DynamicConfiguration.DEFAULT_GROUP));
+    }
+
+    @Test
+    public void testAddListener() throws Exception {
+        CountDownLatch latch = new CountDownLatch(4);
+        TestListener listener1 = new TestListener(latch);
+        TestListener listener2 = new TestListener(latch);
+        TestListener listener3 = new TestListener(latch);
+        TestListener listener4 = new TestListener(latch);
+
+
+        config.addListener("AService.configurators", listener1);
+        config.addListener("AService.configurators", listener2);
+        config.addListener("testapp.tag-router", listener3);
+        config.addListener("testapp.tag-router", listener4);
+
+        put("AService.configurators", "new value1");
+        Thread.sleep(200);
+        put("testapp.tag-router", "new value2");
+        Thread.sleep(200);
+        put("testapp", "new value3");
+        Thread.sleep(5000);
+
+        latch.await();
+
+        Assertions.assertEquals(1, listener1.getCount("AService.configurators"));
+        Assertions.assertEquals(1, listener2.getCount("AService.configurators"));
+        Assertions.assertEquals(1, listener3.getCount("testapp.tag-router"));
+        Assertions.assertEquals(1, listener4.getCount("testapp.tag-router"));
+
+        Assertions.assertEquals("new value1", listener1.getValue());
+        Assertions.assertEquals("new value1", listener2.getValue());
+        Assertions.assertEquals("new value2", listener3.getValue());
+        Assertions.assertEquals("new value2", listener4.getValue());
+
+    }
+
+    @Test
+    public void testGetConfigKeys() {
+
+        put("key1", "a");
+        put("key2", "b");
+
+        SortedSet<String> keys = config.getConfigKeys(DynamicConfiguration.DEFAULT_GROUP);
+
+        Assertions.assertFalse(keys.isEmpty());
+
+    }
+
+    private void put(String key, String value) {
+        put(key, DynamicConfiguration.DEFAULT_GROUP, value);
+    }
+
+    private void put(String key, String group, String value) {
+        try {
+            nacosClient.publishConfig(key, group, value);
+        } catch (Exception e) {
+            System.out.println("Error put value to nacos.");
+        }
+    }
+
+    @BeforeAll
+    public static void setUp() {
+        String urlForDubbo = "nacos://" + "127.0.0.1:8848" + "/org.apache.dubbo.nacos.testService";
+        // timeout in 15 seconds.
+        URL url = URL.valueOf(urlForDubbo)
+                .addParameter(SESSION_TIMEOUT_KEY, 15000);
+        config = new NacosDynamicConfiguration(url);
+
+
+        try {
+            nacosClient = NacosFactory.createConfigService("127.0.0.1:8848");
+        } catch (NacosException e) {
+            e.printStackTrace();
+        }
+    }
+
+    @Test
+    public void testPublishConfig() {
+        String key = "user-service";
+        String group = "org.apache.dubbo.service.UserService";
+        String content = "test";
+
+        assertTrue(config.publishConfig(key, group, content));
+        assertEquals("test", config.getProperties(key, group));
+    }
+
+    @AfterAll
+    public static void tearDown() {
+
+    }
+
+    private class TestListener implements ConfigurationListener {
+        private CountDownLatch latch;
+        private String value;
+        private Map<String, Integer> countMap = new HashMap<>();
+
+        public TestListener(CountDownLatch latch) {
+            this.latch = latch;
+        }
+
+        @Override
+        public void process(ConfigChangedEvent event) {
+            System.out.println(this + ": " + event);
+            Integer count = countMap.computeIfAbsent(event.getKey(), k -> 0);
+            countMap.put(event.getKey(), ++count);
+            value = event.getContent();
+            latch.countDown();
+        }
+
+        public int getCount(String key) {
+            return countMap.get(key);
+        }
+
+        public String getValue() {
+            return value;
+        }
+    }
+
+}
diff --git a/dubbo-spi-configcenter/pom.xml b/dubbo-spi-configcenter/pom.xml
new file mode 100644
index 0000000..0e3813a
--- /dev/null
+++ b/dubbo-spi-configcenter/pom.xml
@@ -0,0 +1,38 @@
+<!--
+  Licensed to the Apache Software Foundation (ASF) under one or more
+  contributor license agreements.  See the NOTICE file distributed with
+  this work for additional information regarding copyright ownership.
+  The ASF licenses this file to You under the Apache License, Version 2.0
+  (the "License"); you may not use this file except in compliance with
+  the License.  You may obtain a copy of the License at
+
+      http://www.apache.org/licenses/LICENSE-2.0
+
+  Unless required by applicable law or agreed to in writing, software
+  distributed under the License is distributed on an "AS IS" BASIS,
+  WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied.
+  See the License for the specific language governing permissions and
+  limitations under the License.
+  -->
+<project xmlns="http://maven.apache.org/POM/4.0.0" xmlns:xsi="http://www.w3.org/2001/XMLSchema-instance" xsi:schemaLocation="http://maven.apache.org/POM/4.0.0 http://maven.apache.org/maven-v4_0_0.xsd">
+    <modelVersion>4.0.0</modelVersion>
+    <parent>
+        <groupId>org.apache.dubbo.spi</groupId>
+        <artifactId>dubbo-spi-extensions</artifactId>
+        <version>${revision}</version>
+    </parent>
+    <artifactId>dubbo-spi-configcenter</artifactId>
+    <packaging>pom</packaging>
+    <name>${project.artifactId}</name>
+    <description>The service config-center module of the Dubbo project</description>
+    <properties>
+        <skip_maven_deploy>true</skip_maven_deploy>
+    </properties>
+
+    <modules>
+        <module>dubbo-configcenter-apollo</module>
+        <module>dubbo-configcenter-consul</module>
+        <module>dubbo-configcenter-etcd</module>
+        <module>dubbo-configcenter-nacos</module>
+    </modules>
+</project>
diff --git a/dubbo-spi-container/dubbo-container-log4j/pom.xml b/dubbo-spi-container/dubbo-container-log4j/pom.xml
new file mode 100644
index 0000000..a92d9b4
--- /dev/null
+++ b/dubbo-spi-container/dubbo-container-log4j/pom.xml
@@ -0,0 +1,38 @@
+<!--
+  Licensed to the Apache Software Foundation (ASF) under one or more
+  contributor license agreements.  See the NOTICE file distributed with
+  this work for additional information regarding copyright ownership.
+  The ASF licenses this file to You under the Apache License, Version 2.0
+  (the "License"); you may not use this file except in compliance with
+  the License.  You may obtain a copy of the License at
+
+      http://www.apache.org/licenses/LICENSE-2.0
+
+  Unless required by applicable law or agreed to in writing, software
+  distributed under the License is distributed on an "AS IS" BASIS,
+  WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied.
+  See the License for the specific language governing permissions and
+  limitations under the License.
+  -->
+<project xmlns="http://maven.apache.org/POM/4.0.0" xmlns:xsi="http://www.w3.org/2001/XMLSchema-instance" xsi:schemaLocation="http://maven.apache.org/POM/4.0.0 http://maven.apache.org/maven-v4_0_0.xsd">
+    <modelVersion>4.0.0</modelVersion>
+    <parent>
+        <groupId>org.apache.dubbo</groupId>
+        <artifactId>dubbo-container</artifactId>
+        <version>2.7.7-SNAPSHOT</version>
+    </parent>
+    <artifactId>dubbo-container-log4j</artifactId>
+    <packaging>jar</packaging>
+    <name>${project.artifactId}</name>
+    <description>The log4j container module of dubbo project</description>
+    <properties>
+        <skip_maven_deploy>false</skip_maven_deploy>
+    </properties>
+    <dependencies>
+        <dependency>
+            <groupId>org.apache.dubbo</groupId>
+            <artifactId>dubbo-container-api</artifactId>
+            <version>${project.parent.version}</version>
+        </dependency>
+    </dependencies>
+</project>
\ No newline at end of file
diff --git a/dubbo-spi-container/dubbo-container-log4j/src/main/java/org/apache/dubbo/container/log4j/Log4jContainer.java b/dubbo-spi-container/dubbo-container-log4j/src/main/java/org/apache/dubbo/container/log4j/Log4jContainer.java
new file mode 100644
index 0000000..4ba9c1c
--- /dev/null
+++ b/dubbo-spi-container/dubbo-container-log4j/src/main/java/org/apache/dubbo/container/log4j/Log4jContainer.java
@@ -0,0 +1,103 @@
+/*
+ * 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.container.log4j;
+
+import org.apache.dubbo.common.config.ConfigurationUtils;
+import org.apache.dubbo.common.utils.StringUtils;
+import org.apache.dubbo.container.Container;
+
+import org.apache.log4j.Appender;
+import org.apache.log4j.FileAppender;
+import org.apache.log4j.LogManager;
+import org.apache.log4j.PropertyConfigurator;
+
+import java.util.Enumeration;
+import java.util.Properties;
+
+/**
+ * Log4jContainer. (SPI, Singleton, ThreadSafe)
+ *
+ * The container class implementation for Log4j
+ */
+public class Log4jContainer implements Container {
+
+    public static final String LOG4J_FILE = "dubbo.log4j.file";
+
+    public static final String LOG4J_LEVEL = "dubbo.log4j.level";
+
+    public static final String LOG4J_SUBDIRECTORY = "dubbo.log4j.subdirectory";
+
+    public static final String DEFAULT_LOG4J_LEVEL = "ERROR";
+
+    @Override
+    @SuppressWarnings("unchecked")
+    public void start() {
+        String file = ConfigurationUtils.getProperty(LOG4J_FILE);
+        if (file != null && file.length() > 0) {
+            String level = ConfigurationUtils.getProperty(LOG4J_LEVEL);
+            if (StringUtils.isEmpty(level)) {
+                level = DEFAULT_LOG4J_LEVEL;
+            }
+            Properties properties = new Properties();
+            properties.setProperty("log4j.rootLogger", level + ",application");
+            properties.setProperty("log4j.appender.application", "org.apache.log4j.DailyRollingFileAppender");
+            properties.setProperty("log4j.appender.application.File", file);
+            properties.setProperty("log4j.appender.application.Append", "true");
+            properties.setProperty("log4j.appender.application.DatePattern", "'.'yyyy-MM-dd");
+            properties.setProperty("log4j.appender.application.layout", "org.apache.log4j.PatternLayout");
+            properties.setProperty("log4j.appender.application.layout.ConversionPattern", "%d [%t] %-5p %C{6} (%F:%L) - %m%n");
+            PropertyConfigurator.configure(properties);
+        }
+        String subdirectory = ConfigurationUtils.getProperty(LOG4J_SUBDIRECTORY);
+        if (subdirectory != null && subdirectory.length() > 0) {
+            Enumeration<org.apache.log4j.Logger> ls = LogManager.getCurrentLoggers();
+            while (ls.hasMoreElements()) {
+                org.apache.log4j.Logger l = ls.nextElement();
+                if (l != null) {
+                    Enumeration<Appender> as = l.getAllAppenders();
+                    while (as.hasMoreElements()) {
+                        Appender a = as.nextElement();
+                        if (a instanceof FileAppender) {
+                            FileAppender fa = (FileAppender) a;
+                            String f = fa.getFile();
+                            if (f != null && f.length() > 0) {
+                                int i = f.replace('\\', '/').lastIndexOf('/');
+                                String path;
+                                if (i == -1) {
+                                    path = subdirectory;
+                                } else {
+                                    path = f.substring(0, i);
+                                    if (!path.endsWith(subdirectory)) {
+                                        path = path + "/" + subdirectory;
+                                    }
+                                    f = f.substring(i + 1);
+                                }
+                                fa.setFile(path + "/" + f);
+                                fa.activateOptions();
+                            }
+                        }
+                    }
+                }
+            }
+        }
+    }
+
+    @Override
+    public void stop() {
+    }
+
+}
diff --git a/dubbo-spi-container/dubbo-container-log4j/src/main/resources/META-INF/dubbo/internal/org.apache.dubbo.container.Container b/dubbo-spi-container/dubbo-container-log4j/src/main/resources/META-INF/dubbo/internal/org.apache.dubbo.container.Container
new file mode 100644
index 0000000..0b4c162
--- /dev/null
+++ b/dubbo-spi-container/dubbo-container-log4j/src/main/resources/META-INF/dubbo/internal/org.apache.dubbo.container.Container
@@ -0,0 +1 @@
+log4j=org.apache.dubbo.container.log4j.Log4jContainer
\ No newline at end of file
diff --git a/dubbo-spi-container/dubbo-container-log4j/src/test/java/org/apache/dubbo/container/log4j/Log4jContainerTest.java b/dubbo-spi-container/dubbo-container-log4j/src/test/java/org/apache/dubbo/container/log4j/Log4jContainerTest.java
new file mode 100644
index 0000000..b75b305
--- /dev/null
+++ b/dubbo-spi-container/dubbo-container-log4j/src/test/java/org/apache/dubbo/container/log4j/Log4jContainerTest.java
@@ -0,0 +1,36 @@
+/*
+ * 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.container.log4j;
+
+import org.apache.dubbo.common.extension.ExtensionLoader;
+import org.apache.dubbo.container.Container;
+
+import org.junit.jupiter.api.Test;
+
+/**
+ * StandaloneContainerTest
+ */
+public class Log4jContainerTest {
+
+    @Test
+    public void testContainer() {
+        Log4jContainer container = (Log4jContainer) ExtensionLoader.getExtensionLoader(Container.class).getExtension("log4j");
+        container.start();
+        container.stop();
+    }
+
+}
\ No newline at end of file
diff --git a/dubbo-spi-container/dubbo-container-logback/pom.xml b/dubbo-spi-container/dubbo-container-logback/pom.xml
new file mode 100644
index 0000000..dec8f54
--- /dev/null
+++ b/dubbo-spi-container/dubbo-container-logback/pom.xml
@@ -0,0 +1,42 @@
+<!--
+  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.
+  -->
+<project xmlns="http://maven.apache.org/POM/4.0.0" xmlns:xsi="http://www.w3.org/2001/XMLSchema-instance" xsi:schemaLocation="http://maven.apache.org/POM/4.0.0 http://maven.apache.org/maven-v4_0_0.xsd">
+    <modelVersion>4.0.0</modelVersion>
+    <parent>
+        <groupId>org.apache.dubbo</groupId>
+        <artifactId>dubbo-container</artifactId>
+        <version>2.7.7-SNAPSHOT</version>
+    </parent>
+    <artifactId>dubbo-container-logback</artifactId>
+    <packaging>jar</packaging>
+    <name>${project.artifactId}</name>
+    <description>The logback container module of dubbo project</description>
+    <properties>
+        <skip_maven_deploy>false</skip_maven_deploy>
+    </properties>
+    <dependencies>
+        <dependency>
+            <groupId>org.apache.dubbo</groupId>
+            <artifactId>dubbo-container-api</artifactId>
+            <version>${project.parent.version}</version>
+        </dependency>
+        <dependency>
+            <groupId>ch.qos.logback</groupId>
+            <artifactId>logback-classic</artifactId>
+        </dependency>
+    </dependencies>
+</project>
diff --git a/dubbo-spi-container/dubbo-container-logback/src/main/java/org/apache/dubbo/container/logback/LogbackContainer.java b/dubbo-spi-container/dubbo-container-logback/src/main/java/org/apache/dubbo/container/logback/LogbackContainer.java
new file mode 100644
index 0000000..430e2e2
--- /dev/null
+++ b/dubbo-spi-container/dubbo-container-logback/src/main/java/org/apache/dubbo/container/logback/LogbackContainer.java
@@ -0,0 +1,108 @@
+/*
+ * 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.container.logback;
+
+import org.apache.dubbo.common.utils.ConfigUtils;
+import org.apache.dubbo.common.utils.StringUtils;
+import org.apache.dubbo.container.Container;
+
+import ch.qos.logback.classic.Level;
+import ch.qos.logback.classic.Logger;
+import ch.qos.logback.classic.LoggerContext;
+import ch.qos.logback.classic.encoder.PatternLayoutEncoder;
+import ch.qos.logback.classic.spi.ILoggingEvent;
+import ch.qos.logback.core.rolling.RollingFileAppender;
+import ch.qos.logback.core.rolling.TimeBasedRollingPolicy;
+import org.slf4j.LoggerFactory;
+
+/**
+ * LogbackContainer. (SPI, Singleton, ThreadSafe)
+ *
+ * The container class implementation for Logback
+ */
+public class LogbackContainer implements Container {
+
+    public static final String LOGBACK_FILE = "dubbo.logback.file";
+
+    public static final String LOGBACK_LEVEL = "dubbo.logback.level";
+
+    public static final String LOGBACK_MAX_HISTORY = "dubbo.logback.maxhistory";
+
+    public static final String DEFAULT_LOGBACK_LEVEL = "ERROR";
+
+    @Override
+    public void start() {
+        String file = ConfigUtils.getProperty(LOGBACK_FILE);
+        if (file != null && file.length() > 0) {
+            String level = ConfigUtils.getProperty(LOGBACK_LEVEL);
+            if (StringUtils.isEmpty(level)) {
+                level = DEFAULT_LOGBACK_LEVEL;
+            }
+            // maxHistory=0 Infinite history
+            int maxHistory = StringUtils.parseInteger(ConfigUtils.getProperty(LOGBACK_MAX_HISTORY));
+
+            doInitializer(file, level, maxHistory);
+        }
+    }
+
+    @Override
+    public void stop() {
+    }
+
+    /**
+     * Initializer logback
+     *
+     * @param file
+     * @param level
+     * @param maxHistory
+     */
+    private void doInitializer(String file, String level, int maxHistory) {
+        LoggerContext loggerContext = (LoggerContext) LoggerFactory.getILoggerFactory();
+        Logger rootLogger = loggerContext.getLogger(Logger.ROOT_LOGGER_NAME);
+        rootLogger.detachAndStopAllAppenders();
+
+        // appender
+        RollingFileAppender<ILoggingEvent> fileAppender = new RollingFileAppender<ILoggingEvent>();
+        fileAppender.setContext(loggerContext);
+        fileAppender.setName("application");
+        fileAppender.setFile(file);
+        fileAppender.setAppend(true);
+
+        // policy
+        TimeBasedRollingPolicy<ILoggingEvent> policy = new TimeBasedRollingPolicy<ILoggingEvent>();
+        policy.setContext(loggerContext);
+        policy.setMaxHistory(maxHistory);
+        policy.setFileNamePattern(file + ".%d{yyyy-MM-dd}");
+        policy.setParent(fileAppender);
+        policy.start();
+        fileAppender.setRollingPolicy(policy);
+
+        // encoder
+        PatternLayoutEncoder encoder = new PatternLayoutEncoder();
+        encoder.setContext(loggerContext);
+        encoder.setPattern("%date [%thread] %-5level %logger (%file:%line\\) - %msg%n");
+        encoder.start();
+        fileAppender.setEncoder(encoder);
+
+        fileAppender.start();
+
+        rootLogger.addAppender(fileAppender);
+        rootLogger.setLevel(Level.toLevel(level));
+        rootLogger.setAdditive(false);
+    }
+
+}
diff --git a/dubbo-spi-container/dubbo-container-logback/src/main/resources/META-INF/dubbo/internal/org.apache.dubbo.container.Container b/dubbo-spi-container/dubbo-container-logback/src/main/resources/META-INF/dubbo/internal/org.apache.dubbo.container.Container
new file mode 100644
index 0000000..04c4eaa
--- /dev/null
+++ b/dubbo-spi-container/dubbo-container-logback/src/main/resources/META-INF/dubbo/internal/org.apache.dubbo.container.Container
@@ -0,0 +1 @@
+logback=org.apache.dubbo.container.logback.LogbackContainer
\ No newline at end of file
diff --git a/dubbo-spi-container/dubbo-container-logback/src/test/java/org/apache/dubbo/container/logback/LogbackContainerTest.java b/dubbo-spi-container/dubbo-container-logback/src/test/java/org/apache/dubbo/container/logback/LogbackContainerTest.java
new file mode 100644
index 0000000..d82e8a4
--- /dev/null
+++ b/dubbo-spi-container/dubbo-container-logback/src/test/java/org/apache/dubbo/container/logback/LogbackContainerTest.java
@@ -0,0 +1,47 @@
+/*
+ * 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.container.logback;
+
+import org.apache.dubbo.common.extension.ExtensionLoader;
+import org.apache.dubbo.common.logger.Logger;
+import org.apache.dubbo.common.logger.LoggerFactory;
+import org.apache.dubbo.container.Container;
+
+import org.junit.jupiter.api.Test;
+
+/**
+ * StandaloneContainerTest
+ */
+public class LogbackContainerTest {
+
+    private static final Logger logger = LoggerFactory.getLogger(LogbackContainerTest.class);
+
+    @Test
+    public void testContainer() {
+        LogbackContainer container = (LogbackContainer) ExtensionLoader.getExtensionLoader(Container.class)
+                .getExtension("logback");
+        container.start();
+
+        logger.debug("Test debug:" + this.getClass().getName());
+        logger.warn("Test warn:" + this.getClass().getName());
+        logger.info("Test info:" + this.getClass().getName());
+        logger.error("Test error:" + this.getClass().getName());
+
+        container.stop();
+    }
+
+}
\ No newline at end of file
diff --git a/dubbo-spi-container/pom.xml b/dubbo-spi-container/pom.xml
new file mode 100644
index 0000000..e5f81c0
--- /dev/null
+++ b/dubbo-spi-container/pom.xml
@@ -0,0 +1,35 @@
+<!--
+  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.
+  -->
+<project xmlns="http://maven.apache.org/POM/4.0.0" xmlns:xsi="http://www.w3.org/2001/XMLSchema-instance" xsi:schemaLocation="http://maven.apache.org/POM/4.0.0 http://maven.apache.org/maven-v4_0_0.xsd">
+    <modelVersion>4.0.0</modelVersion>
+    <parent>
+        <groupId>org.apache.dubbo.spi</groupId>
+        <artifactId>dubbo-spi-extensions</artifactId>
+        <version>${revision}</version>
+    </parent>
+    <artifactId>dubbo-spi-container</artifactId>
+    <packaging>pom</packaging>
+    <name>${project.artifactId}</name>
+    <description>The container module of dubbo project</description>
+    <properties>
+        <skip_maven_deploy>true</skip_maven_deploy>
+    </properties>
+    <modules>
+        <module>dubbo-container-log4j</module>
+        <module>dubbo-container-logback</module>
+    </modules>
+</project>
diff --git a/dubbo-spi-filter/dubbo-filter-cache/pom.xml b/dubbo-spi-filter/dubbo-filter-cache/pom.xml
new file mode 100644
index 0000000..49f99cf
--- /dev/null
+++ b/dubbo-spi-filter/dubbo-filter-cache/pom.xml
@@ -0,0 +1,48 @@
+<!--
+  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.
+  -->
+<project xmlns="http://maven.apache.org/POM/4.0.0" xmlns:xsi="http://www.w3.org/2001/XMLSchema-instance" xsi:schemaLocation="http://maven.apache.org/POM/4.0.0 http://maven.apache.org/maven-v4_0_0.xsd">
+    <modelVersion>4.0.0</modelVersion>
+    <parent>
+        <groupId>org.apache.dubbo</groupId>
+        <artifactId>dubbo-filter</artifactId>
+        <version>2.7.7-SNAPSHOT</version>
+    </parent>
+    <artifactId>dubbo-filter-cache</artifactId>
+    <packaging>jar</packaging>
+    <name>${project.artifactId}</name>
+    <description>The cache module of dubbo project</description>
+    <properties>
+        <skip_maven_deploy>false</skip_maven_deploy>
+    </properties>
+    <dependencies>
+        <dependency>
+            <groupId>org.apache.dubbo</groupId>
+            <artifactId>dubbo-rpc-api</artifactId>
+            <version>${project.parent.version}</version>
+        </dependency>
+        <dependency>
+            <groupId>javax.cache</groupId>
+            <artifactId>cache-api</artifactId>
+        </dependency>
+        <dependency>
+            <groupId>com.hazelcast</groupId>
+            <artifactId>hazelcast</artifactId>
+            <scope>test</scope>
+            <version>${hazelcast_version}</version>
+        </dependency>
+    </dependencies>
+</project>
\ No newline at end of file
diff --git a/dubbo-spi-filter/dubbo-filter-cache/src/main/java/org/apache/dubbo/cache/Cache.java b/dubbo-spi-filter/dubbo-filter-cache/src/main/java/org/apache/dubbo/cache/Cache.java
new file mode 100644
index 0000000..69ae671
--- /dev/null
+++ b/dubbo-spi-filter/dubbo-filter-cache/src/main/java/org/apache/dubbo/cache/Cache.java
@@ -0,0 +1,43 @@
+/*
+ * 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.cache;
+
+/**
+ * Cache interface to support storing and retrieval of value against a lookup key. It has two operation <b>get</b> and <b>put</b>.
+ * <li><b>put</b>-Storing value against a key.</li>
+ * <li><b>get</b>-Retrieval of object.</li>
+ * @see org.apache.dubbo.cache.support.lru.LruCache
+ * @see org.apache.dubbo.cache.support.jcache.JCache
+ * @see org.apache.dubbo.cache.support.expiring.ExpiringCache
+ * @see org.apache.dubbo.cache.support.threadlocal.ThreadLocalCache
+ */
+public interface Cache {
+    /**
+     * API to store value against a key
+     * @param key  Unique identifier for the object being store.
+     * @param value Value getting store
+     */
+    void put(Object key, Object value);
+
+    /**
+     * API to return stored value using a key.
+     * @param key Unique identifier for cache lookup
+     * @return Return stored object against key
+     */
+    Object get(Object key);
+
+}
diff --git a/dubbo-spi-filter/dubbo-filter-cache/src/main/java/org/apache/dubbo/cache/CacheFactory.java b/dubbo-spi-filter/dubbo-filter-cache/src/main/java/org/apache/dubbo/cache/CacheFactory.java
new file mode 100644
index 0000000..66b5b59
--- /dev/null
+++ b/dubbo-spi-filter/dubbo-filter-cache/src/main/java/org/apache/dubbo/cache/CacheFactory.java
@@ -0,0 +1,43 @@
+/*
+ * 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.cache;
+
+import org.apache.dubbo.common.URL;
+import org.apache.dubbo.common.extension.Adaptive;
+import org.apache.dubbo.common.extension.SPI;
+import org.apache.dubbo.rpc.Invocation;
+
+/**
+ * Interface needs to be implemented by all the cache store provider.Along with implementing <b>CacheFactory</b> interface
+ * entry needs to be added in org.apache.dubbo.cache.CacheFactory file in a classpath META-INF sub directories.
+ *
+ * @see Cache
+ */
+@SPI("lru")
+public interface CacheFactory {
+
+    /**
+     * CacheFactory implementation class needs to implement this return underlying cache instance for method against
+     * url and invocation.
+     * @param url
+     * @param invocation
+     * @return Instance of Cache containing cached value against method url and invocation.
+     */
+    @Adaptive("cache")
+    Cache getCache(URL url, Invocation invocation);
+
+}
diff --git a/dubbo-spi-filter/dubbo-filter-cache/src/main/java/org/apache/dubbo/cache/filter/CacheFilter.java b/dubbo-spi-filter/dubbo-filter-cache/src/main/java/org/apache/dubbo/cache/filter/CacheFilter.java
new file mode 100644
index 0000000..02d0e29
--- /dev/null
+++ b/dubbo-spi-filter/dubbo-filter-cache/src/main/java/org/apache/dubbo/cache/filter/CacheFilter.java
@@ -0,0 +1,133 @@
+/*
+ * 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.cache.filter;
+
+import org.apache.dubbo.cache.Cache;
+import org.apache.dubbo.cache.CacheFactory;
+import org.apache.dubbo.common.extension.Activate;
+import org.apache.dubbo.common.utils.ConfigUtils;
+import org.apache.dubbo.common.utils.StringUtils;
+import org.apache.dubbo.rpc.AsyncRpcResult;
+import org.apache.dubbo.rpc.Filter;
+import org.apache.dubbo.rpc.Invocation;
+import org.apache.dubbo.rpc.Invoker;
+import org.apache.dubbo.rpc.Result;
+import org.apache.dubbo.rpc.RpcException;
+
+import java.io.Serializable;
+
+import static org.apache.dubbo.common.constants.CommonConstants.CONSUMER;
+import static org.apache.dubbo.common.constants.CommonConstants.PROVIDER;
+import static org.apache.dubbo.common.constants.FilterConstants.CACHE_KEY;
+
+/**
+ * CacheFilter is a core component of dubbo.Enabling <b>cache</b> key of service,method,consumer or provider dubbo will cache method return value.
+ * Along with cache key we need to configure cache type. Dubbo default implemented cache types are
+ * <li>lur</li>
+ * <li>threadlocal</li>
+ * <li>jcache</li>
+ * <li>expiring</li>
+ *
+ * <pre>
+ *   e.g. 1)&lt;dubbo:service cache="lru" /&gt;
+ *        2)&lt;dubbo:service /&gt; &lt;dubbo:method name="method2" cache="threadlocal" /&gt; &lt;dubbo:service/&gt;
+ *        3)&lt;dubbo:provider cache="expiring" /&gt;
+ *        4)&lt;dubbo:consumer cache="jcache" /&gt;
+ *
+ *If cache type is defined in method level then method level type will get precedence. According to above provided
+ *example, if service has two method, method1 and method2, method2 will have cache type as <b>threadlocal</b> where others will
+ *be backed by <b>lru</b>
+ *</pre>
+ *
+ * @see org.apache.dubbo.rpc.Filter
+ * @see org.apache.dubbo.cache.support.lru.LruCacheFactory
+ * @see org.apache.dubbo.cache.support.lru.LruCache
+ * @see org.apache.dubbo.cache.support.jcache.JCacheFactory
+ * @see org.apache.dubbo.cache.support.jcache.JCache
+ * @see org.apache.dubbo.cache.support.threadlocal.ThreadLocalCacheFactory
+ * @see org.apache.dubbo.cache.support.threadlocal.ThreadLocalCache
+ * @see org.apache.dubbo.cache.support.expiring.ExpiringCacheFactory
+ * @see org.apache.dubbo.cache.support.expiring.ExpiringCache
+ *
+ */
+@Activate(group = {CONSUMER, PROVIDER}, value = CACHE_KEY)
+public class CacheFilter implements Filter {
+
+    private CacheFactory cacheFactory;
+
+    /**
+     * Dubbo will populate and set the cache factory instance based on service/method/consumer/provider configured
+     * cache attribute value. Dubbo will search for the class name implementing configured <b>cache</b> in file org.apache.dubbo.cache.CacheFactory
+     * under META-INF sub folders.
+     *
+     * @param cacheFactory instance of CacheFactory based on <b>cache</b> type
+     */
+    public void setCacheFactory(CacheFactory cacheFactory) {
+        this.cacheFactory = cacheFactory;
+    }
+
+    /**
+     * If cache is configured, dubbo will invoke method on each method call. If cache value is returned by cache store
+     * then it will return otherwise call the remote method and return value. If remote method's return value has error
+     * then it will not cache the value.
+     * @param invoker    service
+     * @param invocation invocation.
+     * @return Cache returned value if found by the underlying cache store. If cache miss it will call target method.
+     * @throws RpcException
+     */
+    @Override
+    public Result invoke(Invoker<?> invoker, Invocation invocation) throws RpcException {
+        if (cacheFactory != null && ConfigUtils.isNotEmpty(invoker.getUrl().getMethodParameter(invocation.getMethodName(), CACHE_KEY))) {
+            Cache cache = cacheFactory.getCache(invoker.getUrl(), invocation);
+            if (cache != null) {
+                String key = StringUtils.toArgumentString(invocation.getArguments());
+                Object value = cache.get(key);
+                if (value != null) {
+                    if (value instanceof ValueWrapper) {
+                        return AsyncRpcResult.newDefaultAsyncResult(((ValueWrapper) value).get(), invocation);
+                    } else {
+                        return AsyncRpcResult.newDefaultAsyncResult(value, invocation);
+                    }
+                }
+                Result result = invoker.invoke(invocation);
+                if (!result.hasException()) {
+                    cache.put(key, new ValueWrapper(result.getValue()));
+                }
+                return result;
+            }
+        }
+        return invoker.invoke(invocation);
+    }
+
+    /**
+     * Cache value wrapper.
+     */
+    static class ValueWrapper implements Serializable {
+
+        private static final long serialVersionUID = -1777337318019193256L;
+
+        private final Object value;
+
+        public ValueWrapper (Object value) {
+            this.value = value;
+        }
+
+        public Object get() {
+            return this.value;
+        }
+    }
+}
diff --git a/dubbo-spi-filter/dubbo-filter-cache/src/main/java/org/apache/dubbo/cache/support/AbstractCacheFactory.java b/dubbo-spi-filter/dubbo-filter-cache/src/main/java/org/apache/dubbo/cache/support/AbstractCacheFactory.java
new file mode 100644
index 0000000..966d923
--- /dev/null
+++ b/dubbo-spi-filter/dubbo-filter-cache/src/main/java/org/apache/dubbo/cache/support/AbstractCacheFactory.java
@@ -0,0 +1,72 @@
+/*
+ * 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.cache.support;
+
+import org.apache.dubbo.cache.Cache;
+import org.apache.dubbo.cache.CacheFactory;
+import org.apache.dubbo.common.URL;
+import org.apache.dubbo.rpc.Invocation;
+
+import java.util.concurrent.ConcurrentHashMap;
+import java.util.concurrent.ConcurrentMap;
+
+import static org.apache.dubbo.common.constants.CommonConstants.METHOD_KEY;
+
+/**
+ * AbstractCacheFactory is a default implementation of {@link CacheFactory}. It abstract out the key formation from URL along with
+ * invocation method. It initially check if the value for key already present in own local in-memory store then it won't check underlying storage cache {@link Cache}.
+ * Internally it used {@link ConcurrentHashMap} to store do level-1 caching.
+ *
+ * @see CacheFactory
+ * @see org.apache.dubbo.cache.support.jcache.JCacheFactory
+ * @see org.apache.dubbo.cache.support.lru.LruCacheFactory
+ * @see org.apache.dubbo.cache.support.threadlocal.ThreadLocalCacheFactory
+ * @see org.apache.dubbo.cache.support.expiring.ExpiringCacheFactory
+ */
+public abstract class AbstractCacheFactory implements CacheFactory {
+
+    /**
+     * This is used to store factory level-1 cached data.
+     */
+    private final ConcurrentMap<String, Cache> caches = new ConcurrentHashMap<String, Cache>();
+
+    /**
+     *  Takes URL and invocation instance and return cache instance for a given url.
+     * @param url url of the method
+     * @param invocation invocation context.
+     * @return Instance of cache store used as storage for caching return values.
+     */
+    @Override
+    public Cache getCache(URL url, Invocation invocation) {
+        url = url.addParameter(METHOD_KEY, invocation.getMethodName());
+        String key = url.toFullString();
+        Cache cache = caches.get(key);
+        if (cache == null) {
+            caches.put(key, createCache(url));
+            cache = caches.get(key);
+        }
+        return cache;
+    }
+
+    /**
+     * Takes url as an method argument and return new instance of cache store implemented by AbstractCacheFactory subclass.
+     * @param url url of the method
+     * @return Create and return new instance of cache store used as storage for caching return values.
+     */
+    protected abstract Cache createCache(URL url);
+
+}
diff --git a/dubbo-spi-filter/dubbo-filter-cache/src/main/java/org/apache/dubbo/cache/support/expiring/ExpiringCache.java b/dubbo-spi-filter/dubbo-filter-cache/src/main/java/org/apache/dubbo/cache/support/expiring/ExpiringCache.java
new file mode 100644
index 0000000..afaf8c6
--- /dev/null
+++ b/dubbo-spi-filter/dubbo-filter-cache/src/main/java/org/apache/dubbo/cache/support/expiring/ExpiringCache.java
@@ -0,0 +1,77 @@
+/*
+ * 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.cache.support.expiring;
+
+import org.apache.dubbo.cache.Cache;
+import org.apache.dubbo.common.URL;
+
+import java.util.Map;
+
+/**
+ * ExpiringCache - With the characteristic of expiration time.
+ */
+
+/**
+ * This class store the cache value with the characteristic of expiration time. If a service,method,consumer or provided is configured with key <b>cache</b>
+ * with value <b>expiring</b>, dubbo initialize the instance of this class using {@link ExpiringCacheFactory} to store method's returns value
+ * to server from store without making method call.
+ * <pre>
+ *     e.g. 1) &lt;dubbo:service cache="expiring" cache.seconds="60" cache.interval="10"/&gt;
+ *          2) &lt;dubbo:consumer cache="expiring" /&gt;
+ * </pre>
+ * <li>It used constructor argument url instance <b>cache.seconds</b> value to decide time to live of cached object.Default value of it is 180 second.</li>
+ * <li>It used constructor argument url instance <b>cache.interval</b> value for cache value expiration interval.Default value of this is 4 second</li>
+ * @see Cache
+ * @see ExpiringCacheFactory
+ * @see org.apache.dubbo.cache.support.AbstractCacheFactory
+ * @see org.apache.dubbo.cache.filter.CacheFilter
+ */
+public class ExpiringCache implements Cache {
+    private final Map<Object, Object> store;
+
+    public ExpiringCache(URL url) {
+        // cache time (second)
+        final int secondsToLive = url.getParameter("cache.seconds", 180);
+        // Cache check interval (second)
+        final int intervalSeconds = url.getParameter("cache.interval", 4);
+        ExpiringMap<Object, Object> expiringMap = new ExpiringMap<>(secondsToLive, intervalSeconds);
+        expiringMap.getExpireThread().startExpiryIfNotStarted();
+        this.store = expiringMap;
+    }
+
+    /**
+     * API to store value against a key in the calling thread scope.
+     * @param key  Unique identifier for the object being store.
+     * @param value Value getting store
+     */
+    @Override
+    public void put(Object key, Object value) {
+        store.put(key, value);
+    }
+
+    /**
+     * API to return stored value using a key against the calling thread specific store.
+     * @param key Unique identifier for cache lookup
+     * @return Return stored object against key
+     */
+
+    @Override
+    public Object get(Object key) {
+        return store.get(key);
+    }
+
+}
diff --git a/dubbo-spi-filter/dubbo-filter-cache/src/main/java/org/apache/dubbo/cache/support/expiring/ExpiringCacheFactory.java b/dubbo-spi-filter/dubbo-filter-cache/src/main/java/org/apache/dubbo/cache/support/expiring/ExpiringCacheFactory.java
new file mode 100644
index 0000000..5259d74
--- /dev/null
+++ b/dubbo-spi-filter/dubbo-filter-cache/src/main/java/org/apache/dubbo/cache/support/expiring/ExpiringCacheFactory.java
@@ -0,0 +1,44 @@
+/*
+ * 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.cache.support.expiring;
+
+import org.apache.dubbo.cache.Cache;
+import org.apache.dubbo.cache.support.AbstractCacheFactory;
+import org.apache.dubbo.common.URL;
+
+
+/**
+ * Implement {@link org.apache.dubbo.cache.CacheFactory} by extending {@link AbstractCacheFactory} and provide
+ * instance of new {@link ExpiringCache}.
+ *
+ * @see AbstractCacheFactory
+ * @see ExpiringCache
+ * @see Cache
+ */
+
+public class ExpiringCacheFactory extends AbstractCacheFactory {
+
+    /**
+     * Takes url as an method argument and return new instance of cache store implemented by JCache.
+     * @param url url of the method
+     * @return ExpiringCache instance of cache
+     */
+    @Override
+    protected Cache createCache(URL url) {
+        return new ExpiringCache(url);
+    }
+}
diff --git a/dubbo-spi-filter/dubbo-filter-cache/src/main/java/org/apache/dubbo/cache/support/expiring/ExpiringMap.java b/dubbo-spi-filter/dubbo-filter-cache/src/main/java/org/apache/dubbo/cache/support/expiring/ExpiringMap.java
new file mode 100644
index 0000000..895f114
--- /dev/null
+++ b/dubbo-spi-filter/dubbo-filter-cache/src/main/java/org/apache/dubbo/cache/support/expiring/ExpiringMap.java
@@ -0,0 +1,374 @@
+/*
+ * 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.cache.support.expiring;
+
+import java.util.ArrayList;
+import java.util.Collection;
+import java.util.List;
+import java.util.Map;
+import java.util.Set;
+import java.util.concurrent.ConcurrentHashMap;
+import java.util.concurrent.atomic.AtomicInteger;
+import java.util.concurrent.atomic.AtomicLong;
+
+/**
+ * can be expired map
+ * Contains a background thread that periodically checks if the data is out of date
+ */
+public class ExpiringMap<K, V> implements Map<K, V> {
+
+    /**
+     * default time to live (second)
+     */
+    private static final int DEFAULT_TIME_TO_LIVE = 180;
+
+    /**
+     * default expire check interval (second)
+     */
+    private static final int DEFAULT_EXPIRATION_INTERVAL = 1;
+
+    private static AtomicInteger expireCount = new AtomicInteger(1);
+
+    private final ConcurrentHashMap<K, ExpiryObject> delegateMap;
+
+    private final ExpireThread expireThread;
+
+    public ExpiringMap() {
+        this(DEFAULT_TIME_TO_LIVE, DEFAULT_EXPIRATION_INTERVAL);
+    }
+
+    /**
+     * Constructor
+     *
+     * @param timeToLive time to live (second)
+     */
+    public ExpiringMap(int timeToLive) {
+        this(timeToLive, DEFAULT_EXPIRATION_INTERVAL);
+    }
+
+    public ExpiringMap(int timeToLive, int expirationInterval) {
+        this(new ConcurrentHashMap<>(), timeToLive, expirationInterval);
+    }
+
+    private ExpiringMap(ConcurrentHashMap<K, ExpiryObject> delegateMap, int timeToLive, int expirationInterval) {
+        this.delegateMap = delegateMap;
+        this.expireThread = new ExpireThread();
+        expireThread.setTimeToLive(timeToLive);
+        expireThread.setExpirationInterval(expirationInterval);
+    }
+
+    @Override
+    public V put(K key, V value) {
+        ExpiryObject answer = delegateMap.put(key, new ExpiryObject(key, value, System.currentTimeMillis()));
+        if (answer == null) {
+            return null;
+        }
+        return answer.getValue();
+    }
+
+    @Override
+    public V get(Object key) {
+        ExpiryObject object = delegateMap.get(key);
+        if (object != null) {
+            object.setLastAccessTime(System.currentTimeMillis());
+            return object.getValue();
+        }
+        return null;
+    }
+
+    @Override
+    public V remove(Object key) {
+        ExpiryObject answer = delegateMap.remove(key);
+        if (answer == null) {
+            return null;
+        }
+        return answer.getValue();
+    }
+
+    @Override
+    public boolean containsKey(Object key) {
+        return delegateMap.containsKey(key);
+    }
+
+    @Override
+    public boolean containsValue(Object value) {
+        return delegateMap.containsValue(value);
+    }
+
+    @Override
+    public int size() {
+        return delegateMap.size();
+    }
+
+    @Override
+    public boolean isEmpty() {
+        return delegateMap.isEmpty();
+    }
+
+    @Override
+    public void clear() {
+        delegateMap.clear();
+        expireThread.stopExpiring();
+    }
+
+    @Override
+    public int hashCode() {
+        return delegateMap.hashCode();
+    }
+
+    @Override
+    public Set<K> keySet() {
+        return delegateMap.keySet();
+    }
+
+    @Override
+    public boolean equals(Object obj) {
+        return delegateMap.equals(obj);
+    }
+
+    @Override
+    public void putAll(Map<? extends K, ? extends V> inMap) {
+        for (Entry<? extends K, ? extends V> e : inMap.entrySet()) {
+            this.put(e.getKey(), e.getValue());
+        }
+    }
+
+    @Override
+    public Collection<V> values() {
+        List<V> list = new ArrayList<V>();
+        Set<Entry<K, ExpiryObject>> delegatedSet = delegateMap.entrySet();
+        for (Entry<K, ExpiryObject> entry : delegatedSet) {
+            ExpiryObject value = entry.getValue();
+            list.add(value.getValue());
+        }
+        return list;
+    }
+
+    @Override
+    public Set<Entry<K, V>> entrySet() {
+        throw new UnsupportedOperationException();
+    }
+
+    public ExpireThread getExpireThread() {
+        return expireThread;
+    }
+
+    public int getExpirationInterval() {
+        return expireThread.getExpirationInterval();
+    }
+
+    public void setExpirationInterval(int expirationInterval) {
+        expireThread.setExpirationInterval(expirationInterval);
+    }
+
+    public int getTimeToLive() {
+        return expireThread.getTimeToLive();
+    }
+
+    public void setTimeToLive(int timeToLive) {
+        expireThread.setTimeToLive(timeToLive);
+    }
+
+    @Override
+    public String toString() {
+        return "ExpiringMap{" +
+                "delegateMap=" + delegateMap.toString() +
+                ", expireThread=" + expireThread.toString() +
+                '}';
+    }
+
+    /**
+     * can be expired object
+     */
+    private class ExpiryObject {
+        private K key;
+        private V value;
+        private AtomicLong lastAccessTime;
+
+        ExpiryObject(K key, V value, long lastAccessTime) {
+            if (value == null) {
+                throw new IllegalArgumentException("An expiring object cannot be null.");
+            }
+            this.key = key;
+            this.value = value;
+            this.lastAccessTime = new AtomicLong(lastAccessTime);
+        }
+
+        public long getLastAccessTime() {
+            return lastAccessTime.get();
+        }
+
+        public void setLastAccessTime(long lastAccessTime) {
+            this.lastAccessTime.set(lastAccessTime);
+        }
+
+        public K getKey() {
+            return key;
+        }
+
+        public V getValue() {
+            return value;
+        }
+
+        @Override
+        public boolean equals(Object obj) {
+            return value.equals(obj);
+        }
+
+        @Override
+        public int hashCode() {
+            return value.hashCode();
+        }
+
+        @Override
+        public String toString() {
+            return "ExpiryObject{" +
+                    "key=" + key +
+                    ", value=" + value +
+                    ", lastAccessTime=" + lastAccessTime +
+                    '}';
+        }
+    }
+
+    /**
+     * Background thread, periodically checking if the data is out of date
+     */
+    public class ExpireThread implements Runnable {
+        private long timeToLiveMillis;
+        private long expirationIntervalMillis;
+        private volatile boolean running = false;
+        private final Thread expirerThread;
+
+        @Override
+        public String toString() {
+            return "ExpireThread{" +
+                    ", timeToLiveMillis=" + timeToLiveMillis +
+                    ", expirationIntervalMillis=" + expirationIntervalMillis +
+                    ", running=" + running +
+                    ", expirerThread=" + expirerThread +
+                    '}';
+        }
+
+        public ExpireThread() {
+            expirerThread = new Thread(this, "ExpiryMapExpire-" + expireCount.getAndIncrement());
+            expirerThread.setDaemon(true);
+        }
+
+        @Override
+        public void run() {
+            while (running) {
+                processExpires();
+                try {
+                    Thread.sleep(expirationIntervalMillis);
+                } catch (InterruptedException e) {
+                    running = false;
+                }
+            }
+        }
+
+        private void processExpires() {
+            long timeNow = System.currentTimeMillis();
+            for (ExpiryObject o : delegateMap.values()) {
+                if (timeToLiveMillis <= 0) {
+                    continue;
+                }
+                long timeIdle = timeNow - o.getLastAccessTime();
+                if (timeIdle >= timeToLiveMillis) {
+                    delegateMap.remove(o.getKey());
+                }
+            }
+        }
+
+        /**
+         * start expiring Thread
+         */
+        public void startExpiring() {
+            if (!running) {
+                running = true;
+                expirerThread.start();
+            }
+        }
+
+        /**
+         * start thread
+         */
+        public void startExpiryIfNotStarted() {
+            if (running) {
+                return;
+            }
+            startExpiring();
+        }
+
+        /**
+         * stop thread
+         */
+        public void stopExpiring() {
+            if (running) {
+                running = false;
+                expirerThread.interrupt();
+            }
+        }
+
+        /**
+         * get thread state
+         *
+         * @return thread state
+         */
+        public boolean isRunning() {
+            return running;
+        }
+
+        /**
+         * get time to live
+         *
+         * @return time to live
+         */
+        public int getTimeToLive() {
+            return (int) timeToLiveMillis / 1000;
+        }
+
+        /**
+         * update time to live
+         *
+         * @param timeToLive time to live
+         */
+        public void setTimeToLive(long timeToLive) {
+            this.timeToLiveMillis = timeToLive * 1000;
+        }
+
+        /**
+         * get expiration interval
+         *
+         * @return expiration interval (second)
+         */
+        public int getExpirationInterval() {
+            return (int) expirationIntervalMillis / 1000;
+        }
+
+        /**
+         * set expiration interval
+         *
+         * @param expirationInterval expiration interval (second)
+         */
+        public void setExpirationInterval(long expirationInterval) {
+            this.expirationIntervalMillis = expirationInterval * 1000;
+        }
+    }
+}
+
+
+
diff --git a/dubbo-spi-filter/dubbo-filter-cache/src/main/java/org/apache/dubbo/cache/support/jcache/JCache.java b/dubbo-spi-filter/dubbo-filter-cache/src/main/java/org/apache/dubbo/cache/support/jcache/JCache.java
new file mode 100644
index 0000000..7972a9d
--- /dev/null
+++ b/dubbo-spi-filter/dubbo-filter-cache/src/main/java/org/apache/dubbo/cache/support/jcache/JCache.java
@@ -0,0 +1,87 @@
+/*
+ * 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.cache.support.jcache;
+
+import org.apache.dubbo.common.URL;
+import org.apache.dubbo.common.utils.StringUtils;
+
+import javax.cache.Cache;
+import javax.cache.CacheException;
+import javax.cache.CacheManager;
+import javax.cache.Caching;
+import javax.cache.configuration.MutableConfiguration;
+import javax.cache.expiry.CreatedExpiryPolicy;
+import javax.cache.expiry.Duration;
+import javax.cache.spi.CachingProvider;
+import java.util.concurrent.TimeUnit;
+
+import static org.apache.dubbo.common.constants.CommonConstants.METHOD_KEY;
+
+/**
+ * This class store the cache value per thread. If a service,method,consumer or provided is configured with key <b>cache</b>
+ * with value <b>jcache</b>, dubbo initialize the instance of this class using {@link JCacheFactory} to store method's returns value
+ * to server from store without making method call.
+ *
+ * @see Cache
+ * @see JCacheFactory
+ * @see org.apache.dubbo.cache.support.AbstractCacheFactory
+ * @see org.apache.dubbo.cache.filter.CacheFilter
+ */
+public class JCache implements org.apache.dubbo.cache.Cache {
+
+    private final Cache<Object, Object> store;
+
+    public JCache(URL url) {
+        String method = url.getParameter(METHOD_KEY, "");
+        String key = url.getAddress() + "." + url.getServiceKey() + "." + method;
+        // jcache parameter is the full-qualified class name of SPI implementation
+        String type = url.getParameter("jcache");
+
+        CachingProvider provider = StringUtils.isEmpty(type) ? Caching.getCachingProvider() : Caching.getCachingProvider(type);
+        CacheManager cacheManager = provider.getCacheManager();
+        Cache<Object, Object> cache = cacheManager.getCache(key);
+        if (cache == null) {
+            try {
+                //configure the cache
+                MutableConfiguration config =
+                        new MutableConfiguration<>()
+                                .setTypes(Object.class, Object.class)
+                                .setExpiryPolicyFactory(CreatedExpiryPolicy.factoryOf(new Duration(TimeUnit.MILLISECONDS, url.getMethodParameter(method, "cache.write.expire", 60 * 1000))))
+                                .setStoreByValue(false)
+                                .setManagementEnabled(true)
+                                .setStatisticsEnabled(true);
+                cache = cacheManager.createCache(key, config);
+            } catch (CacheException e) {
+                // concurrent cache initialization
+                cache = cacheManager.getCache(key);
+            }
+        }
+
+        this.store = cache;
+    }
+
+    @Override
+    public void put(Object key, Object value) {
+        store.put(key, value);
+    }
+
+    @Override
+    public Object get(Object key) {
+        return store.get(key);
+    }
+
+}
diff --git a/dubbo-spi-filter/dubbo-filter-cache/src/main/java/org/apache/dubbo/cache/support/jcache/JCacheFactory.java b/dubbo-spi-filter/dubbo-filter-cache/src/main/java/org/apache/dubbo/cache/support/jcache/JCacheFactory.java
new file mode 100644
index 0000000..aba9a2f
--- /dev/null
+++ b/dubbo-spi-filter/dubbo-filter-cache/src/main/java/org/apache/dubbo/cache/support/jcache/JCacheFactory.java
@@ -0,0 +1,48 @@
+/*
+ * 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.cache.support.jcache;
+
+import org.apache.dubbo.cache.Cache;
+import org.apache.dubbo.cache.support.AbstractCacheFactory;
+import org.apache.dubbo.common.URL;
+
+import javax.cache.spi.CachingProvider;
+
+/**
+ * JCacheFactory is factory class to provide instance of javax spi cache.Implement {@link org.apache.dubbo.cache.CacheFactory} by
+ * extending {@link AbstractCacheFactory} and provide
+ * @see AbstractCacheFactory
+ * @see JCache
+ * @see org.apache.dubbo.cache.filter.CacheFilter
+ * @see Cache
+ * @see CachingProvider
+ * @see javax.cache.Cache
+ * @see javax.cache.CacheManager
+ */
+public class JCacheFactory extends AbstractCacheFactory {
+
+    /**
+     * Takes url as an method argument and return new instance of cache store implemented by JCache.
+     * @param url url of the method
+     * @return JCache instance of cache
+     */
+    @Override
+    protected Cache createCache(URL url) {
+        return new JCache(url);
+    }
+
+}
diff --git a/dubbo-spi-filter/dubbo-filter-cache/src/main/java/org/apache/dubbo/cache/support/lfu/LfuCache.java b/dubbo-spi-filter/dubbo-filter-cache/src/main/java/org/apache/dubbo/cache/support/lfu/LfuCache.java
new file mode 100644
index 0000000..9ccc979
--- /dev/null
+++ b/dubbo-spi-filter/dubbo-filter-cache/src/main/java/org/apache/dubbo/cache/support/lfu/LfuCache.java
@@ -0,0 +1,80 @@
+/*
+ * 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.cache.support.lfu;
+
+import org.apache.dubbo.cache.Cache;
+import org.apache.dubbo.common.URL;
+import org.apache.dubbo.common.utils.LFUCache;
+
+/**
+ * This class store the cache value per thread. If a service,method,consumer or provided is configured with key <b>cache</b>
+ * with value <b>lfu</b>, dubbo initialize the instance of this class using {@link LfuCacheFactory} to store method's returns value
+ * to server from store without making method call.
+ * <pre>
+ *     e.g. 1) &lt;dubbo:service cache="lfu" cache.size="5000" cache.evictionFactor="0.3"/&gt;
+ *          2) &lt;dubbo:consumer cache="lfu" /&gt;
+ * </pre>
+ * <pre>
+ * LfuCache uses url's <b>cache.size</b> value for its max store size, url's <b>cache.evictionFactor</b> value for its eviction factor,
+ * default store size value will be 1000, default eviction factor will be 0.3
+ * </pre>
+ *
+ * @see Cache
+ * @see LfuCacheFactory
+ * @see org.apache.dubbo.cache.support.AbstractCacheFactory
+ * @see org.apache.dubbo.cache.filter.CacheFilter
+ */
+public class LfuCache implements Cache {
+
+    /**
+     * This is used to store cache records
+     */
+    private final LFUCache store;
+
+    /**
+     *  Initialize LfuCache, it uses constructor argument <b>cache.size</b> value as its storage max size.
+     *  If nothing is provided then it will use 1000 as default size value. <b>cache.evictionFactor</b> value as its eviction factor.
+     *  If nothing is provided then it will use 0.3 as default value.
+     * @param url A valid URL instance
+     */
+    public LfuCache (URL url) {
+        final int max = url.getParameter("cache.size", 1000);
+        final float factor = url.getParameter("cache.evictionFactor", 0.75f);
+        this.store = new LFUCache(max, factor);
+    }
+
+    /**
+     * API to store value against a key in the calling thread scope.
+     * @param key  Unique identifier for the object being store.
+     * @param value Value getting store
+     */
+    @Override
+    public void put(Object key, Object value) {
+        store.put(key, value);
+    }
+
+    /**
+     * API to return stored value using a key against the calling thread specific store.
+     * @param key Unique identifier for cache lookup
+     * @return Return stored object against key
+     */
+    @Override
+    public Object get(Object key) {
+        return store.get(key);
+    }
+
+}
diff --git a/dubbo-spi-filter/dubbo-filter-cache/src/main/java/org/apache/dubbo/cache/support/lfu/LfuCacheFactory.java b/dubbo-spi-filter/dubbo-filter-cache/src/main/java/org/apache/dubbo/cache/support/lfu/LfuCacheFactory.java
new file mode 100644
index 0000000..f04edca
--- /dev/null
+++ b/dubbo-spi-filter/dubbo-filter-cache/src/main/java/org/apache/dubbo/cache/support/lfu/LfuCacheFactory.java
@@ -0,0 +1,43 @@
+/*
+ * 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.cache.support.lfu;
+
+import org.apache.dubbo.cache.Cache;
+import org.apache.dubbo.cache.support.AbstractCacheFactory;
+import org.apache.dubbo.common.URL;
+
+/**
+ * Implement {@link org.apache.dubbo.cache.CacheFactory} by extending {@link AbstractCacheFactory} and provide
+ * instance of new {@link LfuCache}.
+ *
+ * @see AbstractCacheFactory
+ * @see LfuCache
+ * @see Cache
+ */
+public class LfuCacheFactory extends AbstractCacheFactory {
+
+    /**
+     * Takes url as an method argument and return new instance of cache store implemented by LfuCache.
+     * @param url url of the method
+     * @return ThreadLocalCache instance of cache
+     */
+    @Override
+    protected Cache createCache(URL url) {
+        return new LfuCache(url);
+    }
+
+}
diff --git a/dubbo-spi-filter/dubbo-filter-cache/src/main/java/org/apache/dubbo/cache/support/lru/LruCache.java b/dubbo-spi-filter/dubbo-filter-cache/src/main/java/org/apache/dubbo/cache/support/lru/LruCache.java
new file mode 100644
index 0000000..1b8022f
--- /dev/null
+++ b/dubbo-spi-filter/dubbo-filter-cache/src/main/java/org/apache/dubbo/cache/support/lru/LruCache.java
@@ -0,0 +1,80 @@
+/*
+ * 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.cache.support.lru;
+
+import org.apache.dubbo.cache.Cache;
+import org.apache.dubbo.common.URL;
+import org.apache.dubbo.common.utils.LRUCache;
+
+import java.util.Map;
+
+/**
+ * This class store the cache value per thread. If a service,method,consumer or provided is configured with key <b>cache</b>
+ * with value <b>lru</b>, dubbo initialize the instance of this class using {@link LruCacheFactory} to store method's returns value
+ * to server from store without making method call.
+ * <pre>
+ *     e.g. 1) &lt;dubbo:service cache="lru" cache.size="5000"/&gt;
+ *          2) &lt;dubbo:consumer cache="lru" /&gt;
+ * </pre>
+ * <pre>
+ * LruCache uses url's <b>cache.size</b> value for its max store size, if nothing is provided then
+ * default value will be 1000
+ * </pre>
+ *
+ * @see Cache
+ * @see LruCacheFactory
+ * @see org.apache.dubbo.cache.support.AbstractCacheFactory
+ * @see org.apache.dubbo.cache.filter.CacheFilter
+ */
+public class LruCache implements Cache {
+
+    /**
+     * This is used to store cache records
+     */
+    private final Map<Object, Object> store;
+
+    /**
+     * Initialize LruCache, it uses constructor argument <b>cache.size</b> value as its storage max size.
+     *  If nothing is provided then it will use 1000 as default value.
+     * @param url A valid URL instance
+     */
+    public LruCache(URL url) {
+        final int max = url.getParameter("cache.size", 1000);
+        this.store = new LRUCache<>(max);
+    }
+
+    /**
+     * API to store value against a key in the calling thread scope.
+     * @param key  Unique identifier for the object being store.
+     * @param value Value getting store
+     */
+    @Override
+    public void put(Object key, Object value) {
+        store.put(key, value);
+    }
+
+    /**
+     * API to return stored value using a key against the calling thread specific store.
+     * @param key Unique identifier for cache lookup
+     * @return Return stored object against key
+     */
+    @Override
+    public Object get(Object key) {
+        return store.get(key);
+    }
+
+}
diff --git a/dubbo-spi-filter/dubbo-filter-cache/src/main/java/org/apache/dubbo/cache/support/lru/LruCacheFactory.java b/dubbo-spi-filter/dubbo-filter-cache/src/main/java/org/apache/dubbo/cache/support/lru/LruCacheFactory.java
new file mode 100644
index 0000000..9ec9486
--- /dev/null
+++ b/dubbo-spi-filter/dubbo-filter-cache/src/main/java/org/apache/dubbo/cache/support/lru/LruCacheFactory.java
@@ -0,0 +1,43 @@
+/*
+ * 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.cache.support.lru;
+
+import org.apache.dubbo.cache.Cache;
+import org.apache.dubbo.cache.support.AbstractCacheFactory;
+import org.apache.dubbo.common.URL;
+
+/**
+ * Implement {@link org.apache.dubbo.cache.CacheFactory} by extending {@link AbstractCacheFactory} and provide
+ * instance of new {@link LruCache}.
+ *
+ * @see AbstractCacheFactory
+ * @see LruCache
+ * @see Cache
+ */
+public class LruCacheFactory extends AbstractCacheFactory {
+
+    /**
+     * Takes url as an method argument and return new instance of cache store implemented by LruCache.
+     * @param url url of the method
+     * @return ThreadLocalCache instance of cache
+     */
+    @Override
+    protected Cache createCache(URL url) {
+        return new LruCache(url);
+    }
+
+}
diff --git a/dubbo-spi-filter/dubbo-filter-cache/src/main/java/org/apache/dubbo/cache/support/threadlocal/ThreadLocalCache.java b/dubbo-spi-filter/dubbo-filter-cache/src/main/java/org/apache/dubbo/cache/support/threadlocal/ThreadLocalCache.java
new file mode 100644
index 0000000..12b3b5c
--- /dev/null
+++ b/dubbo-spi-filter/dubbo-filter-cache/src/main/java/org/apache/dubbo/cache/support/threadlocal/ThreadLocalCache.java
@@ -0,0 +1,77 @@
+/*
+ * 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.cache.support.threadlocal;
+
+import org.apache.dubbo.cache.Cache;
+import org.apache.dubbo.common.URL;
+
+import java.util.HashMap;
+import java.util.Map;
+
+/**
+ * This class store the cache value per thread. If a service,method,consumer or provided is configured with key <b>cache</b>
+ * with value <b>threadlocal</b>, dubbo initialize the instance of this class using {@link ThreadLocalCacheFactory} to store method's returns value
+ * to server from store without making method call.
+ *  <pre>
+ *      e.g. &lt;dubbo:service cache="threadlocal" /&gt;
+ *  </pre>
+ * <pre>
+ * As this ThreadLocalCache stores key-value in memory without any expiry or delete support per thread wise, if number threads and number of key-value are high then jvm should be
+ * configured with appropriate memory.
+ * </pre>
+ *
+ * @see org.apache.dubbo.cache.support.AbstractCacheFactory
+ * @see org.apache.dubbo.cache.filter.CacheFilter
+ * @see Cache
+ */
+public class ThreadLocalCache implements Cache {
+
+    /**
+     * Thread local variable to store cached data.
+     */
+    private final ThreadLocal<Map<Object, Object>> store;
+
+    /**
+     * Taken URL as an argument to create an instance of ThreadLocalCache. In this version of implementation constructor
+     * argument is not getting used in the scope of this class.
+     * @param url
+     */
+    public ThreadLocalCache(URL url) {
+        this.store = ThreadLocal.withInitial(HashMap::new);
+    }
+
+    /**
+     * API to store value against a key in the calling thread scope.
+     * @param key  Unique identifier for the object being store.
+     * @param value Value getting store
+     */
+    @Override
+    public void put(Object key, Object value) {
+        store.get().put(key, value);
+    }
+
+    /**
+     * API to return stored value using a key against the calling thread specific store.
+     * @param key Unique identifier for cache lookup
+     * @return Return stored object against key
+     */
+    @Override
+    public Object get(Object key) {
+        return store.get().get(key);
+    }
+
+}
diff --git a/dubbo-spi-filter/dubbo-filter-cache/src/main/java/org/apache/dubbo/cache/support/threadlocal/ThreadLocalCacheFactory.java b/dubbo-spi-filter/dubbo-filter-cache/src/main/java/org/apache/dubbo/cache/support/threadlocal/ThreadLocalCacheFactory.java
new file mode 100644
index 0000000..cdda6cf
--- /dev/null
+++ b/dubbo-spi-filter/dubbo-filter-cache/src/main/java/org/apache/dubbo/cache/support/threadlocal/ThreadLocalCacheFactory.java
@@ -0,0 +1,43 @@
+/*
+ * 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.cache.support.threadlocal;
+
+import org.apache.dubbo.cache.Cache;
+import org.apache.dubbo.cache.support.AbstractCacheFactory;
+import org.apache.dubbo.common.URL;
+
+/**
+ * Implement {@link org.apache.dubbo.cache.CacheFactory} by extending {@link AbstractCacheFactory} and provide
+ * instance of new {@link ThreadLocalCache}. Note about this class is, each thread does not have a local copy of factory.
+ *
+ * @see AbstractCacheFactory
+ * @see ThreadLocalCache
+ * @see Cache
+ */
+public class ThreadLocalCacheFactory extends AbstractCacheFactory {
+
+    /**
+     * Takes url as an method argument and return new instance of cache store implemented by ThreadLocalCache.
+     * @param url url of the method
+     * @return ThreadLocalCache instance of cache
+     */
+    @Override
+    protected Cache createCache(URL url) {
+        return new ThreadLocalCache(url);
+    }
+
+}
diff --git a/dubbo-spi-filter/dubbo-filter-cache/src/main/resources/META-INF/dubbo/internal/org.apache.dubbo.cache.CacheFactory b/dubbo-spi-filter/dubbo-filter-cache/src/main/resources/META-INF/dubbo/internal/org.apache.dubbo.cache.CacheFactory
new file mode 100644
index 0000000..1ea180a
--- /dev/null
+++ b/dubbo-spi-filter/dubbo-filter-cache/src/main/resources/META-INF/dubbo/internal/org.apache.dubbo.cache.CacheFactory
@@ -0,0 +1,4 @@
+threadlocal=org.apache.dubbo.cache.support.threadlocal.ThreadLocalCacheFactory
+lru=org.apache.dubbo.cache.support.lru.LruCacheFactory
+jcache=org.apache.dubbo.cache.support.jcache.JCacheFactory
+expiring=org.apache.dubbo.cache.support.expiring.ExpiringCacheFactory
\ No newline at end of file
diff --git a/dubbo-spi-filter/dubbo-filter-cache/src/main/resources/META-INF/dubbo/internal/org.apache.dubbo.rpc.Filter b/dubbo-spi-filter/dubbo-filter-cache/src/main/resources/META-INF/dubbo/internal/org.apache.dubbo.rpc.Filter
new file mode 100644
index 0000000..8d6259b
--- /dev/null
+++ b/dubbo-spi-filter/dubbo-filter-cache/src/main/resources/META-INF/dubbo/internal/org.apache.dubbo.rpc.Filter
@@ -0,0 +1 @@
+cache=org.apache.dubbo.cache.filter.CacheFilter
\ No newline at end of file
diff --git a/dubbo-spi-filter/dubbo-filter-cache/src/test/java/org/apache/dubbo/cache/filter/CacheFilterTest.java b/dubbo-spi-filter/dubbo-filter-cache/src/test/java/org/apache/dubbo/cache/filter/CacheFilterTest.java
new file mode 100644
index 0000000..3326833
--- /dev/null
+++ b/dubbo-spi-filter/dubbo-filter-cache/src/test/java/org/apache/dubbo/cache/filter/CacheFilterTest.java
@@ -0,0 +1,137 @@
+/*
+ * 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.cache.filter;
+
+import org.apache.dubbo.cache.CacheFactory;
+import org.apache.dubbo.cache.support.expiring.ExpiringCacheFactory;
+import org.apache.dubbo.cache.support.jcache.JCacheFactory;
+import org.apache.dubbo.cache.support.lru.LruCacheFactory;
+import org.apache.dubbo.cache.support.threadlocal.ThreadLocalCacheFactory;
+import org.apache.dubbo.common.URL;
+import org.apache.dubbo.rpc.AsyncRpcResult;
+import org.apache.dubbo.rpc.Invoker;
+import org.apache.dubbo.rpc.Result;
+import org.apache.dubbo.rpc.RpcInvocation;
+
+import org.junit.jupiter.api.Assertions;
+import org.junit.jupiter.params.ParameterizedTest;
+import org.junit.jupiter.params.provider.Arguments;
+import org.junit.jupiter.params.provider.MethodSource;
+
+import java.util.stream.Stream;
+
+import static org.mockito.BDDMockito.given;
+import static org.mockito.Mockito.mock;
+
+public class CacheFilterTest {
+    private RpcInvocation invocation;
+    private CacheFilter cacheFilter = new CacheFilter();
+    private Invoker<?> invoker = mock(Invoker.class);
+    private Invoker<?> invoker1 = mock(Invoker.class);
+    private Invoker<?> invoker2 = mock(Invoker.class);
+    private Invoker<?> invoker3 = mock(Invoker.class);
+    private Invoker<?> invoker4 = mock(Invoker.class);
+
+    static Stream<Arguments> cacheFactories() {
+        return Stream.of(
+                Arguments.of("lru", new LruCacheFactory()),
+                Arguments.of("jcache", new JCacheFactory()),
+                Arguments.of("threadlocal", new ThreadLocalCacheFactory()),
+                Arguments.of("expiring", new ExpiringCacheFactory())
+        );
+    }
+
+    public void setUp(String cacheType, CacheFactory cacheFactory) {
+        invocation = new RpcInvocation();
+        cacheFilter.setCacheFactory(cacheFactory);
+
+        URL url = URL.valueOf("test://test:11/test?cache=" + cacheType);
+
+        given(invoker.invoke(invocation)).willReturn(AsyncRpcResult.newDefaultAsyncResult("value", invocation));
+        given(invoker.getUrl()).willReturn(url);
+
+        given(invoker1.invoke(invocation)).willReturn(AsyncRpcResult.newDefaultAsyncResult("value1", invocation));
+        given(invoker1.getUrl()).willReturn(url);
+
+        given(invoker2.invoke(invocation)).willReturn(AsyncRpcResult.newDefaultAsyncResult("value2", invocation));
+        given(invoker2.getUrl()).willReturn(url);
+
+        given(invoker3.invoke(invocation)).willReturn(AsyncRpcResult.newDefaultAsyncResult(new RuntimeException(), invocation));
+        given(invoker3.getUrl()).willReturn(url);
+
+        given(invoker4.invoke(invocation)).willReturn(AsyncRpcResult.newDefaultAsyncResult(invocation));
+        given(invoker4.getUrl()).willReturn(url);
+    }
+
+    @ParameterizedTest
+    @MethodSource("cacheFactories")
+    public void testNonArgsMethod(String cacheType, CacheFactory cacheFactory) {
+        setUp(cacheType, cacheFactory);
+        invocation.setMethodName("echo");
+        invocation.setParameterTypes(new Class<?>[]{});
+        invocation.setArguments(new Object[]{});
+
+        cacheFilter.invoke(invoker, invocation);
+        Result rpcResult1 = cacheFilter.invoke(invoker1, invocation);
+        Result rpcResult2 = cacheFilter.invoke(invoker2, invocation);
+        Assertions.assertEquals(rpcResult1.getValue(), rpcResult2.getValue());
+        Assertions.assertEquals(rpcResult1.getValue(), "value");
+    }
+
+    @ParameterizedTest
+    @MethodSource("cacheFactories")
+    public void testMethodWithArgs(String cacheType, CacheFactory cacheFactory) {
+        setUp(cacheType, cacheFactory);
+        invocation.setMethodName("echo1");
+        invocation.setParameterTypes(new Class<?>[]{String.class});
+        invocation.setArguments(new Object[]{"arg1"});
+
+        cacheFilter.invoke(invoker, invocation);
+        Result rpcResult1 = cacheFilter.invoke(invoker1, invocation);
+        Result rpcResult2 = cacheFilter.invoke(invoker2, invocation);
+        Assertions.assertEquals(rpcResult1.getValue(), rpcResult2.getValue());
+        Assertions.assertEquals(rpcResult1.getValue(), "value");
+    }
+
+    @ParameterizedTest
+    @MethodSource("cacheFactories")
+    public void testException(String cacheType, CacheFactory cacheFactory) {
+        setUp(cacheType, cacheFactory);
+        invocation.setMethodName("echo1");
+        invocation.setParameterTypes(new Class<?>[]{String.class});
+        invocation.setArguments(new Object[]{"arg2"});
+
+        cacheFilter.invoke(invoker3, invocation);
+        Result rpcResult = cacheFilter.invoke(invoker2, invocation);
+        Assertions.assertEquals(rpcResult.getValue(), "value2");
+    }
+
+    @ParameterizedTest
+    @MethodSource("cacheFactories")
+    public void testNull(String cacheType, CacheFactory cacheFactory) {
+        setUp(cacheType, cacheFactory);
+        invocation.setMethodName("echo1");
+        invocation.setParameterTypes(new Class<?>[]{String.class});
+        invocation.setArguments(new Object[]{"arg3"});
+
+        cacheFilter.invoke(invoker4, invocation);
+        Result result1 = cacheFilter.invoke(invoker1, invocation);
+        Result result2 = cacheFilter.invoke(invoker2, invocation);
+        Assertions.assertNull(result1.getValue());
+        Assertions.assertNull(result2.getValue());
+    }
+}
diff --git a/dubbo-spi-filter/dubbo-filter-cache/src/test/java/org/apache/dubbo/cache/support/AbstractCacheFactoryTest.java b/dubbo-spi-filter/dubbo-filter-cache/src/test/java/org/apache/dubbo/cache/support/AbstractCacheFactoryTest.java
new file mode 100644
index 0000000..f93a453
--- /dev/null
+++ b/dubbo-spi-filter/dubbo-filter-cache/src/test/java/org/apache/dubbo/cache/support/AbstractCacheFactoryTest.java
@@ -0,0 +1,33 @@
+/*
+ * 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.cache.support;
+
+import org.apache.dubbo.cache.Cache;
+import org.apache.dubbo.common.URL;
+import org.apache.dubbo.rpc.Invocation;
+import org.apache.dubbo.rpc.RpcInvocation;
+
+public abstract class AbstractCacheFactoryTest {
+
+    protected Cache constructCache() {
+        URL url = URL.valueOf("test://test:11/test?cache=lru");
+        Invocation invocation = new RpcInvocation();
+        return getCacheFactory().getCache(url, invocation);
+    }
+
+    protected abstract AbstractCacheFactory getCacheFactory();
+}
\ No newline at end of file
diff --git a/dubbo-spi-filter/dubbo-filter-cache/src/test/java/org/apache/dubbo/cache/support/expiring/ExpiringCacheFactoryTest.java b/dubbo-spi-filter/dubbo-filter-cache/src/test/java/org/apache/dubbo/cache/support/expiring/ExpiringCacheFactoryTest.java
new file mode 100644
index 0000000..23484c6
--- /dev/null
+++ b/dubbo-spi-filter/dubbo-filter-cache/src/test/java/org/apache/dubbo/cache/support/expiring/ExpiringCacheFactoryTest.java
@@ -0,0 +1,38 @@
+/*
+ * Licensed to the Apache Software Foundation (ASF) under one or more
+ * contributor license agreements.  See the NOTICE file distributed with
+ * this work for additional information regarding copyright ownership.
+ * The ASF licenses this file to You under the Apache License, Version 2.0
+ * (the "License"); you may not use this file except in compliance with
+ * the License.  You may obtain a copy of the License at
+ *
+ *     http://www.apache.org/licenses/LICENSE-2.0
+ *
+ * Unless required by applicable law or agreed to in writing, software
+ * distributed under the License is distributed on an "AS IS" BASIS,
+ * WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied.
+ * See the License for the specific language governing permissions and
+ * limitations under the License.
+ */
+package org.apache.dubbo.cache.support.expiring;
+
+import org.apache.dubbo.cache.Cache;
+import org.apache.dubbo.cache.support.AbstractCacheFactory;
+import org.apache.dubbo.cache.support.AbstractCacheFactoryTest;
+import org.junit.jupiter.api.Test;
+
+import static org.hamcrest.core.Is.is;
+import static org.hamcrest.MatcherAssert.assertThat;
+
+public class ExpiringCacheFactoryTest extends AbstractCacheFactoryTest {
+    @Test
+    public void testLruCacheFactory() throws Exception {
+        Cache cache = super.constructCache();
+        assertThat(cache instanceof ExpiringCache, is(true));
+    }
+
+    @Override
+    protected AbstractCacheFactory getCacheFactory() {
+        return new ExpiringCacheFactory();
+    }
+}
\ No newline at end of file
diff --git a/dubbo-spi-filter/dubbo-filter-cache/src/test/java/org/apache/dubbo/cache/support/jcache/JCacheFactoryTest.java b/dubbo-spi-filter/dubbo-filter-cache/src/test/java/org/apache/dubbo/cache/support/jcache/JCacheFactoryTest.java
new file mode 100644
index 0000000..3260fa6
--- /dev/null
+++ b/dubbo-spi-filter/dubbo-filter-cache/src/test/java/org/apache/dubbo/cache/support/jcache/JCacheFactoryTest.java
@@ -0,0 +1,55 @@
+/*
+ * 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.cache.support.jcache;
+
+import org.apache.dubbo.cache.Cache;
+import org.apache.dubbo.cache.support.AbstractCacheFactory;
+import org.apache.dubbo.cache.support.AbstractCacheFactoryTest;
+import org.apache.dubbo.common.URL;
+import org.apache.dubbo.rpc.Invocation;
+import org.apache.dubbo.rpc.RpcInvocation;
+
+import org.junit.jupiter.api.Test;
+
+import static org.hamcrest.MatcherAssert.assertThat;
+import static org.hamcrest.core.Is.is;
+import static org.junit.jupiter.api.Assertions.assertNull;
+
+public class JCacheFactoryTest extends AbstractCacheFactoryTest {
+
+    @Test
+    public void testJCacheFactory() throws Exception {
+        Cache cache = super.constructCache();
+        assertThat(cache instanceof JCache, is(true));
+    }
+
+    @Test
+    public void testJCacheGetExpired() throws Exception {
+        URL url = URL.valueOf("test://test:12/test?cache=jacache&cache.write.expire=1");
+        AbstractCacheFactory cacheFactory = getCacheFactory();
+        Invocation invocation = new RpcInvocation();
+        Cache cache = cacheFactory.getCache(url, invocation);
+        cache.put("testKey", "testValue");
+        Thread.sleep(10);
+        assertNull(cache.get("testKey"));
+    }
+
+    @Override
+    protected AbstractCacheFactory getCacheFactory() {
+        return new JCacheFactory();
+    }
+}
\ No newline at end of file
diff --git a/dubbo-spi-filter/dubbo-filter-cache/src/test/java/org/apache/dubbo/cache/support/lru/LruCacheFactoryTest.java b/dubbo-spi-filter/dubbo-filter-cache/src/test/java/org/apache/dubbo/cache/support/lru/LruCacheFactoryTest.java
new file mode 100644
index 0000000..149c122
--- /dev/null
+++ b/dubbo-spi-filter/dubbo-filter-cache/src/test/java/org/apache/dubbo/cache/support/lru/LruCacheFactoryTest.java
@@ -0,0 +1,38 @@
+/*
+ * Licensed to the Apache Software Foundation (ASF) under one or more
+ * contributor license agreements.  See the NOTICE file distributed with
+ * this work for additional information regarding copyright ownership.
+ * The ASF licenses this file to You under the Apache License, Version 2.0
+ * (the "License"); you may not use this file except in compliance with
+ * the License.  You may obtain a copy of the License at
+ *
+ *     http://www.apache.org/licenses/LICENSE-2.0
+ *
+ * Unless required by applicable law or agreed to in writing, software
+ * distributed under the License is distributed on an "AS IS" BASIS,
+ * WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied.
+ * See the License for the specific language governing permissions and
+ * limitations under the License.
+ */
+package org.apache.dubbo.cache.support.lru;
+
+import org.apache.dubbo.cache.Cache;
+import org.apache.dubbo.cache.support.AbstractCacheFactory;
+import org.apache.dubbo.cache.support.AbstractCacheFactoryTest;
+import org.junit.jupiter.api.Test;
+
+import static org.hamcrest.core.Is.is;
+import static org.hamcrest.MatcherAssert.assertThat;
+
+public class LruCacheFactoryTest extends AbstractCacheFactoryTest{
+    @Test
+    public void testLruCacheFactory() throws Exception {
+        Cache cache = super.constructCache();
+        assertThat(cache instanceof LruCache, is(true));
+    }
+
+    @Override
+    protected AbstractCacheFactory getCacheFactory() {
+        return new LruCacheFactory();
+    }
+}
\ No newline at end of file
diff --git a/dubbo-spi-filter/dubbo-filter-cache/src/test/java/org/apache/dubbo/cache/support/threadlocal/ThreadLocalCacheFactoryTest.java b/dubbo-spi-filter/dubbo-filter-cache/src/test/java/org/apache/dubbo/cache/support/threadlocal/ThreadLocalCacheFactoryTest.java
new file mode 100644
index 0000000..800f5ad
--- /dev/null
+++ b/dubbo-spi-filter/dubbo-filter-cache/src/test/java/org/apache/dubbo/cache/support/threadlocal/ThreadLocalCacheFactoryTest.java
@@ -0,0 +1,38 @@
+/*
+ * Licensed to the Apache Software Foundation (ASF) under one or more
+ * contributor license agreements.  See the NOTICE file distributed with
+ * this work for additional information regarding copyright ownership.
+ * The ASF licenses this file to You under the Apache License, Version 2.0
+ * (the "License"); you may not use this file except in compliance with
+ * the License.  You may obtain a copy of the License at
+ *
+ *     http://www.apache.org/licenses/LICENSE-2.0
+ *
+ * Unless required by applicable law or agreed to in writing, software
+ * distributed under the License is distributed on an "AS IS" BASIS,
+ * WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied.
+ * See the License for the specific language governing permissions and
+ * limitations under the License.
+ */
+package org.apache.dubbo.cache.support.threadlocal;
+
+import org.apache.dubbo.cache.Cache;
+import org.apache.dubbo.cache.support.AbstractCacheFactory;
+import org.apache.dubbo.cache.support.AbstractCacheFactoryTest;
+import org.junit.jupiter.api.Test;
+
+import static org.hamcrest.core.Is.is;
+import static org.hamcrest.MatcherAssert.assertThat;
+
+public class ThreadLocalCacheFactoryTest extends AbstractCacheFactoryTest {
+    @Test
+    public void testThreadLocalCacheFactory() throws Exception {
+        Cache cache = super.constructCache();
+        assertThat(cache instanceof ThreadLocalCache, is(true));
+    }
+
+    @Override
+    protected AbstractCacheFactory getCacheFactory() {
+        return new ThreadLocalCacheFactory();
+    }
+}
\ No newline at end of file
diff --git a/dubbo-spi-filter/dubbo-filter-validation/pom.xml b/dubbo-spi-filter/dubbo-filter-validation/pom.xml
new file mode 100644
index 0000000..933f1c9
--- /dev/null
+++ b/dubbo-spi-filter/dubbo-filter-validation/pom.xml
@@ -0,0 +1,72 @@
+<!--
+  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.
+  -->
+<project xmlns="http://maven.apache.org/POM/4.0.0" xmlns:xsi="http://www.w3.org/2001/XMLSchema-instance" xsi:schemaLocation="http://maven.apache.org/POM/4.0.0 http://maven.apache.org/maven-v4_0_0.xsd">
+    <modelVersion>4.0.0</modelVersion>
+    <parent>
+        <groupId>org.apache.dubbo</groupId>
+        <artifactId>dubbo-filter</artifactId>
+        <version>2.7.7-SNAPSHOT</version>
+    </parent>
+    <artifactId>dubbo-filter-validation</artifactId>
+    <packaging>jar</packaging>
+    <name>${project.artifactId}</name>
+    <description>The validation module of dubbo project</description>
+    <properties>
+        <skip_maven_deploy>false</skip_maven_deploy>
+    </properties>
+    <dependencies>
+        <dependency>
+            <groupId>org.apache.dubbo</groupId>
+            <artifactId>dubbo-rpc-api</artifactId>
+            <version>${project.parent.version}</version>
+        </dependency>
+        <dependency>
+            <groupId>javax.validation</groupId>
+            <artifactId>validation-api</artifactId>
+        </dependency>
+        <dependency>
+            <groupId>org.hibernate</groupId>
+            <artifactId>hibernate-validator</artifactId>
+            <scope>test</scope>
+            <version>${hibernate_validator_version}</version>
+        </dependency>
+        <dependency>
+            <groupId>javax.el</groupId>
+            <artifactId>javax.el-api</artifactId>
+            <scope>test</scope>
+            <version>${el_api_version}</version>
+        </dependency>
+        <dependency>
+            <groupId>javax.xml.bind</groupId>
+            <artifactId>jaxb-api</artifactId>
+            <scope>test</scope>
+            <version>${jaxb_api_version}</version>
+        </dependency>
+        <dependency>
+            <groupId>com.sun.xml.bind</groupId>
+            <artifactId>jaxb-impl</artifactId>
+            <scope>test</scope>
+            <version>${jaxb_api_version}</version>
+        </dependency>
+        <dependency>
+            <groupId>com.sun.xml.bind</groupId>
+            <artifactId>jaxb-core</artifactId>
+            <scope>test</scope>
+            <version>${jaxb_api_version}</version>
+        </dependency>
+    </dependencies>
+</project>
\ No newline at end of file
diff --git a/dubbo-spi-filter/dubbo-filter-validation/src/main/java/org/apache/dubbo/validation/MethodValidated.java b/dubbo-spi-filter/dubbo-filter-validation/src/main/java/org/apache/dubbo/validation/MethodValidated.java
new file mode 100644
index 0000000..ca41a52
--- /dev/null
+++ b/dubbo-spi-filter/dubbo-filter-validation/src/main/java/org/apache/dubbo/validation/MethodValidated.java
@@ -0,0 +1,40 @@
+/*
+ * 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.validation;
+
+import java.lang.annotation.Documented;
+import java.lang.annotation.ElementType;
+import java.lang.annotation.Retention;
+import java.lang.annotation.RetentionPolicy;
+import java.lang.annotation.Target;
+
+/**
+ * Method grouping validation.
+ * <p>
+ * Scenario: this annotation can be used on interface's method when need to check against group before invoke the method
+ * For example: <pre> @MethodValidated({Save.class, Update.class})
+ * void relatedQuery(ValidationParameter parameter);
+ * </pre>
+ * It means both Save group and Update group are needed to check when method relatedQuery is invoked.
+ * </p>
+ */
+@Target({ElementType.METHOD})
+@Retention(RetentionPolicy.RUNTIME)
+@Documented
+public @interface MethodValidated {
+    Class<?>[] value() default {};
+}
diff --git a/dubbo-spi-filter/dubbo-filter-validation/src/main/java/org/apache/dubbo/validation/Validation.java b/dubbo-spi-filter/dubbo-filter-validation/src/main/java/org/apache/dubbo/validation/Validation.java
new file mode 100644
index 0000000..73c4cd8
--- /dev/null
+++ b/dubbo-spi-filter/dubbo-filter-validation/src/main/java/org/apache/dubbo/validation/Validation.java
@@ -0,0 +1,39 @@
+/*
+ * Licensed to the Apache Software Foundation (ASF) under one or more
+ * contributor license agreements.  See the NOTICE file distributed with
+ * this work for additional information regarding copyright ownership.
+ * The ASF licenses this file to You under the Apache License, Version 2.0
+ * (the "License"); you may not use this file except in compliance with
+ * the License.  You may obtain a copy of the License at
+ *
+ *     http://www.apache.org/licenses/LICENSE-2.0
+ *
+ * Unless required by applicable law or agreed to in writing, software
+ * distributed under the License is distributed on an "AS IS" BASIS,
+ * WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied.
+ * See the License for the specific language governing permissions and
+ * limitations under the License.
+ */
+package org.apache.dubbo.validation;
+
+import org.apache.dubbo.common.URL;
+import org.apache.dubbo.common.extension.Adaptive;
+import org.apache.dubbo.common.extension.SPI;
+
+import static org.apache.dubbo.common.constants.FilterConstants.VALIDATION_KEY;
+
+/**
+ * Instance of Validation interface provide instance of {@link Validator} based on the value of <b>validation</b> attribute.
+ */
+@SPI("jvalidation")
+public interface Validation {
+
+    /**
+     * Return the instance of {@link Validator} for a given url.
+     * @param url Invocation url
+     * @return Instance of {@link Validator}
+     */
+    @Adaptive(VALIDATION_KEY)
+    Validator getValidator(URL url);
+
+}
diff --git a/dubbo-spi-filter/dubbo-filter-validation/src/main/java/org/apache/dubbo/validation/Validator.java b/dubbo-spi-filter/dubbo-filter-validation/src/main/java/org/apache/dubbo/validation/Validator.java
new file mode 100644
index 0000000..c78c62a
--- /dev/null
+++ b/dubbo-spi-filter/dubbo-filter-validation/src/main/java/org/apache/dubbo/validation/Validator.java
@@ -0,0 +1,27 @@
+/*
+ * 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.validation;
+
+/**
+ * Instance of validator class is an extension to perform validation on method input parameter before the actual method invocation.
+ *
+ */
+public interface Validator {
+
+    void validate(String methodName, Class<?>[] parameterTypes, Object[] arguments) throws Exception;
+
+}
diff --git a/dubbo-spi-filter/dubbo-filter-validation/src/main/java/org/apache/dubbo/validation/filter/ValidationFilter.java b/dubbo-spi-filter/dubbo-filter-validation/src/main/java/org/apache/dubbo/validation/filter/ValidationFilter.java
new file mode 100644
index 0000000..0df2752
--- /dev/null
+++ b/dubbo-spi-filter/dubbo-filter-validation/src/main/java/org/apache/dubbo/validation/filter/ValidationFilter.java
@@ -0,0 +1,104 @@
+/*
+ * 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.validation.filter;
+
+import org.apache.dubbo.common.extension.Activate;
+import org.apache.dubbo.common.utils.ConfigUtils;
+import org.apache.dubbo.rpc.AsyncRpcResult;
+import org.apache.dubbo.rpc.Filter;
+import org.apache.dubbo.rpc.Invocation;
+import org.apache.dubbo.rpc.Invoker;
+import org.apache.dubbo.rpc.Result;
+import org.apache.dubbo.rpc.RpcException;
+import org.apache.dubbo.validation.Validation;
+import org.apache.dubbo.validation.Validator;
+
+import javax.validation.ValidationException;
+
+import static org.apache.dubbo.common.constants.CommonConstants.CONSUMER;
+import static org.apache.dubbo.common.constants.CommonConstants.PROVIDER;
+import static org.apache.dubbo.common.constants.FilterConstants.VALIDATION_KEY;
+
+/**
+ * ValidationFilter invoke the validation by finding the right {@link Validator} instance based on the
+ * configured <b>validation</b> attribute value of invoker url before the actual method invocation.
+ *
+ * <pre>
+ *     e.g. &lt;dubbo:method name="save" validation="jvalidation" /&gt;
+ *     In the above configuration a validation has been configured of type jvalidation. On invocation of method <b>save</b>
+ *     dubbo will invoke {@link org.apache.dubbo.validation.support.jvalidation.JValidator}
+ * </pre>
+ *
+ * To add a new type of validation
+ * <pre>
+ *     e.g. &lt;dubbo:method name="save" validation="special" /&gt;
+ *     where "special" is representing a validator for special character.
+ * </pre>
+ *
+ * developer needs to do
+ * <br/>
+ * 1)Implement a SpecialValidation.java class (package name xxx.yyy.zzz) either by implementing {@link Validation} or extending {@link org.apache.dubbo.validation.support.AbstractValidation} <br/>
+ * 2)Implement a SpecialValidator.java class (package name xxx.yyy.zzz) <br/>
+ * 3)Add an entry <b>special</b>=<b>xxx.yyy.zzz.SpecialValidation</b> under <b>META-INF folders org.apache.dubbo.validation.Validation file</b>.
+ *
+ * @see Validation
+ * @see Validator
+ * @see Filter
+ * @see org.apache.dubbo.validation.support.AbstractValidation
+ */
+@Activate(group = {CONSUMER, PROVIDER}, value = VALIDATION_KEY, order = 10000)
+public class ValidationFilter implements Filter {
+
+    private Validation validation;
+
+    /**
+     * Sets the validation instance for ValidationFilter
+     * @param validation Validation instance injected by dubbo framework based on "validation" attribute value.
+     */
+    public void setValidation(Validation validation) {
+        this.validation = validation;
+    }
+
+    /**
+     * Perform the validation of before invoking the actual method based on <b>validation</b> attribute value.
+     * @param invoker    service
+     * @param invocation invocation.
+     * @return Method invocation result
+     * @throws RpcException Throws RpcException if  validation failed or any other runtime exception occurred.
+     */
+    @Override
+    public Result invoke(Invoker<?> invoker, Invocation invocation) throws RpcException {
+        if (validation != null && !invocation.getMethodName().startsWith("$")
+                && ConfigUtils.isNotEmpty(invoker.getUrl().getMethodParameter(invocation.getMethodName(), VALIDATION_KEY))) {
+            try {
+                Validator validator = validation.getValidator(invoker.getUrl());
+                if (validator != null) {
+                    validator.validate(invocation.getMethodName(), invocation.getParameterTypes(), invocation.getArguments());
+                }
+            } catch (RpcException e) {
+                throw e;
+            } catch (ValidationException e) {
+                // only use exception's message to avoid potential serialization issue
+                return AsyncRpcResult.newDefaultAsyncResult(new ValidationException(e.getMessage()), invocation);
+            } catch (Throwable t) {
+                return AsyncRpcResult.newDefaultAsyncResult(t, invocation);
+            }
+        }
+        return invoker.invoke(invocation);
+    }
+
+}
diff --git a/dubbo-spi-filter/dubbo-filter-validation/src/main/java/org/apache/dubbo/validation/support/AbstractValidation.java b/dubbo-spi-filter/dubbo-filter-validation/src/main/java/org/apache/dubbo/validation/support/AbstractValidation.java
new file mode 100644
index 0000000..a6f9c8e
--- /dev/null
+++ b/dubbo-spi-filter/dubbo-filter-validation/src/main/java/org/apache/dubbo/validation/support/AbstractValidation.java
@@ -0,0 +1,51 @@
+/*
+ * 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.validation.support;
+
+import org.apache.dubbo.common.URL;
+import org.apache.dubbo.validation.Validation;
+import org.apache.dubbo.validation.Validator;
+
+import java.util.concurrent.ConcurrentHashMap;
+import java.util.concurrent.ConcurrentMap;
+
+/**
+ * AbstractValidation is abstract class for Validation interface. It helps low level Validation implementation classes
+ * by performing common task e.g. key formation, storing instance of validation class to avoid creation of unnecessary
+ * copy of validation instance and faster execution.
+ *
+ * @see Validation
+ * @see Validator
+ */
+public abstract class AbstractValidation implements Validation {
+
+    private final ConcurrentMap<String, Validator> validators = new ConcurrentHashMap<>();
+
+    @Override
+    public Validator getValidator(URL url) {
+        String key = url.toFullString();
+        Validator validator = validators.get(key);
+        if (validator == null) {
+            validators.put(key, createValidator(url));
+            validator = validators.get(key);
+        }
+        return validator;
+    }
+
+    protected abstract Validator createValidator(URL url);
+
+}
diff --git a/dubbo-spi-filter/dubbo-filter-validation/src/main/java/org/apache/dubbo/validation/support/jvalidation/JValidation.java b/dubbo-spi-filter/dubbo-filter-validation/src/main/java/org/apache/dubbo/validation/support/jvalidation/JValidation.java
new file mode 100644
index 0000000..e8b48cf
--- /dev/null
+++ b/dubbo-spi-filter/dubbo-filter-validation/src/main/java/org/apache/dubbo/validation/support/jvalidation/JValidation.java
@@ -0,0 +1,40 @@
+/*
+ * 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.validation.support.jvalidation;
+
+import org.apache.dubbo.common.URL;
+import org.apache.dubbo.validation.Validator;
+import org.apache.dubbo.validation.support.AbstractValidation;
+
+/**
+ * Creates a new instance of {@link Validator} using input argument url.
+ * @see AbstractValidation
+ * @see Validator
+ */
+public class JValidation extends AbstractValidation {
+
+    /**
+     * Return new instance of {@link JValidator}
+     * @param url Valid URL instance
+     * @return Instance of JValidator
+     */
+    @Override
+    protected Validator createValidator(URL url) {
+        return new JValidator(url);
+    }
+
+}
\ No newline at end of file
diff --git a/dubbo-spi-filter/dubbo-filter-validation/src/main/java/org/apache/dubbo/validation/support/jvalidation/JValidator.java b/dubbo-spi-filter/dubbo-filter-validation/src/main/java/org/apache/dubbo/validation/support/jvalidation/JValidator.java
new file mode 100644
index 0000000..ea8c6db
--- /dev/null
+++ b/dubbo-spi-filter/dubbo-filter-validation/src/main/java/org/apache/dubbo/validation/support/jvalidation/JValidator.java
@@ -0,0 +1,330 @@
+/*
+ * 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.validation.support.jvalidation;
+
+import org.apache.dubbo.common.URL;
+import org.apache.dubbo.common.bytecode.ClassGenerator;
+import org.apache.dubbo.common.logger.Logger;
+import org.apache.dubbo.common.logger.LoggerFactory;
+import org.apache.dubbo.common.utils.ReflectUtils;
+import org.apache.dubbo.validation.MethodValidated;
+import org.apache.dubbo.validation.Validator;
+
+import javassist.ClassPool;
+import javassist.CtClass;
+import javassist.CtField;
+import javassist.CtNewConstructor;
+import javassist.Modifier;
+import javassist.NotFoundException;
+import javassist.bytecode.AnnotationsAttribute;
+import javassist.bytecode.ClassFile;
+import javassist.bytecode.ConstPool;
+import javassist.bytecode.annotation.ArrayMemberValue;
+import javassist.bytecode.annotation.BooleanMemberValue;
+import javassist.bytecode.annotation.ByteMemberValue;
+import javassist.bytecode.annotation.CharMemberValue;
+import javassist.bytecode.annotation.ClassMemberValue;
+import javassist.bytecode.annotation.DoubleMemberValue;
+import javassist.bytecode.annotation.EnumMemberValue;
+import javassist.bytecode.annotation.FloatMemberValue;
+import javassist.bytecode.annotation.IntegerMemberValue;
+import javassist.bytecode.annotation.LongMemberValue;
+import javassist.bytecode.annotation.MemberValue;
+import javassist.bytecode.annotation.ShortMemberValue;
+import javassist.bytecode.annotation.StringMemberValue;
+
+import javax.validation.Constraint;
+import javax.validation.ConstraintViolation;
+import javax.validation.ConstraintViolationException;
+import javax.validation.Validation;
+import javax.validation.ValidatorFactory;
+import javax.validation.groups.Default;
+import java.lang.annotation.Annotation;
+import java.lang.reflect.Array;
+import java.lang.reflect.Field;
+import java.lang.reflect.Method;
+import java.util.ArrayList;
+import java.util.Arrays;
+import java.util.Collection;
+import java.util.HashSet;
+import java.util.List;
+import java.util.Map;
+import java.util.Set;
+import java.util.concurrent.ConcurrentHashMap;
+
+/**
+ * Implementation of JValidation. JValidation is invoked if configuration validation attribute value is 'jvalidation'.
+ * <pre>
+ *     e.g. &lt;dubbo:method name="save" validation="jvalidation" /&gt;
+ * </pre>
+ */
+public class JValidator implements Validator {
+
+    private static final Logger logger = LoggerFactory.getLogger(JValidator.class);
+
+    private final Class<?> clazz;
+
+    private final Map<String, Class> methodClassMap;
+
+    private final javax.validation.Validator validator;
+
+    @SuppressWarnings({"unchecked", "rawtypes"})
+    public JValidator(URL url) {
+        this.clazz = ReflectUtils.forName(url.getServiceInterface());
+        String jvalidation = url.getParameter("jvalidation");
+        ValidatorFactory factory;
+        if (jvalidation != null && jvalidation.length() > 0) {
+            factory = Validation.byProvider((Class) ReflectUtils.forName(jvalidation)).configure().buildValidatorFactory();
+        } else {
+            factory = Validation.buildDefaultValidatorFactory();
+        }
+        this.validator = factory.getValidator();
+        this.methodClassMap = new ConcurrentHashMap<>();
+    }
+
+    private static Object getMethodParameterBean(Class<?> clazz, Method method, Object[] args) {
+        if (!hasConstraintParameter(method)) {
+            return null;
+        }
+        try {
+            String parameterClassName = generateMethodParameterClassName(clazz, method);
+            Class<?> parameterClass;
+            try {
+                parameterClass = Class.forName(parameterClassName, true, clazz.getClassLoader());
+            } catch (ClassNotFoundException e) {
+                parameterClass = generateMethodParameterClass(clazz, method, parameterClassName);
+            }
+            Object parameterBean = parameterClass.newInstance();
+            for (int i = 0; i < args.length; i++) {
+                Field field = parameterClass.getField(method.getName() + "Argument" + i);
+                field.set(parameterBean, args[i]);
+            }
+            return parameterBean;
+        } catch (Throwable e) {
+            logger.warn(e.getMessage(), e);
+            return null;
+        }
+    }
+
+    /**
+     * try to generate methodParameterClass.
+     *
+     * @param clazz interface class
+     * @param method invoke method
+     * @param parameterClassName generated parameterClassName
+     * @return Class<?> generated methodParameterClass
+     * @throws Exception
+     */
+    private static Class<?> generateMethodParameterClass(Class<?> clazz, Method method, String parameterClassName)
+        throws Exception {
+        ClassPool pool = ClassGenerator.getClassPool(clazz.getClassLoader());
+        synchronized (parameterClassName.intern()) {
+            CtClass ctClass = null;
+            try {
+                ctClass = pool.getCtClass(parameterClassName);
+            } catch (NotFoundException ignore) {
+            }
+
+            if (null == ctClass) {
+                ctClass = pool.makeClass(parameterClassName);
+                ClassFile classFile = ctClass.getClassFile();
+                classFile.setVersionToJava5();
+                ctClass.addConstructor(CtNewConstructor.defaultConstructor(pool.getCtClass(parameterClassName)));
+                // parameter fields
+                Class<?>[] parameterTypes = method.getParameterTypes();
+                Annotation[][] parameterAnnotations = method.getParameterAnnotations();
+                for (int i = 0; i < parameterTypes.length; i++) {
+                    Class<?> type = parameterTypes[i];
+                    Annotation[] annotations = parameterAnnotations[i];
+                    AnnotationsAttribute attribute = new AnnotationsAttribute(classFile.getConstPool(), AnnotationsAttribute.visibleTag);
+                    for (Annotation annotation : annotations) {
+                        if (annotation.annotationType().isAnnotationPresent(Constraint.class)) {
+                            javassist.bytecode.annotation.Annotation ja = new javassist.bytecode.annotation.Annotation(
+                                classFile.getConstPool(), pool.getCtClass(annotation.annotationType().getName()));
+                            Method[] members = annotation.annotationType().getMethods();
+                            for (Method member : members) {
+                                if (Modifier.isPublic(member.getModifiers())
+                                    && member.getParameterTypes().length == 0
+                                    && member.getDeclaringClass() == annotation.annotationType()) {
+                                    Object value = member.invoke(annotation);
+                                    if (null != value) {
+                                        MemberValue memberValue = createMemberValue(
+                                            classFile.getConstPool(), pool.get(member.getReturnType().getName()), value);
+                                        ja.addMemberValue(member.getName(), memberValue);
+                                    }
+                                }
+                            }
+                            attribute.addAnnotation(ja);
+                        }
+                    }
+                    String fieldName = method.getName() + "Argument" + i;
+                    CtField ctField = CtField.make("public " + type.getCanonicalName() + " " + fieldName + ";", pool.getCtClass(parameterClassName));
+                    ctField.getFieldInfo().addAttribute(attribute);
+                    ctClass.addField(ctField);
+                }
+                return ctClass.toClass(clazz.getClassLoader(), null);
+            } else {
+                return Class.forName(parameterClassName, true, clazz.getClassLoader());
+            }
+        }
+    }
+
+    private static String generateMethodParameterClassName(Class<?> clazz, Method method) {
+        StringBuilder builder = new StringBuilder().append(clazz.getName())
+                .append("_")
+                .append(toUpperMethoName(method.getName()))
+                .append("Parameter");
+
+        Class<?>[] parameterTypes = method.getParameterTypes();
+        for (Class<?> parameterType : parameterTypes) {
+            builder.append("_").append(parameterType.getName());
+        }
+
+        return builder.toString();
+    }
+
+    private static boolean hasConstraintParameter(Method method) {
+        Annotation[][] parameterAnnotations = method.getParameterAnnotations();
+        if (parameterAnnotations != null && parameterAnnotations.length > 0) {
+            for (Annotation[] annotations : parameterAnnotations) {
+                for (Annotation annotation : annotations) {
+                    if (annotation.annotationType().isAnnotationPresent(Constraint.class)) {
+                        return true;
+                    }
+                }
+            }
+        }
+        return false;
+    }
+
+    private static String toUpperMethoName(String methodName) {
+        return methodName.substring(0, 1).toUpperCase() + methodName.substring(1);
+    }
+
+    // Copy from javassist.bytecode.annotation.Annotation.createMemberValue(ConstPool, CtClass);
+    private static MemberValue createMemberValue(ConstPool cp, CtClass type, Object value) throws NotFoundException {
+        MemberValue memberValue = javassist.bytecode.annotation.Annotation.createMemberValue(cp, type);
+        if (memberValue instanceof BooleanMemberValue) {
+            ((BooleanMemberValue) memberValue).setValue((Boolean) value);
+        } else if (memberValue instanceof ByteMemberValue) {
+            ((ByteMemberValue) memberValue).setValue((Byte) value);
+        } else if (memberValue instanceof CharMemberValue) {
+            ((CharMemberValue) memberValue).setValue((Character) value);
+        } else if (memberValue instanceof ShortMemberValue) {
+            ((ShortMemberValue) memberValue).setValue((Short) value);
+        } else if (memberValue instanceof IntegerMemberValue) {
+            ((IntegerMemberValue) memberValue).setValue((Integer) value);
+        } else if (memberValue instanceof LongMemberValue) {
+            ((LongMemberValue) memberValue).setValue((Long) value);
+        } else if (memberValue instanceof FloatMemberValue) {
+            ((FloatMemberValue) memberValue).setValue((Float) value);
+        } else if (memberValue instanceof DoubleMemberValue) {
+            ((DoubleMemberValue) memberValue).setValue((Double) value);
+        } else if (memberValue instanceof ClassMemberValue) {
+            ((ClassMemberValue) memberValue).setValue(((Class<?>) value).getName());
+        } else if (memberValue instanceof StringMemberValue) {
+            ((StringMemberValue) memberValue).setValue((String) value);
+        } else if (memberValue instanceof EnumMemberValue) {
+            ((EnumMemberValue) memberValue).setValue(((Enum<?>) value).name());
+        }
+        /* else if (memberValue instanceof AnnotationMemberValue) */
+        else if (memberValue instanceof ArrayMemberValue) {
+            CtClass arrayType = type.getComponentType();
+            int len = Array.getLength(value);
+            MemberValue[] members = new MemberValue[len];
+            for (int i = 0; i < len; i++) {
+                members[i] = createMemberValue(cp, arrayType, Array.get(value, i));
+            }
+            ((ArrayMemberValue) memberValue).setValue(members);
+        }
+        return memberValue;
+    }
+
+    @Override
+    public void validate(String methodName, Class<?>[] parameterTypes, Object[] arguments) throws Exception {
+        List<Class<?>> groups = new ArrayList<>();
+        Class<?> methodClass = methodClass(methodName);
+        if (methodClass != null) {
+            groups.add(methodClass);
+        }
+        Set<ConstraintViolation<?>> violations = new HashSet<>();
+        Method method = clazz.getMethod(methodName, parameterTypes);
+        Class<?>[] methodClasses;
+        if (method.isAnnotationPresent(MethodValidated.class)){
+            methodClasses = method.getAnnotation(MethodValidated.class).value();
+            groups.addAll(Arrays.asList(methodClasses));
+        }
+        // add into default group
+        groups.add(0, Default.class);
+        groups.add(1, clazz);
+
+        // convert list to array
+        Class<?>[] classgroups = groups.toArray(new Class[groups.size()]);
+
+        Object parameterBean = getMethodParameterBean(clazz, method, arguments);
+        if (parameterBean != null) {
+            violations.addAll(validator.validate(parameterBean, classgroups ));
+        }
+
+        for (Object arg : arguments) {
+            validate(violations, arg, classgroups);
+        }
+
+        if (!violations.isEmpty()) {
+            logger.error("Failed to validate service: " + clazz.getName() + ", method: " + methodName + ", cause: " + violations);
+            throw new ConstraintViolationException("Failed to validate service: " + clazz.getName() + ", method: " + methodName + ", cause: " + violations, violations);
+        }
+    }
+
+    private Class methodClass(String methodName) {
+        Class<?> methodClass = null;
+        String methodClassName = clazz.getName() + "$" + toUpperMethoName(methodName);
+        Class cached = methodClassMap.get(methodClassName);
+        if (cached != null) {
+            return cached == clazz ? null : cached;
+        }
+        try {
+            methodClass = Class.forName(methodClassName, false, Thread.currentThread().getContextClassLoader());
+            methodClassMap.put(methodClassName, methodClass);
+        } catch (ClassNotFoundException e) {
+            methodClassMap.put(methodClassName, clazz);
+        }
+        return methodClass;
+    }
+
+    private void validate(Set<ConstraintViolation<?>> violations, Object arg, Class<?>... groups) {
+        if (arg != null && !ReflectUtils.isPrimitives(arg.getClass())) {
+            if (arg instanceof Object[]) {
+                for (Object item : (Object[]) arg) {
+                    validate(violations, item, groups);
+                }
+            } else if (arg instanceof Collection) {
+                for (Object item : (Collection<?>) arg) {
+                    validate(violations, item, groups);
+                }
+            } else if (arg instanceof Map) {
+                for (Map.Entry<?, ?> entry : ((Map<?, ?>) arg).entrySet()) {
+                    validate(violations, entry.getKey(), groups);
+                    validate(violations, entry.getValue(), groups);
+                }
+            } else {
+                violations.addAll(validator.validate(arg, groups));
+            }
+        }
+    }
+
+}
diff --git a/dubbo-spi-filter/dubbo-filter-validation/src/main/resources/META-INF/dubbo/internal/org.apache.dubbo.rpc.Filter b/dubbo-spi-filter/dubbo-filter-validation/src/main/resources/META-INF/dubbo/internal/org.apache.dubbo.rpc.Filter
new file mode 100644
index 0000000..65bf329
--- /dev/null
+++ b/dubbo-spi-filter/dubbo-filter-validation/src/main/resources/META-INF/dubbo/internal/org.apache.dubbo.rpc.Filter
@@ -0,0 +1 @@
+validation=org.apache.dubbo.validation.filter.ValidationFilter
\ No newline at end of file
diff --git a/dubbo-spi-filter/dubbo-filter-validation/src/main/resources/META-INF/dubbo/internal/org.apache.dubbo.validation.Validation b/dubbo-spi-filter/dubbo-filter-validation/src/main/resources/META-INF/dubbo/internal/org.apache.dubbo.validation.Validation
new file mode 100644
index 0000000..ae3dc96
--- /dev/null
+++ b/dubbo-spi-filter/dubbo-filter-validation/src/main/resources/META-INF/dubbo/internal/org.apache.dubbo.validation.Validation
@@ -0,0 +1 @@
+jvalidation=org.apache.dubbo.validation.support.jvalidation.JValidation
\ No newline at end of file
diff --git a/dubbo-spi-filter/dubbo-filter-validation/src/test/java/org/apache/dubbo/validation/filter/ValidationFilterTest.java b/dubbo-spi-filter/dubbo-filter-validation/src/test/java/org/apache/dubbo/validation/filter/ValidationFilterTest.java
new file mode 100644
index 0000000..f2efdd5
--- /dev/null
+++ b/dubbo-spi-filter/dubbo-filter-validation/src/test/java/org/apache/dubbo/validation/filter/ValidationFilterTest.java
@@ -0,0 +1,137 @@
+/*
+ * 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.validation.filter;
+
+import org.apache.dubbo.common.URL;
+import org.apache.dubbo.rpc.AppResponse;
+import org.apache.dubbo.rpc.Invoker;
+import org.apache.dubbo.rpc.Result;
+import org.apache.dubbo.rpc.RpcException;
+import org.apache.dubbo.rpc.RpcInvocation;
+import org.apache.dubbo.validation.Validation;
+import org.apache.dubbo.validation.Validator;
+
+import org.junit.jupiter.api.Assertions;
+import org.junit.jupiter.api.BeforeEach;
+import org.junit.jupiter.api.Test;
+
+import static org.hamcrest.MatcherAssert.assertThat;
+import static org.hamcrest.core.Is.is;
+import static org.mockito.BDDMockito.given;
+import static org.mockito.Mockito.mock;
+
+public class ValidationFilterTest {
+    private Invoker<?> invoker = mock(Invoker.class);
+    private Validation validation = mock(Validation.class);
+    private Validator validator = mock(Validator.class);
+    private RpcInvocation invocation = mock(RpcInvocation.class);
+
+    private ValidationFilter validationFilter;
+
+    @BeforeEach
+    public void setUp() throws Exception {
+        this.validationFilter = new ValidationFilter();
+    }
+
+    @Test
+    public void testItWithNotExistClass() throws Exception {
+        URL url = URL.valueOf("test://test:11/test?validation=true");
+
+        given(validation.getValidator(url)).willThrow(new IllegalStateException("Not found class test, cause: test"));
+        given(invoker.invoke(invocation)).willReturn(new AppResponse("success"));
+        given(invoker.getUrl()).willReturn(url);
+        given(invocation.getMethodName()).willReturn("echo1");
+        given(invocation.getParameterTypes()).willReturn(new Class<?>[]{String.class});
+        given(invocation.getArguments()).willReturn(new Object[]{"arg1"});
+
+        validationFilter.setValidation(validation);
+        Result result = validationFilter.invoke(invoker, invocation);
+
+        assertThat(result.getException().getMessage(), is("Not found class test, cause: test"));
+
+    }
+
+    @Test
+    public void testItWithExistClass() throws Exception {
+        URL url = URL.valueOf("test://test:11/test?validation=true");
+
+        given(validation.getValidator(url)).willReturn(validator);
+        given(invoker.invoke(invocation)).willReturn(new AppResponse("success"));
+        given(invoker.getUrl()).willReturn(url);
+        given(invocation.getMethodName()).willReturn("echo1");
+        given(invocation.getParameterTypes()).willReturn(new Class<?>[]{String.class});
+        given(invocation.getArguments()).willReturn(new Object[]{"arg1"});
+
+        validationFilter.setValidation(validation);
+        Result result = validationFilter.invoke(invoker, invocation);
+
+        assertThat(String.valueOf(result.getValue()), is("success"));
+    }
+
+    @Test
+    public void testItWithoutUrlParameters() throws Exception {
+        URL url = URL.valueOf("test://test:11/test");
+
+        given(validation.getValidator(url)).willReturn(validator);
+        given(invoker.invoke(invocation)).willReturn(new AppResponse("success"));
+        given(invoker.getUrl()).willReturn(url);
+        given(invocation.getMethodName()).willReturn("echo1");
+        given(invocation.getParameterTypes()).willReturn(new Class<?>[]{String.class});
+        given(invocation.getArguments()).willReturn(new Object[]{"arg1"});
+
+        validationFilter.setValidation(validation);
+        Result result = validationFilter.invoke(invoker, invocation);
+
+        assertThat(String.valueOf(result.getValue()), is("success"));
+    }
+
+    @Test
+    public void testItWhileMethodNameStartWithDollar() throws Exception {
+        URL url = URL.valueOf("test://test:11/test");
+
+        given(validation.getValidator(url)).willReturn(validator);
+        given(invoker.invoke(invocation)).willReturn(new AppResponse("success"));
+        given(invoker.getUrl()).willReturn(url);
+        given(invocation.getMethodName()).willReturn("$echo1");
+        given(invocation.getParameterTypes()).willReturn(new Class<?>[]{String.class});
+        given(invocation.getArguments()).willReturn(new Object[]{"arg1"});
+
+        validationFilter.setValidation(validation);
+        Result result = validationFilter.invoke(invoker, invocation);
+
+        assertThat(String.valueOf(result.getValue()), is("success"));
+
+    }
+
+
+    @Test
+    public void testItWhileThrowoutRpcException() throws Exception {
+        Assertions.assertThrows(RpcException.class, () -> {
+            URL url = URL.valueOf("test://test:11/test?validation=true");
+
+            given(validation.getValidator(url)).willThrow(new RpcException("rpc exception"));
+            given(invoker.invoke(invocation)).willReturn(new AppResponse("success"));
+            given(invoker.getUrl()).willReturn(url);
+            given(invocation.getMethodName()).willReturn("echo1");
+            given(invocation.getParameterTypes()).willReturn(new Class<?>[]{String.class});
+            given(invocation.getArguments()).willReturn(new Object[]{"arg1"});
+
+            validationFilter.setValidation(validation);
+            validationFilter.invoke(invoker, invocation);
+        });
+    }
+}
\ No newline at end of file
diff --git a/dubbo-spi-filter/dubbo-filter-validation/src/test/java/org/apache/dubbo/validation/support/jvalidation/JValidationTest.java b/dubbo-spi-filter/dubbo-filter-validation/src/test/java/org/apache/dubbo/validation/support/jvalidation/JValidationTest.java
new file mode 100644
index 0000000..fbace3f
--- /dev/null
+++ b/dubbo-spi-filter/dubbo-filter-validation/src/test/java/org/apache/dubbo/validation/support/jvalidation/JValidationTest.java
@@ -0,0 +1,50 @@
+/*
+ * 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.validation.support.jvalidation;
+
+import org.apache.dubbo.common.URL;
+import org.apache.dubbo.validation.Validation;
+import org.apache.dubbo.validation.Validator;
+
+import org.junit.jupiter.api.Assertions;
+import org.junit.jupiter.api.Test;
+
+import javax.validation.ValidationException;
+
+import static org.hamcrest.MatcherAssert.assertThat;
+import static org.hamcrest.core.Is.is;
+
+public class JValidationTest {
+    @Test
+    public void testReturnTypeWithInvalidValidationProvider() {
+        Assertions.assertThrows(ValidationException.class, () -> {
+            Validation jValidation = new JValidation();
+            URL url = URL.valueOf("test://test:11/org.apache.dubbo.validation.support.jvalidation.JValidation?" +
+                    "jvalidation=org.apache.dubbo.validation.Validation");
+            jValidation.getValidator(url);
+        });
+
+    }
+
+    @Test
+    public void testReturnTypeWithDefaultValidatorProvider() {
+        Validation jValidation = new JValidation();
+        URL url = URL.valueOf("test://test:11/org.apache.dubbo.validation.support.jvalidation.JValidation");
+        Validator validator = jValidation.getValidator(url);
+        assertThat(validator instanceof JValidator, is(true));
+    }
+}
\ No newline at end of file
diff --git a/dubbo-spi-filter/dubbo-filter-validation/src/test/java/org/apache/dubbo/validation/support/jvalidation/JValidatorTest.java b/dubbo-spi-filter/dubbo-filter-validation/src/test/java/org/apache/dubbo/validation/support/jvalidation/JValidatorTest.java
new file mode 100644
index 0000000..94768d2
--- /dev/null
+++ b/dubbo-spi-filter/dubbo-filter-validation/src/test/java/org/apache/dubbo/validation/support/jvalidation/JValidatorTest.java
@@ -0,0 +1,86 @@
+/*
+ * 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.validation.support.jvalidation;
+
+import org.apache.dubbo.common.URL;
+import org.apache.dubbo.validation.support.jvalidation.mock.ValidationParameter;
+
+import org.junit.jupiter.api.Assertions;
+import org.junit.jupiter.api.Test;
+
+import javax.validation.ConstraintViolationException;
+import java.util.Arrays;
+import java.util.HashMap;
+import java.util.List;
+import java.util.Map;
+
+public class JValidatorTest {
+    @Test
+    public void testItWithNonExistMethod() throws Exception {
+        Assertions.assertThrows(NoSuchMethodException.class, () -> {
+            URL url = URL.valueOf("test://test:11/org.apache.dubbo.validation.support.jvalidation.mock.JValidatorTestTarget");
+            JValidator jValidator = new JValidator(url);
+            jValidator.validate("nonExistingMethod", new Class<?>[]{String.class}, new Object[]{"arg1"});
+        });
+    }
+
+    @Test
+    public void testItWithExistMethod() throws Exception {
+        URL url = URL.valueOf("test://test:11/org.apache.dubbo.validation.support.jvalidation.mock.JValidatorTestTarget");
+        JValidator jValidator = new JValidator(url);
+        jValidator.validate("someMethod1", new Class<?>[]{String.class}, new Object[]{"anything"});
+    }
+
+    @Test
+    public void testItWhenItViolatedConstraint() throws Exception {
+        Assertions.assertThrows(ConstraintViolationException.class, () -> {
+            URL url = URL.valueOf("test://test:11/org.apache.dubbo.validation.support.jvalidation.mock.JValidatorTestTarget");
+            JValidator jValidator = new JValidator(url);
+            jValidator.validate("someMethod2", new Class<?>[]{ValidationParameter.class}, new Object[]{new ValidationParameter()});
+        });
+    }
+
+    @Test
+    public void testItWhenItMeetsConstraint() throws Exception {
+        URL url = URL.valueOf("test://test:11/org.apache.dubbo.validation.support.jvalidation.mock.JValidatorTestTarget");
+        JValidator jValidator = new JValidator(url);
+        jValidator.validate("someMethod2", new Class<?>[]{ValidationParameter.class}, new Object[]{new ValidationParameter("NotBeNull")});
+    }
+
+    @Test
+    public void testItWithArrayArg() throws Exception {
+        URL url = URL.valueOf("test://test:11/org.apache.dubbo.validation.support.jvalidation.mock.JValidatorTestTarget");
+        JValidator jValidator = new JValidator(url);
+        jValidator.validate("someMethod3", new Class<?>[]{ValidationParameter[].class}, new Object[]{new ValidationParameter[]{new ValidationParameter("parameter")}});
+    }
+
+    @Test
+    public void testItWithCollectionArg() throws Exception {
+        URL url = URL.valueOf("test://test:11/org.apache.dubbo.validation.support.jvalidation.mock.JValidatorTestTarget");
+        JValidator jValidator = new JValidator(url);
+        jValidator.validate("someMethod4", new Class<?>[]{List.class}, new Object[]{Arrays.asList("parameter")});
+    }
+
+    @Test
+    public void testItWithMapArg() throws Exception {
+        URL url = URL.valueOf("test://test:11/org.apache.dubbo.validation.support.jvalidation.mock.JValidatorTestTarget");
+        JValidator jValidator = new JValidator(url);
+        Map<String, String> map = new HashMap<>();
+        map.put("key", "value");
+        jValidator.validate("someMethod5", new Class<?>[]{Map.class}, new Object[]{map});
+    }
+}
\ No newline at end of file
diff --git a/dubbo-spi-filter/dubbo-filter-validation/src/test/java/org/apache/dubbo/validation/support/jvalidation/mock/JValidatorTestTarget.java b/dubbo-spi-filter/dubbo-filter-validation/src/test/java/org/apache/dubbo/validation/support/jvalidation/mock/JValidatorTestTarget.java
new file mode 100644
index 0000000..f65eb05
--- /dev/null
+++ b/dubbo-spi-filter/dubbo-filter-validation/src/test/java/org/apache/dubbo/validation/support/jvalidation/mock/JValidatorTestTarget.java
@@ -0,0 +1,41 @@
+/*
+ * 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.validation.support.jvalidation.mock;
+
+import org.apache.dubbo.validation.MethodValidated;
+
+import javax.validation.constraints.NotNull;
+import java.util.List;
+import java.util.Map;
+
+public interface JValidatorTestTarget {
+    @MethodValidated
+    void someMethod1(String anything);
+
+    @MethodValidated(Test2.class)
+    void someMethod2(@NotNull ValidationParameter validationParameter);
+
+    void someMethod3(ValidationParameter[] parameters);
+
+    void someMethod4(List<String> strings);
+
+    void someMethod5(Map<String, String> map);
+
+    @interface Test2 {
+    }
+
+}
diff --git a/dubbo-spi-filter/dubbo-filter-validation/src/test/java/org/apache/dubbo/validation/support/jvalidation/mock/ValidationParameter.java b/dubbo-spi-filter/dubbo-filter-validation/src/test/java/org/apache/dubbo/validation/support/jvalidation/mock/ValidationParameter.java
new file mode 100644
index 0000000..0b54a04
--- /dev/null
+++ b/dubbo-spi-filter/dubbo-filter-validation/src/test/java/org/apache/dubbo/validation/support/jvalidation/mock/ValidationParameter.java
@@ -0,0 +1,31 @@
+/*
+ * 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.validation.support.jvalidation.mock;
+
+import javax.validation.constraints.NotNull;
+
+public class ValidationParameter {
+    @NotNull
+    private String parameter;
+
+    public ValidationParameter() {
+    }
+
+    public ValidationParameter(String parameter) {
+        this.parameter = parameter;
+    }
+}
diff --git a/dubbo-spi-filter/pom.xml b/dubbo-spi-filter/pom.xml
new file mode 100644
index 0000000..248be53
--- /dev/null
+++ b/dubbo-spi-filter/pom.xml
@@ -0,0 +1,35 @@
+<!--
+  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.
+  -->
+<project xmlns="http://maven.apache.org/POM/4.0.0" xmlns:xsi="http://www.w3.org/2001/XMLSchema-instance" xsi:schemaLocation="http://maven.apache.org/POM/4.0.0 http://maven.apache.org/maven-v4_0_0.xsd">
+    <modelVersion>4.0.0</modelVersion>
+    <parent>
+        <groupId>org.apache.dubbo.spi</groupId>
+        <artifactId>dubbo-spi-extensions</artifactId>
+        <version>${revision}</version>
+    </parent>
+    <artifactId>dubbo-spi-filter</artifactId>
+    <packaging>pom</packaging>
+    <name>${project.artifactId}</name>
+    <description>The filter module of dubbo project</description>
+    <properties>
+        <skip_maven_deploy>true</skip_maven_deploy>
+    </properties>
+    <modules>
+        <module>dubbo-filter-cache</module>
+        <module>dubbo-filter-validation</module>
+    </modules>
+</project>
diff --git a/dubbo-spi-metadata/dubbo-metadata-report-consul/pom.xml b/dubbo-spi-metadata/dubbo-metadata-report-consul/pom.xml
new file mode 100644
index 0000000..7a76f17
--- /dev/null
+++ b/dubbo-spi-metadata/dubbo-metadata-report-consul/pom.xml
@@ -0,0 +1,41 @@
+<?xml version="1.0" encoding="UTF-8"?>
+<!--
+  ~ 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.
+  -->
+
+<project xmlns="http://maven.apache.org/POM/4.0.0" xmlns:xsi="http://www.w3.org/2001/XMLSchema-instance" xsi:schemaLocation="http://maven.apache.org/POM/4.0.0 http://maven.apache.org/xsd/maven-4.0.0.xsd">
+    <parent>
+        <groupId>org.apache.dubbo</groupId>
+        <artifactId>dubbo-metadata</artifactId>
+        <version>2.7.7-SNAPSHOT</version>
+    </parent>
+    <modelVersion>4.0.0</modelVersion>
+
+    <artifactId>dubbo-metadata-report-consul</artifactId>
+
+    <dependencies>
+        <dependency>
+            <groupId>org.apache.dubbo</groupId>
+            <artifactId>dubbo-metadata-api</artifactId>
+            <version>${project.parent.version}</version>
+        </dependency>
+        <dependency>
+            <groupId>com.ecwid.consul</groupId>
+            <artifactId>consul-api</artifactId>
+        </dependency>
+    </dependencies>
+
+</project>
diff --git a/dubbo-spi-metadata/dubbo-metadata-report-consul/src/main/java/org/apache/dubbo/metadata/store/consul/ConsulMetadataReport.java b/dubbo-spi-metadata/dubbo-metadata-report-consul/src/main/java/org/apache/dubbo/metadata/store/consul/ConsulMetadataReport.java
new file mode 100644
index 0000000..c1e0a30
--- /dev/null
+++ b/dubbo-spi-metadata/dubbo-metadata-report-consul/src/main/java/org/apache/dubbo/metadata/store/consul/ConsulMetadataReport.java
@@ -0,0 +1,135 @@
+/*
+ * 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.metadata.store.consul;
+
+import org.apache.dubbo.common.URL;
+import org.apache.dubbo.common.logger.Logger;
+import org.apache.dubbo.common.logger.LoggerFactory;
+import org.apache.dubbo.common.utils.StringUtils;
+import org.apache.dubbo.metadata.report.identifier.BaseMetadataIdentifier;
+import org.apache.dubbo.metadata.report.identifier.KeyTypeEnum;
+import org.apache.dubbo.metadata.report.identifier.MetadataIdentifier;
+import org.apache.dubbo.metadata.report.identifier.ServiceMetadataIdentifier;
+import org.apache.dubbo.metadata.report.identifier.SubscriberMetadataIdentifier;
+import org.apache.dubbo.metadata.report.support.AbstractMetadataReport;
+import org.apache.dubbo.rpc.RpcException;
+
+import com.ecwid.consul.v1.ConsulClient;
+import com.ecwid.consul.v1.Response;
+import com.ecwid.consul.v1.kv.model.GetValue;
+
+import java.util.ArrayList;
+import java.util.Arrays;
+import java.util.Collections;
+import java.util.List;
+
+/**
+ * metadata report impl for consul
+ */
+public class ConsulMetadataReport extends AbstractMetadataReport {
+    private static final Logger logger = LoggerFactory.getLogger(ConsulMetadataReport.class);
+    private static final int DEFAULT_PORT = 8500;
+
+    private ConsulClient client;
+
+    public ConsulMetadataReport(URL url) {
+        super(url);
+
+        String host = url.getHost();
+        int port = url.getPort() != 0 ? url.getPort() : DEFAULT_PORT;
+        client = new ConsulClient(host, port);
+    }
+
+    @Override
+    protected void doStoreProviderMetadata(MetadataIdentifier providerMetadataIdentifier, String serviceDefinitions) {
+        this.storeMetadata(providerMetadataIdentifier, serviceDefinitions);
+    }
+
+    @Override
+    protected void doStoreConsumerMetadata(MetadataIdentifier consumerMetadataIdentifier, String value) {
+        this.storeMetadata(consumerMetadataIdentifier, value);
+    }
+
+    @Override
+    protected void doSaveMetadata(ServiceMetadataIdentifier serviceMetadataIdentifier, URL url) {
+        this.storeMetadata(serviceMetadataIdentifier, URL.encode(url.toFullString()));
+    }
+
+    @Override
+    protected void doRemoveMetadata(ServiceMetadataIdentifier serviceMetadataIdentifier) {
+        this.deleteMetadata(serviceMetadataIdentifier);
+    }
+
+    @Override
+    protected List<String> doGetExportedURLs(ServiceMetadataIdentifier metadataIdentifier) {
+        //todo encode and decode
+        String content = getMetadata(metadataIdentifier);
+        if (StringUtils.isEmpty(content)) {
+            return Collections.emptyList();
+        }
+        return new ArrayList<String>(Arrays.asList(URL.decode(content)));
+    }
+
+    @Override
+    protected void doSaveSubscriberData(SubscriberMetadataIdentifier subscriberMetadataIdentifier, String urlListStr) {
+        this.storeMetadata(subscriberMetadataIdentifier, urlListStr);
+    }
+
+    @Override
+    protected String doGetSubscribedURLs(SubscriberMetadataIdentifier subscriberMetadataIdentifier) {
+        return getMetadata(subscriberMetadataIdentifier);
+    }
+
+    private void storeMetadata(BaseMetadataIdentifier identifier, String v) {
+        try {
+            client.setKVValue(identifier.getUniqueKey(KeyTypeEnum.UNIQUE_KEY), v);
+        } catch (Throwable t) {
+            logger.error("Failed to put " + identifier + " to consul " + v + ", cause: " + t.getMessage(), t);
+            throw new RpcException("Failed to put " + identifier + " to consul " + v + ", cause: " + t.getMessage(), t);
+        }
+    }
+
+    private void deleteMetadata(BaseMetadataIdentifier identifier) {
+        try {
+            client.deleteKVValue(identifier.getUniqueKey(KeyTypeEnum.UNIQUE_KEY));
+        } catch (Throwable t) {
+            logger.error("Failed to delete " + identifier + " from consul , cause: " + t.getMessage(), t);
+            throw new RpcException("Failed to delete " + identifier + " from consul , cause: " + t.getMessage(), t);
+        }
+    }
+
+    private String getMetadata(BaseMetadataIdentifier identifier) {
+        try {
+            Response<GetValue> value = client.getKVValue(identifier.getUniqueKey(KeyTypeEnum.UNIQUE_KEY));
+            //FIXME CHECK
+            if (value != null && value.getValue() != null) {
+                //todo check decode value and value diff
+                return value.getValue().getValue();
+            }
+            return null;
+        } catch (Throwable t) {
+            logger.error("Failed to get " + identifier + " from consul , cause: " + t.getMessage(), t);
+            throw new RpcException("Failed to get " + identifier + " from consul , cause: " + t.getMessage(), t);
+        }
+    }
+
+    @Override
+    public String getServiceDefinition(MetadataIdentifier metadataIdentifier) {
+        return getMetadata(metadataIdentifier);
+    }
+}
diff --git a/dubbo-spi-metadata/dubbo-metadata-report-consul/src/main/java/org/apache/dubbo/metadata/store/consul/ConsulMetadataReportFactory.java b/dubbo-spi-metadata/dubbo-metadata-report-consul/src/main/java/org/apache/dubbo/metadata/store/consul/ConsulMetadataReportFactory.java
new file mode 100644
index 0000000..1d1f5bb
--- /dev/null
+++ b/dubbo-spi-metadata/dubbo-metadata-report-consul/src/main/java/org/apache/dubbo/metadata/store/consul/ConsulMetadataReportFactory.java
@@ -0,0 +1,32 @@
+/*
+ * 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.metadata.store.consul;
+
+import org.apache.dubbo.common.URL;
+import org.apache.dubbo.metadata.report.MetadataReport;
+import org.apache.dubbo.metadata.report.support.AbstractMetadataReportFactory;
+
+/**
+ * metadata report factory impl for consul
+ */
+public class ConsulMetadataReportFactory extends AbstractMetadataReportFactory {
+    @Override
+    protected MetadataReport createMetadataReport(URL url) {
+        return new ConsulMetadataReport(url);
+    }
+}
diff --git a/dubbo-spi-metadata/dubbo-metadata-report-consul/src/main/resources/META-INF/dubbo/internal/org.apache.dubbo.metadata.report.MetadataReportFactory b/dubbo-spi-metadata/dubbo-metadata-report-consul/src/main/resources/META-INF/dubbo/internal/org.apache.dubbo.metadata.report.MetadataReportFactory
new file mode 100644
index 0000000..1f27535
--- /dev/null
+++ b/dubbo-spi-metadata/dubbo-metadata-report-consul/src/main/resources/META-INF/dubbo/internal/org.apache.dubbo.metadata.report.MetadataReportFactory
@@ -0,0 +1 @@
+consul=org.apache.dubbo.metadata.store.consul.ConsulMetadataReportFactory
diff --git a/dubbo-spi-metadata/dubbo-metadata-report-etcd/pom.xml b/dubbo-spi-metadata/dubbo-metadata-report-etcd/pom.xml
new file mode 100644
index 0000000..9199ca5
--- /dev/null
+++ b/dubbo-spi-metadata/dubbo-metadata-report-etcd/pom.xml
@@ -0,0 +1,69 @@
+<?xml version="1.0" encoding="UTF-8"?>
+<!--
+  ~ 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.
+  -->
+
+<project xmlns="http://maven.apache.org/POM/4.0.0"
+         xmlns:xsi="http://www.w3.org/2001/XMLSchema-instance"
+         xsi:schemaLocation="http://maven.apache.org/POM/4.0.0 http://maven.apache.org/xsd/maven-4.0.0.xsd">
+    <parent>
+        <groupId>org.apache.dubbo</groupId>
+        <artifactId>dubbo-metadata</artifactId>
+        <version>2.7.7-SNAPSHOT</version>
+    </parent>
+    <modelVersion>4.0.0</modelVersion>
+
+    <artifactId>dubbo-metadata-report-etcd</artifactId>
+
+    <properties>
+        <skipIntegrationTests>true</skipIntegrationTests>
+    </properties>
+
+    <dependencies>
+        <dependency>
+            <groupId>org.apache.dubbo</groupId>
+            <artifactId>dubbo-metadata-api</artifactId>
+            <version>${project.parent.version}</version>
+        </dependency>
+        <dependency>
+            <groupId>org.apache.dubbo</groupId>
+            <artifactId>dubbo-remoting-etcd3</artifactId>
+            <version>${project.parent.version}</version>
+        </dependency>
+        <dependency>
+            <groupId>io.etcd</groupId>
+            <artifactId>jetcd-launcher</artifactId>
+            <scope>test</scope>
+        </dependency>
+        <dependency>
+            <groupId>org.testcontainers</groupId>
+            <artifactId>testcontainers</artifactId>
+            <scope>test</scope>
+        </dependency>
+    </dependencies>
+
+    <build>
+        <plugins>
+            <plugin>
+                <groupId>org.apache.maven.plugins</groupId>
+                <artifactId>maven-surefire-plugin</artifactId>
+                <configuration>
+                    <skipTests>${skipIntegrationTests}</skipTests>
+                </configuration>
+            </plugin>
+        </plugins>
+    </build>
+</project>
diff --git a/dubbo-spi-metadata/dubbo-metadata-report-etcd/src/main/java/org/apache/dubbo/metadata/store/etcd/EtcdMetadataReport.java b/dubbo-spi-metadata/dubbo-metadata-report-etcd/src/main/java/org/apache/dubbo/metadata/store/etcd/EtcdMetadataReport.java
new file mode 100644
index 0000000..a80c6e8
--- /dev/null
+++ b/dubbo-spi-metadata/dubbo-metadata-report-etcd/src/main/java/org/apache/dubbo/metadata/store/etcd/EtcdMetadataReport.java
@@ -0,0 +1,150 @@
+/*
+ * 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.
+ */
+
+/*
+ * 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.metadata.store.etcd;
+
+import org.apache.dubbo.common.URL;
+import org.apache.dubbo.common.logger.Logger;
+import org.apache.dubbo.common.logger.LoggerFactory;
+import org.apache.dubbo.common.utils.StringUtils;
+import org.apache.dubbo.metadata.report.identifier.BaseMetadataIdentifier;
+import org.apache.dubbo.metadata.report.identifier.KeyTypeEnum;
+import org.apache.dubbo.metadata.report.identifier.MetadataIdentifier;
+import org.apache.dubbo.metadata.report.identifier.ServiceMetadataIdentifier;
+import org.apache.dubbo.metadata.report.identifier.SubscriberMetadataIdentifier;
+import org.apache.dubbo.metadata.report.support.AbstractMetadataReport;
+import org.apache.dubbo.remoting.etcd.jetcd.JEtcdClient;
+
+import java.util.ArrayList;
+import java.util.Arrays;
+import java.util.Collections;
+import java.util.List;
+
+import static org.apache.dubbo.common.constants.CommonConstants.GROUP_KEY;
+import static org.apache.dubbo.common.constants.CommonConstants.PATH_SEPARATOR;
+
+/**
+ * Report Metadata to Etcd
+ */
+public class EtcdMetadataReport extends AbstractMetadataReport {
+
+    private final static Logger logger = LoggerFactory.getLogger(EtcdMetadataReport.class);
+
+    private final String root;
+
+    /**
+     * The etcd client
+     */
+    private final JEtcdClient etcdClient;
+
+    public EtcdMetadataReport(URL url) {
+        super(url);
+        if (url.isAnyHost()) {
+            throw new IllegalStateException("registry address == null");
+        }
+        String group = url.getParameter(GROUP_KEY, DEFAULT_ROOT);
+        if (!group.startsWith(PATH_SEPARATOR)) {
+            group = PATH_SEPARATOR + group;
+        }
+        this.root = group;
+        etcdClient = new JEtcdClient(url);
+    }
+
+    @Override
+    protected void doStoreProviderMetadata(MetadataIdentifier providerMetadataIdentifier, String serviceDefinitions) {
+        storeMetadata(providerMetadataIdentifier, serviceDefinitions);
+    }
+
+    @Override
+    protected void doStoreConsumerMetadata(MetadataIdentifier consumerMetadataIdentifier, String value) {
+        storeMetadata(consumerMetadataIdentifier, value);
+    }
+
+    @Override
+    protected void doSaveMetadata(ServiceMetadataIdentifier serviceMetadataIdentifier, URL url) {
+        String key = getNodeKey(serviceMetadataIdentifier);
+        if (!etcdClient.put(key, URL.encode(url.toFullString()))) {
+            logger.error("Failed to put " + serviceMetadataIdentifier + " to etcd, value: " + url);
+        }
+    }
+
+    @Override
+    protected void doRemoveMetadata(ServiceMetadataIdentifier serviceMetadataIdentifier) {
+        etcdClient.delete(getNodeKey(serviceMetadataIdentifier));
+    }
+
+    @Override
+    protected List<String> doGetExportedURLs(ServiceMetadataIdentifier metadataIdentifier) {
+        String content = etcdClient.getKVValue(getNodeKey(metadataIdentifier));
+        if (StringUtils.isEmpty(content)) {
+            return Collections.emptyList();
+        }
+        return new ArrayList<String>(Arrays.asList(URL.decode(content)));
+    }
+
+    @Override
+    protected void doSaveSubscriberData(SubscriberMetadataIdentifier subscriberMetadataIdentifier, String urlListStr) {
+        String key = getNodeKey(subscriberMetadataIdentifier);
+        if (!etcdClient.put(key, urlListStr)) {
+            logger.error("Failed to put " + subscriberMetadataIdentifier + " to etcd, value: " + urlListStr);
+        }
+    }
+
+    @Override
+    protected String doGetSubscribedURLs(SubscriberMetadataIdentifier subscriberMetadataIdentifier) {
+        return etcdClient.getKVValue(getNodeKey(subscriberMetadataIdentifier));
+    }
+
+    @Override
+    public String getServiceDefinition(MetadataIdentifier metadataIdentifier) {
+        return etcdClient.getKVValue(getNodeKey(metadataIdentifier));
+    }
+
+    private void storeMetadata(MetadataIdentifier identifier, String v) {
+        String key = getNodeKey(identifier);
+        if (!etcdClient.put(key, v)) {
+            logger.error("Failed to put " + identifier + " to etcd, value: " + v);
+        }
+    }
+
+    String getNodeKey(BaseMetadataIdentifier identifier) {
+        return toRootDir() + identifier.getUniqueKey(KeyTypeEnum.PATH);
+    }
+
+    String toRootDir() {
+        if (root.equals(PATH_SEPARATOR)) {
+            return root;
+        }
+        return root + PATH_SEPARATOR;
+    }
+}
diff --git a/dubbo-spi-metadata/dubbo-metadata-report-etcd/src/main/java/org/apache/dubbo/metadata/store/etcd/EtcdMetadataReportFactory.java b/dubbo-spi-metadata/dubbo-metadata-report-etcd/src/main/java/org/apache/dubbo/metadata/store/etcd/EtcdMetadataReportFactory.java
new file mode 100644
index 0000000..3bb9e92
--- /dev/null
+++ b/dubbo-spi-metadata/dubbo-metadata-report-etcd/src/main/java/org/apache/dubbo/metadata/store/etcd/EtcdMetadataReportFactory.java
@@ -0,0 +1,50 @@
+/*
+ * 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.
+ */
+
+/*
+ * 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.metadata.store.etcd;
+
+import org.apache.dubbo.common.URL;
+import org.apache.dubbo.metadata.report.MetadataReport;
+import org.apache.dubbo.metadata.report.support.AbstractMetadataReportFactory;
+
+/**
+ * MetadataReportFactory to create an Etcd based {@link MetadataReport}.
+ */
+public class EtcdMetadataReportFactory extends AbstractMetadataReportFactory {
+
+    @Override
+    public MetadataReport createMetadataReport(URL url) {
+        return new EtcdMetadataReport(url);
+    }
+
+}
diff --git a/dubbo-spi-metadata/dubbo-metadata-report-etcd/src/main/resources/META-INF/dubbo/internal/org.apache.dubbo.metadata.report.MetadataReportFactory b/dubbo-spi-metadata/dubbo-metadata-report-etcd/src/main/resources/META-INF/dubbo/internal/org.apache.dubbo.metadata.report.MetadataReportFactory
new file mode 100644
index 0000000..9a3c98c
--- /dev/null
+++ b/dubbo-spi-metadata/dubbo-metadata-report-etcd/src/main/resources/META-INF/dubbo/internal/org.apache.dubbo.metadata.report.MetadataReportFactory
@@ -0,0 +1 @@
+etcd=org.apache.dubbo.metadata.store.etcd.EtcdMetadataReportFactory
diff --git a/dubbo-spi-metadata/dubbo-metadata-report-etcd/src/test/java/org/apache/dubbo/metadata/store/etcd/EtcdMetadata4TstService.java b/dubbo-spi-metadata/dubbo-metadata-report-etcd/src/test/java/org/apache/dubbo/metadata/store/etcd/EtcdMetadata4TstService.java
new file mode 100644
index 0000000..1de21ce
--- /dev/null
+++ b/dubbo-spi-metadata/dubbo-metadata-report-etcd/src/test/java/org/apache/dubbo/metadata/store/etcd/EtcdMetadata4TstService.java
@@ -0,0 +1,28 @@
+/*
+ * 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.metadata.store.etcd;
+
+/**
+ * Test interface for Etcd metadata report
+ */
+public interface EtcdMetadata4TstService {
+
+    int getCounter();
+
+    void printResult(String var);
+}
diff --git a/dubbo-spi-metadata/dubbo-metadata-report-etcd/src/test/java/org/apache/dubbo/metadata/store/etcd/EtcdMetadataReportTest.java b/dubbo-spi-metadata/dubbo-metadata-report-etcd/src/test/java/org/apache/dubbo/metadata/store/etcd/EtcdMetadataReportTest.java
new file mode 100644
index 0000000..2d2efd5
--- /dev/null
+++ b/dubbo-spi-metadata/dubbo-metadata-report-etcd/src/test/java/org/apache/dubbo/metadata/store/etcd/EtcdMetadataReportTest.java
@@ -0,0 +1,259 @@
+/*
+ * 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.metadata.store.etcd;
+
+import org.apache.dubbo.common.URL;
+import org.apache.dubbo.common.utils.NetUtils;
+import org.apache.dubbo.metadata.definition.ServiceDefinitionBuilder;
+import org.apache.dubbo.metadata.definition.model.FullServiceDefinition;
+import org.apache.dubbo.metadata.report.identifier.MetadataIdentifier;
+import org.apache.dubbo.metadata.report.identifier.ServiceMetadataIdentifier;
+import org.apache.dubbo.metadata.report.identifier.SubscriberMetadataIdentifier;
+
+import com.google.gson.Gson;
+import io.etcd.jetcd.ByteSequence;
+import io.etcd.jetcd.Client;
+import io.etcd.jetcd.kv.GetResponse;
+import io.etcd.jetcd.launcher.EtcdCluster;
+import io.etcd.jetcd.launcher.EtcdClusterFactory;
+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 java.net.URI;
+import java.nio.charset.StandardCharsets;
+import java.util.Arrays;
+import java.util.HashMap;
+import java.util.List;
+import java.util.Map;
+import java.util.concurrent.CompletableFuture;
+import java.util.concurrent.ExecutionException;
+
+import static org.apache.dubbo.common.constants.CommonConstants.CONSUMER_SIDE;
+import static org.apache.dubbo.common.constants.CommonConstants.PROVIDER_SIDE;
+
+/**
+ * Unit test for etcd metadata report
+ */
+public class EtcdMetadataReportTest {
+
+    private static final String TEST_SERVICE = "org.apache.dubbo.metadata.store.etcd.EtcdMetadata4TstService";
+
+    private EtcdCluster etcdCluster = EtcdClusterFactory.buildCluster(getClass().getSimpleName(), 1, false, false);
+    private Client etcdClientForTest;
+    private EtcdMetadataReport etcdMetadataReport;
+    private URL registryUrl;
+    private EtcdMetadataReportFactory etcdMetadataReportFactory;
+
+    @BeforeEach
+    public void setUp() {
+        etcdCluster.start();
+        etcdClientForTest = Client.builder().endpoints(etcdCluster.getClientEndpoints()).build();
+        List<URI> clientEndPoints = etcdCluster.getClientEndpoints();
+        this.registryUrl = URL.valueOf("etcd://" + clientEndPoints.get(0).getHost() + ":" + clientEndPoints.get(0).getPort());
+        etcdMetadataReportFactory = new EtcdMetadataReportFactory();
+        this.etcdMetadataReport = (EtcdMetadataReport) etcdMetadataReportFactory.createMetadataReport(registryUrl);
+    }
+
+    @AfterEach
+    public void tearDown() throws Exception {
+        etcdCluster.close();
+    }
+
+    @Test
+    public void testStoreProvider() throws Exception {
+        String version = "1.0.0";
+        String group = null;
+        String application = "etcd-metdata-report-test";
+
+        String r = etcdMetadataReport.getServiceDefinition(new MetadataIdentifier(TEST_SERVICE, version, group, "provider", application));
+        Assertions.assertNull(r);
+        MetadataIdentifier providerIdentifier =
+                storeProvider(etcdMetadataReport, TEST_SERVICE, version, group, application);
+
+        CompletableFuture<GetResponse> response = etcdClientForTest.getKVClient().get(ByteSequence.from(
+                etcdMetadataReport.getNodeKey(providerIdentifier), StandardCharsets.UTF_8));
+        String fileContent = response.get().getKvs().get(0).getValue().toString(StandardCharsets.UTF_8);
+        Assertions.assertNotNull(fileContent);
+
+        Gson gson = new Gson();
+        FullServiceDefinition fullServiceDefinition = gson.fromJson(fileContent, FullServiceDefinition.class);
+        Assertions.assertEquals(fullServiceDefinition.getParameters().get("paramTest"), "etcdTest");
+
+        r = etcdMetadataReport.getServiceDefinition(new MetadataIdentifier(TEST_SERVICE, version, group, "provider", application));
+        Assertions.assertNotNull(r);
+    }
+
+    @Test
+    public void testStoreConsumer() throws Exception {
+        String version = "1.0.0";
+        String group = null;
+        String application = "etc-metadata-report-consumer-test";
+        MetadataIdentifier consumerIdentifier = storeConsumer(etcdMetadataReport, TEST_SERVICE, version, group, application);
+
+        CompletableFuture<GetResponse> response = etcdClientForTest.getKVClient().get(ByteSequence.from(
+                etcdMetadataReport.getNodeKey(consumerIdentifier), StandardCharsets.UTF_8));
+        String fileContent = response.get().getKvs().get(0).getValue().toString(StandardCharsets.UTF_8);
+        Assertions.assertNotNull(fileContent);
+        Assertions.assertEquals(fileContent, "{\"paramConsumerTest\":\"etcdConsumer\"}");
+    }
+
+    @Test
+    public void testDoSaveMetadata() throws ExecutionException, InterruptedException {
+        String version = "1.0.0";
+        String group = null;
+        String application = "etc-metadata-report-consumer-test";
+        String revision = "90980";
+        String protocol = "xxx";
+        URL url = generateURL(TEST_SERVICE, version, group, application);
+        ServiceMetadataIdentifier serviceMetadataIdentifier = new ServiceMetadataIdentifier(TEST_SERVICE, version,
+                group, "provider", revision, protocol);
+        etcdMetadataReport.doSaveMetadata(serviceMetadataIdentifier, url);
+
+        CompletableFuture<GetResponse> response = etcdClientForTest.getKVClient().get(ByteSequence.from(
+                etcdMetadataReport.getNodeKey(serviceMetadataIdentifier), StandardCharsets.UTF_8));
+        String fileContent = response.get().getKvs().get(0).getValue().toString(StandardCharsets.UTF_8);
+        Assertions.assertNotNull(fileContent);
+
+        Assertions.assertEquals(fileContent, URL.encode(url.toFullString()));
+    }
+
+    @Test
+    public void testDoRemoveMetadata() throws ExecutionException, InterruptedException {
+        String version = "1.0.0";
+        String group = null;
+        String application = "etc-metadata-report-consumer-test";
+        String revision = "90980";
+        String protocol = "xxx";
+        URL url = generateURL(TEST_SERVICE, version, group, application);
+        ServiceMetadataIdentifier serviceMetadataIdentifier = new ServiceMetadataIdentifier(TEST_SERVICE, version,
+                group, "provider", revision, protocol);
+        etcdMetadataReport.doSaveMetadata(serviceMetadataIdentifier, url);
+        CompletableFuture<GetResponse> response = etcdClientForTest.getKVClient().get(ByteSequence.from(
+                etcdMetadataReport.getNodeKey(serviceMetadataIdentifier), StandardCharsets.UTF_8));
+        String fileContent = response.get().getKvs().get(0).getValue().toString(StandardCharsets.UTF_8);
+        Assertions.assertNotNull(fileContent);
+
+
+        etcdMetadataReport.doRemoveMetadata(serviceMetadataIdentifier);
+
+        response = etcdClientForTest.getKVClient().get(ByteSequence.from(
+                etcdMetadataReport.getNodeKey(serviceMetadataIdentifier), StandardCharsets.UTF_8));
+        Assertions.assertTrue(response.get().getKvs().isEmpty());
+    }
+
+    @Test
+    public void testDoGetExportedURLs() throws ExecutionException, InterruptedException {
+        String version = "1.0.0";
+        String group = null;
+        String application = "etc-metadata-report-consumer-test";
+        String revision = "90980";
+        String protocol = "xxx";
+        URL url = generateURL(TEST_SERVICE, version, group, application);
+        ServiceMetadataIdentifier serviceMetadataIdentifier = new ServiceMetadataIdentifier(TEST_SERVICE, version,
+                group, "provider", revision, protocol);
+        etcdMetadataReport.doSaveMetadata(serviceMetadataIdentifier, url);
+
+        List<String> r = etcdMetadataReport.doGetExportedURLs(serviceMetadataIdentifier);
+        Assertions.assertTrue(r.size() == 1);
+
+        String fileContent = r.get(0);
+        Assertions.assertNotNull(fileContent);
+
+        Assertions.assertEquals(fileContent, url.toFullString());
+    }
+
+    @Test
+    public void testDoSaveSubscriberData() throws ExecutionException, InterruptedException {
+        String version = "1.0.0";
+        String group = null;
+        String application = "etc-metadata-report-consumer-test";
+        String revision = "90980";
+        String protocol = "xxx";
+        URL url = generateURL(TEST_SERVICE, version, group, application);
+        SubscriberMetadataIdentifier subscriberMetadataIdentifier = new SubscriberMetadataIdentifier(application, revision);
+        Gson gson = new Gson();
+        String r = gson.toJson(Arrays.asList(url));
+        etcdMetadataReport.doSaveSubscriberData(subscriberMetadataIdentifier, r);
+
+        CompletableFuture<GetResponse> response = etcdClientForTest.getKVClient().get(ByteSequence.from(
+                etcdMetadataReport.getNodeKey(subscriberMetadataIdentifier), StandardCharsets.UTF_8));
+        String fileContent = response.get().getKvs().get(0).getValue().toString(StandardCharsets.UTF_8);
+        Assertions.assertNotNull(fileContent);
+
+        Assertions.assertEquals(fileContent, r);
+    }
+
+    @Test
+    public void testDoGetSubscribedURLs() throws ExecutionException, InterruptedException {
+        String version = "1.0.0";
+        String group = null;
+        String application = "etc-metadata-report-consumer-test";
+        String revision = "90980";
+        String protocol = "xxx";
+        URL url = generateURL(TEST_SERVICE, version, group, application);
+        SubscriberMetadataIdentifier subscriberMetadataIdentifier = new SubscriberMetadataIdentifier(application, revision);
+        Gson gson = new Gson();
+        String r = gson.toJson(Arrays.asList(url));
+        etcdMetadataReport.doSaveSubscriberData(subscriberMetadataIdentifier, r);
+
+        CompletableFuture<GetResponse> response = etcdClientForTest.getKVClient().get(ByteSequence.from(
+                etcdMetadataReport.getNodeKey(subscriberMetadataIdentifier), StandardCharsets.UTF_8));
+        String fileContent = etcdMetadataReport.doGetSubscribedURLs(subscriberMetadataIdentifier);
+        Assertions.assertNotNull(fileContent);
+
+        Assertions.assertEquals(fileContent, r);
+    }
+
+    private MetadataIdentifier storeProvider(EtcdMetadataReport etcdMetadataReport, String interfaceName, String version,
+                                             String group, String application)
+            throws ClassNotFoundException, InterruptedException {
+        URL url = URL.valueOf("xxx://" + NetUtils.getLocalAddress().getHostName() + ":4444/" + interfaceName +
+                "?paramTest=etcdTest&version=" + version + "&application="
+                + application + (group == null ? "" : "&group=" + group));
+
+        MetadataIdentifier providerMetadataIdentifier =
+                new MetadataIdentifier(interfaceName, version, group, PROVIDER_SIDE, application);
+        Class interfaceClass = Class.forName(interfaceName);
+        FullServiceDefinition fullServiceDefinition =
+                ServiceDefinitionBuilder.buildFullDefinition(interfaceClass, url.getParameters());
+
+        etcdMetadataReport.storeProviderMetadata(providerMetadataIdentifier, fullServiceDefinition);
+        Thread.sleep(1000);
+        return providerMetadataIdentifier;
+    }
+
+    private URL generateURL(String interfaceName, String version, String group, String application) {
+        URL url = URL.valueOf("xxx://" + NetUtils.getLocalAddress().getHostName() + ":8989/" + interfaceName +
+                "?paramTest=etcdTest&version=" + version + "&application="
+                + application + (group == null ? "" : "&group=" + group));
+        return url;
+    }
+
+    private MetadataIdentifier storeConsumer(EtcdMetadataReport etcdMetadataReport, String interfaceName,
+                                             String version, String group, String application) throws InterruptedException {
+
+        MetadataIdentifier consumerIdentifier = new MetadataIdentifier(interfaceName, version, group, CONSUMER_SIDE, application);
+        Map<String, String> tmp = new HashMap<>();
+        tmp.put("paramConsumerTest", "etcdConsumer");
+        etcdMetadataReport.storeConsumerMetadata(consumerIdentifier, tmp);
+        Thread.sleep(1000);
+        return consumerIdentifier;
+    }
+}
diff --git a/dubbo-spi-metadata/dubbo-metadata-report-nacos/pom.xml b/dubbo-spi-metadata/dubbo-metadata-report-nacos/pom.xml
new file mode 100644
index 0000000..7885a91
--- /dev/null
+++ b/dubbo-spi-metadata/dubbo-metadata-report-nacos/pom.xml
@@ -0,0 +1,41 @@
+<?xml version="1.0" encoding="UTF-8"?>
+<!--
+  ~ 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.
+  -->
+
+<project xmlns="http://maven.apache.org/POM/4.0.0" xmlns:xsi="http://www.w3.org/2001/XMLSchema-instance" xsi:schemaLocation="http://maven.apache.org/POM/4.0.0 http://maven.apache.org/xsd/maven-4.0.0.xsd">
+    <parent>
+        <groupId>org.apache.dubbo</groupId>
+        <artifactId>dubbo-metadata</artifactId>
+        <version>2.7.7-SNAPSHOT</version>
+    </parent>
+    <modelVersion>4.0.0</modelVersion>
+
+    <artifactId>dubbo-metadata-report-nacos</artifactId>
+
+    <dependencies>
+        <dependency>
+            <groupId>org.apache.dubbo</groupId>
+            <artifactId>dubbo-metadata-api</artifactId>
+            <version>${project.parent.version}</version>
+        </dependency>
+        <dependency>
+            <groupId>com.alibaba.nacos</groupId>
+            <artifactId>nacos-client</artifactId>
+        </dependency>
+    </dependencies>
+
+</project>
diff --git a/dubbo-spi-metadata/dubbo-metadata-report-nacos/src/main/java/org/apache/dubbo/metadata/store/nacos/NacosMetadataReport.java b/dubbo-spi-metadata/dubbo-metadata-report-nacos/src/main/java/org/apache/dubbo/metadata/store/nacos/NacosMetadataReport.java
new file mode 100644
index 0000000..707d2b8
--- /dev/null
+++ b/dubbo-spi-metadata/dubbo-metadata-report-nacos/src/main/java/org/apache/dubbo/metadata/store/nacos/NacosMetadataReport.java
@@ -0,0 +1,234 @@
+/*
+ * 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.metadata.store.nacos;
+
+import org.apache.dubbo.common.URL;
+import org.apache.dubbo.common.logger.Logger;
+import org.apache.dubbo.common.logger.LoggerFactory;
+import org.apache.dubbo.common.utils.StringUtils;
+import org.apache.dubbo.metadata.report.identifier.BaseMetadataIdentifier;
+import org.apache.dubbo.metadata.report.identifier.KeyTypeEnum;
+import org.apache.dubbo.metadata.report.identifier.MetadataIdentifier;
+import org.apache.dubbo.metadata.report.identifier.ServiceMetadataIdentifier;
+import org.apache.dubbo.metadata.report.identifier.SubscriberMetadataIdentifier;
+import org.apache.dubbo.metadata.report.support.AbstractMetadataReport;
+import org.apache.dubbo.rpc.RpcException;
+
+import com.alibaba.nacos.api.NacosFactory;
+import com.alibaba.nacos.api.config.ConfigService;
+import com.alibaba.nacos.api.exception.NacosException;
+
+import java.util.ArrayList;
+import java.util.Arrays;
+import java.util.Collections;
+import java.util.List;
+import java.util.Properties;
+
+import static com.alibaba.nacos.api.PropertyKeyConst.ACCESS_KEY;
+import static com.alibaba.nacos.api.PropertyKeyConst.CLUSTER_NAME;
+import static com.alibaba.nacos.api.PropertyKeyConst.CONFIG_LONG_POLL_TIMEOUT;
+import static com.alibaba.nacos.api.PropertyKeyConst.CONFIG_RETRY_TIME;
+import static com.alibaba.nacos.api.PropertyKeyConst.CONTEXT_PATH;
+import static com.alibaba.nacos.api.PropertyKeyConst.ENABLE_REMOTE_SYNC_CONFIG;
+import static com.alibaba.nacos.api.PropertyKeyConst.ENCODE;
+import static com.alibaba.nacos.api.PropertyKeyConst.ENDPOINT;
+import static com.alibaba.nacos.api.PropertyKeyConst.ENDPOINT_PORT;
+import static com.alibaba.nacos.api.PropertyKeyConst.IS_USE_CLOUD_NAMESPACE_PARSING;
+import static com.alibaba.nacos.api.PropertyKeyConst.IS_USE_ENDPOINT_PARSING_RULE;
+import static com.alibaba.nacos.api.PropertyKeyConst.MAX_RETRY;
+import static com.alibaba.nacos.api.PropertyKeyConst.NAMESPACE;
+import static com.alibaba.nacos.api.PropertyKeyConst.NAMING_CLIENT_BEAT_THREAD_COUNT;
+import static com.alibaba.nacos.api.PropertyKeyConst.NAMING_LOAD_CACHE_AT_START;
+import static com.alibaba.nacos.api.PropertyKeyConst.NAMING_POLLING_THREAD_COUNT;
+import static com.alibaba.nacos.api.PropertyKeyConst.RAM_ROLE_NAME;
+import static com.alibaba.nacos.api.PropertyKeyConst.SECRET_KEY;
+import static com.alibaba.nacos.api.PropertyKeyConst.SERVER_ADDR;
+import static com.alibaba.nacos.client.naming.utils.UtilAndComs.NACOS_NAMING_LOG_NAME;
+import static org.apache.dubbo.common.constants.CommonConstants.GROUP_KEY;
+import static org.apache.dubbo.common.constants.RemotingConstants.BACKUP_KEY;
+
+/**
+ * metadata report impl for nacos
+ */
+public class NacosMetadataReport extends AbstractMetadataReport {
+
+    private static final Logger logger = LoggerFactory.getLogger(NacosMetadataReport.class);
+
+    private ConfigService configService;
+
+    /**
+     * The group used to store metadata in Nacos
+     */
+    private String group;
+
+
+    public NacosMetadataReport(URL url) {
+        super(url);
+        this.configService = buildConfigService(url);
+        group = url.getParameter(GROUP_KEY, DEFAULT_ROOT);
+    }
+
+    public ConfigService buildConfigService(URL url) {
+        Properties nacosProperties = buildNacosProperties(url);
+        try {
+            configService = NacosFactory.createConfigService(nacosProperties);
+        } catch (NacosException e) {
+            if (logger.isErrorEnabled()) {
+                logger.error(e.getErrMsg(), e);
+            }
+            throw new IllegalStateException(e);
+        }
+        return configService;
+    }
+
+    private Properties buildNacosProperties(URL url) {
+        Properties properties = new Properties();
+        setServerAddr(url, properties);
+        setProperties(url, properties);
+        return properties;
+    }
+
+    private void setServerAddr(URL url, Properties properties) {
+        StringBuilder serverAddrBuilder =
+                new StringBuilder(url.getHost()) // Host
+                        .append(":")
+                        .append(url.getPort()); // Port
+        // Append backup parameter as other servers
+        String backup = url.getParameter(BACKUP_KEY);
+        if (backup != null) {
+            serverAddrBuilder.append(",").append(backup);
+        }
+        String serverAddr = serverAddrBuilder.toString();
+        properties.put(SERVER_ADDR, serverAddr);
+    }
+
+    private static void setProperties(URL url, Properties properties) {
+        putPropertyIfAbsent(url, properties, NACOS_NAMING_LOG_NAME);
+        putPropertyIfAbsent(url, properties, IS_USE_CLOUD_NAMESPACE_PARSING);
+        putPropertyIfAbsent(url, properties, IS_USE_ENDPOINT_PARSING_RULE);
+        putPropertyIfAbsent(url, properties, ENDPOINT);
+        putPropertyIfAbsent(url, properties, ENDPOINT_PORT);
+        putPropertyIfAbsent(url, properties, NAMESPACE);
+        putPropertyIfAbsent(url, properties, ACCESS_KEY);
+        putPropertyIfAbsent(url, properties, SECRET_KEY);
+        putPropertyIfAbsent(url, properties, RAM_ROLE_NAME);
+        putPropertyIfAbsent(url, properties, CONTEXT_PATH);
+        putPropertyIfAbsent(url, properties, CLUSTER_NAME);
+        putPropertyIfAbsent(url, properties, ENCODE);
+        putPropertyIfAbsent(url, properties, CONFIG_LONG_POLL_TIMEOUT);
+        putPropertyIfAbsent(url, properties, CONFIG_RETRY_TIME);
+        putPropertyIfAbsent(url, properties, MAX_RETRY);
+        putPropertyIfAbsent(url, properties, ENABLE_REMOTE_SYNC_CONFIG);
+        putPropertyIfAbsent(url, properties, NAMING_LOAD_CACHE_AT_START, "true");
+        putPropertyIfAbsent(url, properties, NAMING_CLIENT_BEAT_THREAD_COUNT);
+        putPropertyIfAbsent(url, properties, NAMING_POLLING_THREAD_COUNT);
+    }
+
+    private static void putPropertyIfAbsent(URL url, Properties properties, String propertyName) {
+        String propertyValue = url.getParameter(propertyName);
+        if (StringUtils.isNotEmpty(propertyValue)) {
+            properties.setProperty(propertyName, propertyValue);
+        }
+    }
+
+    private static void putPropertyIfAbsent(URL url, Properties properties, String propertyName, String defaultValue) {
+        String propertyValue = url.getParameter(propertyName);
+        if (StringUtils.isNotEmpty(propertyValue)) {
+            properties.setProperty(propertyName, propertyValue);
+        } else {
+            properties.setProperty(propertyName, defaultValue);
+        }
+    }
+
+    @Override
+    protected void doStoreProviderMetadata(MetadataIdentifier providerMetadataIdentifier, String serviceDefinitions) {
+        this.storeMetadata(providerMetadataIdentifier, serviceDefinitions);
+    }
+
+    @Override
+    protected void doStoreConsumerMetadata(MetadataIdentifier consumerMetadataIdentifier, String value) {
+        this.storeMetadata(consumerMetadataIdentifier, value);
+    }
+
+    @Override
+    protected void doSaveMetadata(ServiceMetadataIdentifier serviceMetadataIdentifier, URL url) {
+        storeMetadata(serviceMetadataIdentifier, URL.encode(url.toFullString()));
+    }
+
+    @Override
+    protected void doRemoveMetadata(ServiceMetadataIdentifier serviceMetadataIdentifier) {
+        deleteMetadata(serviceMetadataIdentifier);
+    }
+
+    @Override
+    protected List<String> doGetExportedURLs(ServiceMetadataIdentifier metadataIdentifier) {
+        String content = getConfig(metadataIdentifier);
+        if (StringUtils.isEmpty(content)) {
+            return Collections.emptyList();
+        }
+        return new ArrayList<String>(Arrays.asList(URL.decode(content)));
+    }
+
+    @Override
+    protected void doSaveSubscriberData(SubscriberMetadataIdentifier subscriberMetadataIdentifier, String urlListStr) {
+        storeMetadata(subscriberMetadataIdentifier, urlListStr);
+    }
+
+    @Override
+    protected String doGetSubscribedURLs(SubscriberMetadataIdentifier subscriberMetadataIdentifier) {
+        return getConfig(subscriberMetadataIdentifier);
+    }
+
+    @Override
+    public String getServiceDefinition(MetadataIdentifier metadataIdentifier) {
+        return getConfig(metadataIdentifier);
+    }
+
+    private void storeMetadata(BaseMetadataIdentifier identifier, String value) {
+        try {
+            boolean publishResult = configService.publishConfig(identifier.getUniqueKey(KeyTypeEnum.UNIQUE_KEY), group, value);
+            if (!publishResult) {
+                throw new RuntimeException("publish nacos metadata failed");
+            }
+        } catch (Throwable t) {
+            logger.error("Failed to put " + identifier + " to nacos " + value + ", cause: " + t.getMessage(), t);
+            throw new RpcException("Failed to put " + identifier + " to nacos " + value + ", cause: " + t.getMessage(), t);
+        }
+    }
+
+    private void deleteMetadata(BaseMetadataIdentifier identifier) {
+        try {
+            boolean publishResult = configService.removeConfig(identifier.getUniqueKey(KeyTypeEnum.UNIQUE_KEY), group);
+            if (!publishResult) {
+                throw new RuntimeException("remove nacos metadata failed");
+            }
+        } catch (Throwable t) {
+            logger.error("Failed to remove " + identifier + " from nacos , cause: " + t.getMessage(), t);
+            throw new RpcException("Failed to remove " + identifier + " from nacos , cause: " + t.getMessage(), t);
+        }
+    }
+
+    private String getConfig(BaseMetadataIdentifier identifier) {
+        try {
+            return configService.getConfig(identifier.getUniqueKey(KeyTypeEnum.UNIQUE_KEY), group, 300);
+        } catch (Throwable t) {
+            logger.error("Failed to get " + identifier + " from nacos , cause: " + t.getMessage(), t);
+            throw new RpcException("Failed to get " + identifier + " from nacos , cause: " + t.getMessage(), t);
+        }
+    }
+}
diff --git a/dubbo-spi-metadata/dubbo-metadata-report-nacos/src/main/java/org/apache/dubbo/metadata/store/nacos/NacosMetadataReportFactory.java b/dubbo-spi-metadata/dubbo-metadata-report-nacos/src/main/java/org/apache/dubbo/metadata/store/nacos/NacosMetadataReportFactory.java
new file mode 100644
index 0000000..2cff74c
--- /dev/null
+++ b/dubbo-spi-metadata/dubbo-metadata-report-nacos/src/main/java/org/apache/dubbo/metadata/store/nacos/NacosMetadataReportFactory.java
@@ -0,0 +1,32 @@
+/*
+ * 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.metadata.store.nacos;
+
+import org.apache.dubbo.common.URL;
+import org.apache.dubbo.metadata.report.MetadataReport;
+import org.apache.dubbo.metadata.report.support.AbstractMetadataReportFactory;
+
+/**
+ * metadata report factory impl for nacos
+ */
+public class NacosMetadataReportFactory extends AbstractMetadataReportFactory {
+    @Override
+    protected MetadataReport createMetadataReport(URL url) {
+        return new NacosMetadataReport(url);
+    }
+}
diff --git a/dubbo-spi-metadata/dubbo-metadata-report-nacos/src/main/resources/META-INF/dubbo/internal/org.apache.dubbo.metadata.report.MetadataReportFactory b/dubbo-spi-metadata/dubbo-metadata-report-nacos/src/main/resources/META-INF/dubbo/internal/org.apache.dubbo.metadata.report.MetadataReportFactory
new file mode 100644
index 0000000..de3b50a
--- /dev/null
+++ b/dubbo-spi-metadata/dubbo-metadata-report-nacos/src/main/resources/META-INF/dubbo/internal/org.apache.dubbo.metadata.report.MetadataReportFactory
@@ -0,0 +1 @@
+nacos=org.apache.dubbo.metadata.store.nacos.NacosMetadataReportFactory
diff --git a/dubbo-spi-metadata/dubbo-metadata-report-nacos/src/test/java/org/apache/dubbo/metadata/store/nacos/NacosMetadata4TstService.java b/dubbo-spi-metadata/dubbo-metadata-report-nacos/src/test/java/org/apache/dubbo/metadata/store/nacos/NacosMetadata4TstService.java
new file mode 100644
index 0000000..e84efc5
--- /dev/null
+++ b/dubbo-spi-metadata/dubbo-metadata-report-nacos/src/test/java/org/apache/dubbo/metadata/store/nacos/NacosMetadata4TstService.java
@@ -0,0 +1,28 @@
+/*
+ * 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.metadata.store.nacos;
+
+/**
+ * Test interface for Nacos metadata report
+ */
+public interface NacosMetadata4TstService {
+
+    int getCounter();
+
+    void printResult(String var);
+}
diff --git a/dubbo-spi-metadata/dubbo-metadata-report-nacos/src/test/java/org/apache/dubbo/metadata/store/nacos/NacosMetadataReportTest.java b/dubbo-spi-metadata/dubbo-metadata-report-nacos/src/test/java/org/apache/dubbo/metadata/store/nacos/NacosMetadataReportTest.java
new file mode 100644
index 0000000..88fc75a
--- /dev/null
+++ b/dubbo-spi-metadata/dubbo-metadata-report-nacos/src/test/java/org/apache/dubbo/metadata/store/nacos/NacosMetadataReportTest.java
@@ -0,0 +1,247 @@
+/*
+ * 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.metadata.store.nacos;
+
+import com.alibaba.nacos.api.exception.NacosException;
+import org.apache.dubbo.common.URL;
+import org.apache.dubbo.common.utils.NetUtils;
+import org.apache.dubbo.metadata.definition.ServiceDefinitionBuilder;
+import org.apache.dubbo.metadata.definition.model.FullServiceDefinition;
+import org.apache.dubbo.metadata.report.identifier.KeyTypeEnum;
+import org.apache.dubbo.metadata.report.identifier.MetadataIdentifier;
+
+import com.alibaba.nacos.api.config.ConfigService;
+import com.google.gson.Gson;
+import org.apache.dubbo.metadata.report.identifier.ServiceMetadataIdentifier;
+import org.apache.dubbo.metadata.report.identifier.SubscriberMetadataIdentifier;
+import org.junit.jupiter.api.AfterEach;
+import org.junit.jupiter.api.Assertions;
+import org.junit.jupiter.api.BeforeEach;
+import org.junit.jupiter.api.Disabled;
+import org.junit.jupiter.api.Test;
+
+import java.util.Arrays;
+import java.util.HashMap;
+import java.util.List;
+import java.util.Map;
+
+import static org.apache.dubbo.common.constants.CommonConstants.CONSUMER_SIDE;
+import static org.apache.dubbo.common.constants.CommonConstants.PROVIDER_SIDE;
+
+//FIXME: waiting for embedded Nacos suport, then we can open the switch.
+@Disabled("https://github.com/alibaba/nacos/issues/1188")
+public class NacosMetadataReportTest {
+
+    private static final String SESSION_TIMEOUT_KEY = "session";
+
+    private static final String TEST_SERVICE = "org.apache.dubbo.metadata.store.nacos.NacosMetadata4TstService";
+
+    private NacosMetadataReport nacosMetadataReport;
+
+    private NacosMetadataReportFactory nacosMetadataReportFactory;
+
+    private ConfigService configService;
+
+    private static final String NACOS_GROUP = "metadata_test";
+
+    /**
+     * timeout(ms) for nacos session
+     */
+    private static final int SESSION_TIMEOUT = 15 * 1000;
+
+    /**
+     * timeout(ms) for query operation on nacos
+     */
+    private static final int NACOS_READ_TIMEOUT = 5 * 1000;
+
+    /**
+     * interval(ms) to make nacos cache refresh
+     */
+    private static final int INTERVAL_TO_MAKE_NACOS_REFRESH = 1000;
+
+    /**
+     * version for test
+     */
+    private static final String VERSION = "1.0.0";
+
+    /**
+     * group for test
+     */
+    private static final String METADATA_GROUP = null;
+
+    /**
+     * application name for test
+     */
+    private static final String APPLICATION_NAME = "nacos-metdata-report-test";
+
+    /**
+     * revision for test
+     */
+    private static final String REVISION = "90980";
+
+    /**
+     * protocol for test
+     */
+    private static final String PROTOCOL = "xxx";
+
+    @BeforeEach
+    public void setUp() {
+        URL url = URL.valueOf("nacos://127.0.0.1:8848?group=" + NACOS_GROUP)
+                .addParameter(SESSION_TIMEOUT_KEY, SESSION_TIMEOUT);
+        nacosMetadataReportFactory = new NacosMetadataReportFactory();
+        this.nacosMetadataReport = (NacosMetadataReport) nacosMetadataReportFactory.createMetadataReport(url);
+        this.configService = nacosMetadataReport.buildConfigService(url);
+    }
+
+    @AfterEach
+    public void tearDown() throws Exception {
+    }
+
+
+    @Test
+    public void testStoreProvider() throws Exception {
+        MetadataIdentifier providerIdentifier =
+                storeProvider(nacosMetadataReport, TEST_SERVICE, VERSION, METADATA_GROUP, APPLICATION_NAME);
+        String serverContent = configService.getConfig(providerIdentifier.getUniqueKey(KeyTypeEnum.UNIQUE_KEY), NACOS_GROUP, NACOS_READ_TIMEOUT);
+        Assertions.assertNotNull(serverContent);
+
+        Gson gson = new Gson();
+        FullServiceDefinition fullServiceDefinition = gson.fromJson(serverContent, FullServiceDefinition.class);
+        Assertions.assertEquals(fullServiceDefinition.getParameters().get("paramTest"), "nacosTest");
+
+        //Clear test data
+        configService.removeConfig(providerIdentifier.getUniqueKey(KeyTypeEnum.UNIQUE_KEY), NACOS_GROUP);
+    }
+
+    @Test
+    public void testStoreConsumer() throws Exception {
+        MetadataIdentifier consumerIdentifier = storeConsumer(nacosMetadataReport, TEST_SERVICE, VERSION, METADATA_GROUP, APPLICATION_NAME);
+
+        String serverContent = configService.getConfig(consumerIdentifier.getUniqueKey(KeyTypeEnum.UNIQUE_KEY), NACOS_GROUP, NACOS_READ_TIMEOUT);
+        Assertions.assertNotNull(serverContent);
+        Assertions.assertEquals(serverContent, "{\"paramConsumerTest\":\"nacosConsumer\"}");
+
+        //clear test data
+        configService.removeConfig(consumerIdentifier.getUniqueKey(KeyTypeEnum.UNIQUE_KEY), NACOS_GROUP);
+    }
+
+    @Test
+    public void testDoSaveServiceMetadata() throws Exception {
+        URL url = URL.valueOf("xxx://" + NetUtils.getLocalAddress().getHostName() + ":4444/" + TEST_SERVICE +
+                "?paramTest=nacosTest&version=" + VERSION + "&application="
+                + APPLICATION_NAME + (METADATA_GROUP == null ? "" : "&group=" + METADATA_GROUP));
+        ServiceMetadataIdentifier serviceMetadataIdentifier = new ServiceMetadataIdentifier(TEST_SERVICE, VERSION,
+                METADATA_GROUP, "provider", REVISION, PROTOCOL);
+        nacosMetadataReport.doSaveMetadata(serviceMetadataIdentifier, url);
+        Thread.sleep(INTERVAL_TO_MAKE_NACOS_REFRESH);
+        String serviceMetaData = configService.getConfig(serviceMetadataIdentifier.getUniqueKey(KeyTypeEnum.UNIQUE_KEY), NACOS_GROUP, NACOS_READ_TIMEOUT);
+        Assertions.assertNotNull(serviceMetaData);
+        Assertions.assertEquals(serviceMetaData, URL.encode(url.toFullString()));
+
+        //clear test data
+        configService.removeConfig(serviceMetadataIdentifier.getUniqueKey(KeyTypeEnum.UNIQUE_KEY), NACOS_GROUP);
+    }
+
+    @Test
+    public void testDoRemoveServiceMetadata() throws Exception {
+        URL url = URL.valueOf("xxx://" + NetUtils.getLocalAddress().getHostName() + ":4444/" + TEST_SERVICE +
+                "?paramTest=nacosTest&version=" + VERSION + "&application="
+                + APPLICATION_NAME + (METADATA_GROUP == null ? "" : "&group=" + METADATA_GROUP));
+        ServiceMetadataIdentifier serviceMetadataIdentifier = new ServiceMetadataIdentifier(TEST_SERVICE, VERSION,
+                METADATA_GROUP, "provider", REVISION, PROTOCOL);
+        nacosMetadataReport.doSaveMetadata(serviceMetadataIdentifier, url);
+        Thread.sleep(INTERVAL_TO_MAKE_NACOS_REFRESH);
+        String serviceMetaData = configService.getConfig(serviceMetadataIdentifier.getUniqueKey(KeyTypeEnum.UNIQUE_KEY), NACOS_GROUP, NACOS_READ_TIMEOUT);
+        Assertions.assertNotNull(serviceMetaData);
+
+        nacosMetadataReport.doRemoveMetadata(serviceMetadataIdentifier);
+        Thread.sleep(INTERVAL_TO_MAKE_NACOS_REFRESH);
+        serviceMetaData = configService.getConfig(serviceMetadataIdentifier.getUniqueKey(KeyTypeEnum.UNIQUE_KEY), NACOS_GROUP, NACOS_READ_TIMEOUT);
+        Assertions.assertNull(serviceMetaData);
+    }
+
+    @Test
+    public void testDoGetExportedURLs() throws InterruptedException, NacosException {
+        URL url = URL.valueOf("xxx://" + NetUtils.getLocalAddress().getHostName() + ":4444/" + TEST_SERVICE +
+                "?paramTest=nacosTest&version=" + VERSION + "&application="
+                + APPLICATION_NAME + (METADATA_GROUP == null ? "" : "&group=" + METADATA_GROUP));
+        ServiceMetadataIdentifier serviceMetadataIdentifier = new ServiceMetadataIdentifier(TEST_SERVICE, VERSION,
+                METADATA_GROUP, "provider", REVISION, PROTOCOL);
+
+        nacosMetadataReport.doSaveMetadata(serviceMetadataIdentifier, url);
+        Thread.sleep(INTERVAL_TO_MAKE_NACOS_REFRESH);
+
+        List<String> exportedURLs = nacosMetadataReport.doGetExportedURLs(serviceMetadataIdentifier);
+        Assertions.assertTrue(exportedURLs.size() == 1);
+
+        String exportedUrl = exportedURLs.get(0);
+        Assertions.assertNotNull(exportedUrl);
+        Assertions.assertEquals(exportedUrl, url.toFullString());
+
+        //clear test data
+        configService.removeConfig(serviceMetadataIdentifier.getUniqueKey(KeyTypeEnum.UNIQUE_KEY), NACOS_GROUP);
+    }
+
+    @Test
+    public void testDoSaveSubscriberData() throws InterruptedException, NacosException {
+        URL url = URL.valueOf("xxx://" + NetUtils.getLocalAddress().getHostName() + ":4444/" + TEST_SERVICE +
+                "?paramTest=nacosTest&version=" + VERSION + "&application="
+                + APPLICATION_NAME + (METADATA_GROUP == null ? "" : "&group=" + METADATA_GROUP));
+        SubscriberMetadataIdentifier subscriberMetadataIdentifier = new SubscriberMetadataIdentifier(APPLICATION_NAME, REVISION);
+        Gson gson = new Gson();
+        String urlListJsonString = gson.toJson(Arrays.asList(url));
+        nacosMetadataReport.doSaveSubscriberData(subscriberMetadataIdentifier, urlListJsonString);
+        Thread.sleep(INTERVAL_TO_MAKE_NACOS_REFRESH);
+
+        String subscriberMetadata = configService.getConfig(subscriberMetadataIdentifier.getUniqueKey(KeyTypeEnum.UNIQUE_KEY), NACOS_GROUP, NACOS_READ_TIMEOUT);
+        Assertions.assertNotNull(subscriberMetadata);
+        Assertions.assertEquals(subscriberMetadata, urlListJsonString);
+
+        //clear test data
+        configService.removeConfig(subscriberMetadataIdentifier.getUniqueKey(KeyTypeEnum.UNIQUE_KEY), NACOS_GROUP);
+
+    }
+
+    private MetadataIdentifier storeProvider(NacosMetadataReport nacosMetadataReport, String interfaceName, String version,
+                                             String group, String application)
+            throws ClassNotFoundException, InterruptedException {
+        URL url = URL.valueOf("xxx://" + NetUtils.getLocalAddress().getHostName() + ":4444/" + interfaceName +
+                "?paramTest=nacosTest&version=" + version + "&application="
+                + application + (group == null ? "" : "&group=" + group));
+
+        MetadataIdentifier providerMetadataIdentifier =
+                new MetadataIdentifier(interfaceName, version, group, PROVIDER_SIDE, application);
+        Class interfaceClass = Class.forName(interfaceName);
+        FullServiceDefinition fullServiceDefinition =
+                ServiceDefinitionBuilder.buildFullDefinition(interfaceClass, url.getParameters());
+
+        nacosMetadataReport.storeProviderMetadata(providerMetadataIdentifier, fullServiceDefinition);
+        Thread.sleep(INTERVAL_TO_MAKE_NACOS_REFRESH);
+        return providerMetadataIdentifier;
+    }
+
+    private MetadataIdentifier storeConsumer(NacosMetadataReport nacosMetadataReport, String interfaceName,
+                                             String version, String group, String application) throws InterruptedException {
+        MetadataIdentifier consumerIdentifier = new MetadataIdentifier(interfaceName, version, group, CONSUMER_SIDE, application);
+        Map<String, String> tmp = new HashMap<>();
+        tmp.put("paramConsumerTest", "nacosConsumer");
+        nacosMetadataReport.storeConsumerMetadata(consumerIdentifier, tmp);
+        Thread.sleep(INTERVAL_TO_MAKE_NACOS_REFRESH);
+        return consumerIdentifier;
+    }
+
+}
diff --git a/dubbo-spi-metadata/dubbo-metadata-report-redis/pom.xml b/dubbo-spi-metadata/dubbo-metadata-report-redis/pom.xml
new file mode 100644
index 0000000..70bd32d
--- /dev/null
+++ b/dubbo-spi-metadata/dubbo-metadata-report-redis/pom.xml
@@ -0,0 +1,57 @@
+<!--
+  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.
+  -->
+<project xmlns="http://maven.apache.org/POM/4.0.0" xmlns:xsi="http://www.w3.org/2001/XMLSchema-instance" xsi:schemaLocation="http://maven.apache.org/POM/4.0.0 http://maven.apache.org/xsd/maven-4.0.0.xsd">
+    <parent>
+        <groupId>org.apache.dubbo</groupId>
+        <artifactId>dubbo-metadata</artifactId>
+        <version>2.7.7-SNAPSHOT</version>
+    </parent>
+    <modelVersion>4.0.0</modelVersion>
+
+    <artifactId>dubbo-metadata-report-redis</artifactId>
+    <properties>
+        <jedis.version>2.9.0</jedis.version>
+    </properties>
+
+    <dependencies>
+        <dependency>
+            <groupId>org.apache.dubbo</groupId>
+            <artifactId>dubbo-metadata-api</artifactId>
+            <version>${project.parent.version}</version>
+        </dependency>
+        <dependency>
+            <groupId>redis.clients</groupId>
+            <artifactId>jedis</artifactId>
+            <version>${jedis.version}</version>
+        </dependency>
+        <dependency>
+            <groupId>org.apache.curator</groupId>
+            <artifactId>curator-test</artifactId>
+            <scope>test</scope>
+        </dependency>
+        <dependency>
+            <groupId>com.github.kstyrc</groupId>
+            <artifactId>embedded-redis</artifactId>
+            <scope>test</scope>
+        </dependency>
+        <dependency>
+            <groupId>org.apache.commons</groupId>
+            <artifactId>commons-lang3</artifactId>
+            <scope>test</scope>
+        </dependency>
+    </dependencies>
+</project>
diff --git a/dubbo-spi-metadata/dubbo-metadata-report-redis/src/main/java/org/apache/dubbo/metadata/store/redis/RedisMetadataReport.java b/dubbo-spi-metadata/dubbo-metadata-report-redis/src/main/java/org/apache/dubbo/metadata/store/redis/RedisMetadataReport.java
new file mode 100644
index 0000000..c00be04
--- /dev/null
+++ b/dubbo-spi-metadata/dubbo-metadata-report-redis/src/main/java/org/apache/dubbo/metadata/store/redis/RedisMetadataReport.java
@@ -0,0 +1,201 @@
+/*
+ * 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
... 70896 lines suppressed ...


[dubbo-spi-extensions] 05/39: move some modules back to core repo

Posted by li...@apache.org.
This is an automated email from the ASF dual-hosted git repository.

liujun pushed a commit to branch 2.7.x
in repository https://gitbox.apache.org/repos/asf/dubbo-spi-extensions.git

commit 3992077ca135d618f3a3e7ef4801b5341656103f
Author: ken.lj <ke...@gmail.com>
AuthorDate: Thu May 21 11:58:14 2020 +0800

    move some modules back to core repo
---
 compiler/pom.xml                                   | 237 -------------
 .../org/apache/dubbo/gen/AbstractGenerator.java    | 293 ----------------
 .../org/apache/dubbo/gen/dubbo/DubboGenerator.java |  42 ---
 .../apache/dubbo/gen/grpc/DubboGrpcGenerator.java  |  41 ---
 .../grpc/reactive/ReactorDubboGrpcGenerator.java   |  42 ---
 .../gen/grpc/reactive/RxDubboGrpcGenerator.java    |  41 ---
 compiler/src/main/resources/DubboGrpcStub.mustache | 312 -----------------
 compiler/src/main/resources/DubboStub.mustache     |  53 ---
 .../main/resources/ReactorDubboGrpcStub.mustache   | 212 ------------
 .../src/main/resources/RxDubboGrpcStub.mustache    | 246 --------------
 dubbo-spi-filter/dubbo-filter-cache/pom.xml        |  48 ---
 .../main/java/org/apache/dubbo/cache/Cache.java    |  43 ---
 .../java/org/apache/dubbo/cache/CacheFactory.java  |  43 ---
 .../org/apache/dubbo/cache/filter/CacheFilter.java | 133 --------
 .../dubbo/cache/support/AbstractCacheFactory.java  |  72 ----
 .../cache/support/expiring/ExpiringCache.java      |  77 -----
 .../support/expiring/ExpiringCacheFactory.java     |  44 ---
 .../dubbo/cache/support/expiring/ExpiringMap.java  | 374 ---------------------
 .../apache/dubbo/cache/support/jcache/JCache.java  |  87 -----
 .../dubbo/cache/support/jcache/JCacheFactory.java  |  48 ---
 .../apache/dubbo/cache/support/lfu/LfuCache.java   |  80 -----
 .../dubbo/cache/support/lfu/LfuCacheFactory.java   |  43 ---
 .../apache/dubbo/cache/support/lru/LruCache.java   |  80 -----
 .../dubbo/cache/support/lru/LruCacheFactory.java   |  43 ---
 .../support/threadlocal/ThreadLocalCache.java      |  77 -----
 .../threadlocal/ThreadLocalCacheFactory.java       |  43 ---
 .../internal/org.apache.dubbo.cache.CacheFactory   |   4 -
 .../dubbo/internal/org.apache.dubbo.rpc.Filter     |   1 -
 .../apache/dubbo/cache/filter/CacheFilterTest.java | 137 --------
 .../cache/support/AbstractCacheFactoryTest.java    |  33 --
 .../support/expiring/ExpiringCacheFactoryTest.java |  38 ---
 .../cache/support/jcache/JCacheFactoryTest.java    |  55 ---
 .../cache/support/lru/LruCacheFactoryTest.java     |  38 ---
 .../threadlocal/ThreadLocalCacheFactoryTest.java   |  38 ---
 dubbo-spi-filter/dubbo-filter-validation/pom.xml   |  72 ----
 .../apache/dubbo/validation/MethodValidated.java   |  40 ---
 .../org/apache/dubbo/validation/Validation.java    |  39 ---
 .../org/apache/dubbo/validation/Validator.java     |  27 --
 .../dubbo/validation/filter/ValidationFilter.java  | 104 ------
 .../validation/support/AbstractValidation.java     |  51 ---
 .../support/jvalidation/JValidation.java           |  40 ---
 .../validation/support/jvalidation/JValidator.java | 330 ------------------
 .../dubbo/internal/org.apache.dubbo.rpc.Filter     |   1 -
 .../org.apache.dubbo.validation.Validation         |   1 -
 .../validation/filter/ValidationFilterTest.java    | 137 --------
 .../support/jvalidation/JValidationTest.java       |  50 ---
 .../support/jvalidation/JValidatorTest.java        |  86 -----
 .../jvalidation/mock/JValidatorTestTarget.java     |  41 ---
 .../jvalidation/mock/ValidationParameter.java      |  31 --
 dubbo-spi-filter/pom.xml                           |  35 --
 .../dubbo-metadata-report-nacos/pom.xml            |  41 ---
 .../metadata/store/nacos/NacosMetadataReport.java  | 234 -------------
 .../store/nacos/NacosMetadataReportFactory.java    |  32 --
 ...che.dubbo.metadata.report.MetadataReportFactory |   1 -
 .../store/nacos/NacosMetadata4TstService.java      |  28 --
 .../store/nacos/NacosMetadataReportTest.java       | 247 --------------
 dubbo-spi-metadata/pom.xml                         |   1 -
 dubbo-spi-rpc/dubbo-rpc-grpc/pom.xml               |  68 ----
 .../rpc/protocol/grpc/DubboHandlerRegistry.java    |  70 ----
 .../apache/dubbo/rpc/protocol/grpc/GrpcConfig.java |  21 --
 .../dubbo/rpc/protocol/grpc/GrpcConstants.java     |  41 ---
 .../dubbo/rpc/protocol/grpc/GrpcInvoker.java       | 118 -------
 .../dubbo/rpc/protocol/grpc/GrpcOptionsUtils.java  | 225 -------------
 .../dubbo/rpc/protocol/grpc/GrpcProtocol.java      | 239 -------------
 .../grpc/ReferenceCountManagedChannel.java         |  85 -----
 .../grpc/interceptors/ClientInterceptor.java       |  26 --
 .../grpc/interceptors/GrpcConfigurator.java        |  41 ---
 .../grpc/interceptors/RpcContextInterceptor.java   | 100 ------
 .../grpc/interceptors/ServerInterceptor.java       |  26 --
 .../grpc/interceptors/ServerTransportFilter.java   |  27 --
 .../dubbo/internal/org.apache.dubbo.rpc.Protocol   |   1 -
 ...pc.protocol.grpc.interceptors.ClientInterceptor |   1 -
 ...pc.protocol.grpc.interceptors.ServerInterceptor |   1 -
 dubbo-spi-rpc/dubbo-rpc-injvm/pom.xml              |  38 ---
 .../dubbo/rpc/protocol/injvm/InjvmExporter.java    |  47 ---
 .../dubbo/rpc/protocol/injvm/InjvmInvoker.java     |  65 ----
 .../dubbo/rpc/protocol/injvm/InjvmProtocol.java    | 120 -------
 .../dubbo/internal/org.apache.dubbo.rpc.Protocol   |   1 -
 .../dubbo/rpc/protocol/injvm/DemoRequest.java      |  58 ----
 .../dubbo/rpc/protocol/injvm/DemoService.java      |  44 ---
 .../dubbo/rpc/protocol/injvm/DemoServiceImpl.java  |  78 -----
 .../org/apache/dubbo/rpc/protocol/injvm/IEcho.java |  21 --
 .../rpc/protocol/injvm/InjvmProtocolTest.java      | 126 -------
 .../dubbo/rpc/protocol/injvm/ProtocolTest.java     |  72 ----
 .../org/apache/dubbo/rpc/protocol/injvm/Type.java  |  21 --
 dubbo-spi-rpc/dubbo-rpc-rest/pom.xml               | 115 -------
 .../rpc/protocol/rest/BaseRestProtocolServer.java  |  80 -----
 .../apache/dubbo/rpc/protocol/rest/Constants.java  |  29 --
 .../rpc/protocol/rest/DubboHttpProtocolServer.java | 131 --------
 .../rpc/protocol/rest/DubboResourceFactory.java    |  76 -----
 .../rpc/protocol/rest/NettyRestProtocolServer.java |  73 ----
 .../rpc/protocol/rest/RestConstraintViolation.java |  66 ----
 .../dubbo/rpc/protocol/rest/RestProtocol.java      | 295 ----------------
 .../rpc/protocol/rest/RestProtocolServer.java      |  33 --
 .../dubbo/rpc/protocol/rest/RestServerFactory.java |  44 ---
 .../dubbo/rpc/protocol/rest/RpcContextFilter.java  | 106 ------
 .../rpc/protocol/rest/RpcExceptionMapper.java      |  51 ---
 .../dubbo/rpc/protocol/rest/ViolationReport.java   |  48 ---
 .../swagger/DubboSwaggerApiListingResource.java    |  48 ---
 .../integration/swagger/DubboSwaggerService.java   |  43 ---
 .../rpc/protocol/rest/support/ContentType.java     |  26 --
 .../rpc/protocol/rest/support/LoggingFilter.java   | 148 --------
 .../dubbo/internal/org.apache.dubbo.rpc.Protocol   |   1 -
 .../dubbo/rpc/protocol/rest/DemoService.java       |  45 ---
 .../dubbo/rpc/protocol/rest/DemoServiceImpl.java   |  57 ----
 .../dubbo/rpc/protocol/rest/RestProtocolTest.java  | 282 ----------------
 .../rpc/protocol/rest/RpcExceptionMapperTest.java  |  67 ----
 .../DubboSwaggerApiListingResourceTest.java        |  62 ----
 .../rest/integration/swagger/SwaggerService.java   |  34 --
 dubbo-spi-rpc/pom.xml                              |   3 -
 110 files changed, 8611 deletions(-)

diff --git a/compiler/pom.xml b/compiler/pom.xml
deleted file mode 100644
index c3d4201..0000000
--- a/compiler/pom.xml
+++ /dev/null
@@ -1,237 +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.
-  -->
-
-<project xmlns="http://maven.apache.org/POM/4.0.0" xmlns:xsi="http://www.w3.org/2001/XMLSchema-instance"
-         xsi:schemaLocation="http://maven.apache.org/POM/4.0.0 http://maven.apache.org/maven-v4_0_0.xsd">
-    <modelVersion>4.0.0</modelVersion>
-    <parent>
-        <groupId>org.apache</groupId>
-        <artifactId>apache</artifactId>
-        <version>21</version>
-    </parent>
-
-    <groupId>org.apache.dubbo</groupId>
-    <artifactId>dubbo-compiler</artifactId>
-    <version>0.0.1</version>
-
-    <packaging>jar</packaging>
-
-    <properties>
-        <maven_compiler_version>3.6.0</maven_compiler_version>
-        <maven_jar_version>3.0.2</maven_jar_version>
-        <maven_source_version>3.0.1</maven_source_version>
-        <maven_javadoc_version>3.0.1</maven_javadoc_version>
-        <java_source_version>1.8</java_source_version>
-        <java_target_version>1.8</java_target_version>
-        <file_encoding>UTF-8</file_encoding>
-    </properties>
-
-    <dependencies>
-        <dependency>
-            <groupId>com.salesforce.servicelibs</groupId>
-            <artifactId>grpc-contrib</artifactId>
-            <version>0.8.1</version>
-        </dependency>
-        <dependency>
-            <groupId>com.salesforce.servicelibs</groupId>
-            <artifactId>jprotoc</artifactId>
-            <version>0.9.1</version>
-        </dependency>
-    </dependencies>
-
-    <build>
-        <plugins>
-            <plugin>
-                <groupId>org.apache.maven.plugins</groupId>
-                <artifactId>maven-compiler-plugin</artifactId>
-                <version>${maven_compiler_version}</version>
-                <configuration>
-                    <compilerArgument>-proc:none</compilerArgument>
-                    <fork>true</fork>
-                    <source>${java_source_version}</source>
-                    <target>${java_target_version}</target>
-                    <encoding>${file_encoding}</encoding>
-                </configuration>
-            </plugin>
-
-            <plugin>
-                <groupId>org.apache.maven.plugins</groupId>
-                <artifactId>maven-jar-plugin</artifactId>
-                <version>${maven_jar_version}</version>
-                <configuration>
-                    <archive>
-                        <manifest>
-                            <addClasspath>true</addClasspath>
-                            <mainClass>org.apache.dubbo.gen.grpc.DubboGrpcGenerator</mainClass>
-                        </manifest>
-                    </archive>
-                </configuration>
-            </plugin>
-
-            <!-- Optional, used to build directly executable packages (without using 'java -jar'),
-            for example 'artifactId-1.0.0-osx-x86_64.exe', 'artifactId-1.0.0-osx-x86_64.exe' -->
-            <plugin>
-                <groupId>com.salesforce.servicelibs</groupId>
-                <artifactId>canteen-maven-plugin</artifactId>
-                <version>1.0.0</version>
-                <executions>
-                    <execution>
-                        <goals>
-                            <goal>bootstrap</goal>
-                        </goals>
-                    </execution>
-                </executions>
-            </plugin>
-        </plugins>
-    </build>
-
-    <profiles>
-        <profile>
-            <id>release</id>
-            <properties>
-                <log4j2_version>2.11.1</log4j2_version>
-            </properties>
-            <build>
-                <plugins>
-                    <plugin>
-                        <artifactId>maven-source-plugin</artifactId>
-                        <version>${maven_source_version}</version>
-                        <executions>
-                            <execution>
-                                <id>attach-sources</id>
-                                <goals>
-                                    <goal>jar</goal>
-                                </goals>
-                            </execution>
-                        </executions>
-                    </plugin>
-                    <plugin>
-                        <artifactId>maven-javadoc-plugin</artifactId>
-                        <version>${maven_javadoc_version}</version>
-                        <executions>
-                            <execution>
-                                <id>attach-javadoc</id>
-                                <goals>
-                                    <goal>jar</goal>
-                                    <goal>aggregate</goal>
-                                </goals>
-                                <configuration>
-                                    <additionalDependencies>
-                                        <additionalDependency>
-                                            <groupId>org.apache.logging.log4j</groupId>
-                                            <artifactId>log4j-api</artifactId>
-                                            <version>${log4j2_version}</version>
-                                        </additionalDependency>
-                                        <additionalDependency>
-                                            <groupId>org.apache.logging.log4j</groupId>
-                                            <artifactId>log4j-core</artifactId>
-                                            <version>${log4j2_version}</version>
-                                        </additionalDependency>
-                                    </additionalDependencies>
-                                </configuration>
-                            </execution>
-                        </executions>
-                        <configuration>
-                            <show>public</show>
-                            <charset>UTF-8</charset>
-                            <encoding>UTF-8</encoding>
-                            <docencoding>UTF-8</docencoding>
-                            <links>
-                                <link>http://docs.oracle.com/javase/8/docs/api</link>
-                            </links>
-                            <doclint>none</doclint>
-                            <excludePackageNames>
-                                org.apache.dubbo.demo,org.apache.dubbo.demo.*
-                            </excludePackageNames>
-                            <doctitle>Apache Dubbo ${project.version} API</doctitle>
-                            <windowtitle>Apache Dubbo ${project.version} API</windowtitle>
-                        </configuration>
-                    </plugin>
-                    <plugin>
-                        <groupId>org.apache.maven.plugins</groupId>
-                        <artifactId>maven-gpg-plugin</artifactId>
-                        <executions>
-                            <execution>
-                                <phase>verify</phase>
-                                <goals>
-                                    <goal>sign</goal>
-                                </goals>
-                            </execution>
-                        </executions>
-                    </plugin>
-                </plugins>
-            </build>
-        </profile>
-    </profiles>
-
-    <name>dubbo-compiler</name>
-    <description>Dubbo customized RPC stub compiler.</description>
-    <url>https://github.com/apache/dubbo</url>
-    <inceptionYear>2011</inceptionYear>
-    <licenses>
-        <license>
-            <name>Apache License, Version 2.0</name>
-            <url>http://www.apache.org/licenses/LICENSE-2.0</url>
-            <distribution>repo</distribution>
-        </license>
-    </licenses>
-
-    <scm>
-        <url>https://github.com/apache/dubbo</url>
-        <connection>scm:git:https://github.com/apache/dubbo.git</connection>
-        <developerConnection>scm:git:https://github.com/apache/dubbo.git</developerConnection>
-        <tag>HEAD</tag>
-    </scm>
-    <mailingLists>
-        <mailingList>
-            <name>Development List</name>
-            <subscribe>dev-subscribe@dubbo.apache.org</subscribe>
-            <unsubscribe>dev-unsubscribe@dubbo.apache.org</unsubscribe>
-            <post>dev@dubbo.apache.org</post>
-        </mailingList>
-        <mailingList>
-            <name>Commits List</name>
-            <subscribe>commits-subscribe@dubbo.apache.org</subscribe>
-            <unsubscribe>commits-unsubscribe@dubbo.apache.org</unsubscribe>
-            <post>commits@dubbo.apache.org</post>
-        </mailingList>
-        <mailingList>
-            <name>Issues List</name>
-            <subscribe>issues-subscribe@dubbo.apache.org</subscribe>
-            <unsubscribe>issues-unsubscribe@dubbo.apache.org</unsubscribe>
-            <post>issues@dubbo.apache.org</post>
-        </mailingList>
-    </mailingLists>
-    <developers>
-        <developer>
-            <id>dubbo.io</id>
-            <name>The Dubbo Project Contributors</name>
-            <email>dev-subscribe@dubbo.apache.org</email>
-            <url>http://dubbo.apache.org/</url>
-        </developer>
-    </developers>
-
-    <organization>
-        <name>The Apache Software Foundation</name>
-        <url>http://www.apache.org/</url>
-    </organization>
-
-    <issueManagement>
-        <system>Github Issues</system>
-        <url>https://github.com/apache/dubbo/issues</url>
-    </issueManagement>
-</project>
\ No newline at end of file
diff --git a/compiler/src/main/java/org/apache/dubbo/gen/AbstractGenerator.java b/compiler/src/main/java/org/apache/dubbo/gen/AbstractGenerator.java
deleted file mode 100644
index 3e8dee1..0000000
--- a/compiler/src/main/java/org/apache/dubbo/gen/AbstractGenerator.java
+++ /dev/null
@@ -1,293 +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.gen;
-
-import com.google.common.base.Strings;
-import com.google.common.html.HtmlEscapers;
-import com.google.protobuf.DescriptorProtos.FileDescriptorProto;
-import com.google.protobuf.DescriptorProtos.FileOptions;
-import com.google.protobuf.DescriptorProtos.MethodDescriptorProto;
-import com.google.protobuf.DescriptorProtos.ServiceDescriptorProto;
-import com.google.protobuf.DescriptorProtos.SourceCodeInfo.Location;
-import com.google.protobuf.compiler.PluginProtos;
-import com.salesforce.jprotoc.Generator;
-import com.salesforce.jprotoc.GeneratorException;
-import com.salesforce.jprotoc.ProtoTypeMap;
-
-import java.util.ArrayList;
-import java.util.Arrays;
-import java.util.HashSet;
-import java.util.List;
-import java.util.Set;
-import java.util.stream.Collectors;
-
-public abstract class AbstractGenerator extends Generator {
-
-    private static final int SERVICE_NUMBER_OF_PATHS = 2;
-    private static final int METHOD_NUMBER_OF_PATHS = 4;
-
-    protected abstract String getClassPrefix();
-
-    protected abstract String getClassSuffix();
-
-    private String getServiceJavaDocPrefix() {
-        return "    ";
-    }
-
-    private String getMethodJavaDocPrefix() {
-        return "        ";
-    }
-
-    @Override
-    public List<PluginProtos.CodeGeneratorResponse.File> generateFiles(PluginProtos.CodeGeneratorRequest request) throws GeneratorException {
-        final ProtoTypeMap typeMap = ProtoTypeMap.of(request.getProtoFileList());
-
-        List<FileDescriptorProto> protosToGenerate = request.getProtoFileList().stream()
-                .filter(protoFile -> request.getFileToGenerateList().contains(protoFile.getName()))
-                .collect(Collectors.toList());
-
-        List<ServiceContext> services = findServices(protosToGenerate, typeMap);
-        return generateFiles(services);
-    }
-
-    private List<ServiceContext> findServices(List<FileDescriptorProto> protos, ProtoTypeMap typeMap) {
-        List<ServiceContext> contexts = new ArrayList<>();
-
-        protos.forEach(fileProto -> {
-            for (int serviceNumber = 0; serviceNumber < fileProto.getServiceCount(); serviceNumber++) {
-                ServiceContext serviceContext = buildServiceContext(
-                    fileProto.getService(serviceNumber),
-                    typeMap,
-                    fileProto.getSourceCodeInfo().getLocationList(),
-                    serviceNumber
-                );
-                serviceContext.protoName = fileProto.getName();
-                serviceContext.packageName = extractPackageName(fileProto);
-                contexts.add(serviceContext);
-            }
-        });
-
-        return contexts;
-    }
-
-    private String extractPackageName(FileDescriptorProto proto) {
-        FileOptions options = proto.getOptions();
-        if (options != null) {
-            String javaPackage = options.getJavaPackage();
-            if (!Strings.isNullOrEmpty(javaPackage)) {
-                return javaPackage;
-            }
-        }
-
-        return Strings.nullToEmpty(proto.getPackage());
-    }
-
-    private ServiceContext buildServiceContext(ServiceDescriptorProto serviceProto, ProtoTypeMap typeMap, List<Location> locations, int serviceNumber) {
-        ServiceContext serviceContext = new ServiceContext();
-        serviceContext.fileName = getClassPrefix() + serviceProto.getName() + getClassSuffix() + ".java";
-        serviceContext.className = getClassPrefix() + serviceProto.getName() + getClassSuffix();
-        serviceContext.serviceName = serviceProto.getName();
-        serviceContext.deprecated = serviceProto.getOptions() != null && serviceProto.getOptions().getDeprecated();
-
-        List<Location> allLocationsForService = locations.stream()
-                .filter(location ->
-                    location.getPathCount() >= 2 &&
-                       location.getPath(0) == FileDescriptorProto.SERVICE_FIELD_NUMBER &&
-                       location.getPath(1) == serviceNumber
-                )
-                .collect(Collectors.toList());
-
-        Location serviceLocation = allLocationsForService.stream()
-                .filter(location -> location.getPathCount() == SERVICE_NUMBER_OF_PATHS)
-                .findFirst()
-                .orElseGet(Location::getDefaultInstance);
-        serviceContext.javaDoc = getJavaDoc(getComments(serviceLocation), getServiceJavaDocPrefix());
-
-        for (int methodNumber = 0; methodNumber < serviceProto.getMethodCount(); methodNumber++) {
-            MethodContext methodContext = buildMethodContext(
-                serviceProto.getMethod(methodNumber),
-                typeMap,
-                locations,
-                methodNumber
-            );
-
-            serviceContext.methods.add(methodContext);
-            serviceContext.methodTypes.add(methodContext.inputType);
-            serviceContext.methodTypes.add(methodContext.outputType);
-        }
-        return serviceContext;
-    }
-
-    private MethodContext buildMethodContext(MethodDescriptorProto methodProto, ProtoTypeMap typeMap, List<Location> locations, int methodNumber) {
-        MethodContext methodContext = new MethodContext();
-        methodContext.methodName = lowerCaseFirst(methodProto.getName());
-        methodContext.inputType = typeMap.toJavaTypeName(methodProto.getInputType());
-        methodContext.outputType = typeMap.toJavaTypeName(methodProto.getOutputType());
-        methodContext.deprecated = methodProto.getOptions() != null && methodProto.getOptions().getDeprecated();
-        methodContext.isManyInput = methodProto.getClientStreaming();
-        methodContext.isManyOutput = methodProto.getServerStreaming();
-        methodContext.methodNumber = methodNumber;
-
-        Location methodLocation = locations.stream()
-                .filter(location ->
-                    location.getPathCount() == METHOD_NUMBER_OF_PATHS &&
-                        location.getPath(METHOD_NUMBER_OF_PATHS - 1) == methodNumber
-                )
-                .findFirst()
-                .orElseGet(Location::getDefaultInstance);
-        methodContext.javaDoc = getJavaDoc(getComments(methodLocation), getMethodJavaDocPrefix());
-
-        if (!methodProto.getClientStreaming() && !methodProto.getServerStreaming()) {
-            methodContext.reactiveCallsMethodName = "oneToOne";
-            methodContext.grpcCallsMethodName = "asyncUnaryCall";
-        }
-        if (!methodProto.getClientStreaming() && methodProto.getServerStreaming()) {
-            methodContext.reactiveCallsMethodName = "oneToMany";
-            methodContext.grpcCallsMethodName = "asyncServerStreamingCall";
-        }
-        if (methodProto.getClientStreaming() && !methodProto.getServerStreaming()) {
-            methodContext.reactiveCallsMethodName = "manyToOne";
-            methodContext.grpcCallsMethodName = "asyncClientStreamingCall";
-        }
-        if (methodProto.getClientStreaming() && methodProto.getServerStreaming()) {
-            methodContext.reactiveCallsMethodName = "manyToMany";
-            methodContext.grpcCallsMethodName = "asyncBidiStreamingCall";
-        }
-        return methodContext;
-    }
-
-    private String lowerCaseFirst(String s) {
-        return Character.toLowerCase(s.charAt(0)) + s.substring(1);
-    }
-
-    private List<PluginProtos.CodeGeneratorResponse.File> generateFiles(List<ServiceContext> services) {
-        return services.stream()
-                .map(this::buildFile)
-                .collect(Collectors.toList());
-    }
-
-    private PluginProtos.CodeGeneratorResponse.File buildFile(ServiceContext context) {
-        String content = applyTemplate(getClassPrefix() + getClassSuffix() + "Stub.mustache", context);
-        return PluginProtos.CodeGeneratorResponse.File
-                .newBuilder()
-                .setName(absoluteFileName(context))
-                .setContent(content)
-                .build();
-    }
-
-    private String absoluteFileName(ServiceContext ctx) {
-        String dir = ctx.packageName.replace('.', '/');
-        if (Strings.isNullOrEmpty(dir)) {
-            return ctx.fileName;
-        } else {
-            return dir + "/" + ctx.fileName;
-        }
-    }
-
-    private String getComments(Location location) {
-        return location.getLeadingComments().isEmpty() ? location.getTrailingComments() : location.getLeadingComments();
-    }
-
-    private String getJavaDoc(String comments, String prefix) {
-        if (!comments.isEmpty()) {
-            StringBuilder builder = new StringBuilder("/**\n")
-                    .append(prefix).append(" * <pre>\n");
-            Arrays.stream(HtmlEscapers.htmlEscaper().escape(comments).split("\n"))
-                    .map(line -> line.replace("*/", "&#42;&#47;").replace("*", "&#42;"))
-                    .forEach(line -> builder.append(prefix).append(" * ").append(line).append("\n"));
-            builder
-                    .append(prefix).append(" * </pre>\n")
-                    .append(prefix).append(" */");
-            return builder.toString();
-        }
-        return null;
-    }
-
-    /**
-     * Template class for proto Service objects.
-     */
-    private class ServiceContext {
-        // CHECKSTYLE DISABLE VisibilityModifier FOR 8 LINES
-        public String fileName;
-        public String protoName;
-        public String packageName;
-        public String className;
-        public String serviceName;
-        public boolean deprecated;
-        public String javaDoc;
-        public List<MethodContext> methods = new ArrayList<>();
-
-        public Set<String> methodTypes = new HashSet<>();
-
-        public List<MethodContext> unaryRequestMethods() {
-            return methods.stream().filter(m -> !m.isManyInput).collect(Collectors.toList());
-        }
-
-        public List<MethodContext> unaryMethods() {
-            return methods.stream().filter(m -> (!m.isManyInput && !m.isManyOutput)).collect(Collectors.toList());
-        }
-
-        public List<MethodContext> serverStreamingMethods() {
-            return methods.stream().filter(m -> !m.isManyInput && m.isManyOutput).collect(Collectors.toList());
-        }
-
-        public List<MethodContext> biStreamingMethods() {
-            return methods.stream().filter(m -> m.isManyInput).collect(Collectors.toList());
-        }
-    }
-
-    /**
-     * Template class for proto RPC objects.
-     */
-    private class MethodContext {
-        // CHECKSTYLE DISABLE VisibilityModifier FOR 10 LINES
-        public String methodName;
-        public String inputType;
-        public String outputType;
-        public boolean deprecated;
-        public boolean isManyInput;
-        public boolean isManyOutput;
-        public String reactiveCallsMethodName;
-        public String grpcCallsMethodName;
-        public int methodNumber;
-        public String javaDoc;
-
-        // This method mimics the upper-casing method ogf gRPC to ensure compatibility
-        // See https://github.com/grpc/grpc-java/blob/v1.8.0/compiler/src/java_plugin/cpp/java_generator.cpp#L58
-        public String methodNameUpperUnderscore() {
-            StringBuilder s = new StringBuilder();
-            for (int i = 0; i < methodName.length(); i++) {
-                char c = methodName.charAt(i);
-                s.append(Character.toUpperCase(c));
-                if ((i < methodName.length() - 1) && Character.isLowerCase(c) && Character.isUpperCase(methodName.charAt(i + 1))) {
-                    s.append('_');
-                }
-            }
-            return s.toString();
-        }
-
-        public String methodNamePascalCase() {
-            String mn = methodName.replace("_", "");
-            return String.valueOf(Character.toUpperCase(mn.charAt(0))) + mn.substring(1);
-        }
-
-        public String methodNameCamelCase() {
-            String mn = methodName.replace("_", "");
-            return String.valueOf(Character.toLowerCase(mn.charAt(0))) + mn.substring(1);
-        }
-    }
-}
diff --git a/compiler/src/main/java/org/apache/dubbo/gen/dubbo/DubboGenerator.java b/compiler/src/main/java/org/apache/dubbo/gen/dubbo/DubboGenerator.java
deleted file mode 100644
index 1c35f0a..0000000
--- a/compiler/src/main/java/org/apache/dubbo/gen/dubbo/DubboGenerator.java
+++ /dev/null
@@ -1,42 +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.gen.dubbo;
-
-import org.apache.dubbo.gen.AbstractGenerator;
-
-import com.salesforce.jprotoc.ProtocPlugin;
-
-public class DubboGenerator extends AbstractGenerator {
-
-    public static void main(String[] args) {
-        if (args.length == 0) {
-            ProtocPlugin.generate(new DubboGenerator());
-        } else {
-            ProtocPlugin.debug(new DubboGenerator(), args[0]);
-        }
-    }
-
-    @Override
-    protected String getClassPrefix() {
-        return "";
-    }
-
-    @Override
-    protected String getClassSuffix() {
-        return "Dubbo";
-    }
-}
\ No newline at end of file
diff --git a/compiler/src/main/java/org/apache/dubbo/gen/grpc/DubboGrpcGenerator.java b/compiler/src/main/java/org/apache/dubbo/gen/grpc/DubboGrpcGenerator.java
deleted file mode 100644
index dafdd5a..0000000
--- a/compiler/src/main/java/org/apache/dubbo/gen/grpc/DubboGrpcGenerator.java
+++ /dev/null
@@ -1,41 +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.gen.grpc;
-
-import org.apache.dubbo.gen.AbstractGenerator;
-
-import com.salesforce.jprotoc.ProtocPlugin;
-
-public class DubboGrpcGenerator extends AbstractGenerator {
-
-    public static void main(String[] args) {
-        if (args.length == 0) {
-            ProtocPlugin.generate(new DubboGrpcGenerator());
-        } else {
-            ProtocPlugin.debug(new DubboGrpcGenerator(), args[0]);
-        }
-    }
-
-    @Override
-    protected String getClassPrefix() {
-        return "Dubbo";
-    }
-
-    protected String getClassSuffix() {
-        return "Grpc";
-    }
-}
diff --git a/compiler/src/main/java/org/apache/dubbo/gen/grpc/reactive/ReactorDubboGrpcGenerator.java b/compiler/src/main/java/org/apache/dubbo/gen/grpc/reactive/ReactorDubboGrpcGenerator.java
deleted file mode 100644
index dd9520b..0000000
--- a/compiler/src/main/java/org/apache/dubbo/gen/grpc/reactive/ReactorDubboGrpcGenerator.java
+++ /dev/null
@@ -1,42 +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.gen.grpc.reactive;
-
-import org.apache.dubbo.gen.AbstractGenerator;
-
-import com.salesforce.jprotoc.ProtocPlugin;
-
-public class ReactorDubboGrpcGenerator extends AbstractGenerator {
-
-    @Override
-    protected String getClassPrefix() {
-        return "ReactorDubbo";
-    }
-
-    @Override
-    protected String getClassSuffix() {
-        return "Grpc";
-    }
-
-    public static void main(String[] args) {
-        if (args.length == 0) {
-            ProtocPlugin.generate(new ReactorDubboGrpcGenerator());
-        } else {
-            ProtocPlugin.debug(new ReactorDubboGrpcGenerator(), args[0]);
-        }
-    }
-}
diff --git a/compiler/src/main/java/org/apache/dubbo/gen/grpc/reactive/RxDubboGrpcGenerator.java b/compiler/src/main/java/org/apache/dubbo/gen/grpc/reactive/RxDubboGrpcGenerator.java
deleted file mode 100644
index 028332a..0000000
--- a/compiler/src/main/java/org/apache/dubbo/gen/grpc/reactive/RxDubboGrpcGenerator.java
+++ /dev/null
@@ -1,41 +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.gen.grpc.reactive;
-
-import org.apache.dubbo.gen.AbstractGenerator;
-
-import com.salesforce.jprotoc.ProtocPlugin;
-
-public class RxDubboGrpcGenerator extends AbstractGenerator {
-    @Override
-    protected String getClassPrefix() {
-        return "RxDubbo";
-    }
-
-    @Override
-    protected String getClassSuffix() {
-        return "Grpc";
-    }
-
-    public static void main(String[] args) {
-        if (args.length == 0) {
-            ProtocPlugin.generate(new RxDubboGrpcGenerator());
-        } else {
-            ProtocPlugin.debug(new RxDubboGrpcGenerator(), args[0]);
-        }
-    }
-}
diff --git a/compiler/src/main/resources/DubboGrpcStub.mustache b/compiler/src/main/resources/DubboGrpcStub.mustache
deleted file mode 100644
index a02d0c4..0000000
--- a/compiler/src/main/resources/DubboGrpcStub.mustache
+++ /dev/null
@@ -1,312 +0,0 @@
-{{#packageName}}
-    package {{packageName}};
-{{/packageName}}
-
-import org.apache.dubbo.common.URL;
-import org.apache.dubbo.config.ReferenceConfigBase;
-
-import java.util.concurrent.TimeUnit;
-
-import static org.apache.dubbo.common.constants.CommonConstants.DEFAULT_TIMEOUT;
-import static org.apache.dubbo.common.constants.CommonConstants.TIMEOUT_KEY;
-
-import static {{packageName}}.{{serviceName}}Grpc.getServiceDescriptor;
-import static io.grpc.stub.ServerCalls.asyncUnaryCall;
-import static io.grpc.stub.ServerCalls.asyncServerStreamingCall;
-import static io.grpc.stub.ServerCalls.asyncClientStreamingCall;
-import static io.grpc.stub.ServerCalls.asyncBidiStreamingCall;
-import static io.grpc.stub.ServerCalls.asyncUnimplementedStreamingCall;
-import static io.grpc.stub.ServerCalls.asyncUnimplementedUnaryCall;
-
-{{#deprecated}}
-    @java.lang.Deprecated
-{{/deprecated}}
-@javax.annotation.Generated(
-value = "by DubboGrpc generator",
-comments = "Source: {{protoName}}")
-public final class {{className}} {
-private {{className}}() {}
-
-public static class Dubbo{{serviceName}}Stub implements I{{serviceName}} {
-
-protected URL url;
-protected ReferenceConfigBase<?> referenceConfig;
-
-protected {{serviceName}}Grpc.{{serviceName}}BlockingStub blockingStub;
-protected {{serviceName}}Grpc.{{serviceName}}FutureStub futureStub;
-protected {{serviceName}}Grpc.{{serviceName}}Stub stub;
-
-public Dubbo{{serviceName}}Stub(io.grpc.Channel channel, io.grpc.CallOptions callOptions, URL url, ReferenceConfigBase<?> referenceConfig) {
-this.url = url;
-this.referenceConfig = referenceConfig;
-
-blockingStub = {{serviceName}}Grpc.newBlockingStub(channel).build(channel, callOptions);
-futureStub = {{serviceName}}Grpc.newFutureStub(channel).build(channel, callOptions);
-stub = {{serviceName}}Grpc.newStub(channel).build(channel, callOptions);
-}
-
-{{#unaryMethods}}
-    {{#javaDoc}}
-        {{{javaDoc}}}
-    {{/javaDoc}}
-    {{#deprecated}}
-        @java.lang.Deprecated
-    {{/deprecated}}
-    public {{outputType}} {{methodName}}({{inputType}} request) {
-    return blockingStub
-    .withDeadlineAfter(url.getParameter(TIMEOUT_KEY, DEFAULT_TIMEOUT), TimeUnit.MILLISECONDS)
-    .{{methodName}}(request);
-    }
-
-    public com.google.common.util.concurrent.ListenableFuture<{{outputType}}> {{methodName}}Async({{inputType}} request) {
-    return futureStub
-    .withDeadlineAfter(url.getParameter(TIMEOUT_KEY, DEFAULT_TIMEOUT), TimeUnit.MILLISECONDS)
-    .{{methodName}}(request);
-    }
-
-    public void {{methodName}}({{inputType}} request, io.grpc.stub.StreamObserver<{{outputType}}> responseObserver){
-    stub
-    .withDeadlineAfter(url.getParameter(TIMEOUT_KEY, DEFAULT_TIMEOUT), TimeUnit.MILLISECONDS)
-    .{{methodName}}(request, responseObserver);
-    }
-
-{{/unaryMethods}}
-{{#serverStreamingMethods}}
-    {{#javaDoc}}
-        {{{javaDoc}}}
-    {{/javaDoc}}
-    {{#deprecated}}
-        @java.lang.Deprecated
-    {{/deprecated}}
-    public java.util.Iterator<{{outputType}}> {{methodName}}({{inputType}} request) {
-    return blockingStub
-    .withDeadlineAfter(url.getParameter(TIMEOUT_KEY, DEFAULT_TIMEOUT), TimeUnit.MILLISECONDS)
-    .{{methodName}}(request);
-    }
-
-    public void {{methodName}}({{inputType}} request, io.grpc.stub.StreamObserver<{{outputType}}> responseObserver) {
-    stub
-    .withDeadlineAfter(url.getParameter(TIMEOUT_KEY, DEFAULT_TIMEOUT), TimeUnit.MILLISECONDS)
-    .{{methodName}}(request, responseObserver);
-    }
-
-{{/serverStreamingMethods}}
-{{#biStreamingMethods}}
-    {{#javaDoc}}
-        {{{javaDoc}}}
-    {{/javaDoc}}
-    {{#deprecated}}
-        @java.lang.Deprecated
-    {{/deprecated}}
-    public io.grpc.stub.StreamObserver<{{inputType}}> {{methodName}}(io.grpc.stub.StreamObserver<{{outputType}}> responseObserver) {
-    return stub
-    .withDeadlineAfter(url.getParameter(TIMEOUT_KEY, DEFAULT_TIMEOUT), TimeUnit.MILLISECONDS)
-    .{{methodName}}(responseObserver);
-    }
-{{/biStreamingMethods}}
-}
-
-public static Dubbo{{serviceName}}Stub getDubboStub(io.grpc.Channel channel, io.grpc.CallOptions callOptions, URL url, ReferenceConfigBase<?> referenceConfig) {
-return new Dubbo{{serviceName}}Stub(channel, callOptions, url, referenceConfig);
-}
-
-public interface I{{serviceName}} {
-{{#unaryMethods}}
-    {{#javaDoc}}
-        {{{javaDoc}}}
-    {{/javaDoc}}
-    {{#deprecated}}
-        @java.lang.Deprecated
-    {{/deprecated}}
-    default public {{outputType}} {{methodName}}({{inputType}} request) {
-    throw new UnsupportedOperationException("No need to override this method, extend XxxImplBase and override all methods it allows.");
-    }
-
-    {{#javaDoc}}
-        {{{javaDoc}}}
-    {{/javaDoc}}
-    {{#deprecated}}
-        @java.lang.Deprecated
-    {{/deprecated}}
-    default public com.google.common.util.concurrent.ListenableFuture<{{outputType}}> {{methodName}}Async({{inputType}} request) {
-    throw new UnsupportedOperationException("No need to override this method, extend XxxImplBase and override all methods it allows.");
-    }
-
-    {{#javaDoc}}
-        {{{javaDoc}}}
-    {{/javaDoc}}
-    {{#deprecated}}
-        @java.lang.Deprecated
-    {{/deprecated}}
-    public void {{methodName}}({{inputType}} request, io.grpc.stub.StreamObserver<{{outputType}}> responseObserver);
-
-{{/unaryMethods}}
-{{#serverStreamingMethods}}
-    {{#javaDoc}}
-        {{{javaDoc}}}
-    {{/javaDoc}}
-    {{#deprecated}}
-        @java.lang.Deprecated
-    {{/deprecated}}
-    default public java.util.Iterator<{{outputType}}> {{methodName}}({{inputType}} request) {
-    throw new UnsupportedOperationException("No need to override this method, extend XxxImplBase and override all methods it allows.");
-    }
-
-    {{#javaDoc}}
-        {{{javaDoc}}}
-    {{/javaDoc}}
-    {{#deprecated}}
-        @java.lang.Deprecated
-    {{/deprecated}}
-    public void {{methodName}}({{inputType}} request, io.grpc.stub.StreamObserver<{{outputType}}> responseObserver);
-
-{{/serverStreamingMethods}}
-{{#biStreamingMethods}}
-    {{#javaDoc}}
-        {{{javaDoc}}}
-    {{/javaDoc}}
-    {{#deprecated}}
-        @java.lang.Deprecated
-    {{/deprecated}}
-    public io.grpc.stub.StreamObserver<{{inputType}}> {{methodName}}(io.grpc.stub.StreamObserver<{{outputType}}> responseObserver);
-
-{{/biStreamingMethods}}
-}
-
-{{#javaDoc}}
-    {{{javaDoc}}}
-{{/javaDoc}}
-public static abstract class {{serviceName}}ImplBase implements io.grpc.BindableService, I{{serviceName}} {
-
-private I{{serviceName}} proxiedImpl;
-
-public final void setProxiedImpl(I{{serviceName}} proxiedImpl) {
-this.proxiedImpl = proxiedImpl;
-}
-
-{{#unaryMethods}}
-    {{#javaDoc}}
-        {{{javaDoc}}}
-    {{/javaDoc}}
-    {{#deprecated}}
-        @java.lang.Deprecated
-    {{/deprecated}}
-    @java.lang.Override
-    public final {{outputType}} {{methodName}}({{inputType}} request) {
-    throw new UnsupportedOperationException("No need to override this method, extend XxxImplBase and override all methods it allows.");
-    }
-
-    {{#javaDoc}}
-        {{{javaDoc}}}
-    {{/javaDoc}}
-    {{#deprecated}}
-        @java.lang.Deprecated
-    {{/deprecated}}
-    @java.lang.Override
-    public final com.google.common.util.concurrent.ListenableFuture<{{outputType}}> {{methodName}}Async({{inputType}} request) {
-    throw new UnsupportedOperationException("No need to override this method, extend XxxImplBase and override all methods it allows.");
-    }
-
-{{/unaryMethods}}
-{{#serverStreamingMethods}}
-    {{#javaDoc}}
-        {{{javaDoc}}}
-    {{/javaDoc}}
-    {{#deprecated}}
-        @java.lang.Deprecated
-    {{/deprecated}}
-    @java.lang.Override
-    public final java.util.Iterator<{{outputType}}> {{methodName}}({{inputType}} request) {
-    throw new UnsupportedOperationException("No need to override this method, extend XxxImplBase and override all methods it allows.");
-    }
-
-{{/serverStreamingMethods}}
-{{#methods}}
-    {{#isManyInput}}
-        public io.grpc.stub.StreamObserver<{{inputType}}> {{methodName}}(
-        io.grpc.stub.StreamObserver<{{outputType}}> responseObserver) {
-        return asyncUnimplementedStreamingCall({{packageName}}.{{serviceName}}Grpc.get{{methodNamePascalCase}}Method(), responseObserver);
-        }
-    {{/isManyInput}}{{^isManyInput}}
-        public void {{methodName}}({{inputType}} request,
-        io.grpc.stub.StreamObserver<{{outputType}}> responseObserver) {
-        asyncUnimplementedUnaryCall({{packageName}}.{{serviceName}}Grpc.get{{methodNamePascalCase}}Method(), responseObserver);
-        }
-    {{/isManyInput}}
-{{/methods}}
-
-@java.lang.Override public final io.grpc.ServerServiceDefinition bindService() {
-return io.grpc.ServerServiceDefinition.builder(getServiceDescriptor())
-{{#methods}}
-    .addMethod(
-    {{packageName}}.{{serviceName}}Grpc.get{{methodNamePascalCase}}Method(),
-    {{grpcCallsMethodName}}(
-    new MethodHandlers<
-    {{inputType}},
-    {{outputType}}>(
-    proxiedImpl, METHODID_{{methodNameUpperUnderscore}})))
-{{/methods}}
-.build();
-}
-}
-{{#methods}}
-    private static final int METHODID_{{methodNameUpperUnderscore}} = {{methodNumber}};
-{{/methods}}
-
-private static final class MethodHandlers
-<Req, Resp> implements
-io.grpc.stub.ServerCalls.UnaryMethod
-<Req, Resp>,
-io.grpc.stub.ServerCalls.ServerStreamingMethod
-<Req, Resp>,
-io.grpc.stub.ServerCalls.ClientStreamingMethod
-<Req, Resp>,
-io.grpc.stub.ServerCalls.BidiStreamingMethod
-<Req, Resp> {
-private final I{{serviceName}} serviceImpl;
-private final int methodId;
-
-MethodHandlers(I{{serviceName}} serviceImpl, int methodId) {
-this.serviceImpl = serviceImpl;
-this.methodId = methodId;
-}
-
-@java.lang.Override
-@java.lang.SuppressWarnings("unchecked")
-public void invoke(Req request, io.grpc.stub.StreamObserver
-<Resp> responseObserver) {
-    switch (methodId) {
-    {{#methods}}
-        {{^isManyInput}}
-            case METHODID_{{methodNameUpperUnderscore}}:
-            serviceImpl.{{methodName}}(({{inputType}}) request,
-            (io.grpc.stub.StreamObserver<{{outputType}}>) responseObserver);
-            break;
-        {{/isManyInput}}
-    {{/methods}}
-    default:
-    throw new java.lang.AssertionError();
-    }
-    }
-
-    @java.lang.Override
-    @java.lang.SuppressWarnings("unchecked")
-    public io.grpc.stub.StreamObserver
-    <Req> invoke(io.grpc.stub.StreamObserver
-        <Resp> responseObserver) {
-            switch (methodId) {
-            {{#methods}}
-                {{#isManyInput}}
-                    case METHODID_{{methodNameUpperUnderscore}}:
-                    return (io.grpc.stub.StreamObserver
-                <Req>) serviceImpl.{{methodName}}(
-                    (io.grpc.stub.StreamObserver<{{outputType}}>) responseObserver);
-                {{/isManyInput}}
-            {{/methods}}
-            default:
-            throw new java.lang.AssertionError();
-            }
-            }
-            }
-
-            }
diff --git a/compiler/src/main/resources/DubboStub.mustache b/compiler/src/main/resources/DubboStub.mustache
deleted file mode 100644
index 06bd7b4..0000000
--- a/compiler/src/main/resources/DubboStub.mustache
+++ /dev/null
@@ -1,53 +0,0 @@
-{{#packageName}}
-    package {{packageName}};
-{{/packageName}}
-
-import java.util.concurrent.CompletableFuture;
-import java.util.concurrent.atomic.AtomicBoolean;
-
-{{#deprecated}}
-    @java.lang.Deprecated
-{{/deprecated}}
-@javax.annotation.Generated(
-value = "by Dubbo generator",
-comments = "Source: {{protoName}}")
-public final class {{className}} {
-private static final AtomicBoolean registered = new AtomicBoolean();
-
-private static Class<?> init() {
-Class<?> clazz = null;
-try {
-clazz = Class.forName({{serviceName}}Dubbo.class.getName());
-if (registered.compareAndSet(false, true)) {
-{{#methodTypes}}
-    org.apache.dubbo.common.serialize.protobuf.support.ProtobufUtils.marshaller(
-    {{.}}.getDefaultInstance());
-{{/methodTypes}}
-}
-} catch (ClassNotFoundException e) {
-// ignore
-}
-return clazz;
-}
-
-private {{serviceName}}Dubbo() {}
-
-public static final String SERVICE_NAME = "{{packageName}}.{{serviceName}}";
-
-/**
-* Code generated for Dubbo
-*/
-public interface I{{serviceName}} {
-
-static Class<?> clazz = init();
-
-{{#methods}}
-    {{outputType}} {{methodName}}({{inputType}} request);
-
-    CompletableFuture<{{outputType}}> {{methodName}}Async({{inputType}} request);
-
-{{/methods}}
-
-}
-
-}
diff --git a/compiler/src/main/resources/ReactorDubboGrpcStub.mustache b/compiler/src/main/resources/ReactorDubboGrpcStub.mustache
deleted file mode 100644
index 2cf1471..0000000
--- a/compiler/src/main/resources/ReactorDubboGrpcStub.mustache
+++ /dev/null
@@ -1,212 +0,0 @@
-{{#packageName}}
-    package {{packageName}};
-{{/packageName}}
-
-import org.apache.dubbo.common.URL;
-import org.apache.dubbo.config.ReferenceConfigBase;
-
-import java.util.concurrent.TimeUnit;
-
-import static org.apache.dubbo.common.constants.CommonConstants.DEFAULT_TIMEOUT;
-import static org.apache.dubbo.common.constants.CommonConstants.TIMEOUT_KEY;
-
-import static {{packageName}}.{{serviceName}}Grpc.getServiceDescriptor;
-import static io.grpc.stub.ServerCalls.asyncUnaryCall;
-import static io.grpc.stub.ServerCalls.asyncServerStreamingCall;
-import static io.grpc.stub.ServerCalls.asyncClientStreamingCall;
-import static io.grpc.stub.ServerCalls.asyncBidiStreamingCall;
-
-
-{{#deprecated}}
-    @java.lang.Deprecated
-{{/deprecated}}
-@javax.annotation.Generated(
-value = "by ReactorDubboGrpc generator",
-comments = "Source: {{protoName}}")
-public final class {{className}} {
-private {{className}}() {}
-
-public static ReactorDubbo{{serviceName}}Stub getDubboStub(io.grpc.Channel channel, io.grpc.CallOptions callOptions, URL url, ReferenceConfigBase<?> referenceConfig) {
-return new ReactorDubbo{{serviceName}}Stub(channel, callOptions, url, referenceConfig);
-}
-
-{{#javaDoc}}
-    {{{javaDoc}}}
-{{/javaDoc}}
-public static final class ReactorDubbo{{serviceName}}Stub implements IReactor{{serviceName}} {
-
-protected URL url;
-protected ReferenceConfigBase<?> referenceConfig;
-
-protected {{serviceName}}Grpc.{{serviceName}}Stub stub;
-
-public ReactorDubbo{{serviceName}}Stub(io.grpc.Channel channel, io.grpc.CallOptions callOptions, URL url, ReferenceConfigBase<?> referenceConfig) {
-this.url = url;
-this.referenceConfig = referenceConfig;
-stub = {{serviceName}}Grpc.newStub(channel).build(channel, callOptions);
-}
-
-{{#methods}}
-    {{#javaDoc}}
-        {{{javaDoc}}}
-    {{/javaDoc}}
-    {{#deprecated}}
-        @java.lang.Deprecated
-    {{/deprecated}}
-    public {{#isManyOutput}}reactor.core.publisher.Flux{{/isManyOutput}}{{^isManyOutput}}reactor.core.publisher.Mono{{/isManyOutput}}<{{outputType}}> {{methodName}}({{#isManyInput}}reactor.core.publisher.Flux{{/isManyInput}}{{^isManyInput}}reactor.core.publisher.Mono{{/isManyInput}}<{{inputType}}> reactorRequest) {
-    {{serviceName}}Grpc.{{serviceName}}Stub localStub = stub.withDeadlineAfter(url.getParameter(TIMEOUT_KEY, DEFAULT_TIMEOUT), TimeUnit.MILLISECONDS);
-    return com.salesforce.reactorgrpc.stub.ClientCalls.{{reactiveCallsMethodName}}(reactorRequest, localStub::{{methodName}});
-    }
-
-{{/methods}}
-{{#unaryRequestMethods}}
-    {{#javaDoc}}
-        {{{javaDoc}}}
-    {{/javaDoc}}
-    {{#deprecated}}
-        @java.lang.Deprecated
-    {{/deprecated}}
-    public {{#isManyOutput}}reactor.core.publisher.Flux{{/isManyOutput}}{{^isManyOutput}}reactor.core.publisher.Mono{{/isManyOutput}}<{{outputType}}> {{methodName}}({{inputType}} reactorRequest) {
-    {{serviceName}}Grpc.{{serviceName}}Stub localStub = stub.withDeadlineAfter(url.getParameter(TIMEOUT_KEY, DEFAULT_TIMEOUT), TimeUnit.MILLISECONDS);
-    return com.salesforce.reactorgrpc.stub.ClientCalls.{{reactiveCallsMethodName}}(reactor.core.publisher.Mono.just(reactorRequest), localStub::{{methodName}});
-    }
-
-{{/unaryRequestMethods}}
-}
-
-public interface IReactor{{serviceName}} {
-{{#methods}}
-    {{#javaDoc}}
-        {{{javaDoc}}}
-    {{/javaDoc}}
-    {{#deprecated}}
-        @java.lang.Deprecated
-    {{/deprecated}}
-    public {{#isManyOutput}}reactor.core.publisher.Flux{{/isManyOutput}}{{^isManyOutput}}reactor.core.publisher.Mono{{/isManyOutput}}<{{outputType}}> {{methodName}}({{#isManyInput}}reactor.core.publisher.Flux{{/isManyInput}}{{^isManyInput}}reactor.core.publisher.Mono{{/isManyInput}}<{{inputType}}> reactorRequest);
-
-{{/methods}}
-{{#unaryRequestMethods}}
-    {{#javaDoc}}
-        {{{javaDoc}}}
-    {{/javaDoc}}
-    {{#deprecated}}
-        @java.lang.Deprecated
-    {{/deprecated}}
-    public {{#isManyOutput}}reactor.core.publisher.Flux{{/isManyOutput}}{{^isManyOutput}}reactor.core.publisher.Mono{{/isManyOutput}}<{{outputType}}> {{methodName}}({{inputType}} reactorRequest);
-
-{{/unaryRequestMethods}}
-}
-
-{{#javaDoc}}
-    {{{javaDoc}}}
-{{/javaDoc}}
-public static abstract class {{serviceName}}ImplBase implements IReactor{{serviceName}}, io.grpc.BindableService {
-
-private IReactor{{serviceName}} proxiedImpl;
-
-public final void setProxiedImpl(IReactor{{serviceName}} proxiedImpl) {
-this.proxiedImpl = proxiedImpl;
-}
-
-{{#unaryRequestMethods}}
-    {{#javaDoc}}
-        {{{javaDoc}}}
-    {{/javaDoc}}
-    {{#deprecated}}
-        @java.lang.Deprecated
-    {{/deprecated}}
-    public final {{#isManyOutput}}reactor.core.publisher.Flux{{/isManyOutput}}{{^isManyOutput}}reactor.core.publisher.Mono{{/isManyOutput}}<{{outputType}}> {{methodName}}({{inputType}} reactorRequest) {
-    throw new UnsupportedOperationException("No need to override this method, extend XxxImplBase and override all methods it allows.");
-    }
-
-{{/unaryRequestMethods}}
-{{#methods}}
-    {{#javaDoc}}
-        {{{javaDoc}}}
-    {{/javaDoc}}
-    {{#deprecated}}
-        @java.lang.Deprecated
-    {{/deprecated}}
-    public {{#isManyOutput}}reactor.core.publisher.Flux{{/isManyOutput}}{{^isManyOutput}}reactor.core.publisher.Mono{{/isManyOutput}}<{{outputType}}> {{methodName}}({{#isManyInput}}reactor.core.publisher.Flux{{/isManyInput}}{{^isManyInput}}reactor.core.publisher.Mono{{/isManyInput}}<{{inputType}}> request) {
-    throw new io.grpc.StatusRuntimeException(io.grpc.Status.UNIMPLEMENTED);
-    }
-
-{{/methods}}
-@java.lang.Override public final io.grpc.ServerServiceDefinition bindService() {
-return io.grpc.ServerServiceDefinition.builder(getServiceDescriptor())
-{{#methods}}
-    .addMethod(
-    {{packageName}}.{{serviceName}}Grpc.get{{methodNamePascalCase}}Method(),
-    {{grpcCallsMethodName}}(
-    new MethodHandlers<
-    {{inputType}},
-    {{outputType}}>(
-    proxiedImpl, METHODID_{{methodNameUpperUnderscore}})))
-{{/methods}}
-.build();
-}
-}
-
-{{#methods}}
-    private static final int METHODID_{{methodNameUpperUnderscore}} = {{methodNumber}};
-{{/methods}}
-
-private static final class MethodHandlers
-<Req, Resp> implements
-io.grpc.stub.ServerCalls.UnaryMethod
-<Req, Resp>,
-io.grpc.stub.ServerCalls.ServerStreamingMethod
-<Req, Resp>,
-io.grpc.stub.ServerCalls.ClientStreamingMethod
-<Req, Resp>,
-io.grpc.stub.ServerCalls.BidiStreamingMethod
-<Req, Resp> {
-private final IReactor{{serviceName}} serviceImpl;
-private final int methodId;
-
-MethodHandlers(IReactor{{serviceName}} serviceImpl, int methodId) {
-this.serviceImpl = serviceImpl;
-this.methodId = methodId;
-}
-
-@java.lang.Override
-@java.lang.SuppressWarnings("unchecked")
-public void invoke(Req request, io.grpc.stub.StreamObserver
-<Resp> responseObserver) {
-    switch (methodId) {
-    {{#methods}}
-        {{^isManyInput}}
-            case METHODID_{{methodNameUpperUnderscore}}:
-            com.salesforce.reactorgrpc.stub.ServerCalls.{{reactiveCallsMethodName}}(({{inputType}}) request,
-            (io.grpc.stub.StreamObserver<{{outputType}}>) responseObserver,
-            serviceImpl::{{methodName}});
-            break;
-        {{/isManyInput}}
-    {{/methods}}
-    default:
-    throw new java.lang.AssertionError();
-    }
-    }
-
-    @java.lang.Override
-    @java.lang.SuppressWarnings("unchecked")
-    public io.grpc.stub.StreamObserver
-    <Req> invoke(io.grpc.stub.StreamObserver
-        <Resp> responseObserver) {
-            switch (methodId) {
-            {{#methods}}
-                {{#isManyInput}}
-                    case METHODID_{{methodNameUpperUnderscore}}:
-                    return (io.grpc.stub.StreamObserver
-                <Req>) com.salesforce.reactorgrpc.stub.ServerCalls.{{reactiveCallsMethodName}}(
-                    (io.grpc.stub.StreamObserver<{{outputType}}>) responseObserver,
-                    serviceImpl::{{methodName}});
-                {{/isManyInput}}
-            {{/methods}}
-            default:
-            throw new java.lang.AssertionError();
-            }
-            }
-            }
-
-            }
diff --git a/compiler/src/main/resources/RxDubboGrpcStub.mustache b/compiler/src/main/resources/RxDubboGrpcStub.mustache
deleted file mode 100644
index 22c06b0..0000000
--- a/compiler/src/main/resources/RxDubboGrpcStub.mustache
+++ /dev/null
@@ -1,246 +0,0 @@
-{{#packageName}}
-    package {{packageName}};
-{{/packageName}}
-
-import org.apache.dubbo.common.URL;
-import org.apache.dubbo.config.ReferenceConfigBase;
-
-import java.util.concurrent.TimeUnit;
-
-import static org.apache.dubbo.common.constants.CommonConstants.DEFAULT_TIMEOUT;
-import static org.apache.dubbo.common.constants.CommonConstants.TIMEOUT_KEY;
-
-import static {{packageName}}.{{serviceName}}Grpc.getServiceDescriptor;
-import static io.grpc.stub.ServerCalls.asyncUnaryCall;
-import static io.grpc.stub.ServerCalls.asyncServerStreamingCall;
-import static io.grpc.stub.ServerCalls.asyncClientStreamingCall;
-import static io.grpc.stub.ServerCalls.asyncBidiStreamingCall;
-
-
-{{#deprecated}}
-    @java.lang.Deprecated
-{{/deprecated}}
-@javax.annotation.Generated(
-value = "by RxDubboGrpc generator",
-comments = "Source: {{protoName}}")
-public final class {{className}} {
-private {{className}}() {}
-
-public static RxDubbo{{serviceName}}Stub getDubboStub(io.grpc.Channel channel, io.grpc.CallOptions callOptions, URL url, ReferenceConfigBase<?> referenceConfig) {
-return new RxDubbo{{serviceName}}Stub(channel, callOptions, url, referenceConfig);
-}
-
-{{#javaDoc}}
-    {{{javaDoc}}}
-{{/javaDoc}}
-public static final class RxDubbo{{serviceName}}Stub implements IRx{{serviceName}} {
-
-protected URL url;
-protected ReferenceConfigBase<?> referenceConfig;
-
-protected {{serviceName}}Grpc.{{serviceName}}Stub stub;
-
-public RxDubbo{{serviceName}}Stub(io.grpc.Channel channel, io.grpc.CallOptions callOptions, URL url, ReferenceConfigBase<?> referenceConfig) {
-this.url = url;
-this.referenceConfig = referenceConfig;
-stub = {{serviceName}}Grpc.newStub(channel).build(channel, callOptions);
-}
-
-{{#methods}}
-    {{#javaDoc}}
-        {{{javaDoc}}}
-    {{/javaDoc}}
-    {{#deprecated}}
-        @java.lang.Deprecated
-    {{/deprecated}}
-    public {{#isManyOutput}}io.reactivex.Flowable{{/isManyOutput}}{{^isManyOutput}}io.reactivex.Single{{/isManyOutput}}<{{outputType}}> {{methodName}}({{#isManyInput}}io.reactivex.Flowable{{/isManyInput}}{{^isManyInput}}io.reactivex.Single{{/isManyInput}}<{{inputType}}> rxRequest) {
-    return com.salesforce.rxgrpc.stub.ClientCalls.{{reactiveCallsMethodName}}(rxRequest,
-    {{^isManyInput}}
-        new com.salesforce.reactivegrpc.common.BiConsumer<{{inputType}}, io.grpc.stub.StreamObserver<{{outputType}}>>() {
-        @java.lang.Override
-        public void accept({{inputType}} request, io.grpc.stub.StreamObserver<{{outputType}}> observer) {
-        stub.withDeadlineAfter(url.getParameter(TIMEOUT_KEY, DEFAULT_TIMEOUT), TimeUnit.MILLISECONDS).{{methodNameCamelCase}}(request, observer);
-        }
-        });
-    {{/isManyInput}}
-    {{#isManyInput}}
-        new com.salesforce.reactivegrpc.common.Function
-        <io.grpc.stub.StreamObserver<{{outputType}}>, io.grpc.stub.StreamObserver<{{inputType}}>>() {
-        @java.lang.Override
-        public io.grpc.stub.StreamObserver<{{inputType}}> apply(io.grpc.stub.StreamObserver<{{outputType}}> observer) {
-        return stub.withDeadlineAfter(url.getParameter(TIMEOUT_KEY, DEFAULT_TIMEOUT), TimeUnit.MILLISECONDS).{{methodNameCamelCase}}(observer);
-        }
-        });
-    {{/isManyInput}}
-    }
-
-{{/methods}}
-{{#unaryRequestMethods}}
-    {{#javaDoc}}
-        {{{javaDoc}}}
-    {{/javaDoc}}
-    {{#deprecated}}
-        @java.lang.Deprecated
-    {{/deprecated}}
-    public {{#isManyOutput}}io.reactivex.Flowable{{/isManyOutput}}{{^isManyOutput}}io.reactivex.Single{{/isManyOutput}}<{{outputType}}> {{methodName}}({{inputType}} rxRequest) {
-    return com.salesforce.rxgrpc.stub.ClientCalls.{{reactiveCallsMethodName}}(io.reactivex.Single.just(rxRequest),
-    new com.salesforce.reactivegrpc.common.BiConsumer<{{inputType}}, io.grpc.stub.StreamObserver<{{outputType}}>>() {
-    @java.lang.Override
-    public void accept({{inputType}} request, io.grpc.stub.StreamObserver<{{outputType}}> observer) {
-    stub.withDeadlineAfter(url.getParameter(TIMEOUT_KEY, DEFAULT_TIMEOUT), TimeUnit.MILLISECONDS).{{methodNameCamelCase}}(request, observer);
-    }
-    });
-    }
-
-{{/unaryRequestMethods}}
-}
-
-public interface IRx{{serviceName}} {
-{{#methods}}
-    {{#javaDoc}}
-        {{{javaDoc}}}
-    {{/javaDoc}}
-    {{#deprecated}}
-        @java.lang.Deprecated
-    {{/deprecated}}
-    public {{#isManyOutput}}io.reactivex.Flowable{{/isManyOutput}}{{^isManyOutput}}io.reactivex.Single{{/isManyOutput}}<{{outputType}}> {{methodName}}({{#isManyInput}}io.reactivex.Flowable{{/isManyInput}}{{^isManyInput}}io.reactivex.Single{{/isManyInput}}<{{inputType}}> rxRequest);
-
-{{/methods}}
-{{#unaryRequestMethods}}
-    {{#javaDoc}}
-        {{{javaDoc}}}
-    {{/javaDoc}}
-    {{#deprecated}}
-        @java.lang.Deprecated
-    {{/deprecated}}
-    public {{#isManyOutput}}io.reactivex.Flowable{{/isManyOutput}}{{^isManyOutput}}io.reactivex.Single{{/isManyOutput}}<{{outputType}}> {{methodName}}({{inputType}} rxRequest);
-
-{{/unaryRequestMethods}}
-}
-
-
-{{#javaDoc}}
-    {{{javaDoc}}}
-{{/javaDoc}}
-public static abstract class {{serviceName}}ImplBase implements IRx{{serviceName}}, io.grpc.BindableService {
-
-private IRx{{serviceName}} proxiedImpl;
-
-public final void setProxiedImpl(IRx{{serviceName}} proxiedImpl) {
-this.proxiedImpl = proxiedImpl;
-}
-{{#unaryRequestMethods}}
-    {{#javaDoc}}
-        {{{javaDoc}}}
-    {{/javaDoc}}
-    {{#deprecated}}
-        @java.lang.Deprecated
-    {{/deprecated}}
-    public final {{#isManyOutput}}io.reactivex.Flowable{{/isManyOutput}}{{^isManyOutput}}io.reactivex.Single{{/isManyOutput}}<{{outputType}}> {{methodName}}({{inputType}} rxRequest) {
-    throw new UnsupportedOperationException("No need to override this method, extend XxxImplBase and override all methods it allows.");
-    }
-
-{{/unaryRequestMethods}}
-{{#methods}}
-    {{#javaDoc}}
-        {{{javaDoc}}}
-    {{/javaDoc}}
-    {{#deprecated}}
-        @java.lang.Deprecated
-    {{/deprecated}}
-    public {{#isManyOutput}}io.reactivex.Flowable{{/isManyOutput}}{{^isManyOutput}}io.reactivex.Single{{/isManyOutput}}<{{outputType}}> {{methodNameCamelCase}}({{#isManyInput}}io.reactivex.Flowable{{/isManyInput}}{{^isManyInput}}io.reactivex.Single{{/isManyInput}}<{{inputType}}> request) {
-    throw new io.grpc.StatusRuntimeException(io.grpc.Status.UNIMPLEMENTED);
-    }
-
-{{/methods}}
-@java.lang.Override public final io.grpc.ServerServiceDefinition bindService() {
-return io.grpc.ServerServiceDefinition.builder(getServiceDescriptor())
-{{#methods}}
-    .addMethod(
-    {{packageName}}.{{serviceName}}Grpc.get{{methodNamePascalCase}}Method(),
-    {{grpcCallsMethodName}}(
-    new MethodHandlers<
-    {{inputType}},
-    {{outputType}}>(
-    proxiedImpl, METHODID_{{methodNameUpperUnderscore}})))
-{{/methods}}
-.build();
-}
-}
-
-{{#methods}}
-    private static final int METHODID_{{methodNameUpperUnderscore}} = {{methodNumber}};
-{{/methods}}
-
-private static final class MethodHandlers
-<Req, Resp> implements
-io.grpc.stub.ServerCalls.UnaryMethod
-<Req, Resp>,
-io.grpc.stub.ServerCalls.ServerStreamingMethod
-<Req, Resp>,
-io.grpc.stub.ServerCalls.ClientStreamingMethod
-<Req, Resp>,
-io.grpc.stub.ServerCalls.BidiStreamingMethod
-<Req, Resp> {
-private final IRx{{serviceName}} serviceImpl;
-private final int methodId;
-
-MethodHandlers(IRx{{serviceName}} serviceImpl, int methodId) {
-this.serviceImpl = serviceImpl;
-this.methodId = methodId;
-}
-
-@java.lang.Override
-@java.lang.SuppressWarnings("unchecked")
-public void invoke(Req request, io.grpc.stub.StreamObserver
-<Resp> responseObserver) {
-    switch (methodId) {
-    {{#methods}}
-        {{^isManyInput}}
-            case METHODID_{{methodNameUpperUnderscore}}:
-            com.salesforce.rxgrpc.stub.ServerCalls.{{reactiveCallsMethodName}}(({{inputType}}) request,
-            (io.grpc.stub.StreamObserver<{{outputType}}>) responseObserver,
-            new com.salesforce.reactivegrpc.common.Function
-                <{{#isManyInput}}io.reactivex.Flowable{{/isManyInput}}{{^isManyInput}}io.reactivex.Single{{/isManyInput}}
-            <{{inputType}}>, {{#isManyOutput}}
-            io.reactivex.Flowable{{/isManyOutput}}{{^isManyOutput}}
-            io.reactivex.Single{{/isManyOutput}}<{{outputType}}>>() {
-            @java.lang.Override
-            public {{#isManyOutput}}
-            io.reactivex.Flowable{{/isManyOutput}}{{^isManyOutput}}
-            io.reactivex.Single{{/isManyOutput}}<{{outputType}}> apply({{#isManyInput}}
-            io.reactivex.Flowable{{/isManyInput}}{{^isManyInput}}
-            io.reactivex.Single{{/isManyInput}}<{{inputType}}> single) {
-            return serviceImpl.{{methodNameCamelCase}}(single);
-            }
-            });
-            break;
-        {{/isManyInput}}
-    {{/methods}}
-    default:
-    throw new java.lang.AssertionError();
-    }
-    }
-
-    @java.lang.Override
-    @java.lang.SuppressWarnings("unchecked")
-    public io.grpc.stub.StreamObserver
-    <Req> invoke(io.grpc.stub.StreamObserver
-        <Resp> responseObserver) {
-            switch (methodId) {
-            {{#methods}}
-                {{#isManyInput}}
-                    case METHODID_{{methodNameUpperUnderscore}}:
-                    return (io.grpc.stub.StreamObserver
-                <Req>) com.salesforce.rxgrpc.stub.ServerCalls.{{reactiveCallsMethodName}}(
-                    (io.grpc.stub.StreamObserver<{{outputType}}>) responseObserver,
-                    serviceImpl::{{methodNameCamelCase}});
-                {{/isManyInput}}
-            {{/methods}}
-            default:
-            throw new java.lang.AssertionError();
-            }
-            }
-            }
-
-            }
diff --git a/dubbo-spi-filter/dubbo-filter-cache/pom.xml b/dubbo-spi-filter/dubbo-filter-cache/pom.xml
deleted file mode 100644
index 49f99cf..0000000
--- a/dubbo-spi-filter/dubbo-filter-cache/pom.xml
+++ /dev/null
@@ -1,48 +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.
-  -->
-<project xmlns="http://maven.apache.org/POM/4.0.0" xmlns:xsi="http://www.w3.org/2001/XMLSchema-instance" xsi:schemaLocation="http://maven.apache.org/POM/4.0.0 http://maven.apache.org/maven-v4_0_0.xsd">
-    <modelVersion>4.0.0</modelVersion>
-    <parent>
-        <groupId>org.apache.dubbo</groupId>
-        <artifactId>dubbo-filter</artifactId>
-        <version>2.7.7-SNAPSHOT</version>
-    </parent>
-    <artifactId>dubbo-filter-cache</artifactId>
-    <packaging>jar</packaging>
-    <name>${project.artifactId}</name>
-    <description>The cache module of dubbo project</description>
-    <properties>
-        <skip_maven_deploy>false</skip_maven_deploy>
-    </properties>
-    <dependencies>
-        <dependency>
-            <groupId>org.apache.dubbo</groupId>
-            <artifactId>dubbo-rpc-api</artifactId>
-            <version>${project.parent.version}</version>
-        </dependency>
-        <dependency>
-            <groupId>javax.cache</groupId>
-            <artifactId>cache-api</artifactId>
-        </dependency>
-        <dependency>
-            <groupId>com.hazelcast</groupId>
-            <artifactId>hazelcast</artifactId>
-            <scope>test</scope>
-            <version>${hazelcast_version}</version>
-        </dependency>
-    </dependencies>
-</project>
\ No newline at end of file
diff --git a/dubbo-spi-filter/dubbo-filter-cache/src/main/java/org/apache/dubbo/cache/Cache.java b/dubbo-spi-filter/dubbo-filter-cache/src/main/java/org/apache/dubbo/cache/Cache.java
deleted file mode 100644
index 69ae671..0000000
--- a/dubbo-spi-filter/dubbo-filter-cache/src/main/java/org/apache/dubbo/cache/Cache.java
+++ /dev/null
@@ -1,43 +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.cache;
-
-/**
- * Cache interface to support storing and retrieval of value against a lookup key. It has two operation <b>get</b> and <b>put</b>.
- * <li><b>put</b>-Storing value against a key.</li>
- * <li><b>get</b>-Retrieval of object.</li>
- * @see org.apache.dubbo.cache.support.lru.LruCache
- * @see org.apache.dubbo.cache.support.jcache.JCache
- * @see org.apache.dubbo.cache.support.expiring.ExpiringCache
- * @see org.apache.dubbo.cache.support.threadlocal.ThreadLocalCache
- */
-public interface Cache {
-    /**
-     * API to store value against a key
-     * @param key  Unique identifier for the object being store.
-     * @param value Value getting store
-     */
-    void put(Object key, Object value);
-
-    /**
-     * API to return stored value using a key.
-     * @param key Unique identifier for cache lookup
-     * @return Return stored object against key
-     */
-    Object get(Object key);
-
-}
diff --git a/dubbo-spi-filter/dubbo-filter-cache/src/main/java/org/apache/dubbo/cache/CacheFactory.java b/dubbo-spi-filter/dubbo-filter-cache/src/main/java/org/apache/dubbo/cache/CacheFactory.java
deleted file mode 100644
index 66b5b59..0000000
--- a/dubbo-spi-filter/dubbo-filter-cache/src/main/java/org/apache/dubbo/cache/CacheFactory.java
+++ /dev/null
@@ -1,43 +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.cache;
-
-import org.apache.dubbo.common.URL;
-import org.apache.dubbo.common.extension.Adaptive;
-import org.apache.dubbo.common.extension.SPI;
-import org.apache.dubbo.rpc.Invocation;
-
-/**
- * Interface needs to be implemented by all the cache store provider.Along with implementing <b>CacheFactory</b> interface
- * entry needs to be added in org.apache.dubbo.cache.CacheFactory file in a classpath META-INF sub directories.
- *
- * @see Cache
- */
-@SPI("lru")
-public interface CacheFactory {
-
-    /**
-     * CacheFactory implementation class needs to implement this return underlying cache instance for method against
-     * url and invocation.
-     * @param url
-     * @param invocation
-     * @return Instance of Cache containing cached value against method url and invocation.
-     */
-    @Adaptive("cache")
-    Cache getCache(URL url, Invocation invocation);
-
-}
diff --git a/dubbo-spi-filter/dubbo-filter-cache/src/main/java/org/apache/dubbo/cache/filter/CacheFilter.java b/dubbo-spi-filter/dubbo-filter-cache/src/main/java/org/apache/dubbo/cache/filter/CacheFilter.java
deleted file mode 100644
index 02d0e29..0000000
--- a/dubbo-spi-filter/dubbo-filter-cache/src/main/java/org/apache/dubbo/cache/filter/CacheFilter.java
+++ /dev/null
@@ -1,133 +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.cache.filter;
-
-import org.apache.dubbo.cache.Cache;
-import org.apache.dubbo.cache.CacheFactory;
-import org.apache.dubbo.common.extension.Activate;
-import org.apache.dubbo.common.utils.ConfigUtils;
-import org.apache.dubbo.common.utils.StringUtils;
-import org.apache.dubbo.rpc.AsyncRpcResult;
-import org.apache.dubbo.rpc.Filter;
-import org.apache.dubbo.rpc.Invocation;
-import org.apache.dubbo.rpc.Invoker;
-import org.apache.dubbo.rpc.Result;
-import org.apache.dubbo.rpc.RpcException;
-
-import java.io.Serializable;
-
-import static org.apache.dubbo.common.constants.CommonConstants.CONSUMER;
-import static org.apache.dubbo.common.constants.CommonConstants.PROVIDER;
-import static org.apache.dubbo.common.constants.FilterConstants.CACHE_KEY;
-
-/**
- * CacheFilter is a core component of dubbo.Enabling <b>cache</b> key of service,method,consumer or provider dubbo will cache method return value.
- * Along with cache key we need to configure cache type. Dubbo default implemented cache types are
- * <li>lur</li>
- * <li>threadlocal</li>
- * <li>jcache</li>
- * <li>expiring</li>
- *
- * <pre>
- *   e.g. 1)&lt;dubbo:service cache="lru" /&gt;
- *        2)&lt;dubbo:service /&gt; &lt;dubbo:method name="method2" cache="threadlocal" /&gt; &lt;dubbo:service/&gt;
- *        3)&lt;dubbo:provider cache="expiring" /&gt;
- *        4)&lt;dubbo:consumer cache="jcache" /&gt;
- *
- *If cache type is defined in method level then method level type will get precedence. According to above provided
- *example, if service has two method, method1 and method2, method2 will have cache type as <b>threadlocal</b> where others will
- *be backed by <b>lru</b>
- *</pre>
- *
- * @see org.apache.dubbo.rpc.Filter
- * @see org.apache.dubbo.cache.support.lru.LruCacheFactory
- * @see org.apache.dubbo.cache.support.lru.LruCache
- * @see org.apache.dubbo.cache.support.jcache.JCacheFactory
- * @see org.apache.dubbo.cache.support.jcache.JCache
- * @see org.apache.dubbo.cache.support.threadlocal.ThreadLocalCacheFactory
- * @see org.apache.dubbo.cache.support.threadlocal.ThreadLocalCache
- * @see org.apache.dubbo.cache.support.expiring.ExpiringCacheFactory
- * @see org.apache.dubbo.cache.support.expiring.ExpiringCache
- *
- */
-@Activate(group = {CONSUMER, PROVIDER}, value = CACHE_KEY)
-public class CacheFilter implements Filter {
-
-    private CacheFactory cacheFactory;
-
-    /**
-     * Dubbo will populate and set the cache factory instance based on service/method/consumer/provider configured
-     * cache attribute value. Dubbo will search for the class name implementing configured <b>cache</b> in file org.apache.dubbo.cache.CacheFactory
-     * under META-INF sub folders.
-     *
-     * @param cacheFactory instance of CacheFactory based on <b>cache</b> type
-     */
-    public void setCacheFactory(CacheFactory cacheFactory) {
-        this.cacheFactory = cacheFactory;
-    }
-
-    /**
-     * If cache is configured, dubbo will invoke method on each method call. If cache value is returned by cache store
-     * then it will return otherwise call the remote method and return value. If remote method's return value has error
-     * then it will not cache the value.
-     * @param invoker    service
-     * @param invocation invocation.
-     * @return Cache returned value if found by the underlying cache store. If cache miss it will call target method.
-     * @throws RpcException
-     */
-    @Override
-    public Result invoke(Invoker<?> invoker, Invocation invocation) throws RpcException {
-        if (cacheFactory != null && ConfigUtils.isNotEmpty(invoker.getUrl().getMethodParameter(invocation.getMethodName(), CACHE_KEY))) {
-            Cache cache = cacheFactory.getCache(invoker.getUrl(), invocation);
-            if (cache != null) {
-                String key = StringUtils.toArgumentString(invocation.getArguments());
-                Object value = cache.get(key);
-                if (value != null) {
-                    if (value instanceof ValueWrapper) {
-                        return AsyncRpcResult.newDefaultAsyncResult(((ValueWrapper) value).get(), invocation);
-                    } else {
-                        return AsyncRpcResult.newDefaultAsyncResult(value, invocation);
-                    }
-                }
-                Result result = invoker.invoke(invocation);
-                if (!result.hasException()) {
-                    cache.put(key, new ValueWrapper(result.getValue()));
-                }
-                return result;
-            }
-        }
-        return invoker.invoke(invocation);
-    }
-
-    /**
-     * Cache value wrapper.
-     */
-    static class ValueWrapper implements Serializable {
-
-        private static final long serialVersionUID = -1777337318019193256L;
-
-        private final Object value;
-
-        public ValueWrapper (Object value) {
-            this.value = value;
-        }
-
-        public Object get() {
-            return this.value;
-        }
-    }
-}
diff --git a/dubbo-spi-filter/dubbo-filter-cache/src/main/java/org/apache/dubbo/cache/support/AbstractCacheFactory.java b/dubbo-spi-filter/dubbo-filter-cache/src/main/java/org/apache/dubbo/cache/support/AbstractCacheFactory.java
deleted file mode 100644
index 966d923..0000000
--- a/dubbo-spi-filter/dubbo-filter-cache/src/main/java/org/apache/dubbo/cache/support/AbstractCacheFactory.java
+++ /dev/null
@@ -1,72 +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.cache.support;
-
-import org.apache.dubbo.cache.Cache;
-import org.apache.dubbo.cache.CacheFactory;
-import org.apache.dubbo.common.URL;
-import org.apache.dubbo.rpc.Invocation;
-
-import java.util.concurrent.ConcurrentHashMap;
-import java.util.concurrent.ConcurrentMap;
-
-import static org.apache.dubbo.common.constants.CommonConstants.METHOD_KEY;
-
-/**
- * AbstractCacheFactory is a default implementation of {@link CacheFactory}. It abstract out the key formation from URL along with
- * invocation method. It initially check if the value for key already present in own local in-memory store then it won't check underlying storage cache {@link Cache}.
- * Internally it used {@link ConcurrentHashMap} to store do level-1 caching.
- *
- * @see CacheFactory
- * @see org.apache.dubbo.cache.support.jcache.JCacheFactory
- * @see org.apache.dubbo.cache.support.lru.LruCacheFactory
- * @see org.apache.dubbo.cache.support.threadlocal.ThreadLocalCacheFactory
- * @see org.apache.dubbo.cache.support.expiring.ExpiringCacheFactory
- */
-public abstract class AbstractCacheFactory implements CacheFactory {
-
-    /**
-     * This is used to store factory level-1 cached data.
-     */
-    private final ConcurrentMap<String, Cache> caches = new ConcurrentHashMap<String, Cache>();
-
-    /**
-     *  Takes URL and invocation instance and return cache instance for a given url.
-     * @param url url of the method
-     * @param invocation invocation context.
-     * @return Instance of cache store used as storage for caching return values.
-     */
-    @Override
-    public Cache getCache(URL url, Invocation invocation) {
-        url = url.addParameter(METHOD_KEY, invocation.getMethodName());
-        String key = url.toFullString();
-        Cache cache = caches.get(key);
-        if (cache == null) {
-            caches.put(key, createCache(url));
-            cache = caches.get(key);
-        }
-        return cache;
-    }
-
-    /**
-     * Takes url as an method argument and return new instance of cache store implemented by AbstractCacheFactory subclass.
-     * @param url url of the method
-     * @return Create and return new instance of cache store used as storage for caching return values.
-     */
-    protected abstract Cache createCache(URL url);
-
-}
diff --git a/dubbo-spi-filter/dubbo-filter-cache/src/main/java/org/apache/dubbo/cache/support/expiring/ExpiringCache.java b/dubbo-spi-filter/dubbo-filter-cache/src/main/java/org/apache/dubbo/cache/support/expiring/ExpiringCache.java
deleted file mode 100644
index afaf8c6..0000000
--- a/dubbo-spi-filter/dubbo-filter-cache/src/main/java/org/apache/dubbo/cache/support/expiring/ExpiringCache.java
+++ /dev/null
@@ -1,77 +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.cache.support.expiring;
-
-import org.apache.dubbo.cache.Cache;
-import org.apache.dubbo.common.URL;
-
-import java.util.Map;
-
-/**
- * ExpiringCache - With the characteristic of expiration time.
- */
-
-/**
- * This class store the cache value with the characteristic of expiration time. If a service,method,consumer or provided is configured with key <b>cache</b>
- * with value <b>expiring</b>, dubbo initialize the instance of this class using {@link ExpiringCacheFactory} to store method's returns value
- * to server from store without making method call.
- * <pre>
- *     e.g. 1) &lt;dubbo:service cache="expiring" cache.seconds="60" cache.interval="10"/&gt;
- *          2) &lt;dubbo:consumer cache="expiring" /&gt;
- * </pre>
- * <li>It used constructor argument url instance <b>cache.seconds</b> value to decide time to live of cached object.Default value of it is 180 second.</li>
- * <li>It used constructor argument url instance <b>cache.interval</b> value for cache value expiration interval.Default value of this is 4 second</li>
- * @see Cache
- * @see ExpiringCacheFactory
- * @see org.apache.dubbo.cache.support.AbstractCacheFactory
- * @see org.apache.dubbo.cache.filter.CacheFilter
- */
-public class ExpiringCache implements Cache {
-    private final Map<Object, Object> store;
-
-    public ExpiringCache(URL url) {
-        // cache time (second)
-        final int secondsToLive = url.getParameter("cache.seconds", 180);
-        // Cache check interval (second)
-        final int intervalSeconds = url.getParameter("cache.interval", 4);
-        ExpiringMap<Object, Object> expiringMap = new ExpiringMap<>(secondsToLive, intervalSeconds);
-        expiringMap.getExpireThread().startExpiryIfNotStarted();
-        this.store = expiringMap;
-    }
-
-    /**
-     * API to store value against a key in the calling thread scope.
-     * @param key  Unique identifier for the object being store.
-     * @param value Value getting store
-     */
-    @Override
-    public void put(Object key, Object value) {
-        store.put(key, value);
-    }
-
-    /**
-     * API to return stored value using a key against the calling thread specific store.
-     * @param key Unique identifier for cache lookup
-     * @return Return stored object against key
-     */
-
-    @Override
-    public Object get(Object key) {
-        return store.get(key);
-    }
-
-}
diff --git a/dubbo-spi-filter/dubbo-filter-cache/src/main/java/org/apache/dubbo/cache/support/expiring/ExpiringCacheFactory.java b/dubbo-spi-filter/dubbo-filter-cache/src/main/java/org/apache/dubbo/cache/support/expiring/ExpiringCacheFactory.java
deleted file mode 100644
index 5259d74..0000000
--- a/dubbo-spi-filter/dubbo-filter-cache/src/main/java/org/apache/dubbo/cache/support/expiring/ExpiringCacheFactory.java
+++ /dev/null
@@ -1,44 +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.cache.support.expiring;
-
-import org.apache.dubbo.cache.Cache;
-import org.apache.dubbo.cache.support.AbstractCacheFactory;
-import org.apache.dubbo.common.URL;
-
-
-/**
- * Implement {@link org.apache.dubbo.cache.CacheFactory} by extending {@link AbstractCacheFactory} and provide
- * instance of new {@link ExpiringCache}.
- *
- * @see AbstractCacheFactory
- * @see ExpiringCache
- * @see Cache
- */
-
-public class ExpiringCacheFactory extends AbstractCacheFactory {
-
-    /**
-     * Takes url as an method argument and return new instance of cache store implemented by JCache.
-     * @param url url of the method
-     * @return ExpiringCache instance of cache
-     */
-    @Override
-    protected Cache createCache(URL url) {
-        return new ExpiringCache(url);
-    }
-}
diff --git a/dubbo-spi-filter/dubbo-filter-cache/src/main/java/org/apache/dubbo/cache/support/expiring/ExpiringMap.java b/dubbo-spi-filter/dubbo-filter-cache/src/main/java/org/apache/dubbo/cache/support/expiring/ExpiringMap.java
deleted file mode 100644
index 895f114..0000000
--- a/dubbo-spi-filter/dubbo-filter-cache/src/main/java/org/apache/dubbo/cache/support/expiring/ExpiringMap.java
+++ /dev/null
@@ -1,374 +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.cache.support.expiring;
-
-import java.util.ArrayList;
-import java.util.Collection;
-import java.util.List;
-import java.util.Map;
-import java.util.Set;
-import java.util.concurrent.ConcurrentHashMap;
-import java.util.concurrent.atomic.AtomicInteger;
-import java.util.concurrent.atomic.AtomicLong;
-
-/**
- * can be expired map
- * Contains a background thread that periodically checks if the data is out of date
- */
-public class ExpiringMap<K, V> implements Map<K, V> {
-
-    /**
-     * default time to live (second)
-     */
-    private static final int DEFAULT_TIME_TO_LIVE = 180;
-
-    /**
-     * default expire check interval (second)
-     */
-    private static final int DEFAULT_EXPIRATION_INTERVAL = 1;
-
-    private static AtomicInteger expireCount = new AtomicInteger(1);
-
-    private final ConcurrentHashMap<K, ExpiryObject> delegateMap;
-
-    private final ExpireThread expireThread;
-
-    public ExpiringMap() {
-        this(DEFAULT_TIME_TO_LIVE, DEFAULT_EXPIRATION_INTERVAL);
-    }
-
-    /**
-     * Constructor
-     *
-     * @param timeToLive time to live (second)
-     */
-    public ExpiringMap(int timeToLive) {
-        this(timeToLive, DEFAULT_EXPIRATION_INTERVAL);
-    }
-
-    public ExpiringMap(int timeToLive, int expirationInterval) {
-        this(new ConcurrentHashMap<>(), timeToLive, expirationInterval);
-    }
-
-    private ExpiringMap(ConcurrentHashMap<K, ExpiryObject> delegateMap, int timeToLive, int expirationInterval) {
-        this.delegateMap = delegateMap;
-        this.expireThread = new ExpireThread();
-        expireThread.setTimeToLive(timeToLive);
-        expireThread.setExpirationInterval(expirationInterval);
-    }
-
-    @Override
-    public V put(K key, V value) {
-        ExpiryObject answer = delegateMap.put(key, new ExpiryObject(key, value, System.currentTimeMillis()));
-        if (answer == null) {
-            return null;
-        }
-        return answer.getValue();
-    }
-
-    @Override
-    public V get(Object key) {
-        ExpiryObject object = delegateMap.get(key);
-        if (object != null) {
-            object.setLastAccessTime(System.currentTimeMillis());
-            return object.getValue();
-        }
-        return null;
-    }
-
-    @Override
-    public V remove(Object key) {
-        ExpiryObject answer = delegateMap.remove(key);
-        if (answer == null) {
-            return null;
-        }
-        return answer.getValue();
-    }
-
-    @Override
-    public boolean containsKey(Object key) {
-        return delegateMap.containsKey(key);
-    }
-
-    @Override
-    public boolean containsValue(Object value) {
-        return delegateMap.containsValue(value);
-    }
-
-    @Override
-    public int size() {
-        return delegateMap.size();
-    }
-
-    @Override
-    public boolean isEmpty() {
-        return delegateMap.isEmpty();
-    }
-
-    @Override
-    public void clear() {
-        delegateMap.clear();
-        expireThread.stopExpiring();
-    }
-
-    @Override
-    public int hashCode() {
-        return delegateMap.hashCode();
-    }
-
-    @Override
-    public Set<K> keySet() {
-        return delegateMap.keySet();
-    }
-
-    @Override
-    public boolean equals(Object obj) {
-        return delegateMap.equals(obj);
-    }
-
-    @Override
-    public void putAll(Map<? extends K, ? extends V> inMap) {
-        for (Entry<? extends K, ? extends V> e : inMap.entrySet()) {
-            this.put(e.getKey(), e.getValue());
-        }
-    }
-
-    @Override
-    public Collection<V> values() {
-        List<V> list = new ArrayList<V>();
-        Set<Entry<K, ExpiryObject>> delegatedSet = delegateMap.entrySet();
-        for (Entry<K, ExpiryObject> entry : delegatedSet) {
-            ExpiryObject value = entry.getValue();
-            list.add(value.getValue());
-        }
-        return list;
-    }
-
-    @Override
-    public Set<Entry<K, V>> entrySet() {
-        throw new UnsupportedOperationException();
-    }
-
-    public ExpireThread getExpireThread() {
-        return expireThread;
-    }
-
-    public int getExpirationInterval() {
-        return expireThread.getExpirationInterval();
-    }
-
-    public void setExpirationInterval(int expirationInterval) {
-        expireThread.setExpirationInterval(expirationInterval);
-    }
-
-    public int getTimeToLive() {
-        return expireThread.getTimeToLive();
-    }
-
-    public void setTimeToLive(int timeToLive) {
-        expireThread.setTimeToLive(timeToLive);
-    }
-
-    @Override
-    public String toString() {
-        return "ExpiringMap{" +
-                "delegateMap=" + delegateMap.toString() +
-                ", expireThread=" + expireThread.toString() +
-                '}';
-    }
-
-    /**
-     * can be expired object
-     */
-    private class ExpiryObject {
-        private K key;
-        private V value;
-        private AtomicLong lastAccessTime;
-
-        ExpiryObject(K key, V value, long lastAccessTime) {
-            if (value == null) {
-                throw new IllegalArgumentException("An expiring object cannot be null.");
-            }
-            this.key = key;
-            this.value = value;
-            this.lastAccessTime = new AtomicLong(lastAccessTime);
-        }
-
-        public long getLastAccessTime() {
-            return lastAccessTime.get();
-        }
-
-        public void setLastAccessTime(long lastAccessTime) {
-            this.lastAccessTime.set(lastAccessTime);
-        }
-
-        public K getKey() {
-            return key;
-        }
-
-        public V getValue() {
-            return value;
-        }
-
-        @Override
-        public boolean equals(Object obj) {
-            return value.equals(obj);
-        }
-
-        @Override
-        public int hashCode() {
-            return value.hashCode();
-        }
-
-        @Override
-        public String toString() {
-            return "ExpiryObject{" +
-                    "key=" + key +
-                    ", value=" + value +
-                    ", lastAccessTime=" + lastAccessTime +
-                    '}';
-        }
-    }
-
-    /**
-     * Background thread, periodically checking if the data is out of date
-     */
-    public class ExpireThread implements Runnable {
-        private long timeToLiveMillis;
-        private long expirationIntervalMillis;
-        private volatile boolean running = false;
-        private final Thread expirerThread;
-
-        @Override
-        public String toString() {
-            return "ExpireThread{" +
-                    ", timeToLiveMillis=" + timeToLiveMillis +
-                    ", expirationIntervalMillis=" + expirationIntervalMillis +
-                    ", running=" + running +
-                    ", expirerThread=" + expirerThread +
-                    '}';
-        }
-
-        public ExpireThread() {
-            expirerThread = new Thread(this, "ExpiryMapExpire-" + expireCount.getAndIncrement());
-            expirerThread.setDaemon(true);
-        }
-
-        @Override
-        public void run() {
-            while (running) {
-                processExpires();
-                try {
-                    Thread.sleep(expirationIntervalMillis);
-                } catch (InterruptedException e) {
-                    running = false;
-                }
-            }
-        }
-
-        private void processExpires() {
-            long timeNow = System.currentTimeMillis();
-            for (ExpiryObject o : delegateMap.values()) {
-                if (timeToLiveMillis <= 0) {
-                    continue;
-                }
-                long timeIdle = timeNow - o.getLastAccessTime();
-                if (timeIdle >= timeToLiveMillis) {
-                    delegateMap.remove(o.getKey());
-                }
-            }
-        }
-
-        /**
-         * start expiring Thread
-         */
-        public void startExpiring() {
-            if (!running) {
-                running = true;
-                expirerThread.start();
-            }
-        }
-
-        /**
-         * start thread
-         */
-        public void startExpiryIfNotStarted() {
-            if (running) {
-                return;
-            }
-            startExpiring();
-        }
-
-        /**
-         * stop thread
-         */
-        public void stopExpiring() {
-            if (running) {
-                running = false;
-                expirerThread.interrupt();
-            }
-        }
-
-        /**
-         * get thread state
-         *
-         * @return thread state
-         */
-        public boolean isRunning() {
-            return running;
-        }
-
-        /**
-         * get time to live
-         *
-         * @return time to live
-         */
-        public int getTimeToLive() {
-            return (int) timeToLiveMillis / 1000;
-        }
-
-        /**
-         * update time to live
-         *
-         * @param timeToLive time to live
-         */
-        public void setTimeToLive(long timeToLive) {
-            this.timeToLiveMillis = timeToLive * 1000;
-        }
-
-        /**
-         * get expiration interval
-         *
-         * @return expiration interval (second)
-         */
-        public int getExpirationInterval() {
-            return (int) expirationIntervalMillis / 1000;
-        }
-
-        /**
-         * set expiration interval
-         *
-         * @param expirationInterval expiration interval (second)
-         */
-        public void setExpirationInterval(long expirationInterval) {
-            this.expirationIntervalMillis = expirationInterval * 1000;
-        }
-    }
-}
-
-
-
diff --git a/dubbo-spi-filter/dubbo-filter-cache/src/main/java/org/apache/dubbo/cache/support/jcache/JCache.java b/dubbo-spi-filter/dubbo-filter-cache/src/main/java/org/apache/dubbo/cache/support/jcache/JCache.java
deleted file mode 100644
index 7972a9d..0000000
--- a/dubbo-spi-filter/dubbo-filter-cache/src/main/java/org/apache/dubbo/cache/support/jcache/JCache.java
+++ /dev/null
@@ -1,87 +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.cache.support.jcache;
-
-import org.apache.dubbo.common.URL;
-import org.apache.dubbo.common.utils.StringUtils;
-
-import javax.cache.Cache;
-import javax.cache.CacheException;
-import javax.cache.CacheManager;
-import javax.cache.Caching;
-import javax.cache.configuration.MutableConfiguration;
-import javax.cache.expiry.CreatedExpiryPolicy;
-import javax.cache.expiry.Duration;
-import javax.cache.spi.CachingProvider;
-import java.util.concurrent.TimeUnit;
-
-import static org.apache.dubbo.common.constants.CommonConstants.METHOD_KEY;
-
-/**
- * This class store the cache value per thread. If a service,method,consumer or provided is configured with key <b>cache</b>
- * with value <b>jcache</b>, dubbo initialize the instance of this class using {@link JCacheFactory} to store method's returns value
- * to server from store without making method call.
- *
- * @see Cache
- * @see JCacheFactory
- * @see org.apache.dubbo.cache.support.AbstractCacheFactory
- * @see org.apache.dubbo.cache.filter.CacheFilter
- */
-public class JCache implements org.apache.dubbo.cache.Cache {
-
-    private final Cache<Object, Object> store;
-
-    public JCache(URL url) {
-        String method = url.getParameter(METHOD_KEY, "");
-        String key = url.getAddress() + "." + url.getServiceKey() + "." + method;
-        // jcache parameter is the full-qualified class name of SPI implementation
-        String type = url.getParameter("jcache");
-
-        CachingProvider provider = StringUtils.isEmpty(type) ? Caching.getCachingProvider() : Caching.getCachingProvider(type);
-        CacheManager cacheManager = provider.getCacheManager();
-        Cache<Object, Object> cache = cacheManager.getCache(key);
-        if (cache == null) {
-            try {
-                //configure the cache
-                MutableConfiguration config =
-                        new MutableConfiguration<>()
-                                .setTypes(Object.class, Object.class)
-                                .setExpiryPolicyFactory(CreatedExpiryPolicy.factoryOf(new Duration(TimeUnit.MILLISECONDS, url.getMethodParameter(method, "cache.write.expire", 60 * 1000))))
-                                .setStoreByValue(false)
-                                .setManagementEnabled(true)
-                                .setStatisticsEnabled(true);
-                cache = cacheManager.createCache(key, config);
-            } catch (CacheException e) {
-                // concurrent cache initialization
-                cache = cacheManager.getCache(key);
-            }
-        }
-
-        this.store = cache;
-    }
-
-    @Override
-    public void put(Object key, Object value) {
-        store.put(key, value);
-    }
-
-    @Override
-    public Object get(Object key) {
-        return store.get(key);
-    }
-
-}
diff --git a/dubbo-spi-filter/dubbo-filter-cache/src/main/java/org/apache/dubbo/cache/support/jcache/JCacheFactory.java b/dubbo-spi-filter/dubbo-filter-cache/src/main/java/org/apache/dubbo/cache/support/jcache/JCacheFactory.java
deleted file mode 100644
index aba9a2f..0000000
--- a/dubbo-spi-filter/dubbo-filter-cache/src/main/java/org/apache/dubbo/cache/support/jcache/JCacheFactory.java
+++ /dev/null
@@ -1,48 +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.cache.support.jcache;
-
-import org.apache.dubbo.cache.Cache;
-import org.apache.dubbo.cache.support.AbstractCacheFactory;
-import org.apache.dubbo.common.URL;
-
-import javax.cache.spi.CachingProvider;
-
-/**
- * JCacheFactory is factory class to provide instance of javax spi cache.Implement {@link org.apache.dubbo.cache.CacheFactory} by
- * extending {@link AbstractCacheFactory} and provide
- * @see AbstractCacheFactory
- * @see JCache
- * @see org.apache.dubbo.cache.filter.CacheFilter
- * @see Cache
- * @see CachingProvider
- * @see javax.cache.Cache
- * @see javax.cache.CacheManager
- */
-public class JCacheFactory extends AbstractCacheFactory {
-
-    /**
-     * Takes url as an method argument and return new instance of cache store implemented by JCache.
-     * @param url url of the method
-     * @return JCache instance of cache
-     */
-    @Override
-    protected Cache createCache(URL url) {
-        return new JCache(url);
-    }
-
-}
diff --git a/dubbo-spi-filter/dubbo-filter-cache/src/main/java/org/apache/dubbo/cache/support/lfu/LfuCache.java b/dubbo-spi-filter/dubbo-filter-cache/src/main/java/org/apache/dubbo/cache/support/lfu/LfuCache.java
deleted file mode 100644
index 9ccc979..0000000
--- a/dubbo-spi-filter/dubbo-filter-cache/src/main/java/org/apache/dubbo/cache/support/lfu/LfuCache.java
+++ /dev/null
@@ -1,80 +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.cache.support.lfu;
-
-import org.apache.dubbo.cache.Cache;
-import org.apache.dubbo.common.URL;
-import org.apache.dubbo.common.utils.LFUCache;
-
-/**
- * This class store the cache value per thread. If a service,method,consumer or provided is configured with key <b>cache</b>
- * with value <b>lfu</b>, dubbo initialize the instance of this class using {@link LfuCacheFactory} to store method's returns value
- * to server from store without making method call.
- * <pre>
- *     e.g. 1) &lt;dubbo:service cache="lfu" cache.size="5000" cache.evictionFactor="0.3"/&gt;
- *          2) &lt;dubbo:consumer cache="lfu" /&gt;
- * </pre>
- * <pre>
- * LfuCache uses url's <b>cache.size</b> value for its max store size, url's <b>cache.evictionFactor</b> value for its eviction factor,
- * default store size value will be 1000, default eviction factor will be 0.3
- * </pre>
- *
- * @see Cache
- * @see LfuCacheFactory
- * @see org.apache.dubbo.cache.support.AbstractCacheFactory
- * @see org.apache.dubbo.cache.filter.CacheFilter
- */
-public class LfuCache implements Cache {
-
-    /**
-     * This is used to store cache records
-     */
-    private final LFUCache store;
-
-    /**
-     *  Initialize LfuCache, it uses constructor argument <b>cache.size</b> value as its storage max size.
-     *  If nothing is provided then it will use 1000 as default size value. <b>cache.evictionFactor</b> value as its eviction factor.
-     *  If nothing is provided then it will use 0.3 as default value.
-     * @param url A valid URL instance
-     */
-    public LfuCache (URL url) {
-        final int max = url.getParameter("cache.size", 1000);
-        final float factor = url.getParameter("cache.evictionFactor", 0.75f);
-        this.store = new LFUCache(max, factor);
-    }
-
-    /**
-     * API to store value against a key in the calling thread scope.
-     * @param key  Unique identifier for the object being store.
-     * @param value Value getting store
-     */
-    @Override
-    public void put(Object key, Object value) {
-        store.put(key, value);
-    }
-
-    /**
-     * API to return stored value using a key against the calling thread specific store.
-     * @param key Unique identifier for cache lookup
-     * @return Return stored object against key
-     */
-    @Override
-    public Object get(Object key) {
-        return store.get(key);
-    }
-
-}
diff --git a/dubbo-spi-filter/dubbo-filter-cache/src/main/java/org/apache/dubbo/cache/support/lfu/LfuCacheFactory.java b/dubbo-spi-filter/dubbo-filter-cache/src/main/java/org/apache/dubbo/cache/support/lfu/LfuCacheFactory.java
deleted file mode 100644
index f04edca..0000000
--- a/dubbo-spi-filter/dubbo-filter-cache/src/main/java/org/apache/dubbo/cache/support/lfu/LfuCacheFactory.java
+++ /dev/null
@@ -1,43 +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.cache.support.lfu;
-
-import org.apache.dubbo.cache.Cache;
-import org.apache.dubbo.cache.support.AbstractCacheFactory;
-import org.apache.dubbo.common.URL;
-
-/**
- * Implement {@link org.apache.dubbo.cache.CacheFactory} by extending {@link AbstractCacheFactory} and provide
- * instance of new {@link LfuCache}.
- *
- * @see AbstractCacheFactory
- * @see LfuCache
- * @see Cache
- */
-public class LfuCacheFactory extends AbstractCacheFactory {
-
-    /**
-     * Takes url as an method argument and return new instance of cache store implemented by LfuCache.
-     * @param url url of the method
-     * @return ThreadLocalCache instance of cache
-     */
-    @Override
-    protected Cache createCache(URL url) {
-        return new LfuCache(url);
-    }
-
-}
diff --git a/dubbo-spi-filter/dubbo-filter-cache/src/main/java/org/apache/dubbo/cache/support/lru/LruCache.java b/dubbo-spi-filter/dubbo-filter-cache/src/main/java/org/apache/dubbo/cache/support/lru/LruCache.java
deleted file mode 100644
index 1b8022f..0000000
--- a/dubbo-spi-filter/dubbo-filter-cache/src/main/java/org/apache/dubbo/cache/support/lru/LruCache.java
+++ /dev/null
@@ -1,80 +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.cache.support.lru;
-
-import org.apache.dubbo.cache.Cache;
-import org.apache.dubbo.common.URL;
-import org.apache.dubbo.common.utils.LRUCache;
-
-import java.util.Map;
-
-/**
- * This class store the cache value per thread. If a service,method,consumer or provided is configured with key <b>cache</b>
- * with value <b>lru</b>, dubbo initialize the instance of this class using {@link LruCacheFactory} to store method's returns value
- * to server from store without making method call.
- * <pre>
- *     e.g. 1) &lt;dubbo:service cache="lru" cache.size="5000"/&gt;
- *          2) &lt;dubbo:consumer cache="lru" /&gt;
- * </pre>
- * <pre>
- * LruCache uses url's <b>cache.size</b> value for its max store size, if nothing is provided then
- * default value will be 1000
- * </pre>
- *
- * @see Cache
- * @see LruCacheFactory
- * @see org.apache.dubbo.cache.support.AbstractCacheFactory
- * @see org.apache.dubbo.cache.filter.CacheFilter
- */
-public class LruCache implements Cache {
-
-    /**
-     * This is used to store cache records
-     */
-    private final Map<Object, Object> store;
-
-    /**
-     * Initialize LruCache, it uses constructor argument <b>cache.size</b> value as its storage max size.
-     *  If nothing is provided then it will use 1000 as default value.
-     * @param url A valid URL instance
-     */
-    public LruCache(URL url) {
-        final int max = url.getParameter("cache.size", 1000);
-        this.store = new LRUCache<>(max);
-    }
-
-    /**
-     * API to store value against a key in the calling thread scope.
-     * @param key  Unique identifier for the object being store.
-     * @param value Value getting store
-     */
-    @Override
-    public void put(Object key, Object value) {
-        store.put(key, value);
-    }
-
-    /**
-     * API to return stored value using a key against the calling thread specific store.
-     * @param key Unique identifier for cache lookup
-     * @return Return stored object against key
-     */
-    @Override
-    public Object get(Object key) {
-        return store.get(key);
-    }
-
-}
diff --git a/dubbo-spi-filter/dubbo-filter-cache/src/main/java/org/apache/dubbo/cache/support/lru/LruCacheFactory.java b/dubbo-spi-filter/dubbo-filter-cache/src/main/java/org/apache/dubbo/cache/support/lru/LruCacheFactory.java
deleted file mode 100644
index 9ec9486..0000000
--- a/dubbo-spi-filter/dubbo-filter-cache/src/main/java/org/apache/dubbo/cache/support/lru/LruCacheFactory.java
+++ /dev/null
@@ -1,43 +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.cache.support.lru;
-
-import org.apache.dubbo.cache.Cache;
-import org.apache.dubbo.cache.support.AbstractCacheFactory;
-import org.apache.dubbo.common.URL;
-
-/**
- * Implement {@link org.apache.dubbo.cache.CacheFactory} by extending {@link AbstractCacheFactory} and provide
- * instance of new {@link LruCache}.
- *
- * @see AbstractCacheFactory
- * @see LruCache
- * @see Cache
- */
-public class LruCacheFactory extends AbstractCacheFactory {
-
-    /**
-     * Takes url as an method argument and return new instance of cache store implemented by LruCache.
-     * @param url url of the method
-     * @return ThreadLocalCache instance of cache
-     */
-    @Override
-    protected Cache createCache(URL url) {
-        return new LruCache(url);
-    }
-
-}
diff --git a/dubbo-spi-filter/dubbo-filter-cache/src/main/java/org/apache/dubbo/cache/support/threadlocal/ThreadLocalCache.java b/dubbo-spi-filter/dubbo-filter-cache/src/main/java/org/apache/dubbo/cache/support/threadlocal/ThreadLocalCache.java
deleted file mode 100644
index 12b3b5c..0000000
--- a/dubbo-spi-filter/dubbo-filter-cache/src/main/java/org/apache/dubbo/cache/support/threadlocal/ThreadLocalCache.java
+++ /dev/null
@@ -1,77 +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.cache.support.threadlocal;
-
-import org.apache.dubbo.cache.Cache;
-import org.apache.dubbo.common.URL;
-
-import java.util.HashMap;
-import java.util.Map;
-
-/**
- * This class store the cache value per thread. If a service,method,consumer or provided is configured with key <b>cache</b>
- * with value <b>threadlocal</b>, dubbo initialize the instance of this class using {@link ThreadLocalCacheFactory} to store method's returns value
- * to server from store without making method call.
- *  <pre>
- *      e.g. &lt;dubbo:service cache="threadlocal" /&gt;
- *  </pre>
- * <pre>
- * As this ThreadLocalCache stores key-value in memory without any expiry or delete support per thread wise, if number threads and number of key-value are high then jvm should be
- * configured with appropriate memory.
- * </pre>
- *
- * @see org.apache.dubbo.cache.support.AbstractCacheFactory
- * @see org.apache.dubbo.cache.filter.CacheFilter
- * @see Cache
- */
-public class ThreadLocalCache implements Cache {
-
-    /**
-     * Thread local variable to store cached data.
-     */
-    private final ThreadLocal<Map<Object, Object>> store;
-
-    /**
-     * Taken URL as an argument to create an instance of ThreadLocalCache. In this version of implementation constructor
-     * argument is not getting used in the scope of this class.
-     * @param url
-     */
-    public ThreadLocalCache(URL url) {
-        this.store = ThreadLocal.withInitial(HashMap::new);
-    }
-
-    /**
-     * API to store value against a key in the calling thread scope.
-     * @param key  Unique identifier for the object being store.
-     * @param value Value getting store
-     */
-    @Override
-    public void put(Object key, Object value) {
-        store.get().put(key, value);
-    }
-
-    /**
-     * API to return stored value using a key against the calling thread specific store.
-     * @param key Unique identifier for cache lookup
-     * @return Return stored object against key
-     */
-    @Override
-    public Object get(Object key) {
-        return store.get().get(key);
-    }
-
-}
diff --git a/dubbo-spi-filter/dubbo-filter-cache/src/main/java/org/apache/dubbo/cache/support/threadlocal/ThreadLocalCacheFactory.java b/dubbo-spi-filter/dubbo-filter-cache/src/main/java/org/apache/dubbo/cache/support/threadlocal/ThreadLocalCacheFactory.java
deleted file mode 100644
index cdda6cf..0000000
--- a/dubbo-spi-filter/dubbo-filter-cache/src/main/java/org/apache/dubbo/cache/support/threadlocal/ThreadLocalCacheFactory.java
+++ /dev/null
@@ -1,43 +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.cache.support.threadlocal;
-
-import org.apache.dubbo.cache.Cache;
-import org.apache.dubbo.cache.support.AbstractCacheFactory;
-import org.apache.dubbo.common.URL;
-
-/**
- * Implement {@link org.apache.dubbo.cache.CacheFactory} by extending {@link AbstractCacheFactory} and provide
- * instance of new {@link ThreadLocalCache}. Note about this class is, each thread does not have a local copy of factory.
- *
- * @see AbstractCacheFactory
- * @see ThreadLocalCache
- * @see Cache
- */
-public class ThreadLocalCacheFactory extends AbstractCacheFactory {
-
-    /**
-     * Takes url as an method argument and return new instance of cache store implemented by ThreadLocalCache.
-     * @param url url of the method
-     * @return ThreadLocalCache instance of cache
-     */
-    @Override
-    protected Cache createCache(URL url) {
-        return new ThreadLocalCache(url);
-    }
-
-}
diff --git a/dubbo-spi-filter/dubbo-filter-cache/src/main/resources/META-INF/dubbo/internal/org.apache.dubbo.cache.CacheFactory b/dubbo-spi-filter/dubbo-filter-cache/src/main/resources/META-INF/dubbo/internal/org.apache.dubbo.cache.CacheFactory
deleted file mode 100644
index 1ea180a..0000000
--- a/dubbo-spi-filter/dubbo-filter-cache/src/main/resources/META-INF/dubbo/internal/org.apache.dubbo.cache.CacheFactory
+++ /dev/null
@@ -1,4 +0,0 @@
-threadlocal=org.apache.dubbo.cache.support.threadlocal.ThreadLocalCacheFactory
-lru=org.apache.dubbo.cache.support.lru.LruCacheFactory
-jcache=org.apache.dubbo.cache.support.jcache.JCacheFactory
-expiring=org.apache.dubbo.cache.support.expiring.ExpiringCacheFactory
\ No newline at end of file
diff --git a/dubbo-spi-filter/dubbo-filter-cache/src/main/resources/META-INF/dubbo/internal/org.apache.dubbo.rpc.Filter b/dubbo-spi-filter/dubbo-filter-cache/src/main/resources/META-INF/dubbo/internal/org.apache.dubbo.rpc.Filter
deleted file mode 100644
index 8d6259b..0000000
--- a/dubbo-spi-filter/dubbo-filter-cache/src/main/resources/META-INF/dubbo/internal/org.apache.dubbo.rpc.Filter
+++ /dev/null
@@ -1 +0,0 @@
-cache=org.apache.dubbo.cache.filter.CacheFilter
\ No newline at end of file
diff --git a/dubbo-spi-filter/dubbo-filter-cache/src/test/java/org/apache/dubbo/cache/filter/CacheFilterTest.java b/dubbo-spi-filter/dubbo-filter-cache/src/test/java/org/apache/dubbo/cache/filter/CacheFilterTest.java
deleted file mode 100644
index 3326833..0000000
--- a/dubbo-spi-filter/dubbo-filter-cache/src/test/java/org/apache/dubbo/cache/filter/CacheFilterTest.java
+++ /dev/null
@@ -1,137 +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.cache.filter;
-
-import org.apache.dubbo.cache.CacheFactory;
-import org.apache.dubbo.cache.support.expiring.ExpiringCacheFactory;
-import org.apache.dubbo.cache.support.jcache.JCacheFactory;
-import org.apache.dubbo.cache.support.lru.LruCacheFactory;
-import org.apache.dubbo.cache.support.threadlocal.ThreadLocalCacheFactory;
-import org.apache.dubbo.common.URL;
-import org.apache.dubbo.rpc.AsyncRpcResult;
-import org.apache.dubbo.rpc.Invoker;
-import org.apache.dubbo.rpc.Result;
-import org.apache.dubbo.rpc.RpcInvocation;
-
-import org.junit.jupiter.api.Assertions;
-import org.junit.jupiter.params.ParameterizedTest;
-import org.junit.jupiter.params.provider.Arguments;
-import org.junit.jupiter.params.provider.MethodSource;
-
-import java.util.stream.Stream;
-
-import static org.mockito.BDDMockito.given;
-import static org.mockito.Mockito.mock;
-
-public class CacheFilterTest {
-    private RpcInvocation invocation;
-    private CacheFilter cacheFilter = new CacheFilter();
-    private Invoker<?> invoker = mock(Invoker.class);
-    private Invoker<?> invoker1 = mock(Invoker.class);
-    private Invoker<?> invoker2 = mock(Invoker.class);
-    private Invoker<?> invoker3 = mock(Invoker.class);
-    private Invoker<?> invoker4 = mock(Invoker.class);
-
-    static Stream<Arguments> cacheFactories() {
-        return Stream.of(
-                Arguments.of("lru", new LruCacheFactory()),
-                Arguments.of("jcache", new JCacheFactory()),
-                Arguments.of("threadlocal", new ThreadLocalCacheFactory()),
-                Arguments.of("expiring", new ExpiringCacheFactory())
-        );
-    }
-
-    public void setUp(String cacheType, CacheFactory cacheFactory) {
-        invocation = new RpcInvocation();
-        cacheFilter.setCacheFactory(cacheFactory);
-
-        URL url = URL.valueOf("test://test:11/test?cache=" + cacheType);
-
-        given(invoker.invoke(invocation)).willReturn(AsyncRpcResult.newDefaultAsyncResult("value", invocation));
-        given(invoker.getUrl()).willReturn(url);
-
-        given(invoker1.invoke(invocation)).willReturn(AsyncRpcResult.newDefaultAsyncResult("value1", invocation));
-        given(invoker1.getUrl()).willReturn(url);
-
-        given(invoker2.invoke(invocation)).willReturn(AsyncRpcResult.newDefaultAsyncResult("value2", invocation));
-        given(invoker2.getUrl()).willReturn(url);
-
-        given(invoker3.invoke(invocation)).willReturn(AsyncRpcResult.newDefaultAsyncResult(new RuntimeException(), invocation));
-        given(invoker3.getUrl()).willReturn(url);
-
-        given(invoker4.invoke(invocation)).willReturn(AsyncRpcResult.newDefaultAsyncResult(invocation));
-        given(invoker4.getUrl()).willReturn(url);
-    }
-
-    @ParameterizedTest
-    @MethodSource("cacheFactories")
-    public void testNonArgsMethod(String cacheType, CacheFactory cacheFactory) {
-        setUp(cacheType, cacheFactory);
-        invocation.setMethodName("echo");
-        invocation.setParameterTypes(new Class<?>[]{});
-        invocation.setArguments(new Object[]{});
-
-        cacheFilter.invoke(invoker, invocation);
-        Result rpcResult1 = cacheFilter.invoke(invoker1, invocation);
-        Result rpcResult2 = cacheFilter.invoke(invoker2, invocation);
-        Assertions.assertEquals(rpcResult1.getValue(), rpcResult2.getValue());
-        Assertions.assertEquals(rpcResult1.getValue(), "value");
-    }
-
-    @ParameterizedTest
-    @MethodSource("cacheFactories")
-    public void testMethodWithArgs(String cacheType, CacheFactory cacheFactory) {
-        setUp(cacheType, cacheFactory);
-        invocation.setMethodName("echo1");
-        invocation.setParameterTypes(new Class<?>[]{String.class});
-        invocation.setArguments(new Object[]{"arg1"});
-
-        cacheFilter.invoke(invoker, invocation);
-        Result rpcResult1 = cacheFilter.invoke(invoker1, invocation);
-        Result rpcResult2 = cacheFilter.invoke(invoker2, invocation);
-        Assertions.assertEquals(rpcResult1.getValue(), rpcResult2.getValue());
-        Assertions.assertEquals(rpcResult1.getValue(), "value");
-    }
-
-    @ParameterizedTest
-    @MethodSource("cacheFactories")
-    public void testException(String cacheType, CacheFactory cacheFactory) {
-        setUp(cacheType, cacheFactory);
-        invocation.setMethodName("echo1");
-        invocation.setParameterTypes(new Class<?>[]{String.class});
-        invocation.setArguments(new Object[]{"arg2"});
-
-        cacheFilter.invoke(invoker3, invocation);
-        Result rpcResult = cacheFilter.invoke(invoker2, invocation);
-        Assertions.assertEquals(rpcResult.getValue(), "value2");
-    }
-
-    @ParameterizedTest
-    @MethodSource("cacheFactories")
-    public void testNull(String cacheType, CacheFactory cacheFactory) {
-        setUp(cacheType, cacheFactory);
-        invocation.setMethodName("echo1");
-        invocation.setParameterTypes(new Class<?>[]{String.class});
-        invocation.setArguments(new Object[]{"arg3"});
-
-        cacheFilter.invoke(invoker4, invocation);
-        Result result1 = cacheFilter.invoke(invoker1, invocation);
-        Result result2 = cacheFilter.invoke(invoker2, invocation);
-        Assertions.assertNull(result1.getValue());
-        Assertions.assertNull(result2.getValue());
-    }
-}
diff --git a/dubbo-spi-filter/dubbo-filter-cache/src/test/java/org/apache/dubbo/cache/support/AbstractCacheFactoryTest.java b/dubbo-spi-filter/dubbo-filter-cache/src/test/java/org/apache/dubbo/cache/support/AbstractCacheFactoryTest.java
deleted file mode 100644
index f93a453..0000000
--- a/dubbo-spi-filter/dubbo-filter-cache/src/test/java/org/apache/dubbo/cache/support/AbstractCacheFactoryTest.java
+++ /dev/null
@@ -1,33 +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.cache.support;
-
-import org.apache.dubbo.cache.Cache;
-import org.apache.dubbo.common.URL;
-import org.apache.dubbo.rpc.Invocation;
-import org.apache.dubbo.rpc.RpcInvocation;
-
-public abstract class AbstractCacheFactoryTest {
-
-    protected Cache constructCache() {
-        URL url = URL.valueOf("test://test:11/test?cache=lru");
-        Invocation invocation = new RpcInvocation();
-        return getCacheFactory().getCache(url, invocation);
-    }
-
-    protected abstract AbstractCacheFactory getCacheFactory();
-}
\ No newline at end of file
diff --git a/dubbo-spi-filter/dubbo-filter-cache/src/test/java/org/apache/dubbo/cache/support/expiring/ExpiringCacheFactoryTest.java b/dubbo-spi-filter/dubbo-filter-cache/src/test/java/org/apache/dubbo/cache/support/expiring/ExpiringCacheFactoryTest.java
deleted file mode 100644
index 23484c6..0000000
--- a/dubbo-spi-filter/dubbo-filter-cache/src/test/java/org/apache/dubbo/cache/support/expiring/ExpiringCacheFactoryTest.java
+++ /dev/null
@@ -1,38 +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.cache.support.expiring;
-
-import org.apache.dubbo.cache.Cache;
-import org.apache.dubbo.cache.support.AbstractCacheFactory;
-import org.apache.dubbo.cache.support.AbstractCacheFactoryTest;
-import org.junit.jupiter.api.Test;
-
-import static org.hamcrest.core.Is.is;
-import static org.hamcrest.MatcherAssert.assertThat;
-
-public class ExpiringCacheFactoryTest extends AbstractCacheFactoryTest {
-    @Test
-    public void testLruCacheFactory() throws Exception {
-        Cache cache = super.constructCache();
-        assertThat(cache instanceof ExpiringCache, is(true));
-    }
-
-    @Override
-    protected AbstractCacheFactory getCacheFactory() {
-        return new ExpiringCacheFactory();
-    }
-}
\ No newline at end of file
diff --git a/dubbo-spi-filter/dubbo-filter-cache/src/test/java/org/apache/dubbo/cache/support/jcache/JCacheFactoryTest.java b/dubbo-spi-filter/dubbo-filter-cache/src/test/java/org/apache/dubbo/cache/support/jcache/JCacheFactoryTest.java
deleted file mode 100644
index 3260fa6..0000000
--- a/dubbo-spi-filter/dubbo-filter-cache/src/test/java/org/apache/dubbo/cache/support/jcache/JCacheFactoryTest.java
+++ /dev/null
@@ -1,55 +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.cache.support.jcache;
-
-import org.apache.dubbo.cache.Cache;
-import org.apache.dubbo.cache.support.AbstractCacheFactory;
-import org.apache.dubbo.cache.support.AbstractCacheFactoryTest;
-import org.apache.dubbo.common.URL;
-import org.apache.dubbo.rpc.Invocation;
-import org.apache.dubbo.rpc.RpcInvocation;
-
-import org.junit.jupiter.api.Test;
-
-import static org.hamcrest.MatcherAssert.assertThat;
-import static org.hamcrest.core.Is.is;
-import static org.junit.jupiter.api.Assertions.assertNull;
-
-public class JCacheFactoryTest extends AbstractCacheFactoryTest {
-
-    @Test
-    public void testJCacheFactory() throws Exception {
-        Cache cache = super.constructCache();
-        assertThat(cache instanceof JCache, is(true));
-    }
-
-    @Test
-    public void testJCacheGetExpired() throws Exception {
-        URL url = URL.valueOf("test://test:12/test?cache=jacache&cache.write.expire=1");
-        AbstractCacheFactory cacheFactory = getCacheFactory();
-        Invocation invocation = new RpcInvocation();
-        Cache cache = cacheFactory.getCache(url, invocation);
-        cache.put("testKey", "testValue");
-        Thread.sleep(10);
-        assertNull(cache.get("testKey"));
-    }
-
-    @Override
-    protected AbstractCacheFactory getCacheFactory() {
-        return new JCacheFactory();
-    }
-}
\ No newline at end of file
diff --git a/dubbo-spi-filter/dubbo-filter-cache/src/test/java/org/apache/dubbo/cache/support/lru/LruCacheFactoryTest.java b/dubbo-spi-filter/dubbo-filter-cache/src/test/java/org/apache/dubbo/cache/support/lru/LruCacheFactoryTest.java
deleted file mode 100644
index 149c122..0000000
--- a/dubbo-spi-filter/dubbo-filter-cache/src/test/java/org/apache/dubbo/cache/support/lru/LruCacheFactoryTest.java
+++ /dev/null
@@ -1,38 +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.cache.support.lru;
-
-import org.apache.dubbo.cache.Cache;
-import org.apache.dubbo.cache.support.AbstractCacheFactory;
-import org.apache.dubbo.cache.support.AbstractCacheFactoryTest;
-import org.junit.jupiter.api.Test;
-
-import static org.hamcrest.core.Is.is;
-import static org.hamcrest.MatcherAssert.assertThat;
-
-public class LruCacheFactoryTest extends AbstractCacheFactoryTest{
-    @Test
-    public void testLruCacheFactory() throws Exception {
-        Cache cache = super.constructCache();
-        assertThat(cache instanceof LruCache, is(true));
-    }
-
-    @Override
-    protected AbstractCacheFactory getCacheFactory() {
-        return new LruCacheFactory();
-    }
-}
\ No newline at end of file
diff --git a/dubbo-spi-filter/dubbo-filter-cache/src/test/java/org/apache/dubbo/cache/support/threadlocal/ThreadLocalCacheFactoryTest.java b/dubbo-spi-filter/dubbo-filter-cache/src/test/java/org/apache/dubbo/cache/support/threadlocal/ThreadLocalCacheFactoryTest.java
deleted file mode 100644
index 800f5ad..0000000
--- a/dubbo-spi-filter/dubbo-filter-cache/src/test/java/org/apache/dubbo/cache/support/threadlocal/ThreadLocalCacheFactoryTest.java
+++ /dev/null
@@ -1,38 +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.cache.support.threadlocal;
-
-import org.apache.dubbo.cache.Cache;
-import org.apache.dubbo.cache.support.AbstractCacheFactory;
-import org.apache.dubbo.cache.support.AbstractCacheFactoryTest;
-import org.junit.jupiter.api.Test;
-
-import static org.hamcrest.core.Is.is;
-import static org.hamcrest.MatcherAssert.assertThat;
-
-public class ThreadLocalCacheFactoryTest extends AbstractCacheFactoryTest {
-    @Test
-    public void testThreadLocalCacheFactory() throws Exception {
-        Cache cache = super.constructCache();
-        assertThat(cache instanceof ThreadLocalCache, is(true));
-    }
-
-    @Override
-    protected AbstractCacheFactory getCacheFactory() {
-        return new ThreadLocalCacheFactory();
-    }
-}
\ No newline at end of file
diff --git a/dubbo-spi-filter/dubbo-filter-validation/pom.xml b/dubbo-spi-filter/dubbo-filter-validation/pom.xml
deleted file mode 100644
index 933f1c9..0000000
--- a/dubbo-spi-filter/dubbo-filter-validation/pom.xml
+++ /dev/null
@@ -1,72 +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.
-  -->
-<project xmlns="http://maven.apache.org/POM/4.0.0" xmlns:xsi="http://www.w3.org/2001/XMLSchema-instance" xsi:schemaLocation="http://maven.apache.org/POM/4.0.0 http://maven.apache.org/maven-v4_0_0.xsd">
-    <modelVersion>4.0.0</modelVersion>
-    <parent>
-        <groupId>org.apache.dubbo</groupId>
-        <artifactId>dubbo-filter</artifactId>
-        <version>2.7.7-SNAPSHOT</version>
-    </parent>
-    <artifactId>dubbo-filter-validation</artifactId>
-    <packaging>jar</packaging>
-    <name>${project.artifactId}</name>
-    <description>The validation module of dubbo project</description>
-    <properties>
-        <skip_maven_deploy>false</skip_maven_deploy>
-    </properties>
-    <dependencies>
-        <dependency>
-            <groupId>org.apache.dubbo</groupId>
-            <artifactId>dubbo-rpc-api</artifactId>
-            <version>${project.parent.version}</version>
-        </dependency>
-        <dependency>
-            <groupId>javax.validation</groupId>
-            <artifactId>validation-api</artifactId>
-        </dependency>
-        <dependency>
-            <groupId>org.hibernate</groupId>
-            <artifactId>hibernate-validator</artifactId>
-            <scope>test</scope>
-            <version>${hibernate_validator_version}</version>
-        </dependency>
-        <dependency>
-            <groupId>javax.el</groupId>
-            <artifactId>javax.el-api</artifactId>
-            <scope>test</scope>
-            <version>${el_api_version}</version>
-        </dependency>
-        <dependency>
-            <groupId>javax.xml.bind</groupId>
-            <artifactId>jaxb-api</artifactId>
-            <scope>test</scope>
-            <version>${jaxb_api_version}</version>
-        </dependency>
-        <dependency>
-            <groupId>com.sun.xml.bind</groupId>
-            <artifactId>jaxb-impl</artifactId>
-            <scope>test</scope>
-            <version>${jaxb_api_version}</version>
-        </dependency>
-        <dependency>
-            <groupId>com.sun.xml.bind</groupId>
-            <artifactId>jaxb-core</artifactId>
-            <scope>test</scope>
-            <version>${jaxb_api_version}</version>
-        </dependency>
-    </dependencies>
-</project>
\ No newline at end of file
diff --git a/dubbo-spi-filter/dubbo-filter-validation/src/main/java/org/apache/dubbo/validation/MethodValidated.java b/dubbo-spi-filter/dubbo-filter-validation/src/main/java/org/apache/dubbo/validation/MethodValidated.java
deleted file mode 100644
index ca41a52..0000000
--- a/dubbo-spi-filter/dubbo-filter-validation/src/main/java/org/apache/dubbo/validation/MethodValidated.java
+++ /dev/null
@@ -1,40 +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.validation;
-
-import java.lang.annotation.Documented;
-import java.lang.annotation.ElementType;
-import java.lang.annotation.Retention;
-import java.lang.annotation.RetentionPolicy;
-import java.lang.annotation.Target;
-
-/**
- * Method grouping validation.
- * <p>
- * Scenario: this annotation can be used on interface's method when need to check against group before invoke the method
- * For example: <pre> @MethodValidated({Save.class, Update.class})
- * void relatedQuery(ValidationParameter parameter);
- * </pre>
- * It means both Save group and Update group are needed to check when method relatedQuery is invoked.
- * </p>
- */
-@Target({ElementType.METHOD})
-@Retention(RetentionPolicy.RUNTIME)
-@Documented
-public @interface MethodValidated {
-    Class<?>[] value() default {};
-}
diff --git a/dubbo-spi-filter/dubbo-filter-validation/src/main/java/org/apache/dubbo/validation/Validation.java b/dubbo-spi-filter/dubbo-filter-validation/src/main/java/org/apache/dubbo/validation/Validation.java
deleted file mode 100644
index 73c4cd8..0000000
--- a/dubbo-spi-filter/dubbo-filter-validation/src/main/java/org/apache/dubbo/validation/Validation.java
+++ /dev/null
@@ -1,39 +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.validation;
-
-import org.apache.dubbo.common.URL;
-import org.apache.dubbo.common.extension.Adaptive;
-import org.apache.dubbo.common.extension.SPI;
-
-import static org.apache.dubbo.common.constants.FilterConstants.VALIDATION_KEY;
-
-/**
- * Instance of Validation interface provide instance of {@link Validator} based on the value of <b>validation</b> attribute.
- */
-@SPI("jvalidation")
-public interface Validation {
-
-    /**
-     * Return the instance of {@link Validator} for a given url.
-     * @param url Invocation url
-     * @return Instance of {@link Validator}
-     */
-    @Adaptive(VALIDATION_KEY)
-    Validator getValidator(URL url);
-
-}
diff --git a/dubbo-spi-filter/dubbo-filter-validation/src/main/java/org/apache/dubbo/validation/Validator.java b/dubbo-spi-filter/dubbo-filter-validation/src/main/java/org/apache/dubbo/validation/Validator.java
deleted file mode 100644
index c78c62a..0000000
--- a/dubbo-spi-filter/dubbo-filter-validation/src/main/java/org/apache/dubbo/validation/Validator.java
+++ /dev/null
@@ -1,27 +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.validation;
-
-/**
- * Instance of validator class is an extension to perform validation on method input parameter before the actual method invocation.
- *
- */
-public interface Validator {
-
-    void validate(String methodName, Class<?>[] parameterTypes, Object[] arguments) throws Exception;
-
-}
diff --git a/dubbo-spi-filter/dubbo-filter-validation/src/main/java/org/apache/dubbo/validation/filter/ValidationFilter.java b/dubbo-spi-filter/dubbo-filter-validation/src/main/java/org/apache/dubbo/validation/filter/ValidationFilter.java
deleted file mode 100644
index 0df2752..0000000
--- a/dubbo-spi-filter/dubbo-filter-validation/src/main/java/org/apache/dubbo/validation/filter/ValidationFilter.java
+++ /dev/null
@@ -1,104 +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.validation.filter;
-
-import org.apache.dubbo.common.extension.Activate;
-import org.apache.dubbo.common.utils.ConfigUtils;
-import org.apache.dubbo.rpc.AsyncRpcResult;
-import org.apache.dubbo.rpc.Filter;
-import org.apache.dubbo.rpc.Invocation;
-import org.apache.dubbo.rpc.Invoker;
-import org.apache.dubbo.rpc.Result;
-import org.apache.dubbo.rpc.RpcException;
-import org.apache.dubbo.validation.Validation;
-import org.apache.dubbo.validation.Validator;
-
-import javax.validation.ValidationException;
-
-import static org.apache.dubbo.common.constants.CommonConstants.CONSUMER;
-import static org.apache.dubbo.common.constants.CommonConstants.PROVIDER;
-import static org.apache.dubbo.common.constants.FilterConstants.VALIDATION_KEY;
-
-/**
- * ValidationFilter invoke the validation by finding the right {@link Validator} instance based on the
- * configured <b>validation</b> attribute value of invoker url before the actual method invocation.
- *
- * <pre>
- *     e.g. &lt;dubbo:method name="save" validation="jvalidation" /&gt;
- *     In the above configuration a validation has been configured of type jvalidation. On invocation of method <b>save</b>
- *     dubbo will invoke {@link org.apache.dubbo.validation.support.jvalidation.JValidator}
- * </pre>
- *
- * To add a new type of validation
- * <pre>
- *     e.g. &lt;dubbo:method name="save" validation="special" /&gt;
- *     where "special" is representing a validator for special character.
- * </pre>
- *
- * developer needs to do
- * <br/>
- * 1)Implement a SpecialValidation.java class (package name xxx.yyy.zzz) either by implementing {@link Validation} or extending {@link org.apache.dubbo.validation.support.AbstractValidation} <br/>
- * 2)Implement a SpecialValidator.java class (package name xxx.yyy.zzz) <br/>
- * 3)Add an entry <b>special</b>=<b>xxx.yyy.zzz.SpecialValidation</b> under <b>META-INF folders org.apache.dubbo.validation.Validation file</b>.
- *
- * @see Validation
- * @see Validator
- * @see Filter
- * @see org.apache.dubbo.validation.support.AbstractValidation
- */
-@Activate(group = {CONSUMER, PROVIDER}, value = VALIDATION_KEY, order = 10000)
-public class ValidationFilter implements Filter {
-
-    private Validation validation;
-
-    /**
-     * Sets the validation instance for ValidationFilter
-     * @param validation Validation instance injected by dubbo framework based on "validation" attribute value.
-     */
-    public void setValidation(Validation validation) {
-        this.validation = validation;
-    }
-
-    /**
-     * Perform the validation of before invoking the actual method based on <b>validation</b> attribute value.
-     * @param invoker    service
-     * @param invocation invocation.
-     * @return Method invocation result
-     * @throws RpcException Throws RpcException if  validation failed or any other runtime exception occurred.
-     */
-    @Override
-    public Result invoke(Invoker<?> invoker, Invocation invocation) throws RpcException {
-        if (validation != null && !invocation.getMethodName().startsWith("$")
-                && ConfigUtils.isNotEmpty(invoker.getUrl().getMethodParameter(invocation.getMethodName(), VALIDATION_KEY))) {
-            try {
-                Validator validator = validation.getValidator(invoker.getUrl());
-                if (validator != null) {
-                    validator.validate(invocation.getMethodName(), invocation.getParameterTypes(), invocation.getArguments());
-                }
-            } catch (RpcException e) {
-                throw e;
-            } catch (ValidationException e) {
-                // only use exception's message to avoid potential serialization issue
-                return AsyncRpcResult.newDefaultAsyncResult(new ValidationException(e.getMessage()), invocation);
-            } catch (Throwable t) {
-                return AsyncRpcResult.newDefaultAsyncResult(t, invocation);
-            }
-        }
-        return invoker.invoke(invocation);
-    }
-
-}
diff --git a/dubbo-spi-filter/dubbo-filter-validation/src/main/java/org/apache/dubbo/validation/support/AbstractValidation.java b/dubbo-spi-filter/dubbo-filter-validation/src/main/java/org/apache/dubbo/validation/support/AbstractValidation.java
deleted file mode 100644
index a6f9c8e..0000000
--- a/dubbo-spi-filter/dubbo-filter-validation/src/main/java/org/apache/dubbo/validation/support/AbstractValidation.java
+++ /dev/null
@@ -1,51 +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.validation.support;
-
-import org.apache.dubbo.common.URL;
-import org.apache.dubbo.validation.Validation;
-import org.apache.dubbo.validation.Validator;
-
-import java.util.concurrent.ConcurrentHashMap;
-import java.util.concurrent.ConcurrentMap;
-
-/**
- * AbstractValidation is abstract class for Validation interface. It helps low level Validation implementation classes
- * by performing common task e.g. key formation, storing instance of validation class to avoid creation of unnecessary
- * copy of validation instance and faster execution.
- *
- * @see Validation
- * @see Validator
- */
-public abstract class AbstractValidation implements Validation {
-
-    private final ConcurrentMap<String, Validator> validators = new ConcurrentHashMap<>();
-
-    @Override
-    public Validator getValidator(URL url) {
-        String key = url.toFullString();
-        Validator validator = validators.get(key);
-        if (validator == null) {
-            validators.put(key, createValidator(url));
-            validator = validators.get(key);
-        }
-        return validator;
-    }
-
-    protected abstract Validator createValidator(URL url);
-
-}
diff --git a/dubbo-spi-filter/dubbo-filter-validation/src/main/java/org/apache/dubbo/validation/support/jvalidation/JValidation.java b/dubbo-spi-filter/dubbo-filter-validation/src/main/java/org/apache/dubbo/validation/support/jvalidation/JValidation.java
deleted file mode 100644
index e8b48cf..0000000
--- a/dubbo-spi-filter/dubbo-filter-validation/src/main/java/org/apache/dubbo/validation/support/jvalidation/JValidation.java
+++ /dev/null
@@ -1,40 +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.validation.support.jvalidation;
-
-import org.apache.dubbo.common.URL;
-import org.apache.dubbo.validation.Validator;
-import org.apache.dubbo.validation.support.AbstractValidation;
-
-/**
- * Creates a new instance of {@link Validator} using input argument url.
- * @see AbstractValidation
- * @see Validator
- */
-public class JValidation extends AbstractValidation {
-
-    /**
-     * Return new instance of {@link JValidator}
-     * @param url Valid URL instance
-     * @return Instance of JValidator
-     */
-    @Override
-    protected Validator createValidator(URL url) {
-        return new JValidator(url);
-    }
-
-}
\ No newline at end of file
diff --git a/dubbo-spi-filter/dubbo-filter-validation/src/main/java/org/apache/dubbo/validation/support/jvalidation/JValidator.java b/dubbo-spi-filter/dubbo-filter-validation/src/main/java/org/apache/dubbo/validation/support/jvalidation/JValidator.java
deleted file mode 100644
index ea8c6db..0000000
--- a/dubbo-spi-filter/dubbo-filter-validation/src/main/java/org/apache/dubbo/validation/support/jvalidation/JValidator.java
+++ /dev/null
@@ -1,330 +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.validation.support.jvalidation;
-
-import org.apache.dubbo.common.URL;
-import org.apache.dubbo.common.bytecode.ClassGenerator;
-import org.apache.dubbo.common.logger.Logger;
-import org.apache.dubbo.common.logger.LoggerFactory;
-import org.apache.dubbo.common.utils.ReflectUtils;
-import org.apache.dubbo.validation.MethodValidated;
-import org.apache.dubbo.validation.Validator;
-
-import javassist.ClassPool;
-import javassist.CtClass;
-import javassist.CtField;
-import javassist.CtNewConstructor;
-import javassist.Modifier;
-import javassist.NotFoundException;
-import javassist.bytecode.AnnotationsAttribute;
-import javassist.bytecode.ClassFile;
-import javassist.bytecode.ConstPool;
-import javassist.bytecode.annotation.ArrayMemberValue;
-import javassist.bytecode.annotation.BooleanMemberValue;
-import javassist.bytecode.annotation.ByteMemberValue;
-import javassist.bytecode.annotation.CharMemberValue;
-import javassist.bytecode.annotation.ClassMemberValue;
-import javassist.bytecode.annotation.DoubleMemberValue;
-import javassist.bytecode.annotation.EnumMemberValue;
-import javassist.bytecode.annotation.FloatMemberValue;
-import javassist.bytecode.annotation.IntegerMemberValue;
-import javassist.bytecode.annotation.LongMemberValue;
-import javassist.bytecode.annotation.MemberValue;
-import javassist.bytecode.annotation.ShortMemberValue;
-import javassist.bytecode.annotation.StringMemberValue;
-
-import javax.validation.Constraint;
-import javax.validation.ConstraintViolation;
-import javax.validation.ConstraintViolationException;
-import javax.validation.Validation;
-import javax.validation.ValidatorFactory;
-import javax.validation.groups.Default;
-import java.lang.annotation.Annotation;
-import java.lang.reflect.Array;
-import java.lang.reflect.Field;
-import java.lang.reflect.Method;
-import java.util.ArrayList;
-import java.util.Arrays;
-import java.util.Collection;
-import java.util.HashSet;
-import java.util.List;
-import java.util.Map;
-import java.util.Set;
-import java.util.concurrent.ConcurrentHashMap;
-
-/**
- * Implementation of JValidation. JValidation is invoked if configuration validation attribute value is 'jvalidation'.
- * <pre>
- *     e.g. &lt;dubbo:method name="save" validation="jvalidation" /&gt;
- * </pre>
- */
-public class JValidator implements Validator {
-
-    private static final Logger logger = LoggerFactory.getLogger(JValidator.class);
-
-    private final Class<?> clazz;
-
-    private final Map<String, Class> methodClassMap;
-
-    private final javax.validation.Validator validator;
-
-    @SuppressWarnings({"unchecked", "rawtypes"})
-    public JValidator(URL url) {
-        this.clazz = ReflectUtils.forName(url.getServiceInterface());
-        String jvalidation = url.getParameter("jvalidation");
-        ValidatorFactory factory;
-        if (jvalidation != null && jvalidation.length() > 0) {
-            factory = Validation.byProvider((Class) ReflectUtils.forName(jvalidation)).configure().buildValidatorFactory();
-        } else {
-            factory = Validation.buildDefaultValidatorFactory();
-        }
-        this.validator = factory.getValidator();
-        this.methodClassMap = new ConcurrentHashMap<>();
-    }
-
-    private static Object getMethodParameterBean(Class<?> clazz, Method method, Object[] args) {
-        if (!hasConstraintParameter(method)) {
-            return null;
-        }
-        try {
-            String parameterClassName = generateMethodParameterClassName(clazz, method);
-            Class<?> parameterClass;
-            try {
-                parameterClass = Class.forName(parameterClassName, true, clazz.getClassLoader());
-            } catch (ClassNotFoundException e) {
-                parameterClass = generateMethodParameterClass(clazz, method, parameterClassName);
-            }
-            Object parameterBean = parameterClass.newInstance();
-            for (int i = 0; i < args.length; i++) {
-                Field field = parameterClass.getField(method.getName() + "Argument" + i);
-                field.set(parameterBean, args[i]);
-            }
-            return parameterBean;
-        } catch (Throwable e) {
-            logger.warn(e.getMessage(), e);
-            return null;
-        }
-    }
-
-    /**
-     * try to generate methodParameterClass.
-     *
-     * @param clazz interface class
-     * @param method invoke method
-     * @param parameterClassName generated parameterClassName
-     * @return Class<?> generated methodParameterClass
-     * @throws Exception
-     */
-    private static Class<?> generateMethodParameterClass(Class<?> clazz, Method method, String parameterClassName)
-        throws Exception {
-        ClassPool pool = ClassGenerator.getClassPool(clazz.getClassLoader());
-        synchronized (parameterClassName.intern()) {
-            CtClass ctClass = null;
-            try {
-                ctClass = pool.getCtClass(parameterClassName);
-            } catch (NotFoundException ignore) {
-            }
-
-            if (null == ctClass) {
-                ctClass = pool.makeClass(parameterClassName);
-                ClassFile classFile = ctClass.getClassFile();
-                classFile.setVersionToJava5();
-                ctClass.addConstructor(CtNewConstructor.defaultConstructor(pool.getCtClass(parameterClassName)));
-                // parameter fields
-                Class<?>[] parameterTypes = method.getParameterTypes();
-                Annotation[][] parameterAnnotations = method.getParameterAnnotations();
-                for (int i = 0; i < parameterTypes.length; i++) {
-                    Class<?> type = parameterTypes[i];
-                    Annotation[] annotations = parameterAnnotations[i];
-                    AnnotationsAttribute attribute = new AnnotationsAttribute(classFile.getConstPool(), AnnotationsAttribute.visibleTag);
-                    for (Annotation annotation : annotations) {
-                        if (annotation.annotationType().isAnnotationPresent(Constraint.class)) {
-                            javassist.bytecode.annotation.Annotation ja = new javassist.bytecode.annotation.Annotation(
-                                classFile.getConstPool(), pool.getCtClass(annotation.annotationType().getName()));
-                            Method[] members = annotation.annotationType().getMethods();
-                            for (Method member : members) {
-                                if (Modifier.isPublic(member.getModifiers())
-                                    && member.getParameterTypes().length == 0
-                                    && member.getDeclaringClass() == annotation.annotationType()) {
-                                    Object value = member.invoke(annotation);
-                                    if (null != value) {
-                                        MemberValue memberValue = createMemberValue(
-                                            classFile.getConstPool(), pool.get(member.getReturnType().getName()), value);
-                                        ja.addMemberValue(member.getName(), memberValue);
-                                    }
-                                }
-                            }
-                            attribute.addAnnotation(ja);
-                        }
-                    }
-                    String fieldName = method.getName() + "Argument" + i;
-                    CtField ctField = CtField.make("public " + type.getCanonicalName() + " " + fieldName + ";", pool.getCtClass(parameterClassName));
-                    ctField.getFieldInfo().addAttribute(attribute);
-                    ctClass.addField(ctField);
-                }
-                return ctClass.toClass(clazz.getClassLoader(), null);
-            } else {
-                return Class.forName(parameterClassName, true, clazz.getClassLoader());
-            }
-        }
-    }
-
-    private static String generateMethodParameterClassName(Class<?> clazz, Method method) {
-        StringBuilder builder = new StringBuilder().append(clazz.getName())
-                .append("_")
-                .append(toUpperMethoName(method.getName()))
-                .append("Parameter");
-
-        Class<?>[] parameterTypes = method.getParameterTypes();
-        for (Class<?> parameterType : parameterTypes) {
-            builder.append("_").append(parameterType.getName());
-        }
-
-        return builder.toString();
-    }
-
-    private static boolean hasConstraintParameter(Method method) {
-        Annotation[][] parameterAnnotations = method.getParameterAnnotations();
-        if (parameterAnnotations != null && parameterAnnotations.length > 0) {
-            for (Annotation[] annotations : parameterAnnotations) {
-                for (Annotation annotation : annotations) {
-                    if (annotation.annotationType().isAnnotationPresent(Constraint.class)) {
-                        return true;
-                    }
-                }
-            }
-        }
-        return false;
-    }
-
-    private static String toUpperMethoName(String methodName) {
-        return methodName.substring(0, 1).toUpperCase() + methodName.substring(1);
-    }
-
-    // Copy from javassist.bytecode.annotation.Annotation.createMemberValue(ConstPool, CtClass);
-    private static MemberValue createMemberValue(ConstPool cp, CtClass type, Object value) throws NotFoundException {
-        MemberValue memberValue = javassist.bytecode.annotation.Annotation.createMemberValue(cp, type);
-        if (memberValue instanceof BooleanMemberValue) {
-            ((BooleanMemberValue) memberValue).setValue((Boolean) value);
-        } else if (memberValue instanceof ByteMemberValue) {
-            ((ByteMemberValue) memberValue).setValue((Byte) value);
-        } else if (memberValue instanceof CharMemberValue) {
-            ((CharMemberValue) memberValue).setValue((Character) value);
-        } else if (memberValue instanceof ShortMemberValue) {
-            ((ShortMemberValue) memberValue).setValue((Short) value);
-        } else if (memberValue instanceof IntegerMemberValue) {
-            ((IntegerMemberValue) memberValue).setValue((Integer) value);
-        } else if (memberValue instanceof LongMemberValue) {
-            ((LongMemberValue) memberValue).setValue((Long) value);
-        } else if (memberValue instanceof FloatMemberValue) {
-            ((FloatMemberValue) memberValue).setValue((Float) value);
-        } else if (memberValue instanceof DoubleMemberValue) {
-            ((DoubleMemberValue) memberValue).setValue((Double) value);
-        } else if (memberValue instanceof ClassMemberValue) {
-            ((ClassMemberValue) memberValue).setValue(((Class<?>) value).getName());
-        } else if (memberValue instanceof StringMemberValue) {
-            ((StringMemberValue) memberValue).setValue((String) value);
-        } else if (memberValue instanceof EnumMemberValue) {
-            ((EnumMemberValue) memberValue).setValue(((Enum<?>) value).name());
-        }
-        /* else if (memberValue instanceof AnnotationMemberValue) */
-        else if (memberValue instanceof ArrayMemberValue) {
-            CtClass arrayType = type.getComponentType();
-            int len = Array.getLength(value);
-            MemberValue[] members = new MemberValue[len];
-            for (int i = 0; i < len; i++) {
-                members[i] = createMemberValue(cp, arrayType, Array.get(value, i));
-            }
-            ((ArrayMemberValue) memberValue).setValue(members);
-        }
-        return memberValue;
-    }
-
-    @Override
-    public void validate(String methodName, Class<?>[] parameterTypes, Object[] arguments) throws Exception {
-        List<Class<?>> groups = new ArrayList<>();
-        Class<?> methodClass = methodClass(methodName);
-        if (methodClass != null) {
-            groups.add(methodClass);
-        }
-        Set<ConstraintViolation<?>> violations = new HashSet<>();
-        Method method = clazz.getMethod(methodName, parameterTypes);
-        Class<?>[] methodClasses;
-        if (method.isAnnotationPresent(MethodValidated.class)){
-            methodClasses = method.getAnnotation(MethodValidated.class).value();
-            groups.addAll(Arrays.asList(methodClasses));
-        }
-        // add into default group
-        groups.add(0, Default.class);
-        groups.add(1, clazz);
-
-        // convert list to array
-        Class<?>[] classgroups = groups.toArray(new Class[groups.size()]);
-
-        Object parameterBean = getMethodParameterBean(clazz, method, arguments);
-        if (parameterBean != null) {
-            violations.addAll(validator.validate(parameterBean, classgroups ));
-        }
-
-        for (Object arg : arguments) {
-            validate(violations, arg, classgroups);
-        }
-
-        if (!violations.isEmpty()) {
-            logger.error("Failed to validate service: " + clazz.getName() + ", method: " + methodName + ", cause: " + violations);
-            throw new ConstraintViolationException("Failed to validate service: " + clazz.getName() + ", method: " + methodName + ", cause: " + violations, violations);
-        }
-    }
-
-    private Class methodClass(String methodName) {
-        Class<?> methodClass = null;
-        String methodClassName = clazz.getName() + "$" + toUpperMethoName(methodName);
-        Class cached = methodClassMap.get(methodClassName);
-        if (cached != null) {
-            return cached == clazz ? null : cached;
-        }
-        try {
-            methodClass = Class.forName(methodClassName, false, Thread.currentThread().getContextClassLoader());
-            methodClassMap.put(methodClassName, methodClass);
-        } catch (ClassNotFoundException e) {
-            methodClassMap.put(methodClassName, clazz);
-        }
-        return methodClass;
-    }
-
-    private void validate(Set<ConstraintViolation<?>> violations, Object arg, Class<?>... groups) {
-        if (arg != null && !ReflectUtils.isPrimitives(arg.getClass())) {
-            if (arg instanceof Object[]) {
-                for (Object item : (Object[]) arg) {
-                    validate(violations, item, groups);
-                }
-            } else if (arg instanceof Collection) {
-                for (Object item : (Collection<?>) arg) {
-                    validate(violations, item, groups);
-                }
-            } else if (arg instanceof Map) {
-                for (Map.Entry<?, ?> entry : ((Map<?, ?>) arg).entrySet()) {
-                    validate(violations, entry.getKey(), groups);
-                    validate(violations, entry.getValue(), groups);
-                }
-            } else {
-                violations.addAll(validator.validate(arg, groups));
-            }
-        }
-    }
-
-}
diff --git a/dubbo-spi-filter/dubbo-filter-validation/src/main/resources/META-INF/dubbo/internal/org.apache.dubbo.rpc.Filter b/dubbo-spi-filter/dubbo-filter-validation/src/main/resources/META-INF/dubbo/internal/org.apache.dubbo.rpc.Filter
deleted file mode 100644
index 65bf329..0000000
--- a/dubbo-spi-filter/dubbo-filter-validation/src/main/resources/META-INF/dubbo/internal/org.apache.dubbo.rpc.Filter
+++ /dev/null
@@ -1 +0,0 @@
-validation=org.apache.dubbo.validation.filter.ValidationFilter
\ No newline at end of file
diff --git a/dubbo-spi-filter/dubbo-filter-validation/src/main/resources/META-INF/dubbo/internal/org.apache.dubbo.validation.Validation b/dubbo-spi-filter/dubbo-filter-validation/src/main/resources/META-INF/dubbo/internal/org.apache.dubbo.validation.Validation
deleted file mode 100644
index ae3dc96..0000000
--- a/dubbo-spi-filter/dubbo-filter-validation/src/main/resources/META-INF/dubbo/internal/org.apache.dubbo.validation.Validation
+++ /dev/null
@@ -1 +0,0 @@
-jvalidation=org.apache.dubbo.validation.support.jvalidation.JValidation
\ No newline at end of file
diff --git a/dubbo-spi-filter/dubbo-filter-validation/src/test/java/org/apache/dubbo/validation/filter/ValidationFilterTest.java b/dubbo-spi-filter/dubbo-filter-validation/src/test/java/org/apache/dubbo/validation/filter/ValidationFilterTest.java
deleted file mode 100644
index f2efdd5..0000000
--- a/dubbo-spi-filter/dubbo-filter-validation/src/test/java/org/apache/dubbo/validation/filter/ValidationFilterTest.java
+++ /dev/null
@@ -1,137 +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.validation.filter;
-
-import org.apache.dubbo.common.URL;
-import org.apache.dubbo.rpc.AppResponse;
-import org.apache.dubbo.rpc.Invoker;
-import org.apache.dubbo.rpc.Result;
-import org.apache.dubbo.rpc.RpcException;
-import org.apache.dubbo.rpc.RpcInvocation;
-import org.apache.dubbo.validation.Validation;
-import org.apache.dubbo.validation.Validator;
-
-import org.junit.jupiter.api.Assertions;
-import org.junit.jupiter.api.BeforeEach;
-import org.junit.jupiter.api.Test;
-
-import static org.hamcrest.MatcherAssert.assertThat;
-import static org.hamcrest.core.Is.is;
-import static org.mockito.BDDMockito.given;
-import static org.mockito.Mockito.mock;
-
-public class ValidationFilterTest {
-    private Invoker<?> invoker = mock(Invoker.class);
-    private Validation validation = mock(Validation.class);
-    private Validator validator = mock(Validator.class);
-    private RpcInvocation invocation = mock(RpcInvocation.class);
-
-    private ValidationFilter validationFilter;
-
-    @BeforeEach
-    public void setUp() throws Exception {
-        this.validationFilter = new ValidationFilter();
-    }
-
-    @Test
-    public void testItWithNotExistClass() throws Exception {
-        URL url = URL.valueOf("test://test:11/test?validation=true");
-
-        given(validation.getValidator(url)).willThrow(new IllegalStateException("Not found class test, cause: test"));
-        given(invoker.invoke(invocation)).willReturn(new AppResponse("success"));
-        given(invoker.getUrl()).willReturn(url);
-        given(invocation.getMethodName()).willReturn("echo1");
-        given(invocation.getParameterTypes()).willReturn(new Class<?>[]{String.class});
-        given(invocation.getArguments()).willReturn(new Object[]{"arg1"});
-
-        validationFilter.setValidation(validation);
-        Result result = validationFilter.invoke(invoker, invocation);
-
-        assertThat(result.getException().getMessage(), is("Not found class test, cause: test"));
-
-    }
-
-    @Test
-    public void testItWithExistClass() throws Exception {
-        URL url = URL.valueOf("test://test:11/test?validation=true");
-
-        given(validation.getValidator(url)).willReturn(validator);
-        given(invoker.invoke(invocation)).willReturn(new AppResponse("success"));
-        given(invoker.getUrl()).willReturn(url);
-        given(invocation.getMethodName()).willReturn("echo1");
-        given(invocation.getParameterTypes()).willReturn(new Class<?>[]{String.class});
-        given(invocation.getArguments()).willReturn(new Object[]{"arg1"});
-
-        validationFilter.setValidation(validation);
-        Result result = validationFilter.invoke(invoker, invocation);
-
-        assertThat(String.valueOf(result.getValue()), is("success"));
-    }
-
-    @Test
-    public void testItWithoutUrlParameters() throws Exception {
-        URL url = URL.valueOf("test://test:11/test");
-
-        given(validation.getValidator(url)).willReturn(validator);
-        given(invoker.invoke(invocation)).willReturn(new AppResponse("success"));
-        given(invoker.getUrl()).willReturn(url);
-        given(invocation.getMethodName()).willReturn("echo1");
-        given(invocation.getParameterTypes()).willReturn(new Class<?>[]{String.class});
-        given(invocation.getArguments()).willReturn(new Object[]{"arg1"});
-
-        validationFilter.setValidation(validation);
-        Result result = validationFilter.invoke(invoker, invocation);
-
-        assertThat(String.valueOf(result.getValue()), is("success"));
-    }
-
-    @Test
-    public void testItWhileMethodNameStartWithDollar() throws Exception {
-        URL url = URL.valueOf("test://test:11/test");
-
-        given(validation.getValidator(url)).willReturn(validator);
-        given(invoker.invoke(invocation)).willReturn(new AppResponse("success"));
-        given(invoker.getUrl()).willReturn(url);
-        given(invocation.getMethodName()).willReturn("$echo1");
-        given(invocation.getParameterTypes()).willReturn(new Class<?>[]{String.class});
-        given(invocation.getArguments()).willReturn(new Object[]{"arg1"});
-
-        validationFilter.setValidation(validation);
-        Result result = validationFilter.invoke(invoker, invocation);
-
-        assertThat(String.valueOf(result.getValue()), is("success"));
-
-    }
-
-
-    @Test
-    public void testItWhileThrowoutRpcException() throws Exception {
-        Assertions.assertThrows(RpcException.class, () -> {
-            URL url = URL.valueOf("test://test:11/test?validation=true");
-
-            given(validation.getValidator(url)).willThrow(new RpcException("rpc exception"));
-            given(invoker.invoke(invocation)).willReturn(new AppResponse("success"));
-            given(invoker.getUrl()).willReturn(url);
-            given(invocation.getMethodName()).willReturn("echo1");
-            given(invocation.getParameterTypes()).willReturn(new Class<?>[]{String.class});
-            given(invocation.getArguments()).willReturn(new Object[]{"arg1"});
-
-            validationFilter.setValidation(validation);
-            validationFilter.invoke(invoker, invocation);
-        });
-    }
-}
\ No newline at end of file
diff --git a/dubbo-spi-filter/dubbo-filter-validation/src/test/java/org/apache/dubbo/validation/support/jvalidation/JValidationTest.java b/dubbo-spi-filter/dubbo-filter-validation/src/test/java/org/apache/dubbo/validation/support/jvalidation/JValidationTest.java
deleted file mode 100644
index fbace3f..0000000
--- a/dubbo-spi-filter/dubbo-filter-validation/src/test/java/org/apache/dubbo/validation/support/jvalidation/JValidationTest.java
+++ /dev/null
@@ -1,50 +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.validation.support.jvalidation;
-
-import org.apache.dubbo.common.URL;
-import org.apache.dubbo.validation.Validation;
-import org.apache.dubbo.validation.Validator;
-
-import org.junit.jupiter.api.Assertions;
-import org.junit.jupiter.api.Test;
-
-import javax.validation.ValidationException;
-
-import static org.hamcrest.MatcherAssert.assertThat;
-import static org.hamcrest.core.Is.is;
-
-public class JValidationTest {
-    @Test
-    public void testReturnTypeWithInvalidValidationProvider() {
-        Assertions.assertThrows(ValidationException.class, () -> {
-            Validation jValidation = new JValidation();
-            URL url = URL.valueOf("test://test:11/org.apache.dubbo.validation.support.jvalidation.JValidation?" +
-                    "jvalidation=org.apache.dubbo.validation.Validation");
-            jValidation.getValidator(url);
-        });
-
-    }
-
-    @Test
-    public void testReturnTypeWithDefaultValidatorProvider() {
-        Validation jValidation = new JValidation();
-        URL url = URL.valueOf("test://test:11/org.apache.dubbo.validation.support.jvalidation.JValidation");
-        Validator validator = jValidation.getValidator(url);
-        assertThat(validator instanceof JValidator, is(true));
-    }
-}
\ No newline at end of file
diff --git a/dubbo-spi-filter/dubbo-filter-validation/src/test/java/org/apache/dubbo/validation/support/jvalidation/JValidatorTest.java b/dubbo-spi-filter/dubbo-filter-validation/src/test/java/org/apache/dubbo/validation/support/jvalidation/JValidatorTest.java
deleted file mode 100644
index 94768d2..0000000
--- a/dubbo-spi-filter/dubbo-filter-validation/src/test/java/org/apache/dubbo/validation/support/jvalidation/JValidatorTest.java
+++ /dev/null
@@ -1,86 +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.validation.support.jvalidation;
-
-import org.apache.dubbo.common.URL;
-import org.apache.dubbo.validation.support.jvalidation.mock.ValidationParameter;
-
-import org.junit.jupiter.api.Assertions;
-import org.junit.jupiter.api.Test;
-
-import javax.validation.ConstraintViolationException;
-import java.util.Arrays;
-import java.util.HashMap;
-import java.util.List;
-import java.util.Map;
-
-public class JValidatorTest {
-    @Test
-    public void testItWithNonExistMethod() throws Exception {
-        Assertions.assertThrows(NoSuchMethodException.class, () -> {
-            URL url = URL.valueOf("test://test:11/org.apache.dubbo.validation.support.jvalidation.mock.JValidatorTestTarget");
-            JValidator jValidator = new JValidator(url);
-            jValidator.validate("nonExistingMethod", new Class<?>[]{String.class}, new Object[]{"arg1"});
-        });
-    }
-
-    @Test
-    public void testItWithExistMethod() throws Exception {
-        URL url = URL.valueOf("test://test:11/org.apache.dubbo.validation.support.jvalidation.mock.JValidatorTestTarget");
-        JValidator jValidator = new JValidator(url);
-        jValidator.validate("someMethod1", new Class<?>[]{String.class}, new Object[]{"anything"});
-    }
-
-    @Test
-    public void testItWhenItViolatedConstraint() throws Exception {
-        Assertions.assertThrows(ConstraintViolationException.class, () -> {
-            URL url = URL.valueOf("test://test:11/org.apache.dubbo.validation.support.jvalidation.mock.JValidatorTestTarget");
-            JValidator jValidator = new JValidator(url);
-            jValidator.validate("someMethod2", new Class<?>[]{ValidationParameter.class}, new Object[]{new ValidationParameter()});
-        });
-    }
-
-    @Test
-    public void testItWhenItMeetsConstraint() throws Exception {
-        URL url = URL.valueOf("test://test:11/org.apache.dubbo.validation.support.jvalidation.mock.JValidatorTestTarget");
-        JValidator jValidator = new JValidator(url);
-        jValidator.validate("someMethod2", new Class<?>[]{ValidationParameter.class}, new Object[]{new ValidationParameter("NotBeNull")});
-    }
-
-    @Test
-    public void testItWithArrayArg() throws Exception {
-        URL url = URL.valueOf("test://test:11/org.apache.dubbo.validation.support.jvalidation.mock.JValidatorTestTarget");
-        JValidator jValidator = new JValidator(url);
-        jValidator.validate("someMethod3", new Class<?>[]{ValidationParameter[].class}, new Object[]{new ValidationParameter[]{new ValidationParameter("parameter")}});
-    }
-
-    @Test
-    public void testItWithCollectionArg() throws Exception {
-        URL url = URL.valueOf("test://test:11/org.apache.dubbo.validation.support.jvalidation.mock.JValidatorTestTarget");
-        JValidator jValidator = new JValidator(url);
-        jValidator.validate("someMethod4", new Class<?>[]{List.class}, new Object[]{Arrays.asList("parameter")});
-    }
-
-    @Test
-    public void testItWithMapArg() throws Exception {
-        URL url = URL.valueOf("test://test:11/org.apache.dubbo.validation.support.jvalidation.mock.JValidatorTestTarget");
-        JValidator jValidator = new JValidator(url);
-        Map<String, String> map = new HashMap<>();
-        map.put("key", "value");
-        jValidator.validate("someMethod5", new Class<?>[]{Map.class}, new Object[]{map});
-    }
-}
\ No newline at end of file
diff --git a/dubbo-spi-filter/dubbo-filter-validation/src/test/java/org/apache/dubbo/validation/support/jvalidation/mock/JValidatorTestTarget.java b/dubbo-spi-filter/dubbo-filter-validation/src/test/java/org/apache/dubbo/validation/support/jvalidation/mock/JValidatorTestTarget.java
deleted file mode 100644
index f65eb05..0000000
--- a/dubbo-spi-filter/dubbo-filter-validation/src/test/java/org/apache/dubbo/validation/support/jvalidation/mock/JValidatorTestTarget.java
+++ /dev/null
@@ -1,41 +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.validation.support.jvalidation.mock;
-
-import org.apache.dubbo.validation.MethodValidated;
-
-import javax.validation.constraints.NotNull;
-import java.util.List;
-import java.util.Map;
-
-public interface JValidatorTestTarget {
-    @MethodValidated
-    void someMethod1(String anything);
-
-    @MethodValidated(Test2.class)
-    void someMethod2(@NotNull ValidationParameter validationParameter);
-
-    void someMethod3(ValidationParameter[] parameters);
-
-    void someMethod4(List<String> strings);
-
-    void someMethod5(Map<String, String> map);
-
-    @interface Test2 {
-    }
-
-}
diff --git a/dubbo-spi-filter/dubbo-filter-validation/src/test/java/org/apache/dubbo/validation/support/jvalidation/mock/ValidationParameter.java b/dubbo-spi-filter/dubbo-filter-validation/src/test/java/org/apache/dubbo/validation/support/jvalidation/mock/ValidationParameter.java
deleted file mode 100644
index 0b54a04..0000000
--- a/dubbo-spi-filter/dubbo-filter-validation/src/test/java/org/apache/dubbo/validation/support/jvalidation/mock/ValidationParameter.java
+++ /dev/null
@@ -1,31 +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.validation.support.jvalidation.mock;
-
-import javax.validation.constraints.NotNull;
-
-public class ValidationParameter {
-    @NotNull
-    private String parameter;
-
-    public ValidationParameter() {
-    }
-
-    public ValidationParameter(String parameter) {
-        this.parameter = parameter;
-    }
-}
diff --git a/dubbo-spi-filter/pom.xml b/dubbo-spi-filter/pom.xml
deleted file mode 100644
index 248be53..0000000
--- a/dubbo-spi-filter/pom.xml
+++ /dev/null
@@ -1,35 +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.
-  -->
-<project xmlns="http://maven.apache.org/POM/4.0.0" xmlns:xsi="http://www.w3.org/2001/XMLSchema-instance" xsi:schemaLocation="http://maven.apache.org/POM/4.0.0 http://maven.apache.org/maven-v4_0_0.xsd">
-    <modelVersion>4.0.0</modelVersion>
-    <parent>
-        <groupId>org.apache.dubbo.spi</groupId>
-        <artifactId>dubbo-spi-extensions</artifactId>
-        <version>${revision}</version>
-    </parent>
-    <artifactId>dubbo-spi-filter</artifactId>
-    <packaging>pom</packaging>
-    <name>${project.artifactId}</name>
-    <description>The filter module of dubbo project</description>
-    <properties>
-        <skip_maven_deploy>true</skip_maven_deploy>
-    </properties>
-    <modules>
-        <module>dubbo-filter-cache</module>
-        <module>dubbo-filter-validation</module>
-    </modules>
-</project>
diff --git a/dubbo-spi-metadata/dubbo-metadata-report-nacos/pom.xml b/dubbo-spi-metadata/dubbo-metadata-report-nacos/pom.xml
deleted file mode 100644
index 7885a91..0000000
--- a/dubbo-spi-metadata/dubbo-metadata-report-nacos/pom.xml
+++ /dev/null
@@ -1,41 +0,0 @@
-<?xml version="1.0" encoding="UTF-8"?>
-<!--
-  ~ 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.
-  -->
-
-<project xmlns="http://maven.apache.org/POM/4.0.0" xmlns:xsi="http://www.w3.org/2001/XMLSchema-instance" xsi:schemaLocation="http://maven.apache.org/POM/4.0.0 http://maven.apache.org/xsd/maven-4.0.0.xsd">
-    <parent>
-        <groupId>org.apache.dubbo</groupId>
-        <artifactId>dubbo-metadata</artifactId>
-        <version>2.7.7-SNAPSHOT</version>
-    </parent>
-    <modelVersion>4.0.0</modelVersion>
-
-    <artifactId>dubbo-metadata-report-nacos</artifactId>
-
-    <dependencies>
-        <dependency>
-            <groupId>org.apache.dubbo</groupId>
-            <artifactId>dubbo-metadata-api</artifactId>
-            <version>${project.parent.version}</version>
-        </dependency>
-        <dependency>
-            <groupId>com.alibaba.nacos</groupId>
-            <artifactId>nacos-client</artifactId>
-        </dependency>
-    </dependencies>
-
-</project>
diff --git a/dubbo-spi-metadata/dubbo-metadata-report-nacos/src/main/java/org/apache/dubbo/metadata/store/nacos/NacosMetadataReport.java b/dubbo-spi-metadata/dubbo-metadata-report-nacos/src/main/java/org/apache/dubbo/metadata/store/nacos/NacosMetadataReport.java
deleted file mode 100644
index 707d2b8..0000000
--- a/dubbo-spi-metadata/dubbo-metadata-report-nacos/src/main/java/org/apache/dubbo/metadata/store/nacos/NacosMetadataReport.java
+++ /dev/null
@@ -1,234 +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.metadata.store.nacos;
-
-import org.apache.dubbo.common.URL;
-import org.apache.dubbo.common.logger.Logger;
-import org.apache.dubbo.common.logger.LoggerFactory;
-import org.apache.dubbo.common.utils.StringUtils;
-import org.apache.dubbo.metadata.report.identifier.BaseMetadataIdentifier;
-import org.apache.dubbo.metadata.report.identifier.KeyTypeEnum;
-import org.apache.dubbo.metadata.report.identifier.MetadataIdentifier;
-import org.apache.dubbo.metadata.report.identifier.ServiceMetadataIdentifier;
-import org.apache.dubbo.metadata.report.identifier.SubscriberMetadataIdentifier;
-import org.apache.dubbo.metadata.report.support.AbstractMetadataReport;
-import org.apache.dubbo.rpc.RpcException;
-
-import com.alibaba.nacos.api.NacosFactory;
-import com.alibaba.nacos.api.config.ConfigService;
-import com.alibaba.nacos.api.exception.NacosException;
-
-import java.util.ArrayList;
-import java.util.Arrays;
-import java.util.Collections;
-import java.util.List;
-import java.util.Properties;
-
-import static com.alibaba.nacos.api.PropertyKeyConst.ACCESS_KEY;
-import static com.alibaba.nacos.api.PropertyKeyConst.CLUSTER_NAME;
-import static com.alibaba.nacos.api.PropertyKeyConst.CONFIG_LONG_POLL_TIMEOUT;
-import static com.alibaba.nacos.api.PropertyKeyConst.CONFIG_RETRY_TIME;
-import static com.alibaba.nacos.api.PropertyKeyConst.CONTEXT_PATH;
-import static com.alibaba.nacos.api.PropertyKeyConst.ENABLE_REMOTE_SYNC_CONFIG;
-import static com.alibaba.nacos.api.PropertyKeyConst.ENCODE;
-import static com.alibaba.nacos.api.PropertyKeyConst.ENDPOINT;
-import static com.alibaba.nacos.api.PropertyKeyConst.ENDPOINT_PORT;
-import static com.alibaba.nacos.api.PropertyKeyConst.IS_USE_CLOUD_NAMESPACE_PARSING;
-import static com.alibaba.nacos.api.PropertyKeyConst.IS_USE_ENDPOINT_PARSING_RULE;
-import static com.alibaba.nacos.api.PropertyKeyConst.MAX_RETRY;
-import static com.alibaba.nacos.api.PropertyKeyConst.NAMESPACE;
-import static com.alibaba.nacos.api.PropertyKeyConst.NAMING_CLIENT_BEAT_THREAD_COUNT;
-import static com.alibaba.nacos.api.PropertyKeyConst.NAMING_LOAD_CACHE_AT_START;
-import static com.alibaba.nacos.api.PropertyKeyConst.NAMING_POLLING_THREAD_COUNT;
-import static com.alibaba.nacos.api.PropertyKeyConst.RAM_ROLE_NAME;
-import static com.alibaba.nacos.api.PropertyKeyConst.SECRET_KEY;
-import static com.alibaba.nacos.api.PropertyKeyConst.SERVER_ADDR;
-import static com.alibaba.nacos.client.naming.utils.UtilAndComs.NACOS_NAMING_LOG_NAME;
-import static org.apache.dubbo.common.constants.CommonConstants.GROUP_KEY;
-import static org.apache.dubbo.common.constants.RemotingConstants.BACKUP_KEY;
-
-/**
- * metadata report impl for nacos
- */
-public class NacosMetadataReport extends AbstractMetadataReport {
-
-    private static final Logger logger = LoggerFactory.getLogger(NacosMetadataReport.class);
-
-    private ConfigService configService;
-
-    /**
-     * The group used to store metadata in Nacos
-     */
-    private String group;
-
-
-    public NacosMetadataReport(URL url) {
-        super(url);
-        this.configService = buildConfigService(url);
-        group = url.getParameter(GROUP_KEY, DEFAULT_ROOT);
-    }
-
-    public ConfigService buildConfigService(URL url) {
-        Properties nacosProperties = buildNacosProperties(url);
-        try {
-            configService = NacosFactory.createConfigService(nacosProperties);
-        } catch (NacosException e) {
-            if (logger.isErrorEnabled()) {
-                logger.error(e.getErrMsg(), e);
-            }
-            throw new IllegalStateException(e);
-        }
-        return configService;
-    }
-
-    private Properties buildNacosProperties(URL url) {
-        Properties properties = new Properties();
-        setServerAddr(url, properties);
-        setProperties(url, properties);
-        return properties;
-    }
-
-    private void setServerAddr(URL url, Properties properties) {
-        StringBuilder serverAddrBuilder =
-                new StringBuilder(url.getHost()) // Host
-                        .append(":")
-                        .append(url.getPort()); // Port
-        // Append backup parameter as other servers
-        String backup = url.getParameter(BACKUP_KEY);
-        if (backup != null) {
-            serverAddrBuilder.append(",").append(backup);
-        }
-        String serverAddr = serverAddrBuilder.toString();
-        properties.put(SERVER_ADDR, serverAddr);
-    }
-
-    private static void setProperties(URL url, Properties properties) {
-        putPropertyIfAbsent(url, properties, NACOS_NAMING_LOG_NAME);
-        putPropertyIfAbsent(url, properties, IS_USE_CLOUD_NAMESPACE_PARSING);
-        putPropertyIfAbsent(url, properties, IS_USE_ENDPOINT_PARSING_RULE);
-        putPropertyIfAbsent(url, properties, ENDPOINT);
-        putPropertyIfAbsent(url, properties, ENDPOINT_PORT);
-        putPropertyIfAbsent(url, properties, NAMESPACE);
-        putPropertyIfAbsent(url, properties, ACCESS_KEY);
-        putPropertyIfAbsent(url, properties, SECRET_KEY);
-        putPropertyIfAbsent(url, properties, RAM_ROLE_NAME);
-        putPropertyIfAbsent(url, properties, CONTEXT_PATH);
-        putPropertyIfAbsent(url, properties, CLUSTER_NAME);
-        putPropertyIfAbsent(url, properties, ENCODE);
-        putPropertyIfAbsent(url, properties, CONFIG_LONG_POLL_TIMEOUT);
-        putPropertyIfAbsent(url, properties, CONFIG_RETRY_TIME);
-        putPropertyIfAbsent(url, properties, MAX_RETRY);
-        putPropertyIfAbsent(url, properties, ENABLE_REMOTE_SYNC_CONFIG);
-        putPropertyIfAbsent(url, properties, NAMING_LOAD_CACHE_AT_START, "true");
-        putPropertyIfAbsent(url, properties, NAMING_CLIENT_BEAT_THREAD_COUNT);
-        putPropertyIfAbsent(url, properties, NAMING_POLLING_THREAD_COUNT);
-    }
-
-    private static void putPropertyIfAbsent(URL url, Properties properties, String propertyName) {
-        String propertyValue = url.getParameter(propertyName);
-        if (StringUtils.isNotEmpty(propertyValue)) {
-            properties.setProperty(propertyName, propertyValue);
-        }
-    }
-
-    private static void putPropertyIfAbsent(URL url, Properties properties, String propertyName, String defaultValue) {
-        String propertyValue = url.getParameter(propertyName);
-        if (StringUtils.isNotEmpty(propertyValue)) {
-            properties.setProperty(propertyName, propertyValue);
-        } else {
-            properties.setProperty(propertyName, defaultValue);
-        }
-    }
-
-    @Override
-    protected void doStoreProviderMetadata(MetadataIdentifier providerMetadataIdentifier, String serviceDefinitions) {
-        this.storeMetadata(providerMetadataIdentifier, serviceDefinitions);
-    }
-
-    @Override
-    protected void doStoreConsumerMetadata(MetadataIdentifier consumerMetadataIdentifier, String value) {
-        this.storeMetadata(consumerMetadataIdentifier, value);
-    }
-
-    @Override
-    protected void doSaveMetadata(ServiceMetadataIdentifier serviceMetadataIdentifier, URL url) {
-        storeMetadata(serviceMetadataIdentifier, URL.encode(url.toFullString()));
-    }
-
-    @Override
-    protected void doRemoveMetadata(ServiceMetadataIdentifier serviceMetadataIdentifier) {
-        deleteMetadata(serviceMetadataIdentifier);
-    }
-
-    @Override
-    protected List<String> doGetExportedURLs(ServiceMetadataIdentifier metadataIdentifier) {
-        String content = getConfig(metadataIdentifier);
-        if (StringUtils.isEmpty(content)) {
-            return Collections.emptyList();
-        }
-        return new ArrayList<String>(Arrays.asList(URL.decode(content)));
-    }
-
-    @Override
-    protected void doSaveSubscriberData(SubscriberMetadataIdentifier subscriberMetadataIdentifier, String urlListStr) {
-        storeMetadata(subscriberMetadataIdentifier, urlListStr);
-    }
-
-    @Override
-    protected String doGetSubscribedURLs(SubscriberMetadataIdentifier subscriberMetadataIdentifier) {
-        return getConfig(subscriberMetadataIdentifier);
-    }
-
-    @Override
-    public String getServiceDefinition(MetadataIdentifier metadataIdentifier) {
-        return getConfig(metadataIdentifier);
-    }
-
-    private void storeMetadata(BaseMetadataIdentifier identifier, String value) {
-        try {
-            boolean publishResult = configService.publishConfig(identifier.getUniqueKey(KeyTypeEnum.UNIQUE_KEY), group, value);
-            if (!publishResult) {
-                throw new RuntimeException("publish nacos metadata failed");
-            }
-        } catch (Throwable t) {
-            logger.error("Failed to put " + identifier + " to nacos " + value + ", cause: " + t.getMessage(), t);
-            throw new RpcException("Failed to put " + identifier + " to nacos " + value + ", cause: " + t.getMessage(), t);
-        }
-    }
-
-    private void deleteMetadata(BaseMetadataIdentifier identifier) {
-        try {
-            boolean publishResult = configService.removeConfig(identifier.getUniqueKey(KeyTypeEnum.UNIQUE_KEY), group);
-            if (!publishResult) {
-                throw new RuntimeException("remove nacos metadata failed");
-            }
-        } catch (Throwable t) {
-            logger.error("Failed to remove " + identifier + " from nacos , cause: " + t.getMessage(), t);
-            throw new RpcException("Failed to remove " + identifier + " from nacos , cause: " + t.getMessage(), t);
-        }
-    }
-
-    private String getConfig(BaseMetadataIdentifier identifier) {
-        try {
-            return configService.getConfig(identifier.getUniqueKey(KeyTypeEnum.UNIQUE_KEY), group, 300);
-        } catch (Throwable t) {
-            logger.error("Failed to get " + identifier + " from nacos , cause: " + t.getMessage(), t);
-            throw new RpcException("Failed to get " + identifier + " from nacos , cause: " + t.getMessage(), t);
-        }
-    }
-}
diff --git a/dubbo-spi-metadata/dubbo-metadata-report-nacos/src/main/java/org/apache/dubbo/metadata/store/nacos/NacosMetadataReportFactory.java b/dubbo-spi-metadata/dubbo-metadata-report-nacos/src/main/java/org/apache/dubbo/metadata/store/nacos/NacosMetadataReportFactory.java
deleted file mode 100644
index 2cff74c..0000000
--- a/dubbo-spi-metadata/dubbo-metadata-report-nacos/src/main/java/org/apache/dubbo/metadata/store/nacos/NacosMetadataReportFactory.java
+++ /dev/null
@@ -1,32 +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.metadata.store.nacos;
-
-import org.apache.dubbo.common.URL;
-import org.apache.dubbo.metadata.report.MetadataReport;
-import org.apache.dubbo.metadata.report.support.AbstractMetadataReportFactory;
-
-/**
- * metadata report factory impl for nacos
- */
-public class NacosMetadataReportFactory extends AbstractMetadataReportFactory {
-    @Override
-    protected MetadataReport createMetadataReport(URL url) {
-        return new NacosMetadataReport(url);
-    }
-}
diff --git a/dubbo-spi-metadata/dubbo-metadata-report-nacos/src/main/resources/META-INF/dubbo/internal/org.apache.dubbo.metadata.report.MetadataReportFactory b/dubbo-spi-metadata/dubbo-metadata-report-nacos/src/main/resources/META-INF/dubbo/internal/org.apache.dubbo.metadata.report.MetadataReportFactory
deleted file mode 100644
index de3b50a..0000000
--- a/dubbo-spi-metadata/dubbo-metadata-report-nacos/src/main/resources/META-INF/dubbo/internal/org.apache.dubbo.metadata.report.MetadataReportFactory
+++ /dev/null
@@ -1 +0,0 @@
-nacos=org.apache.dubbo.metadata.store.nacos.NacosMetadataReportFactory
diff --git a/dubbo-spi-metadata/dubbo-metadata-report-nacos/src/test/java/org/apache/dubbo/metadata/store/nacos/NacosMetadata4TstService.java b/dubbo-spi-metadata/dubbo-metadata-report-nacos/src/test/java/org/apache/dubbo/metadata/store/nacos/NacosMetadata4TstService.java
deleted file mode 100644
index e84efc5..0000000
--- a/dubbo-spi-metadata/dubbo-metadata-report-nacos/src/test/java/org/apache/dubbo/metadata/store/nacos/NacosMetadata4TstService.java
+++ /dev/null
@@ -1,28 +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.metadata.store.nacos;
-
-/**
- * Test interface for Nacos metadata report
- */
-public interface NacosMetadata4TstService {
-
-    int getCounter();
-
-    void printResult(String var);
-}
diff --git a/dubbo-spi-metadata/dubbo-metadata-report-nacos/src/test/java/org/apache/dubbo/metadata/store/nacos/NacosMetadataReportTest.java b/dubbo-spi-metadata/dubbo-metadata-report-nacos/src/test/java/org/apache/dubbo/metadata/store/nacos/NacosMetadataReportTest.java
deleted file mode 100644
index 88fc75a..0000000
--- a/dubbo-spi-metadata/dubbo-metadata-report-nacos/src/test/java/org/apache/dubbo/metadata/store/nacos/NacosMetadataReportTest.java
+++ /dev/null
@@ -1,247 +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.metadata.store.nacos;
-
-import com.alibaba.nacos.api.exception.NacosException;
-import org.apache.dubbo.common.URL;
-import org.apache.dubbo.common.utils.NetUtils;
-import org.apache.dubbo.metadata.definition.ServiceDefinitionBuilder;
-import org.apache.dubbo.metadata.definition.model.FullServiceDefinition;
-import org.apache.dubbo.metadata.report.identifier.KeyTypeEnum;
-import org.apache.dubbo.metadata.report.identifier.MetadataIdentifier;
-
-import com.alibaba.nacos.api.config.ConfigService;
-import com.google.gson.Gson;
-import org.apache.dubbo.metadata.report.identifier.ServiceMetadataIdentifier;
-import org.apache.dubbo.metadata.report.identifier.SubscriberMetadataIdentifier;
-import org.junit.jupiter.api.AfterEach;
-import org.junit.jupiter.api.Assertions;
-import org.junit.jupiter.api.BeforeEach;
-import org.junit.jupiter.api.Disabled;
-import org.junit.jupiter.api.Test;
-
-import java.util.Arrays;
-import java.util.HashMap;
-import java.util.List;
-import java.util.Map;
-
-import static org.apache.dubbo.common.constants.CommonConstants.CONSUMER_SIDE;
-import static org.apache.dubbo.common.constants.CommonConstants.PROVIDER_SIDE;
-
-//FIXME: waiting for embedded Nacos suport, then we can open the switch.
-@Disabled("https://github.com/alibaba/nacos/issues/1188")
-public class NacosMetadataReportTest {
-
-    private static final String SESSION_TIMEOUT_KEY = "session";
-
-    private static final String TEST_SERVICE = "org.apache.dubbo.metadata.store.nacos.NacosMetadata4TstService";
-
-    private NacosMetadataReport nacosMetadataReport;
-
-    private NacosMetadataReportFactory nacosMetadataReportFactory;
-
-    private ConfigService configService;
-
-    private static final String NACOS_GROUP = "metadata_test";
-
-    /**
-     * timeout(ms) for nacos session
-     */
-    private static final int SESSION_TIMEOUT = 15 * 1000;
-
-    /**
-     * timeout(ms) for query operation on nacos
-     */
-    private static final int NACOS_READ_TIMEOUT = 5 * 1000;
-
-    /**
-     * interval(ms) to make nacos cache refresh
-     */
-    private static final int INTERVAL_TO_MAKE_NACOS_REFRESH = 1000;
-
-    /**
-     * version for test
-     */
-    private static final String VERSION = "1.0.0";
-
-    /**
-     * group for test
-     */
-    private static final String METADATA_GROUP = null;
-
-    /**
-     * application name for test
-     */
-    private static final String APPLICATION_NAME = "nacos-metdata-report-test";
-
-    /**
-     * revision for test
-     */
-    private static final String REVISION = "90980";
-
-    /**
-     * protocol for test
-     */
-    private static final String PROTOCOL = "xxx";
-
-    @BeforeEach
-    public void setUp() {
-        URL url = URL.valueOf("nacos://127.0.0.1:8848?group=" + NACOS_GROUP)
-                .addParameter(SESSION_TIMEOUT_KEY, SESSION_TIMEOUT);
-        nacosMetadataReportFactory = new NacosMetadataReportFactory();
-        this.nacosMetadataReport = (NacosMetadataReport) nacosMetadataReportFactory.createMetadataReport(url);
-        this.configService = nacosMetadataReport.buildConfigService(url);
-    }
-
-    @AfterEach
-    public void tearDown() throws Exception {
-    }
-
-
-    @Test
-    public void testStoreProvider() throws Exception {
-        MetadataIdentifier providerIdentifier =
-                storeProvider(nacosMetadataReport, TEST_SERVICE, VERSION, METADATA_GROUP, APPLICATION_NAME);
-        String serverContent = configService.getConfig(providerIdentifier.getUniqueKey(KeyTypeEnum.UNIQUE_KEY), NACOS_GROUP, NACOS_READ_TIMEOUT);
-        Assertions.assertNotNull(serverContent);
-
-        Gson gson = new Gson();
-        FullServiceDefinition fullServiceDefinition = gson.fromJson(serverContent, FullServiceDefinition.class);
-        Assertions.assertEquals(fullServiceDefinition.getParameters().get("paramTest"), "nacosTest");
-
-        //Clear test data
-        configService.removeConfig(providerIdentifier.getUniqueKey(KeyTypeEnum.UNIQUE_KEY), NACOS_GROUP);
-    }
-
-    @Test
-    public void testStoreConsumer() throws Exception {
-        MetadataIdentifier consumerIdentifier = storeConsumer(nacosMetadataReport, TEST_SERVICE, VERSION, METADATA_GROUP, APPLICATION_NAME);
-
-        String serverContent = configService.getConfig(consumerIdentifier.getUniqueKey(KeyTypeEnum.UNIQUE_KEY), NACOS_GROUP, NACOS_READ_TIMEOUT);
-        Assertions.assertNotNull(serverContent);
-        Assertions.assertEquals(serverContent, "{\"paramConsumerTest\":\"nacosConsumer\"}");
-
-        //clear test data
-        configService.removeConfig(consumerIdentifier.getUniqueKey(KeyTypeEnum.UNIQUE_KEY), NACOS_GROUP);
-    }
-
-    @Test
-    public void testDoSaveServiceMetadata() throws Exception {
-        URL url = URL.valueOf("xxx://" + NetUtils.getLocalAddress().getHostName() + ":4444/" + TEST_SERVICE +
-                "?paramTest=nacosTest&version=" + VERSION + "&application="
-                + APPLICATION_NAME + (METADATA_GROUP == null ? "" : "&group=" + METADATA_GROUP));
-        ServiceMetadataIdentifier serviceMetadataIdentifier = new ServiceMetadataIdentifier(TEST_SERVICE, VERSION,
-                METADATA_GROUP, "provider", REVISION, PROTOCOL);
-        nacosMetadataReport.doSaveMetadata(serviceMetadataIdentifier, url);
-        Thread.sleep(INTERVAL_TO_MAKE_NACOS_REFRESH);
-        String serviceMetaData = configService.getConfig(serviceMetadataIdentifier.getUniqueKey(KeyTypeEnum.UNIQUE_KEY), NACOS_GROUP, NACOS_READ_TIMEOUT);
-        Assertions.assertNotNull(serviceMetaData);
-        Assertions.assertEquals(serviceMetaData, URL.encode(url.toFullString()));
-
-        //clear test data
-        configService.removeConfig(serviceMetadataIdentifier.getUniqueKey(KeyTypeEnum.UNIQUE_KEY), NACOS_GROUP);
-    }
-
-    @Test
-    public void testDoRemoveServiceMetadata() throws Exception {
-        URL url = URL.valueOf("xxx://" + NetUtils.getLocalAddress().getHostName() + ":4444/" + TEST_SERVICE +
-                "?paramTest=nacosTest&version=" + VERSION + "&application="
-                + APPLICATION_NAME + (METADATA_GROUP == null ? "" : "&group=" + METADATA_GROUP));
-        ServiceMetadataIdentifier serviceMetadataIdentifier = new ServiceMetadataIdentifier(TEST_SERVICE, VERSION,
-                METADATA_GROUP, "provider", REVISION, PROTOCOL);
-        nacosMetadataReport.doSaveMetadata(serviceMetadataIdentifier, url);
-        Thread.sleep(INTERVAL_TO_MAKE_NACOS_REFRESH);
-        String serviceMetaData = configService.getConfig(serviceMetadataIdentifier.getUniqueKey(KeyTypeEnum.UNIQUE_KEY), NACOS_GROUP, NACOS_READ_TIMEOUT);
-        Assertions.assertNotNull(serviceMetaData);
-
-        nacosMetadataReport.doRemoveMetadata(serviceMetadataIdentifier);
-        Thread.sleep(INTERVAL_TO_MAKE_NACOS_REFRESH);
-        serviceMetaData = configService.getConfig(serviceMetadataIdentifier.getUniqueKey(KeyTypeEnum.UNIQUE_KEY), NACOS_GROUP, NACOS_READ_TIMEOUT);
-        Assertions.assertNull(serviceMetaData);
-    }
-
-    @Test
-    public void testDoGetExportedURLs() throws InterruptedException, NacosException {
-        URL url = URL.valueOf("xxx://" + NetUtils.getLocalAddress().getHostName() + ":4444/" + TEST_SERVICE +
-                "?paramTest=nacosTest&version=" + VERSION + "&application="
-                + APPLICATION_NAME + (METADATA_GROUP == null ? "" : "&group=" + METADATA_GROUP));
-        ServiceMetadataIdentifier serviceMetadataIdentifier = new ServiceMetadataIdentifier(TEST_SERVICE, VERSION,
-                METADATA_GROUP, "provider", REVISION, PROTOCOL);
-
-        nacosMetadataReport.doSaveMetadata(serviceMetadataIdentifier, url);
-        Thread.sleep(INTERVAL_TO_MAKE_NACOS_REFRESH);
-
-        List<String> exportedURLs = nacosMetadataReport.doGetExportedURLs(serviceMetadataIdentifier);
-        Assertions.assertTrue(exportedURLs.size() == 1);
-
-        String exportedUrl = exportedURLs.get(0);
-        Assertions.assertNotNull(exportedUrl);
-        Assertions.assertEquals(exportedUrl, url.toFullString());
-
-        //clear test data
-        configService.removeConfig(serviceMetadataIdentifier.getUniqueKey(KeyTypeEnum.UNIQUE_KEY), NACOS_GROUP);
-    }
-
-    @Test
-    public void testDoSaveSubscriberData() throws InterruptedException, NacosException {
-        URL url = URL.valueOf("xxx://" + NetUtils.getLocalAddress().getHostName() + ":4444/" + TEST_SERVICE +
-                "?paramTest=nacosTest&version=" + VERSION + "&application="
-                + APPLICATION_NAME + (METADATA_GROUP == null ? "" : "&group=" + METADATA_GROUP));
-        SubscriberMetadataIdentifier subscriberMetadataIdentifier = new SubscriberMetadataIdentifier(APPLICATION_NAME, REVISION);
-        Gson gson = new Gson();
-        String urlListJsonString = gson.toJson(Arrays.asList(url));
-        nacosMetadataReport.doSaveSubscriberData(subscriberMetadataIdentifier, urlListJsonString);
-        Thread.sleep(INTERVAL_TO_MAKE_NACOS_REFRESH);
-
-        String subscriberMetadata = configService.getConfig(subscriberMetadataIdentifier.getUniqueKey(KeyTypeEnum.UNIQUE_KEY), NACOS_GROUP, NACOS_READ_TIMEOUT);
-        Assertions.assertNotNull(subscriberMetadata);
-        Assertions.assertEquals(subscriberMetadata, urlListJsonString);
-
-        //clear test data
-        configService.removeConfig(subscriberMetadataIdentifier.getUniqueKey(KeyTypeEnum.UNIQUE_KEY), NACOS_GROUP);
-
-    }
-
-    private MetadataIdentifier storeProvider(NacosMetadataReport nacosMetadataReport, String interfaceName, String version,
-                                             String group, String application)
-            throws ClassNotFoundException, InterruptedException {
-        URL url = URL.valueOf("xxx://" + NetUtils.getLocalAddress().getHostName() + ":4444/" + interfaceName +
-                "?paramTest=nacosTest&version=" + version + "&application="
-                + application + (group == null ? "" : "&group=" + group));
-
-        MetadataIdentifier providerMetadataIdentifier =
-                new MetadataIdentifier(interfaceName, version, group, PROVIDER_SIDE, application);
-        Class interfaceClass = Class.forName(interfaceName);
-        FullServiceDefinition fullServiceDefinition =
-                ServiceDefinitionBuilder.buildFullDefinition(interfaceClass, url.getParameters());
-
-        nacosMetadataReport.storeProviderMetadata(providerMetadataIdentifier, fullServiceDefinition);
-        Thread.sleep(INTERVAL_TO_MAKE_NACOS_REFRESH);
-        return providerMetadataIdentifier;
-    }
-
-    private MetadataIdentifier storeConsumer(NacosMetadataReport nacosMetadataReport, String interfaceName,
-                                             String version, String group, String application) throws InterruptedException {
-        MetadataIdentifier consumerIdentifier = new MetadataIdentifier(interfaceName, version, group, CONSUMER_SIDE, application);
-        Map<String, String> tmp = new HashMap<>();
-        tmp.put("paramConsumerTest", "nacosConsumer");
-        nacosMetadataReport.storeConsumerMetadata(consumerIdentifier, tmp);
-        Thread.sleep(INTERVAL_TO_MAKE_NACOS_REFRESH);
-        return consumerIdentifier;
-    }
-
-}
diff --git a/dubbo-spi-metadata/pom.xml b/dubbo-spi-metadata/pom.xml
index 72fef74..d35ed4b 100644
--- a/dubbo-spi-metadata/pom.xml
+++ b/dubbo-spi-metadata/pom.xml
@@ -34,7 +34,6 @@
     <modules>
         <module>dubbo-metadata-report-consul</module>
         <module>dubbo-metadata-report-etcd</module>
-        <module>dubbo-metadata-report-nacos</module>
     </modules>
 
 </project>
diff --git a/dubbo-spi-rpc/dubbo-rpc-grpc/pom.xml b/dubbo-spi-rpc/dubbo-rpc-grpc/pom.xml
deleted file mode 100644
index 8042750..0000000
--- a/dubbo-spi-rpc/dubbo-rpc-grpc/pom.xml
+++ /dev/null
@@ -1,68 +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.
-  -->
-<project xmlns="http://maven.apache.org/POM/4.0.0" xmlns:xsi="http://www.w3.org/2001/XMLSchema-instance" xsi:schemaLocation="http://maven.apache.org/POM/4.0.0 http://maven.apache.org/maven-v4_0_0.xsd">
-    <modelVersion>4.0.0</modelVersion>
-    <parent>
-        <groupId>org.apache.dubbo</groupId>
-        <artifactId>dubbo-rpc</artifactId>
-        <version>2.7.7-SNAPSHOT</version>
-    </parent>
-    <artifactId>dubbo-rpc-grpc</artifactId>
-    <packaging>jar</packaging>
-    <name>${project.artifactId}</name>
-    <description>The gRPC integration module</description>
-    <properties>
-        <skip_maven_deploy>false</skip_maven_deploy>
-    </properties>
-    <dependencies>
-        <dependency>
-            <groupId>org.apache.dubbo</groupId>
-            <artifactId>dubbo-rpc-api</artifactId>
-            <version>${project.parent.version}</version>
-        </dependency>
-        <dependency>
-            <groupId>org.apache.dubbo</groupId>
-            <artifactId>dubbo-remoting-http</artifactId>
-            <version>${project.parent.version}</version>
-        </dependency>
-        <dependency>
-            <groupId>io.grpc</groupId>
-            <artifactId>grpc-netty</artifactId>
-        </dependency>
-        <!--        <dependency>-->
-        <!--            <groupId>io.grpc</groupId>-->
-        <!--            <artifactId>grpc-netty-shaded</artifactId>-->
-        <!--        </dependency>-->
-        <dependency>
-            <groupId>io.grpc</groupId>
-            <artifactId>grpc-protobuf</artifactId>
-        </dependency>
-        <dependency>
-            <groupId>io.grpc</groupId>
-            <artifactId>grpc-stub</artifactId>
-        </dependency>
-        <dependency>
-            <groupId>io.grpc</groupId>
-            <artifactId>grpc-core</artifactId>
-        </dependency>
-        <dependency>
-            <groupId>org.springframework</groupId>
-            <artifactId>spring-test</artifactId>
-            <scope>test</scope>
-        </dependency>
-    </dependencies>
-</project>
\ No newline at end of file
diff --git a/dubbo-spi-rpc/dubbo-rpc-grpc/src/main/java/org/apache/dubbo/rpc/protocol/grpc/DubboHandlerRegistry.java b/dubbo-spi-rpc/dubbo-rpc-grpc/src/main/java/org/apache/dubbo/rpc/protocol/grpc/DubboHandlerRegistry.java
deleted file mode 100644
index aa9a17b..0000000
--- a/dubbo-spi-rpc/dubbo-rpc-grpc/src/main/java/org/apache/dubbo/rpc/protocol/grpc/DubboHandlerRegistry.java
+++ /dev/null
@@ -1,70 +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.rpc.protocol.grpc;
-
-import io.grpc.BindableService;
-import io.grpc.HandlerRegistry;
-import io.grpc.ServerMethodDefinition;
-import io.grpc.ServerServiceDefinition;
-
-import javax.annotation.Nullable;
-import java.util.ArrayList;
-import java.util.Collections;
-import java.util.List;
-import java.util.Map;
-import java.util.concurrent.ConcurrentHashMap;
-
-/**
- *
- */
-public class DubboHandlerRegistry extends HandlerRegistry {
-
-    private final Map<String, ServerServiceDefinition> services = new ConcurrentHashMap<>();
-    private final Map<String, ServerMethodDefinition<?, ?>> methods = new ConcurrentHashMap<>();
-
-    public DubboHandlerRegistry() {}
-
-    /**
-     * Returns the service definitions in this registry.
-     */
-    @Override
-    public List<ServerServiceDefinition> getServices() {
-        return Collections.unmodifiableList(new ArrayList<>(services.values()));
-    }
-
-    @Nullable
-    @Override
-    public ServerMethodDefinition<?, ?> lookupMethod(String methodName, @Nullable String authority) {
-        // TODO (carl-mastrangelo): honor authority header.
-        return methods.get(methodName);
-    }
-
-    void addService(BindableService bindableService, String key) {
-        ServerServiceDefinition service = bindableService.bindService();
-        services.put(key, service);
-        for (ServerMethodDefinition<?, ?> method : service.getMethods()) {
-            methods.put(method.getMethodDescriptor().getFullMethodName(), method);
-        }
-    }
-
-    void removeService(String serviceKey) {
-        ServerServiceDefinition service = services.remove(serviceKey);
-        for (ServerMethodDefinition<?, ?> method : service.getMethods()) {
-            methods.remove(method.getMethodDescriptor().getFullMethodName(), method);
-        }
-    }
-}
diff --git a/dubbo-spi-rpc/dubbo-rpc-grpc/src/main/java/org/apache/dubbo/rpc/protocol/grpc/GrpcConfig.java b/dubbo-spi-rpc/dubbo-rpc-grpc/src/main/java/org/apache/dubbo/rpc/protocol/grpc/GrpcConfig.java
deleted file mode 100644
index 08b2f6a..0000000
--- a/dubbo-spi-rpc/dubbo-rpc-grpc/src/main/java/org/apache/dubbo/rpc/protocol/grpc/GrpcConfig.java
+++ /dev/null
@@ -1,21 +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.rpc.protocol.grpc;
-
-public class GrpcConfig {
-
-}
diff --git a/dubbo-spi-rpc/dubbo-rpc-grpc/src/main/java/org/apache/dubbo/rpc/protocol/grpc/GrpcConstants.java b/dubbo-spi-rpc/dubbo-rpc-grpc/src/main/java/org/apache/dubbo/rpc/protocol/grpc/GrpcConstants.java
deleted file mode 100644
index 9982751..0000000
--- a/dubbo-spi-rpc/dubbo-rpc-grpc/src/main/java/org/apache/dubbo/rpc/protocol/grpc/GrpcConstants.java
+++ /dev/null
@@ -1,41 +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.rpc.protocol.grpc;
-
-
-public class GrpcConstants {
-
-    public static final String DIERCTOR_KEY = "grpc.director";
-    public static final String HANDSHAKE_TIMEOUT = "grpc.handshakeTimeout";
-    public static final String MAX_INBOUND_MESSAGE_SIZE = "grpc.maxInboundMessageSize";
-    public static final String MAX_INBOUND_METADATA_SIZE = "grpc.maxOutboundMessageSize";
-    public static final String FLOWCONTROL_WINDOW = "grpc.flowControlWindow";
-    public static final String MAX_CONCURRENT_CALLS_PER_CONNECTION = "grpc.maxConcurrentCallsPerConnection";
-
-    public static final String WORKER_THREAD_NUM = "grpc.io.num";
-    public static final String BOSS_THREAD_NUM = "grpc.boss.num";
-    public static final String CHANNEL_TYPE = "grpc.channel.type";
-
-    public static final String SERVER_INTERCEPTORS = "grpc.serverInterceptors";
-    public static final String CLIENT_INTERCEPTORS = "grpc.clientInterceptors";
-    public static final String TRANSPORT_FILTERS = "grpc.transportFilters";
-
-    public static final String EXECUTOR = "grpc.executor";
-
-    public static final String CONFIGURATOR = "grpc.configurator";
-
-}
diff --git a/dubbo-spi-rpc/dubbo-rpc-grpc/src/main/java/org/apache/dubbo/rpc/protocol/grpc/GrpcInvoker.java b/dubbo-spi-rpc/dubbo-rpc-grpc/src/main/java/org/apache/dubbo/rpc/protocol/grpc/GrpcInvoker.java
deleted file mode 100644
index 4ca6fb7..0000000
--- a/dubbo-spi-rpc/dubbo-rpc-grpc/src/main/java/org/apache/dubbo/rpc/protocol/grpc/GrpcInvoker.java
+++ /dev/null
@@ -1,118 +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.rpc.protocol.grpc;
-
-import org.apache.dubbo.common.URL;
-import org.apache.dubbo.rpc.Invocation;
-import org.apache.dubbo.rpc.Invoker;
-import org.apache.dubbo.rpc.Result;
-import org.apache.dubbo.rpc.RpcException;
-import org.apache.dubbo.rpc.protocol.AbstractInvoker;
-
-import io.grpc.Status;
-import io.grpc.StatusException;
-
-import java.util.concurrent.locks.ReentrantLock;
-
-public class GrpcInvoker<T> extends AbstractInvoker<T> {
-    private final ReentrantLock destroyLock = new ReentrantLock();
-
-    private final Invoker<T> target;
-    private ReferenceCountManagedChannel channel;
-
-//    private static List<Exception> grpcExceptions = new ArrayList<>();
-//    static {
-//        grpcExceptions.add();
-//    }
-
-    public GrpcInvoker(Class<T> type, URL url, Invoker<T> target, ReferenceCountManagedChannel channel) {
-        super(type, url);
-        this.target = target;
-        this.channel = channel;
-    }
-
-    @Override
-    protected Result doInvoke(Invocation invocation) throws Throwable {
-        try {
-            Result result = target.invoke(invocation);
-            // FIXME result is an AsyncRpcResult instance.
-            Throwable e = result.getException();
-            if (e != null) {
-                throw getRpcException(getInterface(), getUrl(), invocation, e);
-            }
-            return result;
-        } catch (RpcException e) {
-            if (e.getCode() == RpcException.UNKNOWN_EXCEPTION) {
-                e.setCode(getErrorCode(e.getCause()));
-            }
-            throw e;
-        } catch (Throwable e) {
-            throw getRpcException(getInterface(), getUrl(), invocation, e);
-        }
-    }
-
-    @Override
-    public boolean isAvailable() {
-        return super.isAvailable() && !channel.isShutdown() && !channel.isTerminated();
-    }
-
-    @Override
-    public boolean isDestroyed() {
-        return super.isDestroyed() || channel.isShutdown() || channel.isTerminated();
-    }
-
-    @Override
-    public void destroy() {
-        if (!super.isDestroyed()) {
-            // double check to avoid dup close
-            destroyLock.lock();
-            try {
-                if (super.isDestroyed()) {
-                    return;
-                }
-                super.destroy();
-                channel.shutdown();
-            } finally {
-                destroyLock.unlock();
-            }
-        }
-    }
-
-    private RpcException getRpcException(Class<?> type, URL url, Invocation invocation, Throwable e) {
-        RpcException re = new RpcException("Failed to invoke remote service: " + type + ", method: "
-                + invocation.getMethodName() + ", cause: " + e.getMessage(), e);
-        re.setCode(getErrorCode(e));
-        return re;
-    }
-
-    /**
-     * FIXME, convert gRPC exceptions to equivalent Dubbo exceptions.
-     *
-     * @param e
-     * @return
-     */
-    private int getErrorCode(Throwable e) {
-        if (e instanceof StatusException) {
-            StatusException statusException = (StatusException) e;
-            Status status = statusException.getStatus();
-            if (status.getCode() == Status.Code.DEADLINE_EXCEEDED) {
-                return RpcException.TIMEOUT_EXCEPTION;
-            }
-        }
-        return RpcException.UNKNOWN_EXCEPTION;
-    }
-}
diff --git a/dubbo-spi-rpc/dubbo-rpc-grpc/src/main/java/org/apache/dubbo/rpc/protocol/grpc/GrpcOptionsUtils.java b/dubbo-spi-rpc/dubbo-rpc-grpc/src/main/java/org/apache/dubbo/rpc/protocol/grpc/GrpcOptionsUtils.java
deleted file mode 100644
index d1b1cda..0000000
--- a/dubbo-spi-rpc/dubbo-rpc-grpc/src/main/java/org/apache/dubbo/rpc/protocol/grpc/GrpcOptionsUtils.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.rpc.protocol.grpc;
-
-import org.apache.dubbo.common.URL;
-import org.apache.dubbo.common.extension.ExtensionLoader;
-import org.apache.dubbo.common.threadpool.ThreadPool;
-import org.apache.dubbo.common.utils.CollectionUtils;
-import org.apache.dubbo.config.SslConfig;
-import org.apache.dubbo.config.context.ConfigManager;
-import org.apache.dubbo.rpc.model.ApplicationModel;
-import org.apache.dubbo.rpc.protocol.grpc.interceptors.ClientInterceptor;
-import org.apache.dubbo.rpc.protocol.grpc.interceptors.GrpcConfigurator;
-import org.apache.dubbo.rpc.protocol.grpc.interceptors.ServerInterceptor;
-import org.apache.dubbo.rpc.protocol.grpc.interceptors.ServerTransportFilter;
-
-import io.grpc.CallOptions;
-import io.grpc.ManagedChannel;
-import io.grpc.ServerBuilder;
-import io.grpc.netty.GrpcSslContexts;
-import io.grpc.netty.NettyChannelBuilder;
-import io.grpc.netty.NettyServerBuilder;
-import io.netty.handler.ssl.ClientAuth;
-import io.netty.handler.ssl.SslContext;
-import io.netty.handler.ssl.SslContextBuilder;
-
-import javax.net.ssl.SSLException;
-import java.io.InputStream;
-import java.util.ArrayList;
-import java.util.List;
-import java.util.Optional;
-import java.util.Set;
-
-import static org.apache.dubbo.common.constants.CommonConstants.CONSUMER_SIDE;
-import static org.apache.dubbo.common.constants.CommonConstants.PROVIDER_SIDE;
-import static org.apache.dubbo.common.constants.CommonConstants.SSL_ENABLED_KEY;
-import static org.apache.dubbo.remoting.Constants.DISPATCHER_KEY;
-import static org.apache.dubbo.rpc.Constants.EXECUTES_KEY;
-import static org.apache.dubbo.rpc.protocol.grpc.GrpcConstants.CLIENT_INTERCEPTORS;
-import static org.apache.dubbo.rpc.protocol.grpc.GrpcConstants.EXECUTOR;
-import static org.apache.dubbo.rpc.protocol.grpc.GrpcConstants.MAX_CONCURRENT_CALLS_PER_CONNECTION;
-import static org.apache.dubbo.rpc.protocol.grpc.GrpcConstants.MAX_INBOUND_MESSAGE_SIZE;
-import static org.apache.dubbo.rpc.protocol.grpc.GrpcConstants.MAX_INBOUND_METADATA_SIZE;
-import static org.apache.dubbo.rpc.protocol.grpc.GrpcConstants.SERVER_INTERCEPTORS;
-import static org.apache.dubbo.rpc.protocol.grpc.GrpcConstants.TRANSPORT_FILTERS;
-
-/**
- * Support gRPC configs in a Dubbo specific way.
- */
-public class GrpcOptionsUtils {
-
-    static ServerBuilder buildServerBuilder(URL url, NettyServerBuilder builder) {
-
-        int maxInboundMessageSize = url.getParameter(MAX_INBOUND_MESSAGE_SIZE, 0);
-        if (maxInboundMessageSize > 0) {
-            builder.maxInboundMessageSize(maxInboundMessageSize);
-        }
-
-        int maxInboundMetadataSize = url.getParameter(MAX_INBOUND_METADATA_SIZE, 0);
-        if (maxInboundMetadataSize > 0) {
-            builder.maxInboundMetadataSize(maxInboundMetadataSize);
-        }
-
-        if (url.getParameter(SSL_ENABLED_KEY, false)) {
-            builder.sslContext(buildServerSslContext(url));
-        }
-
-        int flowControlWindow = url.getParameter(MAX_INBOUND_MESSAGE_SIZE, 0);
-        if (flowControlWindow > 0) {
-            builder.flowControlWindow(flowControlWindow);
-        }
-
-        int maxCalls = url.getParameter(MAX_CONCURRENT_CALLS_PER_CONNECTION, url.getParameter(EXECUTES_KEY, 0));
-        if (maxCalls > 0) {
-            builder.maxConcurrentCallsPerConnection(maxCalls);
-        }
-
-        // server interceptors
-        List<ServerInterceptor> serverInterceptors = ExtensionLoader.getExtensionLoader(ServerInterceptor.class)
-                .getActivateExtension(url, SERVER_INTERCEPTORS, PROVIDER_SIDE);
-        for (ServerInterceptor serverInterceptor : serverInterceptors) {
-            builder.intercept(serverInterceptor);
-        }
-
-        // server filters
-        List<ServerTransportFilter> transportFilters = ExtensionLoader.getExtensionLoader(ServerTransportFilter.class)
-                .getActivateExtension(url, TRANSPORT_FILTERS, PROVIDER_SIDE);
-        for (ServerTransportFilter transportFilter : transportFilters) {
-            builder.addTransportFilter(transportFilter.grpcTransportFilter());
-        }
-
-        String thread = url.getParameter(EXECUTOR, url.getParameter(DISPATCHER_KEY));
-        if ("direct".equals(thread)) {
-            builder.directExecutor();
-        } else {
-            builder.executor(ExtensionLoader.getExtensionLoader(ThreadPool.class).getAdaptiveExtension().getExecutor(url));
-        }
-
-        // Give users the chance to customize ServerBuilder
-        return getConfigurator()
-                .map(configurator -> configurator.configureServerBuilder(builder, url))
-                .orElse(builder);
-    }
-
-    static ManagedChannel buildManagedChannel(URL url) {
-
-        NettyChannelBuilder builder = NettyChannelBuilder.forAddress(url.getHost(), url.getPort());
-        if (url.getParameter(SSL_ENABLED_KEY, false)) {
-            builder.sslContext(buildClientSslContext(url));
-        } else {
-            builder.usePlaintext();
-        }
-
-        builder.disableRetry();
-//        builder.directExecutor();
-
-        // client interceptors
-        List<io.grpc.ClientInterceptor> interceptors = new ArrayList<>(
-                ExtensionLoader.getExtensionLoader(ClientInterceptor.class)
-                        .getActivateExtension(url, CLIENT_INTERCEPTORS, CONSUMER_SIDE)
-        );
-
-        builder.intercept(interceptors);
-
-        return getConfigurator()
-                .map(configurator -> configurator.configureChannelBuilder(builder, url))
-                .orElse(builder)
-                .build();
-    }
-
-    static CallOptions buildCallOptions(URL url) {
-        // gRPC Deadline starts counting when it's created, so we need to create and add a new Deadline for each RPC call.
-//        CallOptions callOptions = CallOptions.DEFAULT
-//                .withDeadline(Deadline.after(url.getParameter(TIMEOUT_KEY, DEFAULT_TIMEOUT), TimeUnit.MILLISECONDS));
-        CallOptions callOptions = CallOptions.DEFAULT;
-        return getConfigurator()
-                .map(configurator -> configurator.configureCallOptions(callOptions, url))
-                .orElse(callOptions);
-    }
-
-    private static SslContext buildServerSslContext(URL url) {
-        ConfigManager globalConfigManager = ApplicationModel.getConfigManager();
-        SslConfig sslConfig = globalConfigManager.getSsl().orElseThrow(() -> new IllegalStateException("Ssl enabled, but no ssl cert information provided!"));
-
-        SslContextBuilder sslClientContextBuilder = null;
-        try {
-            String password = sslConfig.getServerKeyPassword();
-            if (password != null) {
-                sslClientContextBuilder = GrpcSslContexts.forServer(sslConfig.getServerKeyCertChainPathStream(),
-                        sslConfig.getServerPrivateKeyPathStream(), password);
-            } else {
-                sslClientContextBuilder = GrpcSslContexts.forServer(sslConfig.getServerKeyCertChainPathStream(),
-                        sslConfig.getServerPrivateKeyPathStream());
-            }
-
-            InputStream trustCertCollectionFilePath = sslConfig.getServerTrustCertCollectionPathStream();
-            if (trustCertCollectionFilePath != null) {
-                sslClientContextBuilder.trustManager(trustCertCollectionFilePath);
-                sslClientContextBuilder.clientAuth(ClientAuth.REQUIRE);
-            }
-        } catch (Exception e) {
-            throw new IllegalArgumentException("Could not find certificate file or the certificate is invalid.", e);
-        }
-        try {
-            return sslClientContextBuilder.build();
-        } catch (SSLException e) {
-            throw new IllegalStateException("Build SslSession failed.", e);
-        }
-    }
-
-    private static SslContext buildClientSslContext(URL url) {
-        ConfigManager globalConfigManager = ApplicationModel.getConfigManager();
-        SslConfig sslConfig = globalConfigManager.getSsl().orElseThrow(() -> new IllegalStateException("Ssl enabled, but no ssl cert information provided!"));
-
-
-        SslContextBuilder builder = GrpcSslContexts.forClient();
-        try {
-            InputStream trustCertCollectionFilePath = sslConfig.getClientTrustCertCollectionPathStream();
-            if (trustCertCollectionFilePath != null) {
-                builder.trustManager(trustCertCollectionFilePath);
-            }
-            InputStream clientCertChainFilePath = sslConfig.getClientKeyCertChainPathStream();
-            InputStream clientPrivateKeyFilePath = sslConfig.getClientPrivateKeyPathStream();
-            if (clientCertChainFilePath != null && clientPrivateKeyFilePath != null) {
-                String password = sslConfig.getClientKeyPassword();
-                if (password != null) {
-                    builder.keyManager(clientCertChainFilePath, clientPrivateKeyFilePath, password);
-                } else {
-                    builder.keyManager(clientCertChainFilePath, clientPrivateKeyFilePath);
-                }
-            }
-        } catch (Exception e) {
-            throw new IllegalArgumentException("Could not find certificate file or find invalid certificate.", e);
-        }
-        try {
-            return builder.build();
-        } catch (SSLException e) {
-            throw new IllegalStateException("Build SslSession failed.", e);
-        }
-    }
-
-    private static Optional<GrpcConfigurator> getConfigurator() {
-        // Give users the chance to customize ServerBuilder
-        Set<GrpcConfigurator> configurators = ExtensionLoader.getExtensionLoader(GrpcConfigurator.class)
-                .getSupportedExtensionInstances();
-        if (CollectionUtils.isNotEmpty(configurators)) {
-            return Optional.of(configurators.iterator().next());
-        }
-        return Optional.empty();
-    }
-}
diff --git a/dubbo-spi-rpc/dubbo-rpc-grpc/src/main/java/org/apache/dubbo/rpc/protocol/grpc/GrpcProtocol.java b/dubbo-spi-rpc/dubbo-rpc-grpc/src/main/java/org/apache/dubbo/rpc/protocol/grpc/GrpcProtocol.java
deleted file mode 100644
index 1342a17..0000000
--- a/dubbo-spi-rpc/dubbo-rpc-grpc/src/main/java/org/apache/dubbo/rpc/protocol/grpc/GrpcProtocol.java
+++ /dev/null
@@ -1,239 +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.rpc.protocol.grpc;
-
-import org.apache.dubbo.common.URL;
-import org.apache.dubbo.common.logger.Logger;
-import org.apache.dubbo.common.logger.LoggerFactory;
-import org.apache.dubbo.config.ReferenceConfigBase;
-import org.apache.dubbo.rpc.Invoker;
-import org.apache.dubbo.rpc.ProtocolServer;
-import org.apache.dubbo.rpc.RpcException;
-import org.apache.dubbo.rpc.model.ApplicationModel;
-import org.apache.dubbo.rpc.model.ProviderModel;
-import org.apache.dubbo.rpc.model.ServiceRepository;
-import org.apache.dubbo.rpc.protocol.AbstractProxyProtocol;
-
-import io.grpc.BindableService;
-import io.grpc.CallOptions;
-import io.grpc.Channel;
-import io.grpc.ManagedChannel;
-import io.grpc.Server;
-import io.grpc.netty.NettyServerBuilder;
-
-import java.io.IOException;
-import java.lang.reflect.InvocationTargetException;
-import java.lang.reflect.Method;
-import java.util.concurrent.ConcurrentHashMap;
-import java.util.concurrent.ConcurrentMap;
-
-/**
- *
- */
-public class GrpcProtocol extends AbstractProxyProtocol {
-
-    private static final Logger logger = LoggerFactory.getLogger(GrpcProtocol.class);
-
-    public final static int DEFAULT_PORT = 50051;
-
-    /* <address, gRPC channels> */
-    private final ConcurrentMap<String, ReferenceCountManagedChannel> channelMap = new ConcurrentHashMap<>();
-    private final Object lock = new Object();
-
-    @Override
-    protected <T> Runnable doExport(T proxiedImpl, Class<T> type, URL url) throws RpcException {
-        String key = url.getAddress();
-        ProtocolServer protocolServer = serverMap.computeIfAbsent(key, k -> {
-            DubboHandlerRegistry registry = new DubboHandlerRegistry();
-
-            NettyServerBuilder builder =
-                    NettyServerBuilder
-                    .forPort(url.getPort())
-                            .fallbackHandlerRegistry(registry);
-
-            Server originalServer = GrpcOptionsUtils.buildServerBuilder(url, builder).build();
-            GrpcRemotingServer remotingServer = new GrpcRemotingServer(originalServer, registry);
-            return new ProxyProtocolServer(remotingServer);
-        });
-
-        GrpcRemotingServer grpcServer = (GrpcRemotingServer) protocolServer.getRemotingServer();
-
-        ServiceRepository serviceRepository = ApplicationModel.getServiceRepository();
-        ProviderModel providerModel = serviceRepository.lookupExportedService(url.getServiceKey());
-        if (providerModel == null) {
-            throw new IllegalStateException("Service " + url.getServiceKey() + "should have already been stored in service repository, " +
-                    "but failed to find it.");
-        }
-        Object originalImpl = providerModel.getServiceInstance();
-
-        Class<?> implClass = originalImpl.getClass();
-        try {
-            Method method = implClass.getMethod("setProxiedImpl", type);
-            method.invoke(originalImpl, proxiedImpl);
-        } catch (Exception e) {
-            throw new IllegalStateException("Failed to set dubbo proxied service impl to stub, please make sure your stub " +
-                    "was generated by the dubbo-protoc-compiler.", e);
-        }
-        grpcServer.getRegistry().addService((BindableService) originalImpl, url.getServiceKey());
-
-        if (!grpcServer.isStarted()) {
-            grpcServer.start();
-        }
-
-        return () -> grpcServer.getRegistry().removeService(url.getServiceKey());
-    }
-
-    @Override
-    protected <T> Invoker<T> protocolBindingRefer(final Class<T> type, final URL url) throws RpcException {
-        Class<?> enclosingClass = type.getEnclosingClass();
-
-        if (enclosingClass == null) {
-            throw new IllegalArgumentException(type.getName() + " must be declared inside protobuf generated classes, " +
-                    "should be something like ServiceNameGrpc.IServiceName.");
-        }
-
-        final Method dubboStubMethod;
-        try {
-            dubboStubMethod = enclosingClass.getDeclaredMethod("getDubboStub", Channel.class, CallOptions.class,
-                    URL.class, ReferenceConfigBase.class);
-        } catch (NoSuchMethodException e) {
-            throw new IllegalArgumentException("Does not find getDubboStub in " + enclosingClass.getName() + ", please use the customized protoc-gen-dubbo-java to update the generated classes.");
-        }
-
-        // Channel
-        ReferenceCountManagedChannel channel = getSharedChannel(url);
-
-        // CallOptions
-        try {
-            @SuppressWarnings("unchecked") final T stub = (T) dubboStubMethod.invoke(null,
-                    channel,
-                    GrpcOptionsUtils.buildCallOptions(url),
-                    url,
-                    ApplicationModel.getConsumerModel(url.getServiceKey()).getReferenceConfig()
-            );
-            final Invoker<T> target = proxyFactory.getInvoker(stub, type, url);
-            GrpcInvoker<T> grpcInvoker = new GrpcInvoker<>(type, url, target, channel);
-            invokers.add(grpcInvoker);
-            return grpcInvoker;
-        } catch (IllegalAccessException | InvocationTargetException e) {
-            throw new IllegalStateException("Could not create stub through reflection.", e);
-        }
-    }
-
-    /**
-     * not used
-     *
-     * @param type
-     * @param url
-     * @param <T>
-     * @return
-     * @throws RpcException
-     */
-    @Override
-    protected <T> T doRefer(Class<T> type, URL url) throws RpcException {
-        throw new UnsupportedOperationException("not used");
-    }
-
-    /**
-     * Get shared channel connection
-     */
-    private ReferenceCountManagedChannel getSharedChannel(URL url) {
-        String key = url.getAddress();
-        ReferenceCountManagedChannel channel = channelMap.get(key);
-
-        if (channel != null && !channel.isTerminated()) {
-            channel.incrementAndGetCount();
-            return channel;
-        }
-
-        synchronized (lock) {
-            channel = channelMap.get(key);
-            // dubbo check
-            if (channel != null && !channel.isTerminated()) {
-                channel.incrementAndGetCount();
-            } else {
-                channel = new ReferenceCountManagedChannel(initChannel(url));
-                channelMap.put(key, channel);
-            }
-        }
-
-        return channel;
-    }
-
-    /**
-     * Create new connection
-     *
-     * @param url
-     */
-    private ManagedChannel initChannel(URL url) {
-        return GrpcOptionsUtils.buildManagedChannel(url);
-    }
-
-    @Override
-    public int getDefaultPort() {
-        return DEFAULT_PORT;
-    }
-
-    @Override
-    public void destroy() {
-        serverMap.values().forEach(ProtocolServer::close);
-        channelMap.values().forEach(ReferenceCountManagedChannel::shutdown);
-        serverMap.clear();
-        channelMap.clear();
-        super.destroy();
-    }
-
-    public class GrpcRemotingServer extends RemotingServerAdapter {
-
-        private Server originalServer;
-        private DubboHandlerRegistry handlerRegistry;
-        private volatile boolean started;
-
-        public GrpcRemotingServer(Server server, DubboHandlerRegistry handlerRegistry) {
-            this.originalServer = server;
-            this.handlerRegistry = handlerRegistry;
-        }
-
-        public void start() throws RpcException {
-            try {
-                originalServer.start();
-                started = true;
-            } catch (IOException e) {
-                throw new RpcException("Starting gRPC server failed. ", e);
-            }
-        }
-
-        public DubboHandlerRegistry getRegistry() {
-            return handlerRegistry;
-        }
-
-        @Override
-        public Object getDelegateServer() {
-            return originalServer;
-        }
-
-        public boolean isStarted() {
-            return started;
-        }
-
-        @Override
-        public void close() {
-            originalServer.shutdown();
-        }
-    }
-
-}
diff --git a/dubbo-spi-rpc/dubbo-rpc-grpc/src/main/java/org/apache/dubbo/rpc/protocol/grpc/ReferenceCountManagedChannel.java b/dubbo-spi-rpc/dubbo-rpc-grpc/src/main/java/org/apache/dubbo/rpc/protocol/grpc/ReferenceCountManagedChannel.java
deleted file mode 100644
index 3b46f1e..0000000
--- a/dubbo-spi-rpc/dubbo-rpc-grpc/src/main/java/org/apache/dubbo/rpc/protocol/grpc/ReferenceCountManagedChannel.java
+++ /dev/null
@@ -1,85 +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.rpc.protocol.grpc;
-
-import io.grpc.CallOptions;
-import io.grpc.ClientCall;
-import io.grpc.ManagedChannel;
-import io.grpc.MethodDescriptor;
-
-import java.util.concurrent.TimeUnit;
-import java.util.concurrent.atomic.AtomicInteger;
-
-/**
- * Also see ReferenceCountExchangeClient
- */
-public class ReferenceCountManagedChannel extends ManagedChannel {
-
-    private final AtomicInteger referenceCount = new AtomicInteger(0);
-
-    private ManagedChannel grpcChannel;
-
-    public ReferenceCountManagedChannel(ManagedChannel delegated) {
-        this.grpcChannel = delegated;
-    }
-
-    /**
-     * The reference count of current ExchangeClient, connection will be closed if all invokers destroyed.
-     */
-    public void incrementAndGetCount() {
-        referenceCount.incrementAndGet();
-    }
-
-    @Override
-    public ManagedChannel shutdown() {
-        if (referenceCount.decrementAndGet() <= 0) {
-            return grpcChannel.shutdown();
-        }
-        return grpcChannel;
-    }
-
-    @Override
-    public boolean isShutdown() {
-        return grpcChannel.isShutdown();
-    }
-
-    @Override
-    public boolean isTerminated() {
-        return grpcChannel.isTerminated();
-    }
-
-    @Override
-    public ManagedChannel shutdownNow() {
-        // TODO
-        return shutdown();
-    }
-
-    @Override
-    public boolean awaitTermination(long timeout, TimeUnit unit) throws InterruptedException {
-        return grpcChannel.awaitTermination(timeout, unit);
-    }
-
-    @Override
-    public <RequestT, ResponseT> ClientCall<RequestT, ResponseT> newCall(MethodDescriptor<RequestT, ResponseT> methodDescriptor, CallOptions callOptions) {
-        return grpcChannel.newCall(methodDescriptor, callOptions);
-    }
-
-    @Override
-    public String authority() {
-        return grpcChannel.authority();
-    }
-}
diff --git a/dubbo-spi-rpc/dubbo-rpc-grpc/src/main/java/org/apache/dubbo/rpc/protocol/grpc/interceptors/ClientInterceptor.java b/dubbo-spi-rpc/dubbo-rpc-grpc/src/main/java/org/apache/dubbo/rpc/protocol/grpc/interceptors/ClientInterceptor.java
deleted file mode 100644
index c97fec9..0000000
--- a/dubbo-spi-rpc/dubbo-rpc-grpc/src/main/java/org/apache/dubbo/rpc/protocol/grpc/interceptors/ClientInterceptor.java
+++ /dev/null
@@ -1,26 +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.rpc.protocol.grpc.interceptors;
-
-import org.apache.dubbo.common.extension.SPI;
-
-/**
- * Adapt to the standard Dubbo SPI, so that we can leverage the advantages of Dubbo ExtensionLoader.
- */
-@SPI
-public interface ClientInterceptor extends io.grpc.ClientInterceptor {
-}
diff --git a/dubbo-spi-rpc/dubbo-rpc-grpc/src/main/java/org/apache/dubbo/rpc/protocol/grpc/interceptors/GrpcConfigurator.java b/dubbo-spi-rpc/dubbo-rpc-grpc/src/main/java/org/apache/dubbo/rpc/protocol/grpc/interceptors/GrpcConfigurator.java
deleted file mode 100644
index d5330dc..0000000
--- a/dubbo-spi-rpc/dubbo-rpc-grpc/src/main/java/org/apache/dubbo/rpc/protocol/grpc/interceptors/GrpcConfigurator.java
+++ /dev/null
@@ -1,41 +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.rpc.protocol.grpc.interceptors;
-
-import org.apache.dubbo.common.URL;
-import org.apache.dubbo.common.extension.SPI;
-
-import io.grpc.CallOptions;
-import io.grpc.netty.NettyChannelBuilder;
-import io.grpc.netty.NettyServerBuilder;
-
-@SPI
-public interface GrpcConfigurator {
-
-    default NettyServerBuilder configureServerBuilder(NettyServerBuilder builder, URL url) {
-        return builder;
-    }
-
-    default NettyChannelBuilder configureChannelBuilder(NettyChannelBuilder builder, URL url) {
-        return builder;
-    }
-
-    default CallOptions configureCallOptions(CallOptions options, URL url) {
-        return options;
-    }
-
-}
diff --git a/dubbo-spi-rpc/dubbo-rpc-grpc/src/main/java/org/apache/dubbo/rpc/protocol/grpc/interceptors/RpcContextInterceptor.java b/dubbo-spi-rpc/dubbo-rpc-grpc/src/main/java/org/apache/dubbo/rpc/protocol/grpc/interceptors/RpcContextInterceptor.java
deleted file mode 100644
index 86915af..0000000
--- a/dubbo-spi-rpc/dubbo-rpc-grpc/src/main/java/org/apache/dubbo/rpc/protocol/grpc/interceptors/RpcContextInterceptor.java
+++ /dev/null
@@ -1,100 +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.rpc.protocol.grpc.interceptors;
-
-import io.grpc.CallOptions;
-import io.grpc.Channel;
-import io.grpc.ClientCall;
-import io.grpc.ForwardingClientCall;
-import io.grpc.ForwardingServerCallListener;
-import io.grpc.Metadata;
-import io.grpc.MethodDescriptor;
-import io.grpc.ServerCall;
-import io.grpc.ServerCallHandler;
-import org.apache.dubbo.common.extension.Activate;
-import org.apache.dubbo.rpc.RpcContext;
-
-import java.util.HashMap;
-import java.util.Map;
-import java.util.Set;
-
-import static io.grpc.Metadata.ASCII_STRING_MARSHALLER;
-import static org.apache.dubbo.common.constants.CommonConstants.CONSUMER;
-import static org.apache.dubbo.common.constants.CommonConstants.PROVIDER;
-
-/**
- * Hand over context information from Dubbo to gRPC.
- */
-@Activate(group = {PROVIDER, CONSUMER})
-public class RpcContextInterceptor implements ClientInterceptor, ServerInterceptor {
-
-    private static final String DUBBO = "D-";
-
-    @Override
-    public <ReqT, RespT> ClientCall<ReqT, RespT> interceptCall(MethodDescriptor<ReqT, RespT> method, CallOptions callOptions, Channel next) {
-        RpcContext rpcContext = RpcContext.getContext();
-        Map<String, Object> attachments = new HashMap<>(rpcContext.getObjectAttachments());
-
-        return new ForwardingClientCall.SimpleForwardingClientCall<ReqT, RespT>(next.newCall(method, callOptions)) {
-            @Override
-            public void start(Listener<RespT> responseListener, Metadata headers) {
-                if (!attachments.isEmpty()) {
-                    for (Map.Entry<String, Object> entry : attachments.entrySet()) {
-                        // only used for string
-                        if (entry.getValue() instanceof String) {
-                            headers.put(Metadata.Key.of(DUBBO + entry.getKey(), ASCII_STRING_MARSHALLER), ((String) entry.getValue()));
-                        }
-                    }
-                }
-                super.start(responseListener, headers);
-            }
-        };
-    }
-
-    @Override
-    public <ReqT, RespT> ServerCall.Listener<ReqT> interceptCall(ServerCall<ReqT, RespT> call, Metadata headers, ServerCallHandler<ReqT, RespT> next) {
-        Set<String> keys = headers.keys();
-        Map<String, Object> attachments = new HashMap<>();
-        // filter out all dubbo attachments and save in map
-        if (keys != null) {
-            keys.stream().filter(k -> k.toUpperCase().startsWith(DUBBO)).forEach(k ->
-                    attachments.put(k.substring(DUBBO.length()), headers.get(Metadata.Key.of(k, Metadata.ASCII_STRING_MARSHALLER)))
-            );
-        }
-
-        return new ForwardingServerCallListener.SimpleForwardingServerCallListener<ReqT>(next.startCall(call, headers)) {
-            @Override
-            public void onHalfClose() {
-                // the client completed all message sending and server will call the biz method if client is not the streaming
-                if (call.getMethodDescriptor().getType().clientSendsOneMessage()) {
-                    RpcContext.getContext().setObjectAttachments(attachments);
-                }
-                super.onHalfClose();
-            }
-
-            @Override
-            public void onMessage(ReqT message) {
-                //server receive the request from client and call the biz method if client is streaming
-                if (!call.getMethodDescriptor().getType().clientSendsOneMessage()) {
-                    RpcContext.getContext().setObjectAttachments(attachments);
-                }
-                super.onMessage(message);
-            }
-        };
-    }
-
-}
diff --git a/dubbo-spi-rpc/dubbo-rpc-grpc/src/main/java/org/apache/dubbo/rpc/protocol/grpc/interceptors/ServerInterceptor.java b/dubbo-spi-rpc/dubbo-rpc-grpc/src/main/java/org/apache/dubbo/rpc/protocol/grpc/interceptors/ServerInterceptor.java
deleted file mode 100644
index a4c9a37..0000000
--- a/dubbo-spi-rpc/dubbo-rpc-grpc/src/main/java/org/apache/dubbo/rpc/protocol/grpc/interceptors/ServerInterceptor.java
+++ /dev/null
@@ -1,26 +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.rpc.protocol.grpc.interceptors;
-
-import org.apache.dubbo.common.extension.SPI;
-
-/**
- * Adapt to the standard Dubbo SPI, so that we can leverage the advantages of Dubbo ExtensionLoader.
- */
-@SPI
-public interface ServerInterceptor extends io.grpc.ServerInterceptor {
-}
diff --git a/dubbo-spi-rpc/dubbo-rpc-grpc/src/main/java/org/apache/dubbo/rpc/protocol/grpc/interceptors/ServerTransportFilter.java b/dubbo-spi-rpc/dubbo-rpc-grpc/src/main/java/org/apache/dubbo/rpc/protocol/grpc/interceptors/ServerTransportFilter.java
deleted file mode 100644
index db815dc..0000000
--- a/dubbo-spi-rpc/dubbo-rpc-grpc/src/main/java/org/apache/dubbo/rpc/protocol/grpc/interceptors/ServerTransportFilter.java
+++ /dev/null
@@ -1,27 +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.rpc.protocol.grpc.interceptors;
-
-import org.apache.dubbo.common.extension.SPI;
-
-/**
- * Adapt to the standard Dubbo SPI, so that we can leverage the advantages of Dubbo ExtensionLoader.
- */
-@SPI
-public interface ServerTransportFilter {
-    io.grpc.ServerTransportFilter grpcTransportFilter();
-}
diff --git a/dubbo-spi-rpc/dubbo-rpc-grpc/src/main/resources/META-INF/dubbo/internal/org.apache.dubbo.rpc.Protocol b/dubbo-spi-rpc/dubbo-rpc-grpc/src/main/resources/META-INF/dubbo/internal/org.apache.dubbo.rpc.Protocol
deleted file mode 100644
index f7acbba..0000000
--- a/dubbo-spi-rpc/dubbo-rpc-grpc/src/main/resources/META-INF/dubbo/internal/org.apache.dubbo.rpc.Protocol
+++ /dev/null
@@ -1 +0,0 @@
-grpc=org.apache.dubbo.rpc.protocol.grpc.GrpcProtocol
\ No newline at end of file
diff --git a/dubbo-spi-rpc/dubbo-rpc-grpc/src/main/resources/META-INF/dubbo/internal/org.apache.dubbo.rpc.protocol.grpc.interceptors.ClientInterceptor b/dubbo-spi-rpc/dubbo-rpc-grpc/src/main/resources/META-INF/dubbo/internal/org.apache.dubbo.rpc.protocol.grpc.interceptors.ClientInterceptor
deleted file mode 100644
index b957657..0000000
--- a/dubbo-spi-rpc/dubbo-rpc-grpc/src/main/resources/META-INF/dubbo/internal/org.apache.dubbo.rpc.protocol.grpc.interceptors.ClientInterceptor
+++ /dev/null
@@ -1 +0,0 @@
-context=org.apache.dubbo.rpc.protocol.grpc.interceptors.RpcContextInterceptor
\ No newline at end of file
diff --git a/dubbo-spi-rpc/dubbo-rpc-grpc/src/main/resources/META-INF/dubbo/internal/org.apache.dubbo.rpc.protocol.grpc.interceptors.ServerInterceptor b/dubbo-spi-rpc/dubbo-rpc-grpc/src/main/resources/META-INF/dubbo/internal/org.apache.dubbo.rpc.protocol.grpc.interceptors.ServerInterceptor
deleted file mode 100644
index b957657..0000000
--- a/dubbo-spi-rpc/dubbo-rpc-grpc/src/main/resources/META-INF/dubbo/internal/org.apache.dubbo.rpc.protocol.grpc.interceptors.ServerInterceptor
+++ /dev/null
@@ -1 +0,0 @@
-context=org.apache.dubbo.rpc.protocol.grpc.interceptors.RpcContextInterceptor
\ No newline at end of file
diff --git a/dubbo-spi-rpc/dubbo-rpc-injvm/pom.xml b/dubbo-spi-rpc/dubbo-rpc-injvm/pom.xml
deleted file mode 100644
index 7d9ce83..0000000
--- a/dubbo-spi-rpc/dubbo-rpc-injvm/pom.xml
+++ /dev/null
@@ -1,38 +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.
-  -->
-<project xmlns="http://maven.apache.org/POM/4.0.0" xmlns:xsi="http://www.w3.org/2001/XMLSchema-instance" xsi:schemaLocation="http://maven.apache.org/POM/4.0.0 http://maven.apache.org/maven-v4_0_0.xsd">
-    <modelVersion>4.0.0</modelVersion>
-    <parent>
-        <groupId>org.apache.dubbo</groupId>
-        <artifactId>dubbo-rpc</artifactId>
-        <version>2.7.7-SNAPSHOT</version>
-    </parent>
-    <artifactId>dubbo-rpc-injvm</artifactId>
-    <packaging>jar</packaging>
-    <name>${project.artifactId}</name>
-    <description>The injvm rpc module of dubbo project</description>
-    <properties>
-        <skip_maven_deploy>false</skip_maven_deploy>
-    </properties>
-    <dependencies>
-        <dependency>
-            <groupId>org.apache.dubbo</groupId>
-            <artifactId>dubbo-rpc-api</artifactId>
-            <version>${project.parent.version}</version>
-        </dependency>
-    </dependencies>
-</project>
\ No newline at end of file
diff --git a/dubbo-spi-rpc/dubbo-rpc-injvm/src/main/java/org/apache/dubbo/rpc/protocol/injvm/InjvmExporter.java b/dubbo-spi-rpc/dubbo-rpc-injvm/src/main/java/org/apache/dubbo/rpc/protocol/injvm/InjvmExporter.java
deleted file mode 100644
index b0a648f..0000000
--- a/dubbo-spi-rpc/dubbo-rpc-injvm/src/main/java/org/apache/dubbo/rpc/protocol/injvm/InjvmExporter.java
+++ /dev/null
@@ -1,47 +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.rpc.protocol.injvm;
-
-import org.apache.dubbo.rpc.Exporter;
-import org.apache.dubbo.rpc.Invoker;
-import org.apache.dubbo.rpc.protocol.AbstractExporter;
-
-import java.util.Map;
-
-/**
- * InjvmExporter
- */
-class InjvmExporter<T> extends AbstractExporter<T> {
-
-    private final String key;
-
-    private final Map<String, Exporter<?>> exporterMap;
-
-    InjvmExporter(Invoker<T> invoker, String key, Map<String, Exporter<?>> exporterMap) {
-        super(invoker);
-        this.key = key;
-        this.exporterMap = exporterMap;
-        exporterMap.put(key, this);
-    }
-
-    @Override
-    public void unexport() {
-        super.unexport();
-        exporterMap.remove(key);
-    }
-
-}
diff --git a/dubbo-spi-rpc/dubbo-rpc-injvm/src/main/java/org/apache/dubbo/rpc/protocol/injvm/InjvmInvoker.java b/dubbo-spi-rpc/dubbo-rpc-injvm/src/main/java/org/apache/dubbo/rpc/protocol/injvm/InjvmInvoker.java
deleted file mode 100644
index a8c75fd..0000000
--- a/dubbo-spi-rpc/dubbo-rpc-injvm/src/main/java/org/apache/dubbo/rpc/protocol/injvm/InjvmInvoker.java
+++ /dev/null
@@ -1,65 +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.rpc.protocol.injvm;
-
-import org.apache.dubbo.common.URL;
-import org.apache.dubbo.rpc.Exporter;
-import org.apache.dubbo.rpc.Invocation;
-import org.apache.dubbo.rpc.Result;
-import org.apache.dubbo.rpc.RpcContext;
-import org.apache.dubbo.rpc.RpcException;
-import org.apache.dubbo.rpc.protocol.AbstractInvoker;
-
-import java.util.Map;
-
-import static org.apache.dubbo.common.constants.CommonConstants.LOCALHOST_VALUE;
-
-/**
- * InjvmInvoker
- */
-class InjvmInvoker<T> extends AbstractInvoker<T> {
-
-    private final String key;
-
-    private final Map<String, Exporter<?>> exporterMap;
-
-    InjvmInvoker(Class<T> type, URL url, String key, Map<String, Exporter<?>> exporterMap) {
-        super(type, url);
-        this.key = key;
-        this.exporterMap = exporterMap;
-    }
-
-    @Override
-    public boolean isAvailable() {
-        InjvmExporter<?> exporter = (InjvmExporter<?>) exporterMap.get(key);
-        if (exporter == null) {
-            return false;
-        } else {
-            return super.isAvailable();
-        }
-    }
-
-    @Override
-    public Result doInvoke(Invocation invocation) throws Throwable {
-        Exporter<?> exporter = InjvmProtocol.getExporter(exporterMap, getUrl());
-        if (exporter == null) {
-            throw new RpcException("Service [" + key + "] not found.");
-        }
-        RpcContext.getContext().setRemoteAddress(LOCALHOST_VALUE, 0);
-        return exporter.getInvoker().invoke(invocation);
-    }
-}
diff --git a/dubbo-spi-rpc/dubbo-rpc-injvm/src/main/java/org/apache/dubbo/rpc/protocol/injvm/InjvmProtocol.java b/dubbo-spi-rpc/dubbo-rpc-injvm/src/main/java/org/apache/dubbo/rpc/protocol/injvm/InjvmProtocol.java
deleted file mode 100644
index 3e681b2..0000000
--- a/dubbo-spi-rpc/dubbo-rpc-injvm/src/main/java/org/apache/dubbo/rpc/protocol/injvm/InjvmProtocol.java
+++ /dev/null
@@ -1,120 +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.rpc.protocol.injvm;
-
-import org.apache.dubbo.common.URL;
-import org.apache.dubbo.common.extension.ExtensionLoader;
-import org.apache.dubbo.common.utils.CollectionUtils;
-import org.apache.dubbo.common.utils.UrlUtils;
-import org.apache.dubbo.rpc.Exporter;
-import org.apache.dubbo.rpc.Invoker;
-import org.apache.dubbo.rpc.Protocol;
-import org.apache.dubbo.rpc.RpcException;
-import org.apache.dubbo.rpc.protocol.AbstractProtocol;
-import org.apache.dubbo.rpc.support.ProtocolUtils;
-
-import java.util.Map;
-
-import static org.apache.dubbo.rpc.Constants.SCOPE_KEY;
-import static org.apache.dubbo.rpc.Constants.SCOPE_LOCAL;
-import static org.apache.dubbo.rpc.Constants.SCOPE_REMOTE;
-import static org.apache.dubbo.rpc.Constants.GENERIC_KEY;
-import static org.apache.dubbo.rpc.Constants.LOCAL_PROTOCOL;
-
-/**
- * InjvmProtocol
- */
-public class InjvmProtocol extends AbstractProtocol implements Protocol {
-
-    public static final String NAME = LOCAL_PROTOCOL;
-
-    public static final int DEFAULT_PORT = 0;
-    private static InjvmProtocol INSTANCE;
-
-    public InjvmProtocol() {
-        INSTANCE = this;
-    }
-
-    public static InjvmProtocol getInjvmProtocol() {
-        if (INSTANCE == null) {
-            ExtensionLoader.getExtensionLoader(Protocol.class).getExtension(InjvmProtocol.NAME); // load
-        }
-        return INSTANCE;
-    }
-
-    static Exporter<?> getExporter(Map<String, Exporter<?>> map, URL key) {
-        Exporter<?> result = null;
-
-        if (!key.getServiceKey().contains("*")) {
-            result = map.get(key.getServiceKey());
-        } else {
-            if (CollectionUtils.isNotEmptyMap(map)) {
-                for (Exporter<?> exporter : map.values()) {
-                    if (UrlUtils.isServiceKeyMatch(key, exporter.getInvoker().getUrl())) {
-                        result = exporter;
-                        break;
-                    }
-                }
-            }
-        }
-
-        if (result == null) {
-            return null;
-        } else if (ProtocolUtils.isGeneric(
-                result.getInvoker().getUrl().getParameter(GENERIC_KEY))) {
-            return null;
-        } else {
-            return result;
-        }
-    }
-
-    @Override
-    public int getDefaultPort() {
-        return DEFAULT_PORT;
-    }
-
-    @Override
-    public <T> Exporter<T> export(Invoker<T> invoker) throws RpcException {
-        return new InjvmExporter<T>(invoker, invoker.getUrl().getServiceKey(), exporterMap);
-    }
-
-    @Override
-    public <T> Invoker<T> protocolBindingRefer(Class<T> serviceType, URL url) throws RpcException {
-        return new InjvmInvoker<T>(serviceType, url, url.getServiceKey(), exporterMap);
-    }
-
-    public boolean isInjvmRefer(URL url) {
-        String scope = url.getParameter(SCOPE_KEY);
-        // Since injvm protocol is configured explicitly, we don't need to set any extra flag, use normal refer process.
-        if (SCOPE_LOCAL.equals(scope) || (url.getParameter(LOCAL_PROTOCOL, false))) {
-            // if it's declared as local reference
-            // 'scope=local' is equivalent to 'injvm=true', injvm will be deprecated in the future release
-            return true;
-        } else if (SCOPE_REMOTE.equals(scope)) {
-            // it's declared as remote reference
-            return false;
-        } else if (url.getParameter(GENERIC_KEY, false)) {
-            // generic invocation is not local reference
-            return false;
-        } else if (getExporter(exporterMap, url) != null) {
-            // by default, go through local reference if there's the service exposed locally
-            return true;
-        } else {
-            return false;
-        }
-    }
-}
diff --git a/dubbo-spi-rpc/dubbo-rpc-injvm/src/main/resources/META-INF/dubbo/internal/org.apache.dubbo.rpc.Protocol b/dubbo-spi-rpc/dubbo-rpc-injvm/src/main/resources/META-INF/dubbo/internal/org.apache.dubbo.rpc.Protocol
deleted file mode 100644
index 92ec2df..0000000
--- a/dubbo-spi-rpc/dubbo-rpc-injvm/src/main/resources/META-INF/dubbo/internal/org.apache.dubbo.rpc.Protocol
+++ /dev/null
@@ -1 +0,0 @@
-injvm=org.apache.dubbo.rpc.protocol.injvm.InjvmProtocol
\ No newline at end of file
diff --git a/dubbo-spi-rpc/dubbo-rpc-injvm/src/test/java/org/apache/dubbo/rpc/protocol/injvm/DemoRequest.java b/dubbo-spi-rpc/dubbo-rpc-injvm/src/test/java/org/apache/dubbo/rpc/protocol/injvm/DemoRequest.java
deleted file mode 100644
index cbd2e34..0000000
--- a/dubbo-spi-rpc/dubbo-rpc-injvm/src/test/java/org/apache/dubbo/rpc/protocol/injvm/DemoRequest.java
+++ /dev/null
@@ -1,58 +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.rpc.protocol.injvm;
-
-import java.io.Serializable;
-
-/**
- * TestRequest.
- */
-
-class DemoRequest implements Serializable {
-    private static final long serialVersionUID = -2579095288792344869L;
-
-    private String mServiceName;
-
-    private String mMethodName;
-
-    private Class<?>[] mParameterTypes;
-
-    private Object[] mArguments;
-
-    public DemoRequest(String serviceName, String methodName, Class<?>[] parameterTypes, Object[] args) {
-        mServiceName = serviceName;
-        mMethodName = methodName;
-        mParameterTypes = parameterTypes;
-        mArguments = args;
-    }
-
-    public String getServiceName() {
-        return mServiceName;
-    }
-
-    public String getMethodName() {
-        return mMethodName;
-    }
-
-    public Class<?>[] getParameterTypes() {
-        return mParameterTypes;
-    }
-
-    public Object[] getArguments() {
-        return mArguments;
-    }
-}
\ No newline at end of file
diff --git a/dubbo-spi-rpc/dubbo-rpc-injvm/src/test/java/org/apache/dubbo/rpc/protocol/injvm/DemoService.java b/dubbo-spi-rpc/dubbo-rpc-injvm/src/test/java/org/apache/dubbo/rpc/protocol/injvm/DemoService.java
deleted file mode 100644
index 821015f..0000000
--- a/dubbo-spi-rpc/dubbo-rpc-injvm/src/test/java/org/apache/dubbo/rpc/protocol/injvm/DemoService.java
+++ /dev/null
@@ -1,44 +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.rpc.protocol.injvm;
-
-/**
- * <code>TestService</code>
- */
-
-public interface DemoService {
-    void sayHello(String name);
-
-    String echo(String text);
-
-    long timestamp();
-
-    String getThreadName();
-
-    int getSize(String[] strs);
-
-    int getSize(Object[] os);
-
-    Object invoke(String service, String method) throws Exception;
-
-    int stringLength(String str);
-
-    Type enumlength(Type... types);
-
-
-    String getRemoteApplicationName();
-}
\ No newline at end of file
diff --git a/dubbo-spi-rpc/dubbo-rpc-injvm/src/test/java/org/apache/dubbo/rpc/protocol/injvm/DemoServiceImpl.java b/dubbo-spi-rpc/dubbo-rpc-injvm/src/test/java/org/apache/dubbo/rpc/protocol/injvm/DemoServiceImpl.java
deleted file mode 100644
index a6e3f2c..0000000
--- a/dubbo-spi-rpc/dubbo-rpc-injvm/src/test/java/org/apache/dubbo/rpc/protocol/injvm/DemoServiceImpl.java
+++ /dev/null
@@ -1,78 +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.rpc.protocol.injvm;
-
-import org.apache.dubbo.rpc.RpcContext;
-
-/**
- * DemoServiceImpl
- */
-
-public class DemoServiceImpl implements DemoService {
-    public DemoServiceImpl() {
-        super();
-    }
-
-    public void sayHello(String name) {
-        System.out.println("hello " + name);
-    }
-
-    public String echo(String text) {
-        return text;
-    }
-
-    public long timestamp() {
-        return System.currentTimeMillis();
-    }
-
-    public String getThreadName() {
-        return Thread.currentThread().getName();
-    }
-
-    public int getSize(String[] strs) {
-        if (strs == null)
-            return -1;
-        return strs.length;
-    }
-
-    public int getSize(Object[] os) {
-        if (os == null)
-            return -1;
-        return os.length;
-    }
-
-    public Object invoke(String service, String method) throws Exception {
-        System.out.println("RpcContext.getContext().getRemoteHost()=" + RpcContext.getContext().getRemoteHost());
-        return service + ":" + method;
-    }
-
-    public Type enumlength(Type... types) {
-        if (types.length == 0)
-            return Type.Lower;
-        return types[0];
-    }
-
-    public int stringLength(String str) {
-        return str.length();
-    }
-
-
-    @Override
-    public String getRemoteApplicationName() {
-        return RpcContext.getContext().getRemoteApplicationName();
-    }
-}
\ No newline at end of file
diff --git a/dubbo-spi-rpc/dubbo-rpc-injvm/src/test/java/org/apache/dubbo/rpc/protocol/injvm/IEcho.java b/dubbo-spi-rpc/dubbo-rpc-injvm/src/test/java/org/apache/dubbo/rpc/protocol/injvm/IEcho.java
deleted file mode 100644
index 0883946..0000000
--- a/dubbo-spi-rpc/dubbo-rpc-injvm/src/test/java/org/apache/dubbo/rpc/protocol/injvm/IEcho.java
+++ /dev/null
@@ -1,21 +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.rpc.protocol.injvm;
-
-public interface IEcho {
-    String echo(String e);
-}
\ No newline at end of file
diff --git a/dubbo-spi-rpc/dubbo-rpc-injvm/src/test/java/org/apache/dubbo/rpc/protocol/injvm/InjvmProtocolTest.java b/dubbo-spi-rpc/dubbo-rpc-injvm/src/test/java/org/apache/dubbo/rpc/protocol/injvm/InjvmProtocolTest.java
deleted file mode 100644
index ea6de85..0000000
--- a/dubbo-spi-rpc/dubbo-rpc-injvm/src/test/java/org/apache/dubbo/rpc/protocol/injvm/InjvmProtocolTest.java
+++ /dev/null
@@ -1,126 +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.rpc.protocol.injvm;
-
-
-import org.apache.dubbo.common.URL;
-import org.apache.dubbo.common.extension.ExtensionLoader;
-import org.apache.dubbo.rpc.Exporter;
-import org.apache.dubbo.rpc.Invoker;
-import org.apache.dubbo.rpc.Protocol;
-import org.apache.dubbo.rpc.ProxyFactory;
-
-import org.junit.jupiter.api.AfterEach;
-import org.junit.jupiter.api.Test;
-
-import java.util.ArrayList;
-import java.util.HashMap;
-import java.util.List;
-
-import static org.apache.dubbo.common.constants.CommonConstants.GROUP_KEY;
-import static org.apache.dubbo.common.constants.CommonConstants.INTERFACE_KEY;
-import static org.apache.dubbo.common.constants.CommonConstants.VERSION_KEY;
-import static org.apache.dubbo.rpc.Constants.SCOPE_KEY;
-import static org.apache.dubbo.rpc.Constants.SCOPE_LOCAL;
-import static org.apache.dubbo.rpc.Constants.SCOPE_REMOTE;
-import static org.apache.dubbo.rpc.Constants.GENERIC_KEY;
-import static org.apache.dubbo.rpc.Constants.LOCAL_PROTOCOL;
-import static org.junit.jupiter.api.Assertions.assertEquals;
-import static org.junit.jupiter.api.Assertions.assertFalse;
-import static org.junit.jupiter.api.Assertions.assertTrue;
-
-/**
- * <code>ProxiesTest</code>
- */
-
-public class InjvmProtocolTest {
-
-    static {
-        InjvmProtocol injvm = InjvmProtocol.getInjvmProtocol();
-    }
-
-    private Protocol protocol = ExtensionLoader.getExtensionLoader(Protocol.class).getAdaptiveExtension();
-    private ProxyFactory proxy = ExtensionLoader.getExtensionLoader(ProxyFactory.class).getAdaptiveExtension();
-    private List<Exporter<?>> exporters = new ArrayList<Exporter<?>>();
-
-    @AfterEach
-    public void after() throws Exception {
-        for (Exporter<?> exporter : exporters) {
-            exporter.unexport();
-        }
-        exporters.clear();
-    }
-
-    @Test
-    public void testLocalProtocol() throws Exception {
-        DemoService service = new DemoServiceImpl();
-        Invoker<?> invoker = proxy.getInvoker(service, DemoService.class, URL.valueOf("injvm://127.0.0.1/TestService").addParameter(INTERFACE_KEY, DemoService.class.getName()));
-        assertTrue(invoker.isAvailable());
-        Exporter<?> exporter = protocol.export(invoker);
-        exporters.add(exporter);
-        service = proxy.getProxy(protocol.refer(DemoService.class, URL.valueOf("injvm://127.0.0.1/TestService").addParameter(INTERFACE_KEY, DemoService.class.getName())));
-        assertEquals(service.getSize(new String[]{"", "", ""}), 3);
-        service.invoke("injvm://127.0.0.1/TestService", "invoke");
-
-        InjvmInvoker injvmInvoker = new InjvmInvoker(DemoService.class, URL.valueOf("injvm://127.0.0.1/TestService"), null, new HashMap<String, Exporter<?>>());
-        assertFalse(injvmInvoker.isAvailable());
-
-    }
-
-    @Test
-    public void testIsInjvmRefer() throws Exception {
-        DemoService service = new DemoServiceImpl();
-        URL url = URL.valueOf("injvm://127.0.0.1/TestService")
-                .addParameter(INTERFACE_KEY, DemoService.class.getName());
-        Exporter<?> exporter = protocol.export(proxy.getInvoker(service, DemoService.class, url));
-        exporters.add(exporter);
-
-        url = url.setProtocol("dubbo");
-        assertTrue(InjvmProtocol.getInjvmProtocol().isInjvmRefer(url));
-
-        url = url.addParameter(GROUP_KEY, "*")
-                .addParameter(VERSION_KEY, "*");
-        assertTrue(InjvmProtocol.getInjvmProtocol().isInjvmRefer(url));
-
-        url = URL.valueOf("fake://127.0.0.1/TestService").addParameter(SCOPE_KEY, SCOPE_LOCAL);
-        assertTrue(InjvmProtocol.getInjvmProtocol().isInjvmRefer(url));
-
-        url = URL.valueOf("fake://127.0.0.1/TestService").addParameter(LOCAL_PROTOCOL, true);
-        assertTrue(InjvmProtocol.getInjvmProtocol().isInjvmRefer(url));
-
-        url = URL.valueOf("fake://127.0.0.1/TestService").addParameter(SCOPE_KEY, SCOPE_REMOTE);
-        assertFalse(InjvmProtocol.getInjvmProtocol().isInjvmRefer(url));
-
-        url = URL.valueOf("fake://127.0.0.1/TestService").addParameter(GENERIC_KEY, true);
-        assertFalse(InjvmProtocol.getInjvmProtocol().isInjvmRefer(url));
-
-    }
-
-
-    @Test
-    public void testRemoteApplicationName() throws Exception {
-        DemoService service = new DemoServiceImpl();
-        URL url = URL.valueOf("injvm://127.0.0.1/TestService").addParameter(INTERFACE_KEY, DemoService.class.getName()).addParameter("application", "consumer");
-        Invoker<?> invoker = proxy.getInvoker(service, DemoService.class, url);
-        assertTrue(invoker.isAvailable());
-        Exporter<?> exporter = protocol.export(invoker);
-        exporters.add(exporter);
-        service = proxy.getProxy(protocol.refer(DemoService.class, url));
-        assertEquals(service.getRemoteApplicationName(), "consumer");
-    }
-
-}
diff --git a/dubbo-spi-rpc/dubbo-rpc-injvm/src/test/java/org/apache/dubbo/rpc/protocol/injvm/ProtocolTest.java b/dubbo-spi-rpc/dubbo-rpc-injvm/src/test/java/org/apache/dubbo/rpc/protocol/injvm/ProtocolTest.java
deleted file mode 100644
index 12de553..0000000
--- a/dubbo-spi-rpc/dubbo-rpc-injvm/src/test/java/org/apache/dubbo/rpc/protocol/injvm/ProtocolTest.java
+++ /dev/null
@@ -1,72 +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.rpc.protocol.injvm;
-
-import org.apache.dubbo.common.URL;
-import org.apache.dubbo.common.extension.ExtensionLoader;
-import org.apache.dubbo.rpc.Invoker;
-import org.apache.dubbo.rpc.Protocol;
-import org.apache.dubbo.rpc.ProxyFactory;
-
-import org.junit.jupiter.api.Test;
-
-import static org.hamcrest.CoreMatchers.containsString;
-import static org.hamcrest.MatcherAssert.assertThat;
-import static org.junit.jupiter.api.Assertions.assertEquals;
-
-public class ProtocolTest {
-
-    IEcho echo = new IEcho() {
-        public String echo(String e) {
-            return e;
-        }
-    };
-
-    static {
-        InjvmProtocol injvm = InjvmProtocol.getInjvmProtocol();
-    }
-
-    ProxyFactory proxyFactory = ExtensionLoader.getExtensionLoader(ProxyFactory.class).getExtension("javassist");
-
-    URL url = URL.valueOf("injvm://localhost:0/org.apache.dubbo.rpc.support.IEcho?interface=org.apache.dubbo.rpc.support.IEcho");
-
-    Invoker<IEcho> invoker = proxyFactory.getInvoker(echo, IEcho.class, url);
-
-    @Test
-    public void test_destroyWontCloseAllProtocol() throws Exception {
-        Protocol autowireProtocol = ExtensionLoader.getExtensionLoader(Protocol.class).getAdaptiveExtension();
-
-        Protocol InjvmProtocol = ExtensionLoader.getExtensionLoader(Protocol.class).getExtension("injvm");
-
-        assertEquals(0, InjvmProtocol.getDefaultPort());
-
-        InjvmProtocol.export(invoker);
-
-        Invoker<IEcho> refer = InjvmProtocol.refer(IEcho.class, url);
-        IEcho echoProxy = proxyFactory.getProxy(refer);
-
-        assertEquals("ok", echoProxy.echo("ok"));
-
-        try {
-            autowireProtocol.destroy();
-        } catch (UnsupportedOperationException expected) {
-            assertThat(expected.getMessage(), containsString("of interface org.apache.dubbo.rpc.Protocol is not adaptive method!"));
-        }
-
-        assertEquals("ok2", echoProxy.echo("ok2"));
-    }
-}
diff --git a/dubbo-spi-rpc/dubbo-rpc-injvm/src/test/java/org/apache/dubbo/rpc/protocol/injvm/Type.java b/dubbo-spi-rpc/dubbo-rpc-injvm/src/test/java/org/apache/dubbo/rpc/protocol/injvm/Type.java
deleted file mode 100644
index 4d39de6..0000000
--- a/dubbo-spi-rpc/dubbo-rpc-injvm/src/test/java/org/apache/dubbo/rpc/protocol/injvm/Type.java
+++ /dev/null
@@ -1,21 +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.rpc.protocol.injvm;
-
-public enum Type {
-    High, Normal, Lower
-}
\ No newline at end of file
diff --git a/dubbo-spi-rpc/dubbo-rpc-rest/pom.xml b/dubbo-spi-rpc/dubbo-rpc-rest/pom.xml
deleted file mode 100644
index 3f379b4..0000000
--- a/dubbo-spi-rpc/dubbo-rpc-rest/pom.xml
+++ /dev/null
@@ -1,115 +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.
--->
-<project xmlns="http://maven.apache.org/POM/4.0.0" xmlns:xsi="http://www.w3.org/2001/XMLSchema-instance" xsi:schemaLocation="http://maven.apache.org/POM/4.0.0 http://maven.apache.org/maven-v4_0_0.xsd">
-	<modelVersion>4.0.0</modelVersion>
-	<parent>
-		<groupId>org.apache.dubbo</groupId>
-		<artifactId>dubbo-rpc</artifactId>
-        <version>2.7.7-SNAPSHOT</version>
-	</parent>
-	<artifactId>dubbo-rpc-rest</artifactId>
-	<packaging>jar</packaging>
-	<name>${project.artifactId}</name>
-	<description>The JAX-RS rpc module of dubbo project</description>
-	<properties>
-        <skip_maven_deploy>false</skip_maven_deploy>
-	</properties>
-	<dependencies>
-		<dependency>
-			<groupId>org.apache.dubbo</groupId>
-			<artifactId>dubbo-rpc-api</artifactId>
-			<version>${project.parent.version}</version>
-		</dependency>
-        <dependency>
-            <groupId>org.apache.dubbo</groupId>
-            <artifactId>dubbo-remoting-http</artifactId>
-            <version>${project.parent.version}</version>
-        </dependency>
-
-        <dependency>
-            <groupId>org.jboss.resteasy</groupId>
-            <artifactId>resteasy-jaxrs</artifactId>
-        </dependency>
-
-        <dependency>
-            <groupId>org.jboss.resteasy</groupId>
-            <artifactId>resteasy-client</artifactId>
-        </dependency>
-
-        <dependency>
-            <groupId>javax.validation</groupId>
-            <artifactId>validation-api</artifactId>
-        </dependency>
-
-        <!-- optional dependencies ==================== -->
-
-        <dependency>
-            <groupId>org.jboss.resteasy</groupId>
-            <artifactId>resteasy-netty4</artifactId>
-        </dependency>
-
-        <dependency>
-            <groupId>org.jboss.resteasy</groupId>
-            <artifactId>resteasy-jdk-http</artifactId>
-        </dependency>
-
-        <dependency>
-            <groupId>org.jboss.resteasy</groupId>
-            <artifactId>resteasy-jackson-provider</artifactId>
-        </dependency>
-
-        <dependency>
-            <groupId>org.jboss.resteasy</groupId>
-            <artifactId>resteasy-jaxb-provider</artifactId>
-        </dependency>
-
-        <dependency>
-            <groupId>io.netty</groupId>
-            <artifactId>netty-all</artifactId>
-        </dependency>
-
-        <!-- swagger -->
-        <dependency>
-            <groupId>io.swagger</groupId>
-            <artifactId>swagger-annotations</artifactId>
-            <exclusions>
-                <exclusion>
-                    <groupId>javax.ws.rs</groupId>
-                    <artifactId>jsr311-api</artifactId>
-                </exclusion>
-            </exclusions>
-        </dependency>
-        <dependency>
-            <groupId>io.swagger</groupId>
-            <artifactId>swagger-jaxrs</artifactId>
-            <exclusions>
-                <exclusion>
-                    <groupId>javax.ws.rs</groupId>
-                    <artifactId>jsr311-api</artifactId>
-                </exclusion>
-            </exclusions>
-        </dependency>
-
-        <dependency>
-            <groupId>org.apache.dubbo</groupId>
-            <artifactId>dubbo-serialization-jdk</artifactId>
-            <version>${project.parent.version}</version>
-            <scope>test</scope>
-        </dependency>
-
-    </dependencies>
-</project>
\ No newline at end of file
diff --git a/dubbo-spi-rpc/dubbo-rpc-rest/src/main/java/org/apache/dubbo/rpc/protocol/rest/BaseRestProtocolServer.java b/dubbo-spi-rpc/dubbo-rpc-rest/src/main/java/org/apache/dubbo/rpc/protocol/rest/BaseRestProtocolServer.java
deleted file mode 100644
index 3621848..0000000
--- a/dubbo-spi-rpc/dubbo-rpc-rest/src/main/java/org/apache/dubbo/rpc/protocol/rest/BaseRestProtocolServer.java
+++ /dev/null
@@ -1,80 +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.rpc.protocol.rest;
-
-import org.apache.dubbo.common.URL;
-import org.apache.dubbo.common.utils.StringUtils;
-
-import org.jboss.resteasy.spi.ResteasyDeployment;
-
-import static org.apache.dubbo.common.constants.CommonConstants.COMMA_SPLIT_PATTERN;
-import static org.apache.dubbo.rpc.protocol.rest.Constants.EXTENSION_KEY;
-
-public abstract class BaseRestProtocolServer implements RestProtocolServer {
-
-    private String address;
-
-    @Override
-    public void start(URL url) {
-        getDeployment().getMediaTypeMappings().put("json", "application/json");
-        getDeployment().getMediaTypeMappings().put("xml", "text/xml");
-//        server.getDeployment().getMediaTypeMappings().put("xml", "application/xml");
-        getDeployment().getProviderClasses().add(RpcContextFilter.class.getName());
-        // TODO users can override this mapper, but we just rely on the current priority strategy of resteasy
-        getDeployment().getProviderClasses().add(RpcExceptionMapper.class.getName());
-
-        loadProviders(url.getParameter(EXTENSION_KEY, ""));
-
-        doStart(url);
-    }
-
-    @Override
-    public void deploy(Class resourceDef, Object resourceInstance, String contextPath) {
-        if (StringUtils.isEmpty(contextPath)) {
-            getDeployment().getRegistry().addResourceFactory(new DubboResourceFactory(resourceInstance, resourceDef));
-        } else {
-            getDeployment().getRegistry().addResourceFactory(new DubboResourceFactory(resourceInstance, resourceDef), contextPath);
-        }
-    }
-
-    @Override
-    public void undeploy(Class resourceDef) {
-        getDeployment().getRegistry().removeRegistrations(resourceDef);
-    }
-
-    @Override
-    public String getAddress() {
-        return address;
-    }
-
-    @Override
-    public void setAddress(String address) {
-        this.address = address;
-    }
-
-    protected void loadProviders(String value) {
-        for (String clazz : COMMA_SPLIT_PATTERN.split(value)) {
-            if (!StringUtils.isEmpty(clazz)) {
-                getDeployment().getProviderClasses().add(clazz.trim());
-            }
-        }
-    }
-
-    protected abstract ResteasyDeployment getDeployment();
-
-    protected abstract void doStart(URL url);
-}
diff --git a/dubbo-spi-rpc/dubbo-rpc-rest/src/main/java/org/apache/dubbo/rpc/protocol/rest/Constants.java b/dubbo-spi-rpc/dubbo-rpc-rest/src/main/java/org/apache/dubbo/rpc/protocol/rest/Constants.java
deleted file mode 100644
index 90747c9..0000000
--- a/dubbo-spi-rpc/dubbo-rpc-rest/src/main/java/org/apache/dubbo/rpc/protocol/rest/Constants.java
+++ /dev/null
@@ -1,29 +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.rpc.protocol.rest;
-
-/**
- *
- */
-public interface Constants {
-    String KEEP_ALIVE_KEY = "keepalive";
-
-    boolean DEFAULT_KEEP_ALIVE = true;
-
-    String EXTENSION_KEY = "extension";
-}
diff --git a/dubbo-spi-rpc/dubbo-rpc-rest/src/main/java/org/apache/dubbo/rpc/protocol/rest/DubboHttpProtocolServer.java b/dubbo-spi-rpc/dubbo-rpc-rest/src/main/java/org/apache/dubbo/rpc/protocol/rest/DubboHttpProtocolServer.java
deleted file mode 100644
index 1ab039a..0000000
--- a/dubbo-spi-rpc/dubbo-rpc-rest/src/main/java/org/apache/dubbo/rpc/protocol/rest/DubboHttpProtocolServer.java
+++ /dev/null
@@ -1,131 +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.rpc.protocol.rest;
-
-import org.apache.dubbo.common.URL;
-import org.apache.dubbo.remoting.http.HttpBinder;
-import org.apache.dubbo.remoting.http.HttpHandler;
-import org.apache.dubbo.remoting.http.HttpServer;
-import org.apache.dubbo.remoting.http.servlet.BootstrapListener;
-import org.apache.dubbo.remoting.http.servlet.ServletManager;
-import org.apache.dubbo.rpc.RpcContext;
-import org.apache.dubbo.rpc.RpcException;
-
-import org.jboss.resteasy.plugins.server.servlet.HttpServletDispatcher;
-import org.jboss.resteasy.spi.ResteasyDeployment;
-
-import javax.servlet.ServletConfig;
-import javax.servlet.ServletContext;
-import javax.servlet.ServletException;
-import javax.servlet.http.HttpServletRequest;
-import javax.servlet.http.HttpServletResponse;
-import java.io.IOException;
-import java.util.Enumeration;
-
-public class DubboHttpProtocolServer extends BaseRestProtocolServer {
-
-    private final HttpServletDispatcher dispatcher = new HttpServletDispatcher();
-    private final ResteasyDeployment deployment = new ResteasyDeployment();
-    private HttpBinder httpBinder;
-    private HttpServer httpServer;
-//    private boolean isExternalServer;
-
-    public DubboHttpProtocolServer(HttpBinder httpBinder) {
-        this.httpBinder = httpBinder;
-    }
-
-    @Override
-    protected void doStart(URL url) {
-        // TODO jetty will by default enable keepAlive so the xml config has no effect now
-        httpServer = httpBinder.bind(url, new RestHandler());
-
-        ServletContext servletContext = ServletManager.getInstance().getServletContext(url.getPort());
-        if (servletContext == null) {
-            servletContext = ServletManager.getInstance().getServletContext(ServletManager.EXTERNAL_SERVER_PORT);
-        }
-        if (servletContext == null) {
-            throw new RpcException("No servlet context found. If you are using server='servlet', " +
-                    "make sure that you've configured " + BootstrapListener.class.getName() + " in web.xml");
-        }
-
-        servletContext.setAttribute(ResteasyDeployment.class.getName(), deployment);
-
-        try {
-            dispatcher.init(new SimpleServletConfig(servletContext));
-        } catch (ServletException e) {
-            throw new RpcException(e);
-        }
-    }
-
-    @Override
-    public void close() {
-        httpServer.close();
-    }
-
-    @Override
-    protected ResteasyDeployment getDeployment() {
-        return deployment;
-    }
-
-    private class RestHandler implements HttpHandler {
-
-        @Override
-        public void handle(HttpServletRequest request, HttpServletResponse response) throws IOException, ServletException {
-            RpcContext.getContext().setRemoteAddress(request.getRemoteAddr(), request.getRemotePort());
-            dispatcher.service(request, response);
-        }
-    }
-
-    private static class SimpleServletConfig implements ServletConfig {
-
-        private final ServletContext servletContext;
-
-        public SimpleServletConfig(ServletContext servletContext) {
-            this.servletContext = servletContext;
-        }
-
-        @Override
-        public String getServletName() {
-            return "DispatcherServlet";
-        }
-
-        @Override
-        public ServletContext getServletContext() {
-            return servletContext;
-        }
-
-        @Override
-        public String getInitParameter(String s) {
-            return null;
-        }
-
-        @Override
-        public Enumeration getInitParameterNames() {
-            return new Enumeration() {
-                @Override
-                public boolean hasMoreElements() {
-                    return false;
-                }
-
-                @Override
-                public Object nextElement() {
-                    return null;
-                }
-            };
-        }
-    }
-}
diff --git a/dubbo-spi-rpc/dubbo-rpc-rest/src/main/java/org/apache/dubbo/rpc/protocol/rest/DubboResourceFactory.java b/dubbo-spi-rpc/dubbo-rpc-rest/src/main/java/org/apache/dubbo/rpc/protocol/rest/DubboResourceFactory.java
deleted file mode 100644
index 191102e..0000000
--- a/dubbo-spi-rpc/dubbo-rpc-rest/src/main/java/org/apache/dubbo/rpc/protocol/rest/DubboResourceFactory.java
+++ /dev/null
@@ -1,76 +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.rpc.protocol.rest;
-
-import org.jboss.resteasy.spi.HttpRequest;
-import org.jboss.resteasy.spi.HttpResponse;
-import org.jboss.resteasy.spi.ResourceFactory;
-import org.jboss.resteasy.spi.ResteasyProviderFactory;
-
-/**
- * We don't support propertyInjector here since the resource impl should be singleton in dubbo
- *
- */
-public class DubboResourceFactory implements ResourceFactory {
-
-    private Object resourceInstance;
-    private Class scannableClass;
-//    private PropertyInjector propertyInjector;
-//    private String context = null;
-
-    public DubboResourceFactory(Object resourceInstance, Class scannableClass) {
-        this.resourceInstance = resourceInstance;
-        this.scannableClass = scannableClass;
-    }
-
-//    public PropertyInjector getPropertyInjector() {
-//        return propertyInjector;
-//    }
-
-    @Override
-    public Object createResource(HttpRequest request, HttpResponse response,
-                                 ResteasyProviderFactory factory) {
-        return resourceInstance;
-    }
-
-    @Override
-    public Class<?> getScannableClass() {
-        return scannableClass;
-    }
-
-    @Override
-    public void registered(ResteasyProviderFactory factory) {
-//        this.propertyInjector = factory.getInjectorFactory().createPropertyInjector(getScannableClass(), factory);
-    }
-
-    @Override
-    public void requestFinished(HttpRequest request, HttpResponse response,
-                                Object resource) {
-    }
-
-    @Override
-    public void unregistered() {
-    }
-
-//    public void setContext(String context) {
-//        this.context = context;
-//    }
-//
-//    public String getContext() {
-//        return context;
-//    }
-}
diff --git a/dubbo-spi-rpc/dubbo-rpc-rest/src/main/java/org/apache/dubbo/rpc/protocol/rest/NettyRestProtocolServer.java b/dubbo-spi-rpc/dubbo-rpc-rest/src/main/java/org/apache/dubbo/rpc/protocol/rest/NettyRestProtocolServer.java
deleted file mode 100644
index b066c79..0000000
--- a/dubbo-spi-rpc/dubbo-rpc-rest/src/main/java/org/apache/dubbo/rpc/protocol/rest/NettyRestProtocolServer.java
+++ /dev/null
@@ -1,73 +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.rpc.protocol.rest;
-
-import org.apache.dubbo.common.URL;
-import org.apache.dubbo.common.utils.NetUtils;
-
-import io.netty.channel.ChannelOption;
-import org.jboss.resteasy.plugins.server.netty.NettyJaxrsServer;
-import org.jboss.resteasy.spi.ResteasyDeployment;
-
-import java.util.HashMap;
-import java.util.Map;
-
-import static org.apache.dubbo.common.constants.CommonConstants.DEFAULT_THREADS;
-import static org.apache.dubbo.common.constants.CommonConstants.IO_THREADS_KEY;
-import static org.apache.dubbo.common.constants.CommonConstants.THREADS_KEY;
-import static org.apache.dubbo.remoting.Constants.BIND_IP_KEY;
-import static org.apache.dubbo.remoting.Constants.BIND_PORT_KEY;
-import static org.apache.dubbo.remoting.Constants.DEFAULT_IO_THREADS;
-import static org.apache.dubbo.remoting.Constants.DEFAULT_PAYLOAD;
-import static org.apache.dubbo.remoting.Constants.PAYLOAD_KEY;
-import static org.apache.dubbo.rpc.protocol.rest.Constants.DEFAULT_KEEP_ALIVE;
-import static org.apache.dubbo.rpc.protocol.rest.Constants.KEEP_ALIVE_KEY;
-
-/**
- * Netty server can't support @Context injection of servlet objects since it's not a servlet container
- *
- */
-public class NettyRestProtocolServer extends BaseRestProtocolServer {
-
-    private final NettyJaxrsServer server = new NettyJaxrsServer();
-
-    @Override
-    protected void doStart(URL url) {
-        String bindIp = url.getParameter(BIND_IP_KEY, url.getHost());
-        if (!url.isAnyHost() && NetUtils.isValidLocalHost(bindIp)) {
-            server.setHostname(bindIp);
-        }
-        server.setPort(url.getParameter(BIND_PORT_KEY, url.getPort()));
-        Map<ChannelOption, Object> channelOption = new HashMap<ChannelOption, Object>();
-        channelOption.put(ChannelOption.SO_KEEPALIVE, url.getParameter(KEEP_ALIVE_KEY, DEFAULT_KEEP_ALIVE));
-        server.setChildChannelOptions(channelOption);
-        server.setExecutorThreadCount(url.getParameter(THREADS_KEY, DEFAULT_THREADS));
-        server.setIoWorkerCount(url.getParameter(IO_THREADS_KEY, DEFAULT_IO_THREADS));
-        server.setMaxRequestSize(url.getParameter(PAYLOAD_KEY, DEFAULT_PAYLOAD));
-        server.start();
-    }
-
-    @Override
-    public void close() {
-        server.stop();
-    }
-
-    @Override
-    protected ResteasyDeployment getDeployment() {
-        return server.getDeployment();
-    }
-}
diff --git a/dubbo-spi-rpc/dubbo-rpc-rest/src/main/java/org/apache/dubbo/rpc/protocol/rest/RestConstraintViolation.java b/dubbo-spi-rpc/dubbo-rpc-rest/src/main/java/org/apache/dubbo/rpc/protocol/rest/RestConstraintViolation.java
deleted file mode 100644
index f229773..0000000
--- a/dubbo-spi-rpc/dubbo-rpc-rest/src/main/java/org/apache/dubbo/rpc/protocol/rest/RestConstraintViolation.java
+++ /dev/null
@@ -1,66 +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.rpc.protocol.rest;
-
-import javax.xml.bind.annotation.XmlAccessType;
-import javax.xml.bind.annotation.XmlAccessorType;
-import javax.xml.bind.annotation.XmlRootElement;
-import java.io.Serializable;
-
-@XmlRootElement(name = "constraintViolation")
-@XmlAccessorType(XmlAccessType.FIELD)
-public class RestConstraintViolation implements Serializable {
-
-    private static final long serialVersionUID = -23497234978L;
-
-    private String path;
-    private String message;
-    private String value;
-
-    public RestConstraintViolation(String path, String message, String value) {
-        this.path = path;
-        this.message = message;
-        this.value = value;
-    }
-
-    public RestConstraintViolation() {
-    }
-
-    public String getPath() {
-        return path;
-    }
-
-    public void setPath(String path) {
-        this.path = path;
-    }
-
-    public String getMessage() {
-        return message;
-    }
-
-    public void setMessage(String message) {
-        this.message = message;
-    }
-
-    public String getValue() {
-        return value;
-    }
-
-    public void setValue(String value) {
-        this.value = value;
-    }
-}
diff --git a/dubbo-spi-rpc/dubbo-rpc-rest/src/main/java/org/apache/dubbo/rpc/protocol/rest/RestProtocol.java b/dubbo-spi-rpc/dubbo-rpc-rest/src/main/java/org/apache/dubbo/rpc/protocol/rest/RestProtocol.java
deleted file mode 100644
index 7e22132..0000000
--- a/dubbo-spi-rpc/dubbo-rpc-rest/src/main/java/org/apache/dubbo/rpc/protocol/rest/RestProtocol.java
+++ /dev/null
@@ -1,295 +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.rpc.protocol.rest;
-
-import org.apache.dubbo.common.URL;
-import org.apache.dubbo.common.utils.StringUtils;
-import org.apache.dubbo.remoting.http.HttpBinder;
-import org.apache.dubbo.remoting.http.servlet.BootstrapListener;
-import org.apache.dubbo.remoting.http.servlet.ServletManager;
-import org.apache.dubbo.rpc.ProtocolServer;
-import org.apache.dubbo.rpc.RpcException;
-import org.apache.dubbo.rpc.model.ApplicationModel;
-import org.apache.dubbo.rpc.protocol.AbstractProxyProtocol;
-
-import org.apache.http.HeaderElement;
-import org.apache.http.HeaderElementIterator;
-import org.apache.http.client.config.RequestConfig;
-import org.apache.http.config.SocketConfig;
-import org.apache.http.impl.client.CloseableHttpClient;
-import org.apache.http.impl.client.HttpClientBuilder;
-import org.apache.http.impl.conn.PoolingHttpClientConnectionManager;
-import org.apache.http.message.BasicHeaderElementIterator;
-import org.apache.http.protocol.HTTP;
-import org.jboss.resteasy.client.jaxrs.ResteasyClient;
-import org.jboss.resteasy.client.jaxrs.ResteasyClientBuilder;
-import org.jboss.resteasy.client.jaxrs.ResteasyWebTarget;
-import org.jboss.resteasy.client.jaxrs.engines.ApacheHttpClient4Engine;
-import org.jboss.resteasy.util.GetRestful;
-
-import javax.servlet.ServletContext;
-import javax.ws.rs.ProcessingException;
-import javax.ws.rs.WebApplicationException;
-import java.util.Collections;
-import java.util.LinkedList;
-import java.util.List;
-import java.util.Map;
-import java.util.concurrent.TimeUnit;
-
-import static org.apache.dubbo.common.constants.CommonConstants.COMMA_SPLIT_PATTERN;
-import static org.apache.dubbo.common.constants.CommonConstants.DEFAULT_TIMEOUT;
-import static org.apache.dubbo.common.constants.CommonConstants.INTERFACE_KEY;
-import static org.apache.dubbo.common.constants.CommonConstants.TIMEOUT_KEY;
-import static org.apache.dubbo.remoting.Constants.CONNECTIONS_KEY;
-import static org.apache.dubbo.remoting.Constants.CONNECT_TIMEOUT_KEY;
-import static org.apache.dubbo.remoting.Constants.DEFAULT_CONNECT_TIMEOUT;
-import static org.apache.dubbo.remoting.Constants.SERVER_KEY;
-import static org.apache.dubbo.rpc.protocol.rest.Constants.EXTENSION_KEY;
-
-public class RestProtocol extends AbstractProxyProtocol {
-
-    private static final int DEFAULT_PORT = 80;
-    private static final String DEFAULT_SERVER = "jetty";
-
-    private static final int HTTPCLIENTCONNECTIONMANAGER_MAXPERROUTE = 20;
-    private static final int HTTPCLIENTCONNECTIONMANAGER_MAXTOTAL = 20;
-    private static final int HTTPCLIENT_KEEPALIVEDURATION = 30 * 1000;
-    private static final int HTTPCLIENTCONNECTIONMANAGER_CLOSEWAITTIME_MS = 1000;
-    private static final int HTTPCLIENTCONNECTIONMANAGER_CLOSEIDLETIME_S = 30;
-
-    private final RestServerFactory serverFactory = new RestServerFactory();
-
-    // TODO in the future maybe we can just use a single rest client and connection manager
-    private final List<ResteasyClient> clients = Collections.synchronizedList(new LinkedList<>());
-
-    private volatile ConnectionMonitor connectionMonitor;
-
-    public RestProtocol() {
-        super(WebApplicationException.class, ProcessingException.class);
-    }
-
-    public void setHttpBinder(HttpBinder httpBinder) {
-        serverFactory.setHttpBinder(httpBinder);
-    }
-
-    @Override
-    public int getDefaultPort() {
-        return DEFAULT_PORT;
-    }
-
-    @Override
-    protected <T> Runnable doExport(T impl, Class<T> type, URL url) throws RpcException {
-        String addr = getAddr(url);
-        Class implClass = ApplicationModel.getProviderModel(url.getServiceKey()).getServiceInstance().getClass();
-        RestProtocolServer server = (RestProtocolServer) serverMap.computeIfAbsent(addr, restServer -> {
-            RestProtocolServer s = serverFactory.createServer(url.getParameter(SERVER_KEY, DEFAULT_SERVER));
-            s.setAddress(url.getAddress());
-            s.start(url);
-            return s;
-        });
-
-        String contextPath = getContextPath(url);
-        if ("servlet".equalsIgnoreCase(url.getParameter(SERVER_KEY, DEFAULT_SERVER))) {
-            ServletContext servletContext = ServletManager.getInstance().getServletContext(ServletManager.EXTERNAL_SERVER_PORT);
-            if (servletContext == null) {
-                throw new RpcException("No servlet context found. Since you are using server='servlet', " +
-                        "make sure that you've configured " + BootstrapListener.class.getName() + " in web.xml");
-            }
-            String webappPath = servletContext.getContextPath();
-            if (StringUtils.isNotEmpty(webappPath)) {
-                webappPath = webappPath.substring(1);
-                if (!contextPath.startsWith(webappPath)) {
-                    throw new RpcException("Since you are using server='servlet', " +
-                            "make sure that the 'contextpath' property starts with the path of external webapp");
-                }
-                contextPath = contextPath.substring(webappPath.length());
-                if (contextPath.startsWith("/")) {
-                    contextPath = contextPath.substring(1);
-                }
-            }
-        }
-
-        final Class resourceDef = GetRestful.getRootResourceClass(implClass) != null ? implClass : type;
-
-        server.deploy(resourceDef, impl, contextPath);
-
-        final RestProtocolServer s = server;
-        return () -> {
-            // TODO due to dubbo's current architecture,
-            // it will be called from registry protocol in the shutdown process and won't appear in logs
-            s.undeploy(resourceDef);
-        };
-    }
-
-    @Override
-    protected <T> T doRefer(Class<T> serviceType, URL url) throws RpcException {
-
-        // TODO more configs to add
-        PoolingHttpClientConnectionManager connectionManager = new PoolingHttpClientConnectionManager();
-        // 20 is the default maxTotal of current PoolingClientConnectionManager
-        connectionManager.setMaxTotal(url.getParameter(CONNECTIONS_KEY, HTTPCLIENTCONNECTIONMANAGER_MAXTOTAL));
-        connectionManager.setDefaultMaxPerRoute(url.getParameter(CONNECTIONS_KEY, HTTPCLIENTCONNECTIONMANAGER_MAXPERROUTE));
-
-        if (connectionMonitor == null) {
-            connectionMonitor = new ConnectionMonitor();
-            connectionMonitor.start();
-        }
-        connectionMonitor.addConnectionManager(connectionManager);
-        RequestConfig requestConfig = RequestConfig.custom()
-                .setConnectTimeout(url.getParameter(CONNECT_TIMEOUT_KEY, DEFAULT_CONNECT_TIMEOUT))
-                .setSocketTimeout(url.getParameter(TIMEOUT_KEY, DEFAULT_TIMEOUT))
-                .build();
-
-        SocketConfig socketConfig = SocketConfig.custom()
-                .setSoKeepAlive(true)
-                .setTcpNoDelay(true)
-                .build();
-
-        CloseableHttpClient httpClient = HttpClientBuilder.create()
-                .setConnectionManager(connectionManager)
-                .setKeepAliveStrategy((response, context) -> {
-                    HeaderElementIterator it = new BasicHeaderElementIterator(response.headerIterator(HTTP.CONN_KEEP_ALIVE));
-                    while (it.hasNext()) {
-                        HeaderElement he = it.nextElement();
-                        String param = he.getName();
-                        String value = he.getValue();
-                        if (value != null && param.equalsIgnoreCase(TIMEOUT_KEY)) {
-                            return Long.parseLong(value) * 1000;
-                        }
-                    }
-                    return HTTPCLIENT_KEEPALIVEDURATION;
-                })
-                .setDefaultRequestConfig(requestConfig)
-                .setDefaultSocketConfig(socketConfig)
-                .build();
-
-        ApacheHttpClient4Engine engine = new ApacheHttpClient4Engine(httpClient/*, localContext*/);
-
-        ResteasyClient client = new ResteasyClientBuilder().httpEngine(engine).build();
-        clients.add(client);
-
-        client.register(RpcContextFilter.class);
-        for (String clazz : COMMA_SPLIT_PATTERN.split(url.getParameter(EXTENSION_KEY, ""))) {
-            if (!StringUtils.isEmpty(clazz)) {
-                try {
-                    client.register(Thread.currentThread().getContextClassLoader().loadClass(clazz.trim()));
-                } catch (ClassNotFoundException e) {
-                    throw new RpcException("Error loading JAX-RS extension class: " + clazz.trim(), e);
-                }
-            }
-        }
-
-        // TODO protocol
-        ResteasyWebTarget target = client.target("http://" + url.getHost() + ":" + url.getPort() + "/" + getContextPath(url));
-        return target.proxy(serviceType);
-    }
-
-    @Override
-    protected int getErrorCode(Throwable e) {
-        // TODO
-        return super.getErrorCode(e);
-    }
-
-    @Override
-    public void destroy() {
-        super.destroy();
-
-        if (connectionMonitor != null) {
-            connectionMonitor.shutdown();
-        }
-
-        for (Map.Entry<String, ProtocolServer> entry : serverMap.entrySet()) {
-            try {
-                if (logger.isInfoEnabled()) {
-                    logger.info("Closing the rest server at " + entry.getKey());
-                }
-                entry.getValue().close();
-            } catch (Throwable t) {
-                logger.warn("Error closing rest server", t);
-            }
-        }
-        serverMap.clear();
-
-        if (logger.isInfoEnabled()) {
-            logger.info("Closing rest clients");
-        }
-        for (ResteasyClient client : clients) {
-            try {
-                client.close();
-            } catch (Throwable t) {
-                logger.warn("Error closing rest client", t);
-            }
-        }
-        clients.clear();
-    }
-
-    /**
-     *  getPath() will return: [contextpath + "/" +] path
-     *  1. contextpath is empty if user does not set through ProtocolConfig or ProviderConfig
-     *  2. path will never be empty, it's default value is the interface name.
-     *
-     * @return return path only if user has explicitly gave then a value.
-     */
-    protected String getContextPath(URL url) {
-        String contextPath = url.getPath();
-        if (contextPath != null) {
-            if (contextPath.equalsIgnoreCase(url.getParameter(INTERFACE_KEY))) {
-                return "";
-            }
-            if (contextPath.endsWith(url.getParameter(INTERFACE_KEY))) {
-                contextPath = contextPath.substring(0, contextPath.lastIndexOf(url.getParameter(INTERFACE_KEY)));
-            }
-            return contextPath.endsWith("/") ? contextPath.substring(0, contextPath.length() - 1) : contextPath;
-        } else {
-            return "";
-        }
-    }
-
-    protected class ConnectionMonitor extends Thread {
-        private volatile boolean shutdown;
-        private final List<PoolingHttpClientConnectionManager> connectionManagers = Collections.synchronizedList(new LinkedList<>());
-
-        public void addConnectionManager(PoolingHttpClientConnectionManager connectionManager) {
-            connectionManagers.add(connectionManager);
-        }
-
-        @Override
-        public void run() {
-            try {
-                while (!shutdown) {
-                    synchronized (this) {
-                        wait(HTTPCLIENTCONNECTIONMANAGER_CLOSEWAITTIME_MS);
-                        for (PoolingHttpClientConnectionManager connectionManager : connectionManagers) {
-                            connectionManager.closeExpiredConnections();
-                            connectionManager.closeIdleConnections(HTTPCLIENTCONNECTIONMANAGER_CLOSEIDLETIME_S, TimeUnit.SECONDS);
-                        }
-                    }
-                }
-            } catch (InterruptedException ex) {
-                shutdown();
-            }
-        }
-
-        public void shutdown() {
-            shutdown = true;
-            connectionManagers.clear();
-            synchronized (this) {
-                notifyAll();
-            }
-        }
-    }
-}
diff --git a/dubbo-spi-rpc/dubbo-rpc-rest/src/main/java/org/apache/dubbo/rpc/protocol/rest/RestProtocolServer.java b/dubbo-spi-rpc/dubbo-rpc-rest/src/main/java/org/apache/dubbo/rpc/protocol/rest/RestProtocolServer.java
deleted file mode 100644
index fe16f46..0000000
--- a/dubbo-spi-rpc/dubbo-rpc-rest/src/main/java/org/apache/dubbo/rpc/protocol/rest/RestProtocolServer.java
+++ /dev/null
@@ -1,33 +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.rpc.protocol.rest;
-
-import org.apache.dubbo.common.URL;
-import org.apache.dubbo.rpc.ProtocolServer;
-
-public interface RestProtocolServer extends ProtocolServer {
-
-    void start(URL url);
-
-    /**
-     * @param resourceDef it could be either resource interface or resource impl
-     */
-    void deploy(Class resourceDef, Object resourceInstance, String contextPath);
-
-    void undeploy(Class resourceDef);
-
-}
diff --git a/dubbo-spi-rpc/dubbo-rpc-rest/src/main/java/org/apache/dubbo/rpc/protocol/rest/RestServerFactory.java b/dubbo-spi-rpc/dubbo-rpc-rest/src/main/java/org/apache/dubbo/rpc/protocol/rest/RestServerFactory.java
deleted file mode 100644
index 6fcf7f6..0000000
--- a/dubbo-spi-rpc/dubbo-rpc-rest/src/main/java/org/apache/dubbo/rpc/protocol/rest/RestServerFactory.java
+++ /dev/null
@@ -1,44 +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.rpc.protocol.rest;
-
-import org.apache.dubbo.remoting.http.HttpBinder;
-
-/**
- * Only the server that implements servlet container
- * could support something like @Context injection of servlet objects.
- *
- */
-public class RestServerFactory {
-
-    private HttpBinder httpBinder;
-
-    public void setHttpBinder(HttpBinder httpBinder) {
-        this.httpBinder = httpBinder;
-    }
-
-    public RestProtocolServer createServer(String name) {
-        // TODO move names to Constants
-        if ("servlet".equalsIgnoreCase(name) || "jetty".equalsIgnoreCase(name) || "tomcat".equalsIgnoreCase(name)) {
-            return new DubboHttpProtocolServer(httpBinder);
-        } else if ("netty".equalsIgnoreCase(name)) {
-            return new NettyRestProtocolServer();
-        } else {
-            throw new IllegalArgumentException("Unrecognized server name: " + name);
-        }
-    }
-}
diff --git a/dubbo-spi-rpc/dubbo-rpc-rest/src/main/java/org/apache/dubbo/rpc/protocol/rest/RpcContextFilter.java b/dubbo-spi-rpc/dubbo-rpc-rest/src/main/java/org/apache/dubbo/rpc/protocol/rest/RpcContextFilter.java
deleted file mode 100644
index 1711181..0000000
--- a/dubbo-spi-rpc/dubbo-rpc-rest/src/main/java/org/apache/dubbo/rpc/protocol/rest/RpcContextFilter.java
+++ /dev/null
@@ -1,106 +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.rpc.protocol.rest;
-
-import org.apache.dubbo.common.utils.StringUtils;
-import org.apache.dubbo.rpc.RpcContext;
-
-import org.jboss.resteasy.spi.ResteasyProviderFactory;
-
-import javax.annotation.Priority;
-import javax.servlet.http.HttpServletRequest;
-import javax.servlet.http.HttpServletResponse;
-import javax.ws.rs.client.ClientRequestContext;
-import javax.ws.rs.client.ClientRequestFilter;
-import javax.ws.rs.container.ContainerRequestContext;
-import javax.ws.rs.container.ContainerRequestFilter;
-import java.io.IOException;
-import java.nio.charset.StandardCharsets;
-import java.util.Map;
-
-@Priority(Integer.MIN_VALUE + 1)
-public class RpcContextFilter implements ContainerRequestFilter, ClientRequestFilter {
-
-    private static final String DUBBO_ATTACHMENT_HEADER = "Dubbo-Attachments";
-
-    // currently we use a single header to hold the attachments so that the total attachment size limit is about 8k
-    private static final int MAX_HEADER_SIZE = 8 * 1024;
-
-    @Override
-    public void filter(ContainerRequestContext requestContext) throws IOException {
-        HttpServletRequest request = ResteasyProviderFactory.getContextData(HttpServletRequest.class);
-        RpcContext.getContext().setRequest(request);
-
-        // this only works for servlet containers
-        if (request != null && RpcContext.getContext().getRemoteAddress() == null) {
-            RpcContext.getContext().setRemoteAddress(request.getRemoteAddr(), request.getRemotePort());
-        }
-
-        RpcContext.getContext().setResponse(ResteasyProviderFactory.getContextData(HttpServletResponse.class));
-
-        String headers = requestContext.getHeaderString(DUBBO_ATTACHMENT_HEADER);
-        if (headers != null) {
-            for (String header : headers.split(",")) {
-                int index = header.indexOf("=");
-                if (index > 0) {
-                    String key = header.substring(0, index);
-                    String value = header.substring(index + 1);
-                    if (!StringUtils.isEmpty(key)) {
-                        RpcContext.getContext().setAttachment(key.trim(), value.trim());
-                    }
-                }
-            }
-        }
-    }
-
-    @Override
-    public void filter(ClientRequestContext requestContext) throws IOException {
-        int size = 0;
-        for (Map.Entry<String, Object> entry : RpcContext.getContext().getObjectAttachments().entrySet()) {
-            String key = entry.getKey();
-            String value = (String) entry.getValue();
-            if (illegalHttpHeaderKey(key) || illegalHttpHeaderValue(value)) {
-                throw new IllegalArgumentException("The attachments of " + RpcContext.class.getSimpleName() + " must not contain ',' or '=' when using rest protocol");
-            }
-
-            // TODO for now we don't consider the differences of encoding and server limit
-            if (value != null) {
-                size += value.getBytes(StandardCharsets.UTF_8).length;
-            }
-            if (size > MAX_HEADER_SIZE) {
-                throw new IllegalArgumentException("The attachments of " + RpcContext.class.getSimpleName() + " is too big");
-            }
-
-            String attachments = key + "=" + value;
-            requestContext.getHeaders().add(DUBBO_ATTACHMENT_HEADER, attachments);
-        }
-    }
-
-    private boolean illegalHttpHeaderKey(String key) {
-        if (StringUtils.isNotEmpty(key)) {
-            return key.contains(",") || key.contains("=");
-        }
-        return false;
-    }
-
-    private boolean illegalHttpHeaderValue(String value) {
-        if (StringUtils.isNotEmpty(value)) {
-            return value.contains(",");
-        }
-        return false;
-    }
-}
diff --git a/dubbo-spi-rpc/dubbo-rpc-rest/src/main/java/org/apache/dubbo/rpc/protocol/rest/RpcExceptionMapper.java b/dubbo-spi-rpc/dubbo-rpc-rest/src/main/java/org/apache/dubbo/rpc/protocol/rest/RpcExceptionMapper.java
deleted file mode 100644
index e0fb782..0000000
--- a/dubbo-spi-rpc/dubbo-rpc-rest/src/main/java/org/apache/dubbo/rpc/protocol/rest/RpcExceptionMapper.java
+++ /dev/null
@@ -1,51 +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.rpc.protocol.rest;
-
-import org.apache.dubbo.rpc.RpcException;
-import org.apache.dubbo.rpc.protocol.rest.support.ContentType;
-
-import javax.validation.ConstraintViolation;
-import javax.validation.ConstraintViolationException;
-import javax.ws.rs.core.Response;
-import javax.ws.rs.ext.ExceptionMapper;
-
-public class RpcExceptionMapper implements ExceptionMapper<RpcException> {
-
-    @Override
-    public Response toResponse(RpcException e) {
-        // TODO do more sophisticated exception handling and output
-        if (e.getCause() instanceof ConstraintViolationException) {
-            return handleConstraintViolationException((ConstraintViolationException) e.getCause());
-        }
-        // we may want to avoid exposing the dubbo exception details to certain clients
-        // TODO for now just do plain text output
-        return Response.status(Response.Status.INTERNAL_SERVER_ERROR).entity("Internal server error: " + e.getMessage()).type(ContentType.TEXT_PLAIN_UTF_8).build();
-    }
-
-    protected Response handleConstraintViolationException(ConstraintViolationException cve) {
-        ViolationReport report = new ViolationReport();
-        for (ConstraintViolation cv : cve.getConstraintViolations()) {
-            report.addConstraintViolation(new RestConstraintViolation(
-                    cv.getPropertyPath().toString(),
-                    cv.getMessage(),
-                    cv.getInvalidValue() == null ? "null" : cv.getInvalidValue().toString()));
-        }
-        // TODO for now just do xml output
-        return Response.status(Response.Status.INTERNAL_SERVER_ERROR).entity(report).type(ContentType.TEXT_XML_UTF_8).build();
-    }
-}
diff --git a/dubbo-spi-rpc/dubbo-rpc-rest/src/main/java/org/apache/dubbo/rpc/protocol/rest/ViolationReport.java b/dubbo-spi-rpc/dubbo-rpc-rest/src/main/java/org/apache/dubbo/rpc/protocol/rest/ViolationReport.java
deleted file mode 100644
index 1d53460..0000000
--- a/dubbo-spi-rpc/dubbo-rpc-rest/src/main/java/org/apache/dubbo/rpc/protocol/rest/ViolationReport.java
+++ /dev/null
@@ -1,48 +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.rpc.protocol.rest;
-
-import javax.xml.bind.annotation.XmlAccessType;
-import javax.xml.bind.annotation.XmlAccessorType;
-import javax.xml.bind.annotation.XmlRootElement;
-import java.io.Serializable;
-import java.util.LinkedList;
-import java.util.List;
-
-@XmlRootElement(name="violationReport")
-@XmlAccessorType(XmlAccessType.FIELD)
-public class ViolationReport implements Serializable {
-
-    private static final long serialVersionUID = -130498234L;
-
-    private List<RestConstraintViolation> constraintViolations;
-
-    public List<RestConstraintViolation> getConstraintViolations() {
-        return constraintViolations;
-    }
-
-    public void setConstraintViolations(List<RestConstraintViolation> constraintViolations) {
-        this.constraintViolations = constraintViolations;
-    }
-
-    public void addConstraintViolation(RestConstraintViolation constraintViolation) {
-        if (constraintViolations == null) {
-            constraintViolations = new LinkedList<RestConstraintViolation>();
-        }
-        constraintViolations.add(constraintViolation);
-    }
-}
diff --git a/dubbo-spi-rpc/dubbo-rpc-rest/src/main/java/org/apache/dubbo/rpc/protocol/rest/integration/swagger/DubboSwaggerApiListingResource.java b/dubbo-spi-rpc/dubbo-rpc-rest/src/main/java/org/apache/dubbo/rpc/protocol/rest/integration/swagger/DubboSwaggerApiListingResource.java
deleted file mode 100644
index 41b8ff5..0000000
--- a/dubbo-spi-rpc/dubbo-rpc-rest/src/main/java/org/apache/dubbo/rpc/protocol/rest/integration/swagger/DubboSwaggerApiListingResource.java
+++ /dev/null
@@ -1,48 +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.rpc.protocol.rest.integration.swagger;
-
-import org.apache.dubbo.config.annotation.Service;
-
-import com.fasterxml.jackson.core.JsonProcessingException;
-import io.swagger.jaxrs.listing.BaseApiListingResource;
-
-import javax.servlet.ServletConfig;
-import javax.servlet.ServletContext;
-import javax.ws.rs.core.Application;
-import javax.ws.rs.core.Context;
-import javax.ws.rs.core.HttpHeaders;
-import javax.ws.rs.core.Response;
-import javax.ws.rs.core.UriInfo;
-
-@Service
-public class DubboSwaggerApiListingResource extends BaseApiListingResource implements DubboSwaggerService {
-
-    @Context
-    ServletContext context;
-
-    @Override
-    public Response getListingJson(Application app, ServletConfig sc,
-                                   HttpHeaders headers, UriInfo uriInfo)  throws JsonProcessingException {
-        Response response =  getListingJsonResponse(app, context, sc, headers, uriInfo);
-        response.getHeaders().add("Access-Control-Allow-Origin", "*");
-        response.getHeaders().add("Access-Control-Allow-Headers", "x-requested-with, ssi-token");
-        response.getHeaders().add("Access-Control-Max-Age", "3600");
-        response.getHeaders().add("Access-Control-Allow-Methods","GET,POST,PUT,DELETE,OPTIONS");
-        return response;
-    }
-}
\ No newline at end of file
diff --git a/dubbo-spi-rpc/dubbo-rpc-rest/src/main/java/org/apache/dubbo/rpc/protocol/rest/integration/swagger/DubboSwaggerService.java b/dubbo-spi-rpc/dubbo-rpc-rest/src/main/java/org/apache/dubbo/rpc/protocol/rest/integration/swagger/DubboSwaggerService.java
deleted file mode 100644
index bc3eae8..0000000
--- a/dubbo-spi-rpc/dubbo-rpc-rest/src/main/java/org/apache/dubbo/rpc/protocol/rest/integration/swagger/DubboSwaggerService.java
+++ /dev/null
@@ -1,43 +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.rpc.protocol.rest.integration.swagger;
-
-import com.fasterxml.jackson.core.JsonProcessingException;
-
-import javax.servlet.ServletConfig;
-import javax.ws.rs.Consumes;
-import javax.ws.rs.GET;
-import javax.ws.rs.Path;
-import javax.ws.rs.Produces;
-import javax.ws.rs.core.Application;
-import javax.ws.rs.core.Context;
-import javax.ws.rs.core.HttpHeaders;
-import javax.ws.rs.core.MediaType;
-import javax.ws.rs.core.Response;
-import javax.ws.rs.core.UriInfo;
-
-
-@Path("dubbo")
-@Consumes({MediaType.APPLICATION_JSON, MediaType.TEXT_XML})
-@Produces({MediaType.APPLICATION_JSON + "; " + "charset=UTF-8", MediaType.TEXT_XML + "; " + "charset=UTF-8"})
-public interface DubboSwaggerService {
-
-    @GET
-    @Path("swagger")
-    Response getListingJson(@Context Application app, @Context ServletConfig sc,
-                            @Context HttpHeaders headers, @Context UriInfo uriInfo) throws JsonProcessingException;
-}
\ No newline at end of file
diff --git a/dubbo-spi-rpc/dubbo-rpc-rest/src/main/java/org/apache/dubbo/rpc/protocol/rest/support/ContentType.java b/dubbo-spi-rpc/dubbo-rpc-rest/src/main/java/org/apache/dubbo/rpc/protocol/rest/support/ContentType.java
deleted file mode 100644
index 1457966..0000000
--- a/dubbo-spi-rpc/dubbo-rpc-rest/src/main/java/org/apache/dubbo/rpc/protocol/rest/support/ContentType.java
+++ /dev/null
@@ -1,26 +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.rpc.protocol.rest.support;
-
-import javax.ws.rs.core.MediaType;
-
-public class ContentType {
-
-    public static final String APPLICATION_JSON_UTF_8 = MediaType.APPLICATION_JSON + "; " + MediaType.CHARSET_PARAMETER + "=UTF-8";
-    public static final String TEXT_XML_UTF_8 = MediaType.TEXT_XML + "; " + MediaType.CHARSET_PARAMETER + "=UTF-8";
-    public static final String TEXT_PLAIN_UTF_8 = MediaType.TEXT_PLAIN + "; " + MediaType.CHARSET_PARAMETER + "=UTF-8";
-}
diff --git a/dubbo-spi-rpc/dubbo-rpc-rest/src/main/java/org/apache/dubbo/rpc/protocol/rest/support/LoggingFilter.java b/dubbo-spi-rpc/dubbo-rpc-rest/src/main/java/org/apache/dubbo/rpc/protocol/rest/support/LoggingFilter.java
deleted file mode 100644
index 62c168e..0000000
--- a/dubbo-spi-rpc/dubbo-rpc-rest/src/main/java/org/apache/dubbo/rpc/protocol/rest/support/LoggingFilter.java
+++ /dev/null
@@ -1,148 +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.rpc.protocol.rest.support;
-
-import org.apache.dubbo.common.logger.Logger;
-import org.apache.dubbo.common.logger.LoggerFactory;
-
-import org.apache.commons.io.IOUtils;
-
-import javax.annotation.Priority;
-import javax.ws.rs.WebApplicationException;
-import javax.ws.rs.client.ClientRequestContext;
-import javax.ws.rs.client.ClientRequestFilter;
-import javax.ws.rs.client.ClientResponseContext;
-import javax.ws.rs.client.ClientResponseFilter;
-import javax.ws.rs.container.ContainerRequestContext;
-import javax.ws.rs.container.ContainerRequestFilter;
-import javax.ws.rs.container.ContainerResponseContext;
-import javax.ws.rs.container.ContainerResponseFilter;
-import javax.ws.rs.core.MultivaluedMap;
-import javax.ws.rs.ext.ReaderInterceptor;
-import javax.ws.rs.ext.ReaderInterceptorContext;
-import javax.ws.rs.ext.WriterInterceptor;
-import javax.ws.rs.ext.WriterInterceptorContext;
-import java.io.ByteArrayInputStream;
-import java.io.ByteArrayOutputStream;
-import java.io.IOException;
-import java.io.OutputStream;
-import java.nio.charset.StandardCharsets;
-import java.util.List;
-import java.util.Map;
-
-/**
- * This logging filter is not highly optimized for now
- *
- */
-@Priority(Integer.MIN_VALUE)
-public class LoggingFilter implements ContainerRequestFilter, ClientRequestFilter, ContainerResponseFilter, ClientResponseFilter, WriterInterceptor, ReaderInterceptor {
-
-    private static final Logger logger = LoggerFactory.getLogger(LoggingFilter.class);
-
-    @Override
-    public void filter(ClientRequestContext context) throws IOException {
-        logHttpHeaders(context.getStringHeaders());
-    }
-
-    @Override
-    public void filter(ClientRequestContext requestContext, ClientResponseContext responseContext) throws IOException {
-        logHttpHeaders(responseContext.getHeaders());
-    }
-
-    @Override
-    public void filter(ContainerRequestContext context) throws IOException {
-        logHttpHeaders(context.getHeaders());
-    }
-
-    @Override
-    public void filter(ContainerRequestContext requestContext, ContainerResponseContext responseContext) throws IOException {
-        logHttpHeaders(responseContext.getStringHeaders());
-    }
-
-    @Override
-    public Object aroundReadFrom(ReaderInterceptorContext context) throws IOException, WebApplicationException {
-        byte[] buffer = IOUtils.toByteArray(context.getInputStream());
-        logger.info("The contents of request body is: \n" + new String(buffer, StandardCharsets.UTF_8) + "\n");
-        context.setInputStream(new ByteArrayInputStream(buffer));
-        return context.proceed();
-    }
-
-    @Override
-    public void aroundWriteTo(WriterInterceptorContext context) throws IOException, WebApplicationException {
-        OutputStreamWrapper wrapper = new OutputStreamWrapper(context.getOutputStream());
-        context.setOutputStream(wrapper);
-        context.proceed();
-        logger.info("The contents of response body is: \n" + new String(wrapper.getBytes(), StandardCharsets.UTF_8) + "\n");
-    }
-
-    protected void logHttpHeaders(MultivaluedMap<String, String> headers) {
-        StringBuilder msg = new StringBuilder("The HTTP headers are: \n");
-        for (Map.Entry<String, List<String>> entry : headers.entrySet()) {
-            msg.append(entry.getKey()).append(": ");
-            for (int i = 0; i < entry.getValue().size(); i++) {
-                msg.append(entry.getValue().get(i));
-                if (i < entry.getValue().size() - 1) {
-                    msg.append(", ");
-                }
-            }
-            msg.append("\n");
-        }
-        logger.info(msg.toString());
-    }
-
-    protected static class OutputStreamWrapper extends OutputStream {
-
-        private final ByteArrayOutputStream buffer = new ByteArrayOutputStream();
-        private final OutputStream output;
-
-        private OutputStreamWrapper(OutputStream output) {
-            this.output = output;
-        }
-
-        @Override
-        public void write(int i) throws IOException {
-            buffer.write(i);
-            output.write(i);
-        }
-
-        @Override
-        public void write(byte[] b) throws IOException {
-            buffer.write(b);
-            output.write(b);
-        }
-
-        @Override
-        public void write(byte[] b, int off, int len) throws IOException {
-            buffer.write(b, off, len);
-            output.write(b, off, len);
-        }
-
-        @Override
-        public void flush() throws IOException {
-            output.flush();
-        }
-
-        @Override
-        public void close() throws IOException {
-            output.close();
-        }
-
-        public byte[] getBytes() {
-            return buffer.toByteArray();
-        }
-    }
-}
diff --git a/dubbo-spi-rpc/dubbo-rpc-rest/src/main/resources/META-INF/dubbo/internal/org.apache.dubbo.rpc.Protocol b/dubbo-spi-rpc/dubbo-rpc-rest/src/main/resources/META-INF/dubbo/internal/org.apache.dubbo.rpc.Protocol
deleted file mode 100644
index d492da9..0000000
--- a/dubbo-spi-rpc/dubbo-rpc-rest/src/main/resources/META-INF/dubbo/internal/org.apache.dubbo.rpc.Protocol
+++ /dev/null
@@ -1 +0,0 @@
-rest=org.apache.dubbo.rpc.protocol.rest.RestProtocol
\ No newline at end of file
diff --git a/dubbo-spi-rpc/dubbo-rpc-rest/src/test/java/org/apache/dubbo/rpc/protocol/rest/DemoService.java b/dubbo-spi-rpc/dubbo-rpc-rest/src/test/java/org/apache/dubbo/rpc/protocol/rest/DemoService.java
deleted file mode 100644
index 78a132a..0000000
--- a/dubbo-spi-rpc/dubbo-rpc-rest/src/test/java/org/apache/dubbo/rpc/protocol/rest/DemoService.java
+++ /dev/null
@@ -1,45 +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.rpc.protocol.rest;
-
-import javax.ws.rs.Consumes;
-import javax.ws.rs.GET;
-import javax.ws.rs.POST;
-import javax.ws.rs.Path;
-import javax.ws.rs.QueryParam;
-import javax.ws.rs.core.MediaType;
-
-
-@Path("/demoService")
-public interface DemoService {
-    @GET
-    @Path("/hello")
-    Integer hello(@QueryParam("a") Integer a, @QueryParam("b") Integer b);
-
-    @GET
-    @Path("/error")
-    String error();
-
-    @POST
-    @Path("/say")
-    @Consumes({MediaType.TEXT_PLAIN})
-    String sayHello(String name);
-
-    @GET
-    @Path("/getRemoteApplicationName")
-    String getRemoteApplicationName();
-}
diff --git a/dubbo-spi-rpc/dubbo-rpc-rest/src/test/java/org/apache/dubbo/rpc/protocol/rest/DemoServiceImpl.java b/dubbo-spi-rpc/dubbo-rpc-rest/src/test/java/org/apache/dubbo/rpc/protocol/rest/DemoServiceImpl.java
deleted file mode 100644
index f7d3921..0000000
--- a/dubbo-spi-rpc/dubbo-rpc-rest/src/test/java/org/apache/dubbo/rpc/protocol/rest/DemoServiceImpl.java
+++ /dev/null
@@ -1,57 +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.rpc.protocol.rest;
-
-
-import org.apache.dubbo.rpc.RpcContext;
-
-import java.util.Map;
-
-public class DemoServiceImpl implements DemoService {
-    private static Map<String, Object> context;
-    private boolean called;
-
-    public String sayHello(String name) {
-        called = true;
-        return "Hello, " + name;
-    }
-
-
-    public boolean isCalled() {
-        return called;
-    }
-
-    @Override
-    public Integer hello(Integer a, Integer b) {
-        context = RpcContext.getContext().getObjectAttachments();
-        return a + b;
-    }
-
-    @Override
-    public String error() {
-        throw new RuntimeException();
-    }
-
-    public static Map<String, Object> getAttachments() {
-        return context;
-    }
-
-    @Override
-    public String getRemoteApplicationName() {
-        return RpcContext.getContext().getRemoteApplicationName();
-    }
-}
diff --git a/dubbo-spi-rpc/dubbo-rpc-rest/src/test/java/org/apache/dubbo/rpc/protocol/rest/RestProtocolTest.java b/dubbo-spi-rpc/dubbo-rpc-rest/src/test/java/org/apache/dubbo/rpc/protocol/rest/RestProtocolTest.java
deleted file mode 100644
index b07997f..0000000
--- a/dubbo-spi-rpc/dubbo-rpc-rest/src/test/java/org/apache/dubbo/rpc/protocol/rest/RestProtocolTest.java
+++ /dev/null
@@ -1,282 +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.rpc.protocol.rest;
-
-import org.apache.dubbo.common.URL;
-import org.apache.dubbo.common.extension.ExtensionLoader;
-import org.apache.dubbo.common.utils.NetUtils;
-import org.apache.dubbo.rpc.Exporter;
-import org.apache.dubbo.rpc.Invoker;
-import org.apache.dubbo.rpc.Protocol;
-import org.apache.dubbo.rpc.ProxyFactory;
-import org.apache.dubbo.rpc.Result;
-import org.apache.dubbo.rpc.RpcContext;
-import org.apache.dubbo.rpc.RpcException;
-import org.apache.dubbo.rpc.RpcInvocation;
-import org.apache.dubbo.rpc.model.ApplicationModel;
-import org.apache.dubbo.rpc.model.ServiceDescriptor;
-import org.apache.dubbo.rpc.model.ServiceRepository;
-
-import org.hamcrest.CoreMatchers;
-import org.junit.jupiter.api.AfterEach;
-import org.junit.jupiter.api.Assertions;
-import org.junit.jupiter.api.Test;
-
-import java.util.Map;
-
-import static org.apache.dubbo.remoting.Constants.SERVER_KEY;
-import static org.apache.dubbo.rpc.protocol.rest.Constants.EXTENSION_KEY;
-import static org.hamcrest.CoreMatchers.equalTo;
-import static org.hamcrest.CoreMatchers.is;
-import static org.hamcrest.CoreMatchers.nullValue;
-import static org.hamcrest.MatcherAssert.assertThat;
-
-public class RestProtocolTest {
-    private Protocol protocol = ExtensionLoader.getExtensionLoader(Protocol.class).getExtension("rest");
-    private ProxyFactory proxy = ExtensionLoader.getExtensionLoader(ProxyFactory.class).getAdaptiveExtension();
-    private final int availablePort = NetUtils.getAvailablePort();
-    private final URL exportUrl = URL.valueOf("rest://127.0.0.1:" + availablePort + "/rest?interface=org.apache.dubbo.rpc.protocol.rest.DemoService");
-    private final ServiceRepository repository = ApplicationModel.getServiceRepository();
-
-    @AfterEach
-    public void tearDown() {
-        protocol.destroy();
-    }
-
-    @Test
-    public void testRestProtocol() {
-        URL url = URL.valueOf("rest://127.0.0.1:" + NetUtils.getAvailablePort() + "/rest/say?version=1.0.0&interface=org.apache.dubbo.rpc.protocol.rest.DemoService");
-        DemoServiceImpl server = new DemoServiceImpl();
-
-        this.registerProvider(url, server, DemoService.class);
-
-        Exporter<DemoService> exporter = protocol.export(proxy.getInvoker(server, DemoService.class, url));
-        Invoker<DemoService> invoker = protocol.refer(DemoService.class, url);
-        Assertions.assertFalse(server.isCalled());
-
-        DemoService client = proxy.getProxy(invoker);
-        String result = client.sayHello("haha");
-        Assertions.assertTrue(server.isCalled());
-        Assertions.assertEquals("Hello, haha", result);
-        invoker.destroy();
-        exporter.unexport();
-    }
-
-    @Test
-    public void testRestProtocolWithContextPath() {
-        DemoServiceImpl server = new DemoServiceImpl();
-        Assertions.assertFalse(server.isCalled());
-        int port = NetUtils.getAvailablePort();
-        URL url = URL.valueOf("rest://127.0.0.1:" + port + "/a/b/c?version=1.0.0&interface=org.apache.dubbo.rpc.protocol.rest.DemoService");
-
-        this.registerProvider(url, server, DemoService.class);
-
-        ServiceDescriptor serviceDescriptor = repository.registerService(DemoService.class);
-        repository.registerProvider(
-                url.getPathKey(),
-                server,
-                serviceDescriptor,
-                null,
-                null
-        );
-
-        Exporter<DemoService> exporter = protocol.export(proxy.getInvoker(server, DemoService.class, url));
-
-        url = URL.valueOf("rest://127.0.0.1:" + port + "/a/b/c/?version=1.0.0&interface=org.apache.dubbo.rpc.protocol.rest.DemoService");
-        Invoker<DemoService> invoker = protocol.refer(DemoService.class, url);
-        DemoService client = proxy.getProxy(invoker);
-        String result = client.sayHello("haha");
-        Assertions.assertTrue(server.isCalled());
-        Assertions.assertEquals("Hello, haha", result);
-        invoker.destroy();
-        exporter.unexport();
-    }
-
-    @Test
-    public void testExport() {
-        DemoService server = new DemoServiceImpl();
-
-        this.registerProvider(exportUrl, server, DemoService.class);
-
-        RpcContext.getContext().setAttachment("timeout", "200");
-        Exporter<DemoService> exporter = protocol.export(proxy.getInvoker(server, DemoService.class, exportUrl));
-
-        DemoService demoService = this.proxy.getProxy(protocol.refer(DemoService.class, exportUrl));
-
-        Integer echoString = demoService.hello(1, 2);
-        assertThat(echoString, is(3));
-
-        exporter.unexport();
-    }
-
-    @Test
-    public void testNettyServer() {
-        DemoService server = new DemoServiceImpl();
-
-        this.registerProvider(exportUrl, server, DemoService.class);
-
-        URL nettyUrl = exportUrl.addParameter(SERVER_KEY, "netty");
-        Exporter<DemoService> exporter = protocol.export(proxy.getInvoker(new DemoServiceImpl(), DemoService.class, nettyUrl));
-
-        DemoService demoService = this.proxy.getProxy(protocol.refer(DemoService.class, nettyUrl));
-
-        Integer echoString = demoService.hello(10, 10);
-        assertThat(echoString, is(20));
-
-        exporter.unexport();
-    }
-
-    @Test
-    public void testServletWithoutWebConfig() {
-        Assertions.assertThrows(RpcException.class, () -> {
-            DemoService server = new DemoServiceImpl();
-
-            this.registerProvider(exportUrl, server, DemoService.class);
-
-            URL servletUrl = exportUrl.addParameter(SERVER_KEY, "servlet");
-
-            protocol.export(proxy.getInvoker(server, DemoService.class, servletUrl));
-        });
-    }
-
-    @Test
-    public void testErrorHandler() {
-        Assertions.assertThrows(RpcException.class, () -> {
-            DemoService server = new DemoServiceImpl();
-
-            this.registerProvider(exportUrl, server, DemoService.class);
-
-            URL nettyUrl = exportUrl.addParameter(SERVER_KEY, "netty");
-            Exporter<DemoService> exporter = protocol.export(proxy.getInvoker(server, DemoService.class, nettyUrl));
-
-            DemoService demoService = this.proxy.getProxy(protocol.refer(DemoService.class, nettyUrl));
-
-            demoService.error();
-        });
-    }
-
-    @Test
-    public void testInvoke() {
-        DemoService server = new DemoServiceImpl();
-
-        this.registerProvider(exportUrl, server, DemoService.class);
-
-        Exporter<DemoService> exporter = protocol.export(proxy.getInvoker(server, DemoService.class, exportUrl));
-
-        RpcInvocation rpcInvocation = new RpcInvocation("hello", DemoService.class.getName(), new Class[]{Integer.class, Integer.class}, new Integer[]{2, 3});
-
-        Result result = exporter.getInvoker().invoke(rpcInvocation);
-        assertThat(result.getValue(), CoreMatchers.<Object>is(5));
-    }
-
-    @Test
-    public void testFilter() {
-        DemoService server = new DemoServiceImpl();
-
-        this.registerProvider(exportUrl, server, DemoService.class);
-
-        URL nettyUrl = exportUrl.addParameter(SERVER_KEY, "netty")
-                .addParameter(EXTENSION_KEY, "org.apache.dubbo.rpc.protocol.rest.support.LoggingFilter");
-        Exporter<DemoService> exporter = protocol.export(proxy.getInvoker(server, DemoService.class, nettyUrl));
-
-        DemoService demoService = this.proxy.getProxy(protocol.refer(DemoService.class, nettyUrl));
-
-        Integer result = demoService.hello(1, 2);
-
-        assertThat(result, is(3));
-
-        exporter.unexport();
-    }
-
-    @Test
-    public void testRpcContextFilter() {
-        DemoService server = new DemoServiceImpl();
-
-        this.registerProvider(exportUrl, server, DemoService.class);
-
-        // use RpcContextFilter
-        URL nettyUrl = exportUrl.addParameter(SERVER_KEY, "netty")
-                .addParameter(EXTENSION_KEY, "org.apache.dubbo.rpc.protocol.rest.RpcContextFilter");
-        Exporter<DemoService> exporter = protocol.export(proxy.getInvoker(server, DemoService.class, nettyUrl));
-
-        DemoService demoService = this.proxy.getProxy(protocol.refer(DemoService.class, nettyUrl));
-
-        // make sure null and base64 encoded string can work
-        RpcContext.getContext().setAttachment("key1", null);
-        RpcContext.getContext().setAttachment("key2", "value");
-        RpcContext.getContext().setAttachment("key3", "=value");
-        RpcContext.getContext().setAttachment("key4", "YWJjZGVmCg==");
-        RpcContext.getContext().setAttachment("key5", "val=ue");
-        Integer result = demoService.hello(1, 2);
-
-        assertThat(result, is(3));
-
-        Map<String, Object> attachment = DemoServiceImpl.getAttachments();
-        assertThat(attachment.get("key1"), nullValue());
-        assertThat(attachment.get("key2"), equalTo("value"));
-        assertThat(attachment.get("key3"), equalTo("=value"));
-        assertThat(attachment.get("key4"), equalTo("YWJjZGVmCg=="));
-        assertThat(attachment.get("key5"), equalTo("val=ue"));
-
-        exporter.unexport();
-    }
-
-    @Test
-    public void testRegFail() {
-        Assertions.assertThrows(RuntimeException.class, () -> {
-            DemoService server = new DemoServiceImpl();
-
-            this.registerProvider(exportUrl, server, DemoService.class);
-
-            URL nettyUrl = exportUrl.addParameter(EXTENSION_KEY, "com.not.existing.Filter");
-            protocol.export(proxy.getInvoker(server, DemoService.class, nettyUrl));
-        });
-    }
-
-    @Test
-    public void testDefaultPort() {
-        assertThat(protocol.getDefaultPort(), is(80));
-    }
-
-    @Test
-    public void testRemoteApplicationName() {
-        URL url = URL.valueOf("rest://127.0.0.1:" + NetUtils.getAvailablePort() + "/rest/say?version=1.0.0&interface=org.apache.dubbo.rpc.protocol.rest.DemoService").addParameter("application", "consumer");
-        DemoServiceImpl server = new DemoServiceImpl();
-
-        this.registerProvider(url, server, DemoService.class);
-
-        Exporter<DemoService> exporter = protocol.export(proxy.getInvoker(server, DemoService.class, url));
-        Invoker<DemoService> invoker = protocol.refer(DemoService.class, url);
-
-        DemoService client = proxy.getProxy(invoker);
-        String result = client.getRemoteApplicationName();
-        Assertions.assertEquals("consumer", result);
-        invoker.destroy();
-        exporter.unexport();
-    }
-
-    private void registerProvider(URL url, Object impl, Class<?> interfaceClass) {
-        ServiceDescriptor serviceDescriptor = repository.registerService(interfaceClass);
-        repository.registerProvider(
-                url.getServiceKey(),
-                impl,
-                serviceDescriptor,
-                null,
-                null
-        );
-    }
-}
diff --git a/dubbo-spi-rpc/dubbo-rpc-rest/src/test/java/org/apache/dubbo/rpc/protocol/rest/RpcExceptionMapperTest.java b/dubbo-spi-rpc/dubbo-rpc-rest/src/test/java/org/apache/dubbo/rpc/protocol/rest/RpcExceptionMapperTest.java
deleted file mode 100644
index 74a133a..0000000
--- a/dubbo-spi-rpc/dubbo-rpc-rest/src/test/java/org/apache/dubbo/rpc/protocol/rest/RpcExceptionMapperTest.java
+++ /dev/null
@@ -1,67 +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.rpc.protocol.rest;
-
-import org.apache.dubbo.rpc.RpcException;
-import org.junit.jupiter.api.BeforeEach;
-import org.junit.jupiter.api.Test;
-import org.mockito.Answers;
-import org.mockito.internal.util.collections.Sets;
-
-import javax.validation.ConstraintViolation;
-import javax.validation.ConstraintViolationException;
-import javax.ws.rs.core.Response;
-
-import static org.hamcrest.CoreMatchers.instanceOf;
-import static org.hamcrest.CoreMatchers.not;
-import static org.hamcrest.CoreMatchers.nullValue;
-import static org.hamcrest.MatcherAssert.assertThat;
-import static org.mockito.BDDMockito.given;
-import static org.mockito.Mockito.mock;
-
-public class RpcExceptionMapperTest {
-
-    private RpcExceptionMapper exceptionMapper;
-
-    @BeforeEach
-    public void setUp() {
-        this.exceptionMapper = new RpcExceptionMapper();
-    }
-
-    @Test
-    public void testConstraintViolationException() {
-        ConstraintViolationException violationException = mock(ConstraintViolationException.class);
-        ConstraintViolation violation = mock(ConstraintViolation.class, Answers.RETURNS_DEEP_STUBS);
-        given(violationException.getConstraintViolations()).willReturn(Sets.<ConstraintViolation<?>>newSet(violation));
-        RpcException rpcException = new RpcException("violation", violationException);
-
-        Response response = exceptionMapper.toResponse(rpcException);
-
-        assertThat(response, not(nullValue()));
-        assertThat(response.getEntity(), instanceOf(ViolationReport.class));
-    }
-
-    @Test
-    public void testNormalException() {
-        RpcException rpcException = new RpcException();
-        Response response = exceptionMapper.toResponse(rpcException);
-
-
-        assertThat(response, not(nullValue()));
-        assertThat(response.getEntity(), instanceOf(String.class));
-    }
-}
\ No newline at end of file
diff --git a/dubbo-spi-rpc/dubbo-rpc-rest/src/test/java/org/apache/dubbo/rpc/protocol/rest/integration/swagger/DubboSwaggerApiListingResourceTest.java b/dubbo-spi-rpc/dubbo-rpc-rest/src/test/java/org/apache/dubbo/rpc/protocol/rest/integration/swagger/DubboSwaggerApiListingResourceTest.java
deleted file mode 100644
index 565ddf7..0000000
--- a/dubbo-spi-rpc/dubbo-rpc-rest/src/test/java/org/apache/dubbo/rpc/protocol/rest/integration/swagger/DubboSwaggerApiListingResourceTest.java
+++ /dev/null
@@ -1,62 +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.rpc.protocol.rest.integration.swagger;
-
-import io.swagger.models.Swagger;
-import org.jboss.resteasy.spi.ResteasyUriInfo;
-import org.junit.jupiter.api.Assertions;
-import org.junit.jupiter.api.Test;
-
-import javax.servlet.ServletConfig;
-import javax.servlet.ServletContext;
-import javax.ws.rs.core.Application;
-import javax.ws.rs.core.Response;
-import java.net.URI;
-import java.util.HashSet;
-import java.util.Set;
-
-import static org.mockito.Mockito.mock;
-import static org.mockito.Mockito.when;
-
-public class DubboSwaggerApiListingResourceTest {
-
-    private Application app;
-    private ServletConfig sc;
-
-    @Test
-    public void test() throws Exception {
-
-        DubboSwaggerApiListingResource resource = new  DubboSwaggerApiListingResource();
-
-        app = mock(Application.class);
-        sc = mock(ServletConfig.class);
-        Set<Class<?>> sets = new HashSet<Class<?>>();
-        sets.add(SwaggerService.class);
-
-        when(sc.getServletContext()).thenReturn(mock(ServletContext.class));
-        when(app.getClasses()).thenReturn(sets);
-
-        Response response = resource.getListingJson(app, sc,
-                null, new ResteasyUriInfo(new URI("http://rest.test")));
-
-        Assertions.assertNotNull(response);
-        Swagger swagger = (Swagger)response.getEntity();
-        Assertions.assertEquals("SwaggerService",swagger.getTags().get(0).getName());
-        Assertions.assertEquals("/demoService/hello",swagger.getPaths().keySet().toArray()[0].toString());
-    }
-
-}
diff --git a/dubbo-spi-rpc/dubbo-rpc-rest/src/test/java/org/apache/dubbo/rpc/protocol/rest/integration/swagger/SwaggerService.java b/dubbo-spi-rpc/dubbo-rpc-rest/src/test/java/org/apache/dubbo/rpc/protocol/rest/integration/swagger/SwaggerService.java
deleted file mode 100644
index 8c00af4..0000000
--- a/dubbo-spi-rpc/dubbo-rpc-rest/src/test/java/org/apache/dubbo/rpc/protocol/rest/integration/swagger/SwaggerService.java
+++ /dev/null
@@ -1,34 +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.rpc.protocol.rest.integration.swagger;
-
-import io.swagger.annotations.Api;
-import io.swagger.annotations.ApiOperation;
-
-import javax.ws.rs.GET;
-import javax.ws.rs.Path;
-import javax.ws.rs.QueryParam;
-
-@Path("/demoService")
-@Api(value = "SwaggerService")
-public interface SwaggerService {
-    @GET
-    @Path("/hello")
-    @ApiOperation(value = "hello")
-    Integer hello(@QueryParam("a") Integer a, @QueryParam("b") Integer b);
-
-}
diff --git a/dubbo-spi-rpc/pom.xml b/dubbo-spi-rpc/pom.xml
index 076bf30..0641187 100644
--- a/dubbo-spi-rpc/pom.xml
+++ b/dubbo-spi-rpc/pom.xml
@@ -29,7 +29,6 @@
         <skip_maven_deploy>true</skip_maven_deploy>
     </properties>
     <modules>
-        <module>dubbo-rpc-injvm</module>
         <module>dubbo-rpc-http</module>
         <module>dubbo-rpc-rmi</module>
         <module>dubbo-rpc-hessian</module>
@@ -38,8 +37,6 @@
         <module>dubbo-rpc-thrift</module>
         <module>dubbo-rpc-memcached</module>
         <module>dubbo-rpc-redis</module>
-        <module>dubbo-rpc-rest</module>
         <module>dubbo-rpc-xml</module>
-        <module>dubbo-rpc-grpc</module>
     </modules>
 </project>


[dubbo-spi-extensions] 27/39: 修改CI脚本

Posted by li...@apache.org.
This is an automated email from the ASF dual-hosted git repository.

liujun pushed a commit to branch 2.7.x
in repository https://gitbox.apache.org/repos/asf/dubbo-spi-extensions.git

commit 048bce4bedb43f714cc969c01e87af8f1b4bfbe3
Author: qq213539 <21...@qq.com>
AuthorDate: Wed Dec 23 15:49:30 2020 +0800

    修改CI脚本
---
 .travis.yml | 3 ++-
 1 file changed, 2 insertions(+), 1 deletion(-)

diff --git a/.travis.yml b/.travis.yml
index f13d3e6..89959b8 100644
--- a/.travis.yml
+++ b/.travis.yml
@@ -13,7 +13,8 @@ install: true
 
 script:
   - rm -rf $HOME/.m2/repository/org/glassfish/javax.el/3.0.1-b08
-  - travis_wait 30 ./mvnw --batch-mode --no-transfer-progress clean install -DskipTests=false -DskipIntegrationTests=false -Dcheckstyle.skip=false -Drat.skip=false -Dmaven.javadoc.skip=true
+  - cd ./dubbo-api-docs
+  - travis_wait 30 mvn clean install -DskipTests=false -DskipIntegrationTests=false -Dcheckstyle.skip=false -Drat.skip=false -Dmaven.javadoc.skip=true
 
 after_success:
   - bash <(curl -s https://codecov.io/bash)


[dubbo-spi-extensions] 33/39: 升级版本号,修复 #9, 增加使用SPI扫描的测试

Posted by li...@apache.org.
This is an automated email from the ASF dual-hosted git repository.

liujun pushed a commit to branch 2.7.x
in repository https://gitbox.apache.org/repos/asf/dubbo-spi-extensions.git

commit 971ffafd699337f6a8e1e343e2a33680d0b15668
Author: qq213539 <21...@qq.com>
AuthorDate: Thu Jan 28 13:54:26 2021 +0800

    升级版本号,修复 #9, 增加使用SPI扫描的测试
---
 .../core/DubboApiDocsAnnotationScanner.java        | 50 +++++++++++++++++---
 .../apache/dubbo/apidocs/utils/ClassTypeUtil.java  | 19 +++++++-
 .../apidocs/examples/api/IQuickStartDemo.java      | 14 +++++-
 .../examples/params/QuickStartRequestBase.java     | 53 ++++++++++++++++++++++
 .../examples-provider/pom.xml                      |  5 --
 .../apidocs/examples/api/impl/AsyncDemoImpl.java   |  4 +-
 .../examples/api/impl/QuickStartDemoImpl.java      | 20 +++++---
 .../apidocs/examples/api/impl/SyncDemoImpl.java    |  4 +-
 .../examples/spi/DubboDocExporterListener.java     | 24 ++++++++++
 .../examples/spi/TestConfigInitializer.java        | 20 ++++++++
 .../examples/spi/TestConfigPostProcessor.java      | 24 ++++++++++
 .../org.apache.dubbo.config.ConfigInitializer      |  1 +
 .../org.apache.dubbo.config.ConfigPostProcessor    |  1 +
 .../dubbo/org.apache.dubbo.rpc.ExporterListener    |  1 +
 dubbo-api-docs/pom.xml                             |  2 +-
 15 files changed, 218 insertions(+), 24 deletions(-)

diff --git a/dubbo-api-docs/dubbo-api-docs-core/src/main/java/org/apache/dubbo/apidocs/core/DubboApiDocsAnnotationScanner.java b/dubbo-api-docs/dubbo-api-docs-core/src/main/java/org/apache/dubbo/apidocs/core/DubboApiDocsAnnotationScanner.java
index 717bfa5..e8a8565 100644
--- a/dubbo-api-docs/dubbo-api-docs-core/src/main/java/org/apache/dubbo/apidocs/core/DubboApiDocsAnnotationScanner.java
+++ b/dubbo-api-docs/dubbo-api-docs-core/src/main/java/org/apache/dubbo/apidocs/core/DubboApiDocsAnnotationScanner.java
@@ -35,19 +35,24 @@ import org.apache.dubbo.apidocs.annotations.*;
 import org.apache.dubbo.apidocs.utils.ClassTypeUtil;
 
 import com.alibaba.fastjson.JSON;
+import org.apache.commons.lang3.StringUtils;
 import org.springframework.aop.support.AopUtils;
 import org.springframework.beans.factory.annotation.Autowired;
 import org.springframework.boot.context.event.ApplicationReadyEvent;
 import org.springframework.context.ApplicationContext;
 import org.springframework.context.ApplicationListener;
 import org.springframework.context.annotation.Import;
+import sun.reflect.generics.reflectiveObjects.ParameterizedTypeImpl;
 
 import java.lang.annotation.Annotation;
 import java.lang.reflect.Field;
 import java.lang.reflect.InvocationTargetException;
 import java.lang.reflect.Method;
 import java.lang.reflect.Parameter;
+import java.lang.reflect.Type;
+import java.lang.reflect.TypeVariable;
 import java.util.ArrayList;
+import java.util.HashMap;
 import java.util.List;
 import java.util.Map;
 
@@ -126,6 +131,7 @@ public class DubboApiDocsAnnotationScanner implements ApplicationListener<Applic
 
     private void processApiDocAnnotation(Method method, List<ApiCacheItem> moduleApiList, ApiModule moduleAnn,
                                          boolean async, ModuleCacheItem moduleCacheItem) {
+
         ApiDoc dubboApi = method.getAnnotation(ApiDoc.class);
 
         // API basic information in API list in module
@@ -150,6 +156,7 @@ public class DubboApiDocsAnnotationScanner implements ApplicationListener<Applic
         Class<?>[] argsClass = method.getParameterTypes();
         Annotation[][] argsAnns = method.getParameterAnnotations();
         Parameter[] parameters = method.getParameters();
+        Type[] parametersTypes = method.getGenericParameterTypes();
         List<ApiParamsCacheItem> paramList = new ArrayList<>(argsClass.length);
         apiParamsAndResp.setAsync(async);
         apiParamsAndResp.setApiName(method.getName());
@@ -163,6 +170,7 @@ public class DubboApiDocsAnnotationScanner implements ApplicationListener<Applic
         StringBuilder methodParamInfoSb = new StringBuilder();
         for (int i = 0; i < argsClass.length; i++) {
             Class<?> argClass = argsClass[i];
+            Type parameterType = parametersTypes[i];
             methodParamInfoSb.append("[").append(i).append("]").append(argClass.getCanonicalName());
             if (i + 1 < argsClass.length) {
                 methodParamInfoSb.append(" | ");
@@ -182,7 +190,7 @@ public class DubboApiDocsAnnotationScanner implements ApplicationListener<Applic
             ParamBean paramBean = this.processHtmlType(argClass, requestParam, null);
             if (paramBean == null) {
                 // Not a basic type, handling properties in method parameters
-                List<ParamBean> apiParamsList = processField(argClass);
+                List<ParamBean> apiParamsList = processField(argClass, parameterType);
                 if (apiParamsList != null && !apiParamsList.isEmpty()) {
                     paramListItem.setParamInfo(apiParamsList);
                 }
@@ -211,7 +219,20 @@ public class DubboApiDocsAnnotationScanner implements ApplicationListener<Applic
      * For the attributes in the method parameters, only one layer is processed.
      * The deeper layer is directly converted to JSON, and the deeper layer is up to 5 layers
      */
-    private List<ParamBean> processField(Class<?> argClass) {
+    private List<ParamBean> processField(Class<?> argClass, Type parameterType) {
+        Map<String, String> genericTypeAndNamesMap;
+        if (parameterType instanceof ParameterizedTypeImpl) {
+            ParameterizedTypeImpl parameterTypeImpl = (ParameterizedTypeImpl) parameterType;
+            TypeVariable<? extends Class<?>>[] typeVariables = parameterTypeImpl.getRawType().getTypeParameters();
+            Type[] actualTypeArguments = parameterTypeImpl.getActualTypeArguments();
+            genericTypeAndNamesMap =  new HashMap<>(typeVariables.length);
+            for (int i = 0; i < typeVariables.length; i++) {
+                TypeVariable<? extends Class<?>> typeVariable = typeVariables[i];
+                genericTypeAndNamesMap.put(typeVariable.getTypeName(), actualTypeArguments[i].getTypeName());
+            }
+        } else {
+            genericTypeAndNamesMap =  new HashMap<>(0);
+        }
 
         List<ParamBean> apiParamsList = new ArrayList(16);
         // get all fields
@@ -219,7 +240,18 @@ public class DubboApiDocsAnnotationScanner implements ApplicationListener<Applic
         for (Field field : allFields) {
             ParamBean paramBean = new ParamBean();
             paramBean.setName(field.getName());
-            paramBean.setJavaType(field.getType().getCanonicalName());
+            String genericTypeName = genericTypeAndNamesMap.get(field.getGenericType().getTypeName());
+            Class<?> genericType = null;
+            if (StringUtils.isBlank(genericTypeName)) {
+                paramBean.setJavaType(field.getType().getCanonicalName());
+            } else {
+                paramBean.setJavaType(genericTypeName);
+                try {
+                    genericType = Class.forName(genericTypeName);
+                } catch (ClassNotFoundException e) {
+                    e.printStackTrace();
+                }
+            }
             RequestParam requestParam = null;
             if (field.isAnnotationPresent(RequestParam.class)) {
                 // Handling @RequestParam annotations on properties
@@ -233,10 +265,16 @@ public class DubboApiDocsAnnotationScanner implements ApplicationListener<Applic
                 paramBean.setRequired(false);
             }
 
-            if (this.processHtmlType(field.getType(), requestParam, paramBean) == null) {
+            if (this.processHtmlType(null == genericType ? field.getType() : genericType, requestParam, paramBean) == null) {
                 // Not a basic type, handle as JSON
-                Object objResult = ClassTypeUtil.initClassTypeWithDefaultValue(
-                        field.getGenericType(), field.getType(), 0);
+                Object objResult;
+                if (null == genericType) {
+                    objResult =ClassTypeUtil.initClassTypeWithDefaultValue(
+                            field.getGenericType(), field.getType(), 0);
+                } else {
+                    objResult =ClassTypeUtil.initClassTypeWithDefaultValue(
+                            null, genericType, 0, true);
+                }
                 if (!ClassTypeUtil.isBaseType(objResult)) {
                     paramBean.setHtmlType(HtmlTypeEnum.TEXT_AREA);
                     paramBean.setSubParamsJson(JSON.toJSONString(objResult, ClassTypeUtil.FAST_JSON_FEATURES));
diff --git a/dubbo-api-docs/dubbo-api-docs-core/src/main/java/org/apache/dubbo/apidocs/utils/ClassTypeUtil.java b/dubbo-api-docs/dubbo-api-docs-core/src/main/java/org/apache/dubbo/apidocs/utils/ClassTypeUtil.java
index b11d534..559f288 100644
--- a/dubbo-api-docs/dubbo-api-docs-core/src/main/java/org/apache/dubbo/apidocs/utils/ClassTypeUtil.java
+++ b/dubbo-api-docs/dubbo-api-docs-core/src/main/java/org/apache/dubbo/apidocs/utils/ClassTypeUtil.java
@@ -77,6 +77,20 @@ public class ClassTypeUtil {
      * @return java.lang.Object
      */
     public static Object initClassTypeWithDefaultValue(Type genericType, Class<?> classType, int processCount) {
+        return initClassTypeWithDefaultValue(genericType, classType, processCount, false);
+    }
+
+    /**
+     * Instantiate class and its fields.
+     *
+     * @param genericType  genericType
+     * @param classType    classType
+     * @param processCount processCount
+     * @param isBuildClassAttribute isBuildClassAttribute
+     * @return java.lang.Object
+     */
+    public static Object initClassTypeWithDefaultValue(Type genericType, Class<?> classType, int processCount,
+                                                       boolean isBuildClassAttribute) {
         if (processCount >= PROCESS_COUNT_MAX) {
             LOG.warn("The depth of bean has exceeded 10 layers, the deeper layer will be ignored! " +
                     "Please modify the parameter structure or check whether there is circular reference in bean!");
@@ -90,6 +104,9 @@ public class ClassTypeUtil {
         }
 
         Map<String, Object> result = new HashMap<>(16);
+        if (isBuildClassAttribute) {
+            result.put("class", classType.getCanonicalName());
+        }
         // get all fields
         List<Field> allFields = getAllFields(null, classType);
         for (Field field2 : allFields) {
@@ -280,7 +297,7 @@ public class ClassTypeUtil {
         className = className.trim();
         try {
             if (className.indexOf(GENERIC_START_SYMBOL) == -1) {
-                // CompletableFuture 中的类没有泛型
+                // classes in CompletableFuture have no generics
                 return Class.forName(className);
             } else {
                 return Class.forName(className.substring(0, className.indexOf("<")));
diff --git a/dubbo-api-docs/dubbo-api-docs-examples/examples-api/src/main/java/org/apache/dubbo/apidocs/examples/api/IQuickStartDemo.java b/dubbo-api-docs/dubbo-api-docs-examples/examples-api/src/main/java/org/apache/dubbo/apidocs/examples/api/IQuickStartDemo.java
index ed99fe4..aa5251e 100644
--- a/dubbo-api-docs/dubbo-api-docs-examples/examples-api/src/main/java/org/apache/dubbo/apidocs/examples/api/IQuickStartDemo.java
+++ b/dubbo-api-docs/dubbo-api-docs-examples/examples-api/src/main/java/org/apache/dubbo/apidocs/examples/api/IQuickStartDemo.java
@@ -16,9 +16,13 @@
  */
 package org.apache.dubbo.apidocs.examples.api;
 
+import org.apache.dubbo.apidocs.examples.params.DemoParamBean4;
+import org.apache.dubbo.apidocs.examples.params.QuickStartRequestBase;
 import org.apache.dubbo.apidocs.examples.params.QuickStartRequestBean;
 import org.apache.dubbo.apidocs.examples.params.QuickStartRespBean;
 
+import java.util.List;
+
 /**
  * quick start demo.
  */
@@ -31,6 +35,14 @@ public interface IQuickStartDemo {
      * @param beanParam
      * @return org.apache.dubbo.apidocs.examples.params.QuickStartRespBean
      */
-    QuickStartRespBean quickStart(String strParam, QuickStartRequestBean beanParam);
+//    QuickStartRespBean quickStart(String strParam, QuickStartRequestBean beanParam);
+
+    /**
+     * quick start demo, request use generic.
+     * @param beanList
+     * @param beanParam
+     * @return org.apache.dubbo.apidocs.examples.params.QuickStartRespBean
+     */
+    QuickStartRespBean quickStart2(List<String> beanList, QuickStartRequestBase<QuickStartRequestBean, DemoParamBean4> beanParam);
 
 }
diff --git a/dubbo-api-docs/dubbo-api-docs-examples/examples-api/src/main/java/org/apache/dubbo/apidocs/examples/params/QuickStartRequestBase.java b/dubbo-api-docs/dubbo-api-docs-examples/examples-api/src/main/java/org/apache/dubbo/apidocs/examples/params/QuickStartRequestBase.java
new file mode 100644
index 0000000..94cbd0f
--- /dev/null
+++ b/dubbo-api-docs/dubbo-api-docs-examples/examples-api/src/main/java/org/apache/dubbo/apidocs/examples/params/QuickStartRequestBase.java
@@ -0,0 +1,53 @@
+package org.apache.dubbo.apidocs.examples.params;
+
+import org.apache.dubbo.apidocs.annotations.RequestParam;
+
+/**
+ * QuickStartRequestBase.
+ *
+ * @date 2021/1/26 15:24
+ */
+public class QuickStartRequestBase<E, T> {
+
+    @RequestParam(value = "Request method", required = true)
+    private String method;
+
+    private T body;
+
+    private E body3;
+
+    private QuickStartRequestBean body2;
+
+    public String getMethod() {
+        return method;
+    }
+
+    public void setMethod(String method) {
+        this.method = method;
+    }
+
+    public T getBody() {
+        return body;
+    }
+
+    public void setBody(T body) {
+        this.body = body;
+    }
+
+    public QuickStartRequestBean getBody2() {
+        return body2;
+    }
+
+    public void setBody2(QuickStartRequestBean body2) {
+        this.body2 = body2;
+    }
+
+    public E getBody3() {
+        return body3;
+    }
+
+    public void setBody3(E body3) {
+        this.body3 = body3;
+    }
+
+}
diff --git a/dubbo-api-docs/dubbo-api-docs-examples/examples-provider/pom.xml b/dubbo-api-docs/dubbo-api-docs-examples/examples-provider/pom.xml
index dd05f82..cc6ac7f 100644
--- a/dubbo-api-docs/dubbo-api-docs-examples/examples-provider/pom.xml
+++ b/dubbo-api-docs/dubbo-api-docs-examples/examples-provider/pom.xml
@@ -66,11 +66,6 @@
 
         <dependency>
             <groupId>org.apache.dubbo</groupId>
-            <artifactId>dubbo</artifactId>
-        </dependency>
-
-        <dependency>
-            <groupId>org.apache.dubbo</groupId>
             <artifactId>dubbo-spring-boot-starter</artifactId>
         </dependency>
 
diff --git a/dubbo-api-docs/dubbo-api-docs-examples/examples-provider/src/main/java/org/apache/dubbo/apidocs/examples/api/impl/AsyncDemoImpl.java b/dubbo-api-docs/dubbo-api-docs-examples/examples-provider/src/main/java/org/apache/dubbo/apidocs/examples/api/impl/AsyncDemoImpl.java
index 9a4b4c7..7f45ef2 100644
--- a/dubbo-api-docs/dubbo-api-docs-examples/examples-provider/src/main/java/org/apache/dubbo/apidocs/examples/api/impl/AsyncDemoImpl.java
+++ b/dubbo-api-docs/dubbo-api-docs-examples/examples-provider/src/main/java/org/apache/dubbo/apidocs/examples/api/impl/AsyncDemoImpl.java
@@ -37,8 +37,8 @@ import java.util.concurrent.ScheduledThreadPoolExecutor;
 /**
  * Asynchronous demo implementation.
  */
-@DubboService(async = true)
-@ApiModule(value = "Asynchronous demo", apiInterface = IAsyncDemo.class)
+//@DubboService(async = true)
+//@ApiModule(value = "Asynchronous demo", apiInterface = IAsyncDemo.class)
 public class AsyncDemoImpl implements IAsyncDemo {
 
     public static final ScheduledExecutorService EXECUTOR = new ScheduledThreadPoolExecutor(
diff --git a/dubbo-api-docs/dubbo-api-docs-examples/examples-provider/src/main/java/org/apache/dubbo/apidocs/examples/api/impl/QuickStartDemoImpl.java b/dubbo-api-docs/dubbo-api-docs-examples/examples-provider/src/main/java/org/apache/dubbo/apidocs/examples/api/impl/QuickStartDemoImpl.java
index 0d9bdc7..c2c9d17 100644
--- a/dubbo-api-docs/dubbo-api-docs-examples/examples-provider/src/main/java/org/apache/dubbo/apidocs/examples/api/impl/QuickStartDemoImpl.java
+++ b/dubbo-api-docs/dubbo-api-docs-examples/examples-provider/src/main/java/org/apache/dubbo/apidocs/examples/api/impl/QuickStartDemoImpl.java
@@ -18,25 +18,33 @@ package org.apache.dubbo.apidocs.examples.api.impl;
 
 import org.apache.dubbo.apidocs.annotations.ApiDoc;
 import org.apache.dubbo.apidocs.annotations.ApiModule;
-import org.apache.dubbo.apidocs.annotations.RequestParam;
 import org.apache.dubbo.apidocs.examples.api.IQuickStartDemo;
+import org.apache.dubbo.apidocs.examples.params.DemoParamBean4;
+import org.apache.dubbo.apidocs.examples.params.QuickStartRequestBase;
 import org.apache.dubbo.apidocs.examples.params.QuickStartRequestBean;
 import org.apache.dubbo.apidocs.examples.params.QuickStartRespBean;
 import org.apache.dubbo.config.annotation.DubboService;
 
+import java.util.List;
+
 /**
  * quick start demo implement.
  *
- * @author klw(213539 @ qq.com)
  * @date 2020/12/23 17:21
  */
-@DubboService
+@DubboService(version = "v0.1")
 @ApiModule(value = "quick start demo", apiInterface = IQuickStartDemo.class, version = "v0.1")
 public class QuickStartDemoImpl implements IQuickStartDemo {
 
-    @ApiDoc(value = "quick start demo", version = "v0.1", description = "this api is a quick start demo", responseClassDescription="A quick star response bean")
+//    @ApiDoc(value = "quick start demo", version = "v0.1", description = "this api is a quick start demo", responseClassDescription="A quick star response bean")
+//    @Override
+//    public QuickStartRespBean quickStart(@RequestParam(value = "strParam", required = true) String strParam, QuickStartRequestBean beanParam) {
+//        return new QuickStartRespBean(200, "hello " + beanParam.getName() + ", " + beanParam.toString());
+//    }
+
+    @ApiDoc(value = "quick start demo, request use generic.", version = "v0.1", description = "quick start demo, request use generic.", responseClassDescription="A quick star response bean")
     @Override
-    public QuickStartRespBean quickStart(@RequestParam(value = "strParam", required = true) String strParam, QuickStartRequestBean beanParam) {
-        return new QuickStartRespBean(200, "hello " + beanParam.getName() + ", " + beanParam.toString());
+    public QuickStartRespBean quickStart2(List<String> beanList, QuickStartRequestBase<QuickStartRequestBean, DemoParamBean4> beanParam) {
+        return new QuickStartRespBean(200, "【" + beanParam.getMethod() + "】hello " + beanParam.getBody3().getName() + ", " + beanParam.toString());
     }
 }
diff --git a/dubbo-api-docs/dubbo-api-docs-examples/examples-provider/src/main/java/org/apache/dubbo/apidocs/examples/api/impl/SyncDemoImpl.java b/dubbo-api-docs/dubbo-api-docs-examples/examples-provider/src/main/java/org/apache/dubbo/apidocs/examples/api/impl/SyncDemoImpl.java
index 8998566..faf4166 100644
--- a/dubbo-api-docs/dubbo-api-docs-examples/examples-provider/src/main/java/org/apache/dubbo/apidocs/examples/api/impl/SyncDemoImpl.java
+++ b/dubbo-api-docs/dubbo-api-docs-examples/examples-provider/src/main/java/org/apache/dubbo/apidocs/examples/api/impl/SyncDemoImpl.java
@@ -37,8 +37,8 @@ import java.util.Map;
 /**
  * Synchronous demo implementation.
  */
-@DubboService
-@ApiModule(value = "Synchronous demo", apiInterface = ISyncDemo.class)
+//@DubboService
+//@ApiModule(value = "Synchronous demo", apiInterface = ISyncDemo.class)
 public class SyncDemoImpl implements ISyncDemo {
 
     private static final Logger log = LoggerFactory.getLogger(SyncDemoImpl.class);
diff --git a/dubbo-api-docs/dubbo-api-docs-examples/examples-provider/src/main/java/org/apache/dubbo/apidocs/examples/spi/DubboDocExporterListener.java b/dubbo-api-docs/dubbo-api-docs-examples/examples-provider/src/main/java/org/apache/dubbo/apidocs/examples/spi/DubboDocExporterListener.java
new file mode 100644
index 0000000..bf37d55
--- /dev/null
+++ b/dubbo-api-docs/dubbo-api-docs-examples/examples-provider/src/main/java/org/apache/dubbo/apidocs/examples/spi/DubboDocExporterListener.java
@@ -0,0 +1,24 @@
+package org.apache.dubbo.apidocs.examples.spi;
+
+import org.apache.dubbo.common.extension.Activate;
+import org.apache.dubbo.rpc.Exporter;
+import org.apache.dubbo.rpc.ExporterListener;
+import org.apache.dubbo.rpc.RpcException;
+
+/**
+ * .
+ *
+ * @date 2020/10/29 10:50
+ */
+@Activate
+public class DubboDocExporterListener implements ExporterListener {
+    @Override
+    public void exported(Exporter<?> exporter) throws RpcException {
+        System.out.println("=============exported=============");
+    }
+
+    @Override
+    public void unexported(Exporter<?> exporter) {
+        System.out.println("=============unexported=============");
+    }
+}
diff --git a/dubbo-api-docs/dubbo-api-docs-examples/examples-provider/src/main/java/org/apache/dubbo/apidocs/examples/spi/TestConfigInitializer.java b/dubbo-api-docs/dubbo-api-docs-examples/examples-provider/src/main/java/org/apache/dubbo/apidocs/examples/spi/TestConfigInitializer.java
new file mode 100644
index 0000000..e4900cd
--- /dev/null
+++ b/dubbo-api-docs/dubbo-api-docs-examples/examples-provider/src/main/java/org/apache/dubbo/apidocs/examples/spi/TestConfigInitializer.java
@@ -0,0 +1,20 @@
+package org.apache.dubbo.apidocs.examples.spi;
+
+import org.apache.dubbo.common.extension.Activate;
+import org.apache.dubbo.config.ConfigInitializer;
+import org.apache.dubbo.config.ServiceConfig;
+
+/**
+ * .
+ *
+ * @date 2021/1/12 17:09
+ */
+@Activate
+public class TestConfigInitializer implements ConfigInitializer {
+
+    @Override
+    public void initServiceConfig(ServiceConfig serviceConfig) {
+        System.out.println("====initServiceConfig");
+    }
+
+}
diff --git a/dubbo-api-docs/dubbo-api-docs-examples/examples-provider/src/main/java/org/apache/dubbo/apidocs/examples/spi/TestConfigPostProcessor.java b/dubbo-api-docs/dubbo-api-docs-examples/examples-provider/src/main/java/org/apache/dubbo/apidocs/examples/spi/TestConfigPostProcessor.java
new file mode 100644
index 0000000..d600abd
--- /dev/null
+++ b/dubbo-api-docs/dubbo-api-docs-examples/examples-provider/src/main/java/org/apache/dubbo/apidocs/examples/spi/TestConfigPostProcessor.java
@@ -0,0 +1,24 @@
+package org.apache.dubbo.apidocs.examples.spi;
+
+import org.apache.dubbo.common.extension.Activate;
+import org.apache.dubbo.config.ConfigPostProcessor;
+import org.apache.dubbo.config.ServiceConfig;
+
+/**
+ * .
+ *
+ * @date 2021/1/12 16:51
+ */
+@Activate
+public class TestConfigPostProcessor implements ConfigPostProcessor {
+
+
+    @Override
+    public void postProcessServiceConfig(ServiceConfig serviceConfig) {
+//        ((ServiceBean)serviceConfig).getService()
+//        ((ServiceBean)serviceConfig).applicationContext.getBean(((ServiceBean) serviceConfig).getInterfaceClass());
+        serviceConfig.getRef();  // 拿实例
+        System.out.println("====postProcessServiceConfig");
+    }
+
+}
diff --git a/dubbo-api-docs/dubbo-api-docs-examples/examples-provider/src/main/resources/META-INF/dubbo/org.apache.dubbo.config.ConfigInitializer b/dubbo-api-docs/dubbo-api-docs-examples/examples-provider/src/main/resources/META-INF/dubbo/org.apache.dubbo.config.ConfigInitializer
new file mode 100644
index 0000000..9d71897
--- /dev/null
+++ b/dubbo-api-docs/dubbo-api-docs-examples/examples-provider/src/main/resources/META-INF/dubbo/org.apache.dubbo.config.ConfigInitializer
@@ -0,0 +1 @@
+testConfigInitializer=org.apache.dubbo.apidocs.examples.spi.TestConfigInitializer
\ No newline at end of file
diff --git a/dubbo-api-docs/dubbo-api-docs-examples/examples-provider/src/main/resources/META-INF/dubbo/org.apache.dubbo.config.ConfigPostProcessor b/dubbo-api-docs/dubbo-api-docs-examples/examples-provider/src/main/resources/META-INF/dubbo/org.apache.dubbo.config.ConfigPostProcessor
new file mode 100644
index 0000000..2d3fe88
--- /dev/null
+++ b/dubbo-api-docs/dubbo-api-docs-examples/examples-provider/src/main/resources/META-INF/dubbo/org.apache.dubbo.config.ConfigPostProcessor
@@ -0,0 +1 @@
+testConfigPostProcessor=org.apache.dubbo.apidocs.examples.spi.TestConfigPostProcessor
\ No newline at end of file
diff --git a/dubbo-api-docs/dubbo-api-docs-examples/examples-provider/src/main/resources/META-INF/dubbo/org.apache.dubbo.rpc.ExporterListener b/dubbo-api-docs/dubbo-api-docs-examples/examples-provider/src/main/resources/META-INF/dubbo/org.apache.dubbo.rpc.ExporterListener
new file mode 100644
index 0000000..154368f
--- /dev/null
+++ b/dubbo-api-docs/dubbo-api-docs-examples/examples-provider/src/main/resources/META-INF/dubbo/org.apache.dubbo.rpc.ExporterListener
@@ -0,0 +1 @@
+dubboDoc=org.apache.dubbo.apidocs.examples.spi.DubboDocExporterListener
\ No newline at end of file
diff --git a/dubbo-api-docs/pom.xml b/dubbo-api-docs/pom.xml
index 42c634e..28c4f00 100644
--- a/dubbo-api-docs/pom.xml
+++ b/dubbo-api-docs/pom.xml
@@ -85,7 +85,7 @@
     </issueManagement>
 
     <properties>
-        <revision>2.7.8.1</revision>
+        <revision>2.7.8.2-SNAPSHOT</revision>
         <project.build.jdkVersion>1.8</project.build.jdkVersion>
         <argLine>-Dfile.encoding=UTF-8</argLine>
         <project.build.sourceEncoding>UTF-8</project.build.sourceEncoding>


[dubbo-spi-extensions] 31/39: prepare for release

Posted by li...@apache.org.
This is an automated email from the ASF dual-hosted git repository.

liujun pushed a commit to branch 2.7.x
in repository https://gitbox.apache.org/repos/asf/dubbo-spi-extensions.git

commit 30f2014b498c74ec593f2c908758895a2ec501d3
Author: ken.lj <ke...@gmail.com>
AuthorDate: Wed Jan 6 00:06:41 2021 +0800

    prepare for release
---
 .../dubbo-api-docs-examples/examples-api/pom.xml   |   7 +-
 .../examples-provider-sca/pom.xml                  |   5 +-
 .../examples-provider/pom.xml                      |   4 +
 dubbo-api-docs/dubbo-api-docs-examples/pom.xml     |   4 +
 dubbo-api-docs/pom.xml                             | 117 +++++++++++++++------
 5 files changed, 103 insertions(+), 34 deletions(-)

diff --git a/dubbo-api-docs/dubbo-api-docs-examples/examples-api/pom.xml b/dubbo-api-docs/dubbo-api-docs-examples/examples-api/pom.xml
index 961cb5c..ccd5cff 100644
--- a/dubbo-api-docs/dubbo-api-docs-examples/examples-api/pom.xml
+++ b/dubbo-api-docs/dubbo-api-docs-examples/examples-api/pom.xml
@@ -27,14 +27,15 @@
 
     <artifactId>examples-api</artifactId>
 
-    <dependencies>
+    <properties>
+        <skip_maven_deploy>true</skip_maven_deploy>
+    </properties>
 
+    <dependencies>
         <dependency>
             <groupId>org.apache.dubbo</groupId>
             <artifactId>dubbo-api-docs-annotations</artifactId>
         </dependency>
-        
     </dependencies>
 
-
 </project>
diff --git a/dubbo-api-docs/dubbo-api-docs-examples/examples-provider-sca/pom.xml b/dubbo-api-docs/dubbo-api-docs-examples/examples-provider-sca/pom.xml
index c1ff683..de8500c 100644
--- a/dubbo-api-docs/dubbo-api-docs-examples/examples-provider-sca/pom.xml
+++ b/dubbo-api-docs/dubbo-api-docs-examples/examples-provider-sca/pom.xml
@@ -27,8 +27,11 @@
 
     <artifactId>examples-provider-sca</artifactId>
 
-    <dependencies>
+    <properties>
+        <skip_maven_deploy>true</skip_maven_deploy>
+    </properties>
 
+    <dependencies>
         <dependency>
             <groupId>org.apache.dubbo</groupId>
             <artifactId>dubbo-api-docs-core</artifactId>
diff --git a/dubbo-api-docs/dubbo-api-docs-examples/examples-provider/pom.xml b/dubbo-api-docs/dubbo-api-docs-examples/examples-provider/pom.xml
index aa16cae..dd05f82 100644
--- a/dubbo-api-docs/dubbo-api-docs-examples/examples-provider/pom.xml
+++ b/dubbo-api-docs/dubbo-api-docs-examples/examples-provider/pom.xml
@@ -27,6 +27,10 @@
 
     <artifactId>examples-provider</artifactId>
 
+    <properties>
+        <skip_maven_deploy>true</skip_maven_deploy>
+    </properties>
+
     <dependencies>
         <dependency>
             <groupId>org.apache.dubbo</groupId>
diff --git a/dubbo-api-docs/dubbo-api-docs-examples/pom.xml b/dubbo-api-docs/dubbo-api-docs-examples/pom.xml
index 1fe85e5..ddadcc8 100644
--- a/dubbo-api-docs/dubbo-api-docs-examples/pom.xml
+++ b/dubbo-api-docs/dubbo-api-docs-examples/pom.xml
@@ -31,6 +31,10 @@
     <packaging>pom</packaging>
     <name>${project.artifactId}</name>
     <description>Dubbo interface documentation examples</description>
+
+    <properties>
+        <skip_maven_deploy>true</skip_maven_deploy>
+    </properties>
     
     <modules>
         <module>examples-api</module>
diff --git a/dubbo-api-docs/pom.xml b/dubbo-api-docs/pom.xml
index 75e5de5..ed3449d 100644
--- a/dubbo-api-docs/pom.xml
+++ b/dubbo-api-docs/pom.xml
@@ -29,14 +29,68 @@
     <packaging>pom</packaging>
     <name>${project.artifactId}</name>
     <description>Dubbo interface documentation, testing tools</description>
+    <url>https://github.com/apache/dubbo</url>
+    <inceptionYear>2020</inceptionYear>
+    <licenses>
+        <license>
+            <name>Apache License, Version 2.0</name>
+            <url>http://www.apache.org/licenses/LICENSE-2.0</url>
+            <distribution>repo</distribution>
+        </license>
+    </licenses>
+
+    <scm>
+        <url>https://github.com/apache/dubbo</url>
+        <connection>scm:git:https://github.com/apache/dubbo-spi-extensions.git</connection>
+        <developerConnection>scm:git:https://github.com/apache/dubbo-spi-extensions.git</developerConnection>
+        <tag>HEAD</tag>
+    </scm>
+    <mailingLists>
+        <mailingList>
+            <name>Development List</name>
+            <subscribe>dev-subscribe@dubbo.apache.org</subscribe>
+            <unsubscribe>dev-unsubscribe@dubbo.apache.org</unsubscribe>
+            <post>dev@dubbo.apache.org</post>
+        </mailingList>
+        <mailingList>
+            <name>Commits List</name>
+            <subscribe>commits-subscribe@dubbo.apache.org</subscribe>
+            <unsubscribe>commits-unsubscribe@dubbo.apache.org</unsubscribe>
+            <post>commits@dubbo.apache.org</post>
+        </mailingList>
+        <mailingList>
+            <name>Issues List</name>
+            <subscribe>issues-subscribe@dubbo.apache.org</subscribe>
+            <unsubscribe>issues-unsubscribe@dubbo.apache.org</unsubscribe>
+            <post>issues@dubbo.apache.org</post>
+        </mailingList>
+    </mailingLists>
+    <developers>
+        <developer>
+            <id>dubbo.io</id>
+            <name>The Dubbo Project Contributors</name>
+            <email>dev-subscribe@dubbo.apache.org</email>
+            <url>http://dubbo.apache.org/</url>
+        </developer>
+    </developers>
+
+    <organization>
+        <name>The Apache Software Foundation</name>
+        <url>http://www.apache.org/</url>
+    </organization>
+
+    <issueManagement>
+        <system>Github Issues</system>
+        <url>https://github.com/apache/dubbo-spi-extensions/issues</url>
+    </issueManagement>
+
     <properties>
-        <revision>2.7.8-SNAPSHOT</revision>
+        <revision>2.7.8</revision>
         <project.build.jdkVersion>1.8</project.build.jdkVersion>
         <argLine>-Dfile.encoding=UTF-8</argLine>
         <project.build.sourceEncoding>UTF-8</project.build.sourceEncoding>
         <skipJunitTest>true</skipJunitTest>
 
-        <skip_maven_deploy>true</skip_maven_deploy>
         <maven-flatten-version>1.1.0</maven-flatten-version>
 
         <spring-boot.version>2.3.4.RELEASE</spring-boot.version>
@@ -161,34 +215,6 @@
     <build>
         <plugins>
             <plugin>
-                <groupId>org.codehaus.mojo</groupId>
-                <artifactId>flatten-maven-plugin</artifactId>
-                <version>${maven-flatten-version}</version>
-                <configuration>
-                    <updatePomFile>true</updatePomFile>
-                    <flattenMode>resolveCiFriendliesOnly</flattenMode>
-                    <pomElements>
-                        <dependencies>expand</dependencies>
-                    </pomElements>
-                </configuration>
-                <executions>
-                    <execution>
-                        <id>flatten</id>
-                        <phase>process-resources</phase>
-                        <goals>
-                            <goal>flatten</goal>
-                        </goals>
-                    </execution>
-                    <execution>
-                        <id>flatten.clean</id>
-                        <phase>clean</phase>
-                        <goals>
-                            <goal>clean</goal>
-                        </goals>
-                    </execution>
-                </executions>
-            </plugin>
-            <plugin>
                 <artifactId>maven-compiler-plugin</artifactId>
                 <configuration>
                     <source>${project.build.jdkVersion}</source>
@@ -208,6 +234,15 @@
             </plugin>
 
             <plugin>
+                <groupId>org.apache.maven.plugins</groupId>
+                <artifactId>maven-deploy-plugin</artifactId>
+                <version>2.8.2</version>
+                <configuration>
+                    <skip>${skip_maven_deploy}</skip>
+                </configuration>
+            </plugin>
+
+            <plugin>
                 <artifactId>maven-surefire-plugin</artifactId>
                 <configuration>
                     <skip>${skipJunitTest}</skip>
@@ -247,4 +282,26 @@
             </plugin>
         </plugins>
     </build>
+
+    <profiles>
+        <profile>
+            <id>release</id>
+            <build>
+                <plugins>
+                    <plugin>
+                        <groupId>org.apache.maven.plugins</groupId>
+                        <artifactId>maven-gpg-plugin</artifactId>
+                        <executions>
+                            <execution>
+                                <phase>verify</phase>
+                                <goals>
+                                    <goal>sign</goal>
+                                </goals>
+                            </execution>
+                        </executions>
+                    </plugin>
+                </plugins>
+            </build>
+        </profile>
+    </profiles>
 </project>


[dubbo-spi-extensions] 01/39: first commit

Posted by li...@apache.org.
This is an automated email from the ASF dual-hosted git repository.

liujun pushed a commit to branch 2.7.x
in repository https://gitbox.apache.org/repos/asf/dubbo-spi-extensions.git

commit aa5162b14a682aa98015bf191f9c365c8a1f71e3
Author: ken.lj <ke...@gmail.com>
AuthorDate: Mon May 18 11:22:29 2020 +0800

    first commit
---
 README.md | 1 +
 1 file changed, 1 insertion(+)

diff --git a/README.md b/README.md
new file mode 100644
index 0000000..3b188df
--- /dev/null
+++ b/README.md
@@ -0,0 +1 @@
+# dubbo-spi-extensions


[dubbo-spi-extensions] 21/39: 移除UI和UI-server(相关功能已合并到dubbo-admin中) 移除对 lombok 的依赖

Posted by li...@apache.org.
This is an automated email from the ASF dual-hosted git repository.

liujun pushed a commit to branch 2.7.x
in repository https://gitbox.apache.org/repos/asf/dubbo-spi-extensions.git

commit 0784b810c1c34c010fe5472d42e68c8a2f3e03ec
Author: qq213539 <21...@qq.com>
AuthorDate: Fri Dec 18 15:12:45 2020 +0800

    移除UI和UI-server(相关功能已合并到dubbo-admin中)
    移除对 lombok 的依赖
---
 dubbo-api-docs/README.md                           |    48 +-
 dubbo-api-docs/README_ch.md                        |    48 +-
 dubbo-api-docs/distribution/LICENSE-BIN            |   334 -
 .../distribution/bin/config/application.yml        |    11 -
 dubbo-api-docs/distribution/bin/log4j2.xml         |    23 -
 dubbo-api-docs/distribution/bin/shutdown.cmd       |    26 -
 dubbo-api-docs/distribution/bin/shutdown.sh        |    31 -
 dubbo-api-docs/distribution/bin/startup.cmd        |    31 -
 dubbo-api-docs/distribution/bin/startup.sh         |    57 -
 dubbo-api-docs/distribution/pom.xml                |    76 -
 .../distribution/release-dubboApiDocs.xml          |    54 -
 .../core/DubboApiDocsAnnotationScanner.java        |    18 +-
 .../dubbo/apidocs/core/beans/ApiCacheItem.java     |    85 +-
 .../apidocs/core/beans/ApiParamsCacheItem.java     |    92 +-
 .../dubbo/apidocs/core/beans/ModuleCacheItem.java  |    36 +-
 .../apache/dubbo/apidocs/core/beans/ParamBean.java |    91 +-
 .../core/providers/DubboDocProviderImpl.java       |     5 +-
 .../apache/dubbo/apidocs/utils/ClassTypeUtil.java  |    18 +-
 .../dubbo/apidocs/examples/api/ISyncDemo.java      |     3 -
 .../apidocs/examples/params/DemoParamBean1.java    |   117 +-
 .../examples/params/DemoParamBean1SubBean1.java    |    29 +-
 .../apidocs/examples/params/DemoParamBean2.java    |    20 +-
 .../apidocs/examples/params/DemoParamBean3.java    |    20 +-
 .../apidocs/examples/params/DemoParamBean4.java    |    12 +-
 .../dubbo/apidocs/examples/params/TestBean.java    |    11 +-
 .../apidocs/examples/responses/BaseResponse.java   |    38 +-
 .../apidocs/examples/responses/DemoRespBean1.java  |    68 +-
 .../apidocs/examples/api/impl/SyncDemoImpl.java    |     6 +-
 .../apidocs/examples/api/impl/SyncDemoImpl.java    |     8 +-
 dubbo-api-docs/dubbo-api-docs-ui-server/pom.xml    |   280 -
 .../apidocs/DubboApiDocsUiServerApplication.java   |    35 -
 .../apache/dubbo/apidocs/cfg/SwaggerConfig.java    |    60 -
 .../org/apache/dubbo/apidocs/cfg/WebConfig.java    |    40 -
 .../apidocs/controller/DubboApiDocsController.java |   189 -
 .../apidocs/controller/vo/ApiInfoRequest.java      |    39 -
 .../controller/vo/CallDubboServiceRequest.java     |    43 -
 .../vo/CallDubboServiceRequestInterfaceParam.java  |    36 -
 .../dubbo/apidocs/editor/CustomDateEditor.java     |   120 -
 .../apidocs/editor/CustomLocalDateEditor.java      |    43 -
 .../apidocs/editor/CustomLocalDateTimeEditor.java  |    43 -
 .../dubbo/apidocs/utils/DubboGenericUtil.java      |   211 -
 .../dubbo/apidocs/utils/LocalDateTimeUtil.java     |    73 -
 .../src/main/resources/application.yml             |    11 -
 .../src/main/resources/banner.txt                  |     7 -
 .../src/main/resources/log4j2.xml                  |    23 -
 .../src/main/resources/static/css/index.css        |     1 -
 .../src/main/resources/static/favicon.png          |   Bin 2719 -> 0 bytes
 .../src/main/resources/static/index.html           |    29 -
 .../src/main/resources/static/js/index.js          |   112 -
 dubbo-api-docs/dubbo-api-docs-ui/.editorconfig     |    12 -
 dubbo-api-docs/dubbo-api-docs-ui/.eslintignore     |    11 -
 dubbo-api-docs/dubbo-api-docs-ui/.eslintrc.js      |     3 -
 dubbo-api-docs/dubbo-api-docs-ui/.gitignore        |    16 -
 dubbo-api-docs/dubbo-api-docs-ui/.prettierignore   |     9 -
 dubbo-api-docs/dubbo-api-docs-ui/.prettierrc.js    |     3 -
 dubbo-api-docs/dubbo-api-docs-ui/.stylelintignore  |     7 -
 dubbo-api-docs/dubbo-api-docs-ui/.stylelintrc.js   |     3 -
 dubbo-api-docs/dubbo-api-docs-ui/README.md         |    14 -
 dubbo-api-docs/dubbo-api-docs-ui/build.json        |    21 -
 dubbo-api-docs/dubbo-api-docs-ui/package-lock.json | 24011 -------------------
 dubbo-api-docs/dubbo-api-docs-ui/package.json      |    51 -
 .../dubbo-api-docs-ui/public/favicon.png           |   Bin 2719 -> 0 bytes
 dubbo-api-docs/dubbo-api-docs-ui/public/index.html |    29 -
 dubbo-api-docs/dubbo-api-docs-ui/src/app.tsx       |   108 -
 .../src/components/NotFound/index.module.scss      |    76 -
 .../src/components/NotFound/index.tsx              |    45 -
 .../src/components/PageLoading/index.jsx           |    24 -
 dubbo-api-docs/dubbo-api-docs-ui/src/constants.js  |    19 -
 dubbo-api-docs/dubbo-api-docs-ui/src/emit.js       |    20 -
 dubbo-api-docs/dubbo-api-docs-ui/src/global.scss   |    39 -
 .../components/Footer/index.module.scss            |    29 -
 .../BasicLayout/components/Footer/index.tsx        |    26 -
 .../BasicLayout/components/PageNav/index.tsx       |    98 -
 .../src/layouts/BasicLayout/index.tsx              |   143 -
 .../dubbo-api-docs-ui/src/locales/en-US.json       |    35 -
 .../dubbo-api-docs-ui/src/locales/zh-CN.json       |    35 -
 .../dubbo-api-docs-ui/src/pages/ApiForm/index.tsx  |   619 -
 .../dubbo-api-docs-ui/src/pages/Home/index.tsx     |    27 -
 dubbo-api-docs/dubbo-api-docs-ui/src/routes.ts     |    28 -
 dubbo-api-docs/dubbo-api-docs-ui/tsconfig.json     |    36 -
 dubbo-api-docs/pom.xml                             |    80 -
 dubbo-api-docs/readmeImgs/DubboDoc.png             |   Bin 74904 -> 0 bytes
 dubbo-api-docs/readmeImgs/dubbo_docs_en.png        |   Bin 0 -> 600733 bytes
 dubbo-api-docs/readmeImgs/dubbo_docs_zh.png        |   Bin 0 -> 538526 bytes
 84 files changed, 623 insertions(+), 27865 deletions(-)

diff --git a/dubbo-api-docs/README.md b/dubbo-api-docs/README.md
index cb86f20..3ed8aed 100644
--- a/dubbo-api-docs/README.md
+++ b/dubbo-api-docs/README.md
@@ -1,4 +1,4 @@
-# dubboDoc
+# dubbo api docs
 
 [中文](./README_ch.md)
 
@@ -6,23 +6,6 @@ Dubbo api documents, test tools, generate documents according to annotations, an
 
 Adding some annotations can generate a swagger like document without turning a non web Dubbo project into a web project
 
-## Version planning
-### First edition
-* Parsing annotations and generating UI
-* Unfriendly user interface (without handling some exceptions)
-### Second edition
-* Replace the JSON text area with a proper JSON editor, and verify the JSON format
-* Add tabs
-* It can save the test and facilitate the next direct loading test
-* Some exceptions are handled as friendly text prompts
-* Add apiRemark.md and show it in the front end
-* Add apiChangelog.md and show it in the front end
-### Follow up edition
-* According to user requirements and issue planning
-* Planning according to Dubbo upgrading
-## Registry center suppor
-* In theory, all registries supported by Dubbo support
-
 ## How to use?
 1. Dubbo api docs annotation added to method parameters of Dubbo project
    * Dubbo provider project introduces dubbo-api-docs-core
@@ -42,13 +25,14 @@ Adding some annotations can generate a swagger like document without turning a n
     <version>${dubbo-version}</version>
 </dependency>
 ```
-2.Download dubbo-doc-ui-server [Download](https://github.com/apache/dubbo-spi-extensions/releases)
+2. Download [dubbo-admin](https://github.com/apache/dubbo-admin) [Download](https://github.com/apache/dubbo-admin/releases)
+
+3. Start dubbo-admin
 
-3. Start dubbo-api-docs-ui-server
+4. Visit: http:// localhost:8080
+
+5. Enter the "API Doc" module
 
-4. Visit: http:// localhost:8888
-   * Port can be modified in application.yml
-   * swagger-ui http:// localhost:8888/swagger-ui/
 ### Annotation use
 * @ApiModule class annotation: dubbo API module information, used to mark the purpose of an interface class module
     * value: module name
@@ -72,15 +56,14 @@ Adding some annotations can generate a swagger like document without turning a n
 * @ResponseProperty Class attribute annotation: mark response parameters
     * value: parameter name
     * example: example
-### dubbo-api-docs-ui
-* Get API list direct connection: 
-> Because Dubbo services with different functions may be registered in the same registration center, 
-> but the name of the interface used by Dubbo doc is the same, so the interface of Dubbo doc uses direct 
-connection to obtain the list of different interfaces of different functions.
-
-* The test can be connected directly or through the registration center
 
 ### Use note
+* Get API list direct connection:
+> Because Dubbo services with different functions may be registered in the same registration center,
+> but the name of the interface used by Dubbo doc is the same, so the interface of Dubbo doc uses direct
+connection to obtain the list of different interfaces of different functions.
+> The test can be connected directly or through the registration center
+
 * The response bean (the return type of the interface) supports custom generics, but only one generic placeholder.
 * About the use of Map: the key of map can only use the basic data type. If the key of map is not the basic data type, the generated key is not in the standard JSON format, and an exception will occur
 * The API's synchronous / asynchronous is from org.apache.dubbo.config.annotation.Service.async
@@ -88,8 +71,6 @@ connection to obtain the list of different interfaces of different functions.
 ## Project structure
 * dubbo-api-docs-annotations: Document generation annotation project
 * dubbo-api-docs-core: Responsible for annotation analysis and document information acquisition interface (Dubbo API)
-* dubbo-api-docs-ui-server: Web service, responsible for displaying doc and providing testing function
-* dubbo-api-docs-ui: The front-end project will be packaged into Dubbo doc UI server project when it is published
 * dubbo-api-docs-examples: Use example
 * readmeImgs: Pictures used by README.md
 
@@ -97,3 +78,6 @@ connection to obtain the list of different interfaces of different functions.
 * spring-boot: 2.3.4.RELEASE
 * dubbo: apache dubbo 2.7.8
 * icework in front(iceworks 4.0)
+
+## Screenshot
+![Screenshot](./readmeImgs/dubbo_docs_en.png)
diff --git a/dubbo-api-docs/README_ch.md b/dubbo-api-docs/README_ch.md
index fa75434..89c231d 100644
--- a/dubbo-api-docs/README_ch.md
+++ b/dubbo-api-docs/README_ch.md
@@ -1,4 +1,4 @@
-# dubboDoc
+# dubbo api docs
 
 [English](./README.md)
 
@@ -6,29 +6,13 @@ dubbo 接口文档、测试工具,根据注解生成文档,并提供测试功能
 
 增加一些注解就能生成类似swagger的文档, 不会把非web的dubbo项目变为web项目.
 
-## 版本规划
-### 第一版
-* 解析注解并生成界面
-* 不太友好的使用界面(没有处理一些异常)
-### 第二版
-* 放json的文本域找一个合适的json编辑器替换,校验json格式
-* 增加标签页
-* 能保存测试,方便下次直接加载测试
-* 部分异常处理为友好的文字提示
-* 增加 apiRemark.md 并在前端展示
-* 增加 apiChangelog.md 并在前端展示
-### 后续版本
-* 根据用户需求和issue规划
-* 根据dubbo升级情况规划
-## 注册中心支持
-* 理论上dubbo支持的所有注册中心都支持
-
 ## 如何使用?
 1. dubbo项目的方法参数中加上 dubbo api docs注解
    * dubbo提供者项目引入 dubbo-api-docs-core
    * 如果dubbo的接口和参数是一个单独的jar包项目,引入dubbo-api-docs-annotations
    
 ### 当前版本: 同Dubbo版本号
+
 ```
 <dependency>
     <groupId>org.apache.dubbo</groupId>
@@ -42,13 +26,15 @@ dubbo 接口文档、测试工具,根据注解生成文档,并提供测试功能
     <version>${dubbo-version}</version>
 </dependency>
 ```
-2.下载 dubbo-api-docs-ui-server [下载地址](https://github.com/apache/dubbo-spi-extensions/releases)
 
-3. 启动 dubbo-api-docs-ui-server
+2. 下载 [dubbo-admin](https://github.com/apache/dubbo-admin) [下载地址](https://github.com/apache/dubbo-admin/releases)
+
+3. 启动 dubbo-admin
+
+4. 访问: http:// localhost:8080
+
+5. 进入"接口文档"模块
 
-4. 访问: http:// localhost:8888
-   * application.yml 中可以修改端口
-   * swagger-ui http:// localhost:8888/swagger-ui/
 ### 注解使用
 * @ApiModule 类注解: dubbo接口模块信息,用于标注一个接口类模块的用途
     * value: 模块名称
@@ -72,12 +58,13 @@ dubbo 接口文档、测试工具,根据注解生成文档,并提供测试功能
 * @ResponseProperty 类属性注解: 标注响应参数
     * value: 参数名
     * example: 示例
-### dubbo-api-docs-ui
-* 获取接口列表直连: 由于可能不同功能的dubbo服务都会注册到同一个注册中心,但是dubbo doc
-使用的接口名是一样的,所以dubbo doc的接口采用直连方式以获取到不同功能服务的不同接口列表
-* 测试可以直连或者走注册中心
-
+    
 ### 使用注意
+* 获取接口列表直连:
+> 由于可能不同功能的dubbo服务都会注册到同一个注册中心,但是dubbo doc
+> 使用的接口名是一样的,所以dubbo doc的接口采用直连方式以获取到不同功能服务的不同接口列表
+> 测试可以直连或者走注册中心
+
 * 响应bean(接口的返回类型)支持自定义泛型, 但只支持一个泛型占位符
 * 关于Map的使用:Map的key只能用基本数据类型.如果Map的key不是基础数据类型,生成的
 就不是标准json格式,会出异常
@@ -86,8 +73,6 @@ dubbo 接口文档、测试工具,根据注解生成文档,并提供测试功能
 ## 项目结构
 * dubbo-api-docs-annotations: 文档生成辅助注解项目
 * dubbo-api-docs-core: 负责注解解析,文档信息获取接口(dubbo接口)
-* dubbo-api-docs-ui-server: web服务,负责展示doc,并提供测试功能
-* dubbo-api-docs-ui: 前端项目, 发布时会打包到 dubbo-doc-ui-server 项目中
 * dubbo-api-docs-examples: 使用示例
 * readmeImgs: README.md 用到的图片
 
@@ -96,4 +81,5 @@ dubbo 接口文档、测试工具,根据注解生成文档,并提供测试功能
 * dubbo: apache dubbo 2.7.8
 * 前端使用飞冰(iceworks 4.0)
 
-![界面](./readmeImgs/DubboDoc.png)
\ No newline at end of file
+## 页面截图
+![页面截图](./readmeImgs/dubbo_docs_zh.png)
\ No newline at end of file
diff --git a/dubbo-api-docs/distribution/LICENSE-BIN b/dubbo-api-docs/distribution/LICENSE-BIN
deleted file mode 100644
index 3726172..0000000
--- a/dubbo-api-docs/distribution/LICENSE-BIN
+++ /dev/null
@@ -1,334 +0,0 @@
-                                 Apache License
-                           Version 2.0, January 2004
-                        http://www.apache.org/licenses/
-
-   TERMS AND CONDITIONS FOR USE, REPRODUCTION, AND DISTRIBUTION
-
-   1. Definitions.
-
-      "License" shall mean the terms and conditions for use, reproduction,
-      and distribution as defined by Sections 1 through 9 of this document.
-
-      "Licensor" shall mean the copyright owner or entity authorized by
-      the copyright owner that is granting the License.
-
-      "Legal Entity" shall mean the union of the acting entity and all
-      other entities that control, are controlled by, or are under common
-      control with that entity. For the purposes of this definition,
-      "control" means (properties) the power, direct or indirect, to cause the
-      direction or management of such entity, whether by contract or
-      otherwise, or (ii) ownership of fifty percent (50%) or more of the
-      outstanding shares, or (iii) beneficial ownership of such entity.
-
-      "You" (or "Your") shall mean an individual or Legal Entity
-      exercising permissions granted by this License.
-
-      "Source" form shall mean the preferred form for making modifications,
-      including but not limited to software source code, documentation
-      source, and configuration files.
-
-      "Object" form shall mean any form resulting from mechanical
-      transformation or translation of a Source form, including but
-      not limited to compiled object code, generated documentation,
-      and conversions to other media types.
-
-      "Work" shall mean the work of authorship, whether in Source or
-      Object form, made available under the License, as indicated by a
-      copyright notice that is included in or attached to the work
-      (an example is provided in the Appendix below).
-
-      "Derivative Works" shall mean any work, whether in Source or Object
-      form, that is based on (or derived from) the Work and for which the
-      editorial revisions, annotations, elaborations, or other modifications
-      represent, as a whole, an original work of authorship. For the purposes
-      of this License, Derivative Works shall not include works that remain
-      separable from, or merely link (or bind by name) to the interfaces of,
-      the Work and Derivative Works thereof.
-
-      "Contribution" shall mean any work of authorship, including
-      the original version of the Work and any modifications or additions
-      to that Work or Derivative Works thereof, that is intentionally
-      submitted to Licensor for inclusion in the Work by the copyright owner
-      or by an individual or Legal Entity authorized to submit on behalf of
-      the copyright owner. For the purposes of this definition, "submitted"
-      means any form of electronic, verbal, or written communication sent
-      to the Licensor or its representatives, including but not limited to
-      communication on electronic mailing lists, source code control systems,
-      and issue tracking systems that are managed by, or on behalf of, the
-      Licensor for the purpose of discussing and improving the Work, but
-      excluding communication that is conspicuously marked or otherwise
-      designated in writing by the copyright owner as "Not a Contribution."
-
-      "Contributor" shall mean Licensor and any individual or Legal Entity
-      on behalf of whom a Contribution has been received by Licensor and
-      subsequently incorporated within the Work.
-
-   2. Grant of Copyright License. Subject to the terms and conditions of
-      this License, each Contributor hereby grants to You a perpetual,
-      worldwide, non-exclusive, no-charge, royalty-free, irrevocable
-      copyright license to reproduce, prepare Derivative Works of,
-      publicly display, publicly perform, sublicense, and distribute the
-      Work and such Derivative Works in Source or Object form.
-
-   3. Grant of Patent License. Subject to the terms and conditions of
-      this License, each Contributor hereby grants to You a perpetual,
-      worldwide, non-exclusive, no-charge, royalty-free, irrevocable
-      (except as stated in this section) patent license to make, have made,
-      use, offer to sell, sell, import, and otherwise transfer the Work,
-      where such license applies only to those patent claims licensable
-      by such Contributor that are necessarily infringed by their
-      Contribution(s) alone or by combination of their Contribution(s)
-      with the Work to which such Contribution(s) was submitted. If You
-      institute patent litigation against any entity (including a
-      cross-claim or counterclaim in a lawsuit) alleging that the Work
-      or a Contribution incorporated within the Work constitutes direct
-      or contributory patent infringement, then any patent licenses
-      granted to You under this License for that Work shall terminate
-      as of the date such litigation is filed.
-
-   4. Redistribution. You may reproduce and distribute copies of the
-      Work or Derivative Works thereof in any medium, with or without
-      modifications, and in Source or Object form, provided that You
-      meet the following conditions:
-
-      (a) You must give any other recipients of the Work or
-          Derivative Works a copy of this License; and
-
-      (b) You must cause any modified files to carry prominent notices
-          stating that You changed the files; and
-
-      (c) You must retain, in the Source form of any Derivative Works
-          that You distribute, all copyright, patent, trademark, and
-          attribution notices from the Source form of the Work,
-          excluding those notices that do not pertain to any part of
-          the Derivative Works; and
-
-      (d) If the Work includes a "NOTICE" text file as part of its
-          distribution, then any Derivative Works that You distribute must
-          include a readable copy of the attribution notices contained
-          within such NOTICE file, excluding those notices that do not
-          pertain to any part of the Derivative Works, in at least one
-          of the following places: within a NOTICE text file distributed
-          as part of the Derivative Works; within the Source form or
-          documentation, if provided along with the Derivative Works; or,
-          within a display generated by the Derivative Works, if and
-          wherever such third-party notices normally appear. The contents
-          of the NOTICE file are for informational purposes only and
-          do not modify the License. You may add Your own attribution
-          notices within Derivative Works that You distribute, alongside
-          or as an addendum to the NOTICE text from the Work, provided
-          that such additional attribution notices cannot be construed
-          as modifying the License.
-
-      You may add Your own copyright statement to Your modifications and
-      may provide additional or different license terms and conditions
-      for use, reproduction, or distribution of Your modifications, or
-      for any such Derivative Works as a whole, provided Your use,
-      reproduction, and distribution of the Work otherwise complies with
-      the conditions stated in this License.
-
-   5. Submission of Contributions. Unless You explicitly state otherwise,
-      any Contribution intentionally submitted for inclusion in the Work
-      by You to the Licensor shall be under the terms and conditions of
-      this License, without any additional terms or conditions.
-      Notwithstanding the above, nothing herein shall supersede or modify
-      the terms of any separate license agreement you may have executed
-      with Licensor regarding such Contributions.
-
-   6. Trademarks. This License does not grant permission to use the trade
-      names, trademarks, service marks, or product names of the Licensor,
-      except as required for reasonable and customary use in describing the
-      origin of the Work and reproducing the content of the NOTICE file.
-
-   7. Disclaimer of Warranty. Unless required by applicable law or
-      agreed to in writing, Licensor provides the Work (and each
-      Contributor provides its Contributions) on an "AS IS" BASIS,
-      WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or
-      implied, including, without limitation, any warranties or conditions
-      of TITLE, NON-INFRINGEMENT, MERCHANTABILITY, or FITNESS FOR A
-      PARTICULAR PURPOSE. You are solely responsible for determining the
-      appropriateness of using or redistributing the Work and assume any
-      risks associated with Your exercise of permissions under this License.
-
-   8. Limitation of Liability. In no event and under no legal theory,
-      whether in tort (including negligence), contract, or otherwise,
-      unless required by applicable law (such as deliberate and grossly
-      negligent acts) or agreed to in writing, shall any Contributor be
-      liable to You for damages, including any direct, indirect, special,
-      incidental, or consequential damages of any character arising as a
-      result of this License or out of the use or inability to use the
-      Work (including but not limited to damages for loss of goodwill,
-      work stoppage, computer failure or malfunction, or any and all
-      other commercial damages or losses), even if such Contributor
-      has been advised of the possibility of such damages.
-
-   9. Accepting Warranty or Additional Liability. While redistributing
-      the Work or Derivative Works thereof, You may choose to offer,
-      and charge a fee for, acceptance of support, warranty, indemnity,
-      or other liability obligations and/or rights consistent with this
-      License. However, in accepting such obligations, You may act only
-      on Your own behalf and on Your sole responsibility, not on behalf
-      of any other Contributor, and only if You agree to indemnify,
-      defend, and hold each Contributor harmless for any liability
-      incurred by, or claims asserted against, such Contributor by reason
-      of your accepting any such warranty or additional liability.
-
-   END OF TERMS AND CONDITIONS
-
-   APPENDIX: How to apply the Apache License to your work.
-
-      To apply the Apache License to your work, attach the following
-      boilerplate notice, with the fields enclosed by brackets "[]"
-      replaced with your own identifying information. (Don't include
-      the brackets!)  The text should be enclosed in the appropriate
-      comment syntax for the file format. We also recommend that a
-      file or class name and description of purpose be included on the
-      same "printed page" as the copyright notice for easier
-      identification within third-party archives.
-
-   Copyright [yyyy] [name of copyright owner]
-
-   Licensed 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.
-
-------
-This product has a bundle logback, which is available under the EPL v1.0 License.
-The source code of logback can be found at https://github.com/qos-ch/logback.
-
-Logback LICENSE
----------------
-
-Logback: the reliable, generic, fast and flexible logging framework.
-Copyright (C) 1999-2015, QOS.ch. All rights reserved.
-
-This program and the accompanying materials are dual-licensed under
-either the terms of the Eclipse Public License v1.0 as published by
-the Eclipse Foundation
-
-  or (per the licensee's choosing)
-
-under the terms of the GNU Lesser General Public License version 2.1
-as published by the Free Software Foundation.
-
-------
-This product has a bundle slf4j, which is available under the MIT License.
-The source code of slf4j can be found at https://github.com/qos-ch/slf4j.
-
- Copyright (c) 2004-2017 QOS.ch
- All rights reserved.
-
- Permission is hereby granted, free  of charge, to any person obtaining
- a  copy  of this  software  and  associated  documentation files  (the
- "Software"), to  deal in  the Software without  restriction, including
- without limitation  the rights to  use, copy, modify,  merge, publish,
- distribute,  sublicense, and/or sell  copies of  the Software,  and to
- permit persons to whom the Software  is furnished to do so, subject to
- the following conditions:
-
- The  above  copyright  notice  and  this permission  notice  shall  be
- included in all copies or substantial portions of the Software.
-
- THE  SOFTWARE IS  PROVIDED  "AS  IS", WITHOUT  WARRANTY  OF ANY  KIND,
- EXPRESS OR  IMPLIED, INCLUDING  BUT NOT LIMITED  TO THE  WARRANTIES OF
- MERCHANTABILITY,    FITNESS    FOR    A   PARTICULAR    PURPOSE    AND
- NONINFRINGEMENT. IN NO EVENT SHALL THE AUTHORS OR COPYRIGHT HOLDERS BE
- LIABLE FOR ANY CLAIM, DAMAGES OR OTHER LIABILITY, WHETHER IN AN ACTION
- OF CONTRACT, TORT OR OTHERWISE,  ARISING FROM, OUT OF OR IN CONNECTION
- WITH THE SOFTWARE OR THE USE OR OTHER DEALINGS IN THE SOFTWARE.
-
-------
-This product has a bundle fastjson, which is available under the ASL2 License.
-The source code of fastjson can be found at https://github.com/alibaba/fastjson.
-
- Copyright 1999-2016 Alibaba Group Holding Ltd.
-
- Licensed 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.
-
-------
-This product has a bundle javassist, which is available under the ASL2 License.
-The source code of javassist can be found at https://github.com/jboss-javassist/javassist.
-
- Copyright (C) 1999- by Shigeru Chiba, All rights reserved.
-
- Javassist (JAVA programming ASSISTant) makes Java bytecode manipulation simple.
- It is a class library for editing bytecodes in Java; it enables Java programs to define a new class
- at runtime and to modify a class file when the JVM loads it. Unlike other similar bytecode editors,
- Javassist provides two levels of API: source level and bytecode level. If the users use the source- level API,
- they can edit a class file without knowledge of the specifications of the Java bytecode.
- The whole API is designed with only the vocabulary of the Java language.
- You can even specify inserted bytecode in the form of source text; Javassist compiles it on the fly.
- On the other hand, the bytecode-level API allows the users to directly edit a class file as other editors.
-
- This software is distributed under the Mozilla Public License Version 1.1,
- the GNU Lesser General Public License Version 2.1 or later, or the Apache License Version 2.0.
-
-------
-This product has a bundle jna, which is available under the ASL2 License.
-The source code of jna can be found at https://github.com/java-native-access/jna.
-
- This copy of JNA is licensed under the
- Apache (Software) License, version 2.0 ("the License").
- See the License for details about distribution rights, and the
- specific rights regarding derivate works.
-
- You may obtain a copy of the License at:
-
- http://www.apache.org/licenses/
-
- A copy is also included in the downloadable source code package
- containing JNA, in file "AL2.0", under the same directory
- as this file.
-------
-This product has a bundle guava, which is available under the ASL2 License.
-The source code of guava can be found at https://github.com/google/guava.
-
- Copyright (C) 2007 The Guava authors 
-
- Licensed 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.
-------
-This product has a bundle OpenMessaging, which is available under the ASL2 License.
-The source code of OpenMessaging can be found at https://github.com/openmessaging/openmessaging.
-
- Copyright (C) 2017 The OpenMessaging authors.
-
- Licensed 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.
-
diff --git a/dubbo-api-docs/distribution/bin/config/application.yml b/dubbo-api-docs/distribution/bin/config/application.yml
deleted file mode 100644
index 76231ff..0000000
--- a/dubbo-api-docs/distribution/bin/config/application.yml
+++ /dev/null
@@ -1,11 +0,0 @@
-server:
-  port: 8888
-spring:
-  application:
-    name: dubbo-api-docs-ui-server
-dubbo:
-  reference:
-    heartbeat: 1000
-  consumer:
-    timeout: 10000
-    retries: 0
\ No newline at end of file
diff --git a/dubbo-api-docs/distribution/bin/log4j2.xml b/dubbo-api-docs/distribution/bin/log4j2.xml
deleted file mode 100644
index 8bd3515..0000000
--- a/dubbo-api-docs/distribution/bin/log4j2.xml
+++ /dev/null
@@ -1,23 +0,0 @@
-<?xml version="1.0" encoding="UTF-8"?>
-<Configuration status="WARN" monitorInterval="600" shutdownHook="disable">
-    <Properties>
-        <Property name="logDir" value="/home/weihu/deploy/logs/dubbo-api-docs/" />
-        <Property name="genericPattern" value="[dubboDoc]-%d{yyyy-MM-dd HH:mm:ss.SSS} [%t] %-5level %logger{36} - %msg%n" />
-        <Property name="genericFilePattern" value="%d{yyyy-MM-dd HH:mm}-%i" />
-    </Properties>
-    <Appenders>
-        <Console name="consoleAppender" target="SYSTEM_OUT">
-            <PatternLayout pattern="${genericPattern}" />
-        </Console>
-
-    </Appenders>
-    <Loggers>
-        <asyncRoot level="INFO">
-            <AppenderRef ref="consoleAppender" />
-        </asyncRoot>
-
-        <logger name="org.springframework" level="ERROR" />
-        <logger name="com.alibaba" level="ERROR" />
-        <logger name="org.apache" level="ERROR" />
-    </Loggers>
-</Configuration>
diff --git a/dubbo-api-docs/distribution/bin/shutdown.cmd b/dubbo-api-docs/distribution/bin/shutdown.cmd
deleted file mode 100644
index 9eb749d..0000000
--- a/dubbo-api-docs/distribution/bin/shutdown.cmd
+++ /dev/null
@@ -1,26 +0,0 @@
-@echo off
-rem Licensed to the Apache Software Foundation (ASF) under one or more
-rem contributor license agreements.  See the NOTICE file distributed with
-rem this work for additional information regarding copyright ownership.
-rem The ASF licenses this file to You under the Apache License, Version 2.0
-rem (the "License"); you may not use this file except in compliance with
-rem the License.  You may obtain a copy of the License at
-rem
-rem http://www.apache.org/licenses/LICENSE-2.0
-rem
-rem Unless required by applicable law or agreed to in writing, software
-rem distributed under the License is distributed on an "AS IS" BASIS,
-rem WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied.
-rem See the License for the specific language governing permissions and
-rem limitations under the License.
-if not exist "%JAVA_HOME%\bin\jps.exe" echo Please set the JAVA_HOME variable in your environment, We need java(x64)! jdk8 or later is better! & EXIT /B 1
-
-setlocal
-
-set "PATH=%JAVA_HOME%\bin;%PATH%"
-
-echo killing dubbo Doc server
-
-for /f "tokens=1" %%i in ('jps -m ^| find "dubbo.api.docs"') do ( taskkill /F /PID %%i )
-
-echo Done!
diff --git a/dubbo-api-docs/distribution/bin/shutdown.sh b/dubbo-api-docs/distribution/bin/shutdown.sh
deleted file mode 100644
index 0b45640..0000000
--- a/dubbo-api-docs/distribution/bin/shutdown.sh
+++ /dev/null
@@ -1,31 +0,0 @@
-#!/bin/sh
-
-# 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.
-
-cd `dirname $0`/../lib
-target_dir=`pwd`
-
-pid=`ps ax | grep -i 'dubbo.api.docs' | grep ${target_dir} | grep java | grep -v grep | awk '{print $1}'`
-if [ -z "$pid" ] ; then
-        echo "No dubbo-api-docs-ui-server running."
-        exit -1;
-fi
-
-echo "The dubbo-api-docs-ui-server(${pid}) is running..."
-
-kill ${pid}
-
-echo "Send shutdown request to dubbo-api-docs-ui-server(${pid}) OK"
diff --git a/dubbo-api-docs/distribution/bin/startup.cmd b/dubbo-api-docs/distribution/bin/startup.cmd
deleted file mode 100644
index d748ab2..0000000
--- a/dubbo-api-docs/distribution/bin/startup.cmd
+++ /dev/null
@@ -1,31 +0,0 @@
-@echo off
-rem Licensed to the Apache Software Foundation (ASF) under one or more
-rem contributor license agreements.  See the NOTICE file distributed with
-rem this work for additional information regarding copyright ownership.
-rem The ASF licenses this file to You under the Apache License, Version 2.0
-rem (the "License"); you may not use this file except in compliance with
-rem the License.  You may obtain a copy of the License at
-rem
-rem http://www.apache.org/licenses/LICENSE-2.0
-rem
-rem Unless required by applicable law or agreed to in writing, software
-rem distributed under the License is distributed on an "AS IS" BASIS,
-rem WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied.
-rem See the License for the specific language governing permissions and
-rem limitations under the License.
-if not exist "%JAVA_HOME%\bin\java.exe" echo Please set the JAVA_HOME variable in your environment, We need java(x64)! jdk8 or later is better! & EXIT /B 1
-set "JAVA=%JAVA_HOME%\bin\java.exe"
-
-setlocal enabledelayedexpansion
-set BASE_DIR=%~dp0
-rem added double quotation marks to avoid the issue caused by the folder names containing spaces.
-rem removed the last 5 chars(which means \bin\) to get the base DIR.
-set BASE_DIR=%BASE_DIR:~0,-5%
-
-set SERVER=dubbo-api-docs-ui-server
-
-set "JAVA_OPT=%JAVA_OPT% -Xms512m -Xmx512m -Xmn256m"
-
-set "JAVA_OPT=%JAVA_OPT% -jar %BASE_DIR%\lib\%SERVER%.jar"
-
-call "%JAVA%" %JAVA_OPT% dubbo.api.docs %*
diff --git a/dubbo-api-docs/distribution/bin/startup.sh b/dubbo-api-docs/distribution/bin/startup.sh
deleted file mode 100644
index c3fd3aa..0000000
--- a/dubbo-api-docs/distribution/bin/startup.sh
+++ /dev/null
@@ -1,57 +0,0 @@
-#!/bin/sh
-
-# 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.
-
-cygwin=false
-darwin=false
-os400=false
-case "`uname`" in
-CYGWIN*) cygwin=true;;
-Darwin*) darwin=true;;
-OS400*) os400=true;;
-esac
-[ ! -e "$JAVA_HOME/bin/java" ] && JAVA_HOME=$HOME/jdk/java
-[ ! -e "$JAVA_HOME/bin/java" ] && JAVA_HOME=/usr/java
-[ ! -e "$JAVA_HOME/bin/java" ] && JAVA_HOME=/opt/taobao/java
-[ ! -e "$JAVA_HOME/bin/java" ] && unset JAVA_HOME
-
-if [ -z "$JAVA_HOME" ]; then
-  if $darwin; then
-
-    if [ -x '/usr/libexec/java_home' ] ; then
-      export JAVA_HOME=`/usr/libexec/java_home`
-
-    elif [ -d "/System/Library/Frameworks/JavaVM.framework/Versions/CurrentJDK/Home" ]; then
-      export JAVA_HOME="/System/Library/Frameworks/JavaVM.framework/Versions/CurrentJDK/Home"
-    fi
-  else
-    JAVA_PATH=`dirname $(readlink -f $(which javac))`
-    if [ "x$JAVA_PATH" != "x" ]; then
-      export JAVA_HOME=`dirname $JAVA_PATH 2>/dev/null`
-    fi
-  fi
-  if [ -z "$JAVA_HOME" ]; then
-        error_exit "Please set the JAVA_HOME variable in your environment, We need java(x64)! jdk8 or later is better!"
-  fi
-fi
-export SERVER="dubbo-api-docs-ui-server"
-export JAVA_HOME
-export JAVA="$JAVA_HOME/bin/java"
-export BASE_DIR=`cd $(dirname $0)/..; pwd`
-JAVA_OPT="${JAVA_OPT} -Xms512m -Xmx512m -Xmn256m"
-JAVA_OPT="${JAVA_OPT} -jar ${BASE_DIR}/lib/${SERVER}.jar"
-nohup $JAVA ${JAVA_OPT} dubbo.api.docs >> ${BASE_DIR}/logs/catlog.out 2>&1 &
-echo "${SERVER} is starting,you can check the ${BASE_DIR}/logs/catlog.out"
\ No newline at end of file
diff --git a/dubbo-api-docs/distribution/pom.xml b/dubbo-api-docs/distribution/pom.xml
deleted file mode 100644
index 72a573c..0000000
--- a/dubbo-api-docs/distribution/pom.xml
+++ /dev/null
@@ -1,76 +0,0 @@
-<?xml version="1.0" encoding="UTF-8"?>
-<!--
-  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.
- -->
-<project xmlns="http://maven.apache.org/POM/4.0.0"
-         xmlns:xsi="http://www.w3.org/2001/XMLSchema-instance"
-         xsi:schemaLocation="http://maven.apache.org/POM/4.0.0 http://maven.apache.org/xsd/maven-4.0.0.xsd">
-
-    <parent>
-        <groupId>org.apache.dubbo</groupId>
-        <artifactId>dubbo-api-docs</artifactId>
-        <version>${revision}</version>
-        <relativePath>../pom.xml</relativePath>
-    </parent>
-
-    <modelVersion>4.0.0</modelVersion>
-
-    <artifactId>dubbo-api-docs-distribution</artifactId>
-    <name>dubbo-api-docs-distribution ${project.version}</name>
-    <packaging>pom</packaging>
-
-    <dependencies>
-        <dependency>
-            <groupId>org.apache.dubbo</groupId>
-            <artifactId>dubbo-api-docs-ui-server</artifactId>
-        </dependency>
-    </dependencies>
-    <profiles>
-        <profile>
-            <id>release-dubboApiDocs</id>
-            <dependencies>
-                <dependency>
-                    <groupId>org.apache.dubbo</groupId>
-                    <artifactId>dubbo-api-docs-ui-server</artifactId>
-                </dependency>
-            </dependencies>
-            <build>
-                <plugins>
-                    <plugin>
-                        <artifactId>maven-assembly-plugin</artifactId>
-                        <version>3.0.0</version>
-                        <configuration>
-                            <descriptors>
-                                <descriptor>release-dubboApiDocs.xml</descriptor>
-                            </descriptors>
-                            <tarLongFileMode>posix</tarLongFileMode>
-                        </configuration>
-                        <executions>
-                            <execution>
-                                <id>make-assembly</id>
-                                <phase>install</phase>
-                                <goals>
-                                    <goal>single</goal>
-                                </goals>
-                            </execution>
-                        </executions>
-                    </plugin>
-                </plugins>
-                <finalName>dubboApiDocs</finalName>
-            </build>
-        </profile>
-    </profiles>
-</project>
diff --git a/dubbo-api-docs/distribution/release-dubboApiDocs.xml b/dubbo-api-docs/distribution/release-dubboApiDocs.xml
deleted file mode 100644
index 837d40c..0000000
--- a/dubbo-api-docs/distribution/release-dubboApiDocs.xml
+++ /dev/null
@@ -1,54 +0,0 @@
-<?xml version="1.0" encoding="UTF-8"?>
-<!--
-  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.
- -->
-<assembly>
-    <id>ui-server-${project.version}</id>
-    <includeBaseDirectory>true</includeBaseDirectory>
-    <formats>
-        <format>dir</format>
-        <format>zip</format>
-    </formats>
-    <fileSets>
-
-        <fileSet>
-            <includes>
-                <include>bin/**</include>
-            </includes>
-            <fileMode>0755</fileMode>
-        </fileSet>
-    </fileSets>
-    <files>
-        <file>
-            <source>LICENSE-BIN</source>
-            <destName>LICENSE</destName>
-        </file>
-        <file>
-            <!--打好的jar包名称和放置目录-->
-            <source>../dubbo-api-docs-ui-server/target/dubbo-api-docs-ui-server.jar</source>
-            <outputDirectory>./lib/</outputDirectory>
-        </file>
-    </files>
-
-    <moduleSets>
-        <moduleSet>
-            <useAllReactorProjects>true</useAllReactorProjects>
-            <includes>
-                <include>org.apache.dubbo:dubbo-api-docs-ui-server</include>
-            </includes>
-        </moduleSet>
-    </moduleSets>
-</assembly>
diff --git a/dubbo-api-docs/dubbo-api-docs-core/src/main/java/org/apache/dubbo/apidocs/core/DubboApiDocsAnnotationScanner.java b/dubbo-api-docs/dubbo-api-docs-core/src/main/java/org/apache/dubbo/apidocs/core/DubboApiDocsAnnotationScanner.java
index b357068..3780c6e 100644
--- a/dubbo-api-docs/dubbo-api-docs-core/src/main/java/org/apache/dubbo/apidocs/core/DubboApiDocsAnnotationScanner.java
+++ b/dubbo-api-docs/dubbo-api-docs-core/src/main/java/org/apache/dubbo/apidocs/core/DubboApiDocsAnnotationScanner.java
@@ -23,6 +23,8 @@ import org.apache.dubbo.apidocs.core.beans.HtmlTypeEnum;
 import org.apache.dubbo.apidocs.core.beans.ParamBean;
 import org.apache.dubbo.apidocs.core.providers.DubboDocProviderImpl;
 import org.apache.dubbo.apidocs.core.providers.IDubboDocProvider;
+import org.apache.dubbo.common.logger.Logger;
+import org.apache.dubbo.common.logger.LoggerFactory;
 import org.apache.dubbo.config.ApplicationConfig;
 import org.apache.dubbo.config.ProtocolConfig;
 import org.apache.dubbo.config.RegistryConfig;
@@ -33,7 +35,6 @@ import org.apache.dubbo.apidocs.annotations.*;
 import org.apache.dubbo.apidocs.utils.ClassTypeUtil;
 
 import com.alibaba.fastjson.JSON;
-import lombok.extern.slf4j.Slf4j;
 import org.springframework.aop.support.AopUtils;
 import org.springframework.beans.factory.annotation.Autowired;
 import org.springframework.boot.context.event.ApplicationReadyEvent;
@@ -53,10 +54,11 @@ import java.util.Map;
 /**
  * Scan and process dubbo doc annotations.
  */
-@Slf4j
 @Import({DubboDocProviderImpl.class})
 public class DubboApiDocsAnnotationScanner implements ApplicationListener<ApplicationReadyEvent> {
 
+    private static final Logger LOG = LoggerFactory.getLogger(DubboApiDocsAnnotationScanner.class);
+
     @Autowired
     private ApplicationContext applicationContext;
 
@@ -75,7 +77,7 @@ public class DubboApiDocsAnnotationScanner implements ApplicationListener<Applic
         IDubboDocProvider dubboDocProvider = applicationContext.getBean(IDubboDocProvider.class);
         exportDubboService(IDubboDocProvider.class, dubboDocProvider, false);
 
-        log.info("================= Dubbo API Docs--Start scanning and processing doc annotations ================");
+        LOG.info("================= Dubbo API Docs--Start scanning and processing doc annotations ================");
 
         Map<String, Object> apiModules = applicationContext.getBeansWithAnnotation(ApiModule.class);
         apiModules.forEach((key, apiModuleTemp) -> {
@@ -87,9 +89,9 @@ public class DubboApiDocsAnnotationScanner implements ApplicationListener<Applic
             }
             ApiModule moduleAnn = apiModuleClass.getAnnotation(ApiModule.class);
             if (!apiModuleClass.isAnnotationPresent(Service.class) && !apiModuleClass.isAnnotationPresent(DubboService.class)) {
-                log.warn(
-                        "【Warning】{} @ApiModule annotation is used, but it is not a dubbo provider (without {} annotation)",
-                        apiModuleClass.getName(), Service.class.getName() + " or " + DubboService.class.getName());
+                LOG.warn( "【Warning】" + apiModuleClass.getName() + " @ApiModule annotation is used, " +
+                                "but it is not a dubbo provider (without " + Service.class.getName() + " or " +
+                                DubboService.class.getName() + " annotation)");
                 return;
             }
             boolean async;
@@ -119,7 +121,7 @@ public class DubboApiDocsAnnotationScanner implements ApplicationListener<Applic
                 }
             }
         });
-        log.info("================= Dubbo API Docs-- doc annotations scanning and processing completed ================");
+        LOG.info("================= Dubbo API Docs-- doc annotations scanning and processing completed ================");
     }
 
     private void processApiDocAnnotation(Method method, List<ApiCacheItem> moduleApiList, ApiModule moduleAnn,
@@ -320,7 +322,7 @@ public class DubboApiDocsAnnotationScanner implements ApplicationListener<Applic
                         enumAllowableValues[i] = (String) getNameMethod.invoke(obj);
                     }
                 } catch (NoSuchMethodException | IllegalAccessException | InvocationTargetException e) {
-                    log.error("", e);
+                    LOG.error("", e);
                 }
                 param.setAllowableValues(enumAllowableValues);
             }
diff --git a/dubbo-api-docs/dubbo-api-docs-core/src/main/java/org/apache/dubbo/apidocs/core/beans/ApiCacheItem.java b/dubbo-api-docs/dubbo-api-docs-core/src/main/java/org/apache/dubbo/apidocs/core/beans/ApiCacheItem.java
index 853c89d..21a7011 100644
--- a/dubbo-api-docs/dubbo-api-docs-core/src/main/java/org/apache/dubbo/apidocs/core/beans/ApiCacheItem.java
+++ b/dubbo-api-docs/dubbo-api-docs-core/src/main/java/org/apache/dubbo/apidocs/core/beans/ApiCacheItem.java
@@ -1,16 +1,10 @@
 package org.apache.dubbo.apidocs.core.beans;
 
-import lombok.Getter;
-import lombok.Setter;
-
 import java.util.List;
-import java.util.Map;
 
 /**
  * api cache item.
  */
-@Getter
-@Setter
 public class ApiCacheItem {
 
     private Boolean async;
@@ -33,4 +27,83 @@ public class ApiCacheItem {
 
     private String methodParamInfo;
 
+    public Boolean getAsync() {
+        return async;
+    }
+
+    public void setAsync(Boolean async) {
+        this.async = async;
+    }
+
+    public String getApiName() {
+        return apiName;
+    }
+
+    public void setApiName(String apiName) {
+        this.apiName = apiName;
+    }
+
+    public String getApiDocName() {
+        return apiDocName;
+    }
+
+    public void setApiDocName(String apiDocName) {
+        this.apiDocName = apiDocName;
+    }
+
+    public String getApiVersion() {
+        return apiVersion;
+    }
+
+    public void setApiVersion(String apiVersion) {
+        this.apiVersion = apiVersion;
+    }
+
+    public String getDescription() {
+        return description;
+    }
+
+    public void setDescription(String description) {
+        this.description = description;
+    }
+
+    public String getApiRespDec() {
+        return apiRespDec;
+    }
+
+    public void setApiRespDec(String apiRespDec) {
+        this.apiRespDec = apiRespDec;
+    }
+
+    public String getApiModelClass() {
+        return apiModelClass;
+    }
+
+    public void setApiModelClass(String apiModelClass) {
+        this.apiModelClass = apiModelClass;
+    }
+
+    public List<ApiParamsCacheItem> getParams() {
+        return params;
+    }
+
+    public void setParams(List<ApiParamsCacheItem> params) {
+        this.params = params;
+    }
+
+    public String getResponse() {
+        return response;
+    }
+
+    public void setResponse(String response) {
+        this.response = response;
+    }
+
+    public String getMethodParamInfo() {
+        return methodParamInfo;
+    }
+
+    public void setMethodParamInfo(String methodParamInfo) {
+        this.methodParamInfo = methodParamInfo;
+    }
 }
diff --git a/dubbo-api-docs/dubbo-api-docs-core/src/main/java/org/apache/dubbo/apidocs/core/beans/ApiParamsCacheItem.java b/dubbo-api-docs/dubbo-api-docs-core/src/main/java/org/apache/dubbo/apidocs/core/beans/ApiParamsCacheItem.java
index 8f0149f..93347af 100644
--- a/dubbo-api-docs/dubbo-api-docs-core/src/main/java/org/apache/dubbo/apidocs/core/beans/ApiParamsCacheItem.java
+++ b/dubbo-api-docs/dubbo-api-docs-core/src/main/java/org/apache/dubbo/apidocs/core/beans/ApiParamsCacheItem.java
@@ -1,15 +1,10 @@
 package org.apache.dubbo.apidocs.core.beans;
 
-import lombok.Getter;
-import lombok.Setter;
-
 import java.util.List;
 
 /**
  * api params cache item.
  */
-@Getter
-@Setter
 public class ApiParamsCacheItem {
 
     private String name;
@@ -34,4 +29,91 @@ public class ApiParamsCacheItem {
 
     private Boolean required;
 
+    public String getName() {
+        return name;
+    }
+
+    public void setName(String name) {
+        this.name = name;
+    }
+
+    public String getDocName() {
+        return docName;
+    }
+
+    public void setDocName(String docName) {
+        this.docName = docName;
+    }
+
+    public String getHtmlType() {
+        return htmlType;
+    }
+
+    public void setHtmlType(String htmlType) {
+        this.htmlType = htmlType;
+    }
+
+    public String[] getAllowableValues() {
+        return allowableValues;
+    }
+
+    public void setAllowableValues(String[] allowableValues) {
+        this.allowableValues = allowableValues;
+    }
+
+    public String getParamType() {
+        return paramType;
+    }
+
+    public void setParamType(String paramType) {
+        this.paramType = paramType;
+    }
+
+    public Integer getParamIndex() {
+        return paramIndex;
+    }
+
+    public void setParamIndex(Integer paramIndex) {
+        this.paramIndex = paramIndex;
+    }
+
+    public List<ParamBean> getParamInfo() {
+        return paramInfo;
+    }
+
+    public void setParamInfo(List<ParamBean> paramInfo) {
+        this.paramInfo = paramInfo;
+    }
+
+    public String getDescription() {
+        return description;
+    }
+
+    public void setDescription(String description) {
+        this.description = description;
+    }
+
+    public String getExample() {
+        return example;
+    }
+
+    public void setExample(String example) {
+        this.example = example;
+    }
+
+    public String getDefaultValue() {
+        return defaultValue;
+    }
+
+    public void setDefaultValue(String defaultValue) {
+        this.defaultValue = defaultValue;
+    }
+
+    public Boolean getRequired() {
+        return required;
+    }
+
+    public void setRequired(Boolean required) {
+        this.required = required;
+    }
 }
diff --git a/dubbo-api-docs/dubbo-api-docs-core/src/main/java/org/apache/dubbo/apidocs/core/beans/ModuleCacheItem.java b/dubbo-api-docs/dubbo-api-docs-core/src/main/java/org/apache/dubbo/apidocs/core/beans/ModuleCacheItem.java
index 10a5133..5f48980 100644
--- a/dubbo-api-docs/dubbo-api-docs-core/src/main/java/org/apache/dubbo/apidocs/core/beans/ModuleCacheItem.java
+++ b/dubbo-api-docs/dubbo-api-docs-core/src/main/java/org/apache/dubbo/apidocs/core/beans/ModuleCacheItem.java
@@ -1,15 +1,10 @@
 package org.apache.dubbo.apidocs.core.beans;
 
-import lombok.Getter;
-import lombok.Setter;
-
 import java.util.List;
 
 /**
  * api module cache item.
  */
-@Getter
-@Setter
 public class ModuleCacheItem {
 
     private String moduleDocName;
@@ -20,4 +15,35 @@ public class ModuleCacheItem {
 
     private List<ApiCacheItem> moduleApiList;
 
+    public String getModuleDocName() {
+        return moduleDocName;
+    }
+
+    public void setModuleDocName(String moduleDocName) {
+        this.moduleDocName = moduleDocName;
+    }
+
+    public String getModuleClassName() {
+        return moduleClassName;
+    }
+
+    public void setModuleClassName(String moduleClassName) {
+        this.moduleClassName = moduleClassName;
+    }
+
+    public String getModuleVersion() {
+        return moduleVersion;
+    }
+
+    public void setModuleVersion(String moduleVersion) {
+        this.moduleVersion = moduleVersion;
+    }
+
+    public List<ApiCacheItem> getModuleApiList() {
+        return moduleApiList;
+    }
+
+    public void setModuleApiList(List<ApiCacheItem> moduleApiList) {
+        this.moduleApiList = moduleApiList;
+    }
 }
diff --git a/dubbo-api-docs/dubbo-api-docs-core/src/main/java/org/apache/dubbo/apidocs/core/beans/ParamBean.java b/dubbo-api-docs/dubbo-api-docs-core/src/main/java/org/apache/dubbo/apidocs/core/beans/ParamBean.java
index b3d1875..d06f00a 100644
--- a/dubbo-api-docs/dubbo-api-docs-core/src/main/java/org/apache/dubbo/apidocs/core/beans/ParamBean.java
+++ b/dubbo-api-docs/dubbo-api-docs-core/src/main/java/org/apache/dubbo/apidocs/core/beans/ParamBean.java
@@ -17,16 +17,12 @@
 package org.apache.dubbo.apidocs.core.beans;
 
 import com.alibaba.fastjson.annotation.JSONField;
-import lombok.Getter;
-import lombok.Setter;
 
 import java.util.List;
 
 /**
  * Parameter bean corresponding to {@link org.apache.dubbo.apidocs.annotations.RequestParam}, for caching.
  */
-@Getter
-@Setter
 public class ParamBean {
 
     /**
@@ -88,4 +84,91 @@ public class ParamBean {
      */
     private String subParamsJson;
 
+    public String getName() {
+        return name;
+    }
+
+    public void setName(String name) {
+        this.name = name;
+    }
+
+    public String getDocName() {
+        return docName;
+    }
+
+    public void setDocName(String docName) {
+        this.docName = docName;
+    }
+
+    public Boolean getRequired() {
+        return required;
+    }
+
+    public void setRequired(Boolean required) {
+        this.required = required;
+    }
+
+    public String getDescription() {
+        return description;
+    }
+
+    public void setDescription(String description) {
+        this.description = description;
+    }
+
+    public String getExample() {
+        return example;
+    }
+
+    public void setExample(String example) {
+        this.example = example;
+    }
+
+    public String getDefaultValue() {
+        return defaultValue;
+    }
+
+    public void setDefaultValue(String defaultValue) {
+        this.defaultValue = defaultValue;
+    }
+
+    public String getJavaType() {
+        return javaType;
+    }
+
+    public void setJavaType(String javaType) {
+        this.javaType = javaType;
+    }
+
+    public HtmlTypeEnum getHtmlType() {
+        return htmlType;
+    }
+
+    public void setHtmlType(HtmlTypeEnum htmlType) {
+        this.htmlType = htmlType;
+    }
+
+    public String[] getAllowableValues() {
+        return allowableValues;
+    }
+
+    public void setAllowableValues(String[] allowableValues) {
+        this.allowableValues = allowableValues;
+    }
+
+    public List<ParamBean> getSubParams() {
+        return subParams;
+    }
+
+    public void setSubParams(List<ParamBean> subParams) {
+        this.subParams = subParams;
+    }
+
+    public String getSubParamsJson() {
+        return subParamsJson;
+    }
+
+    public void setSubParamsJson(String subParamsJson) {
+        this.subParamsJson = subParamsJson;
+    }
 }
diff --git a/dubbo-api-docs/dubbo-api-docs-core/src/main/java/org/apache/dubbo/apidocs/core/providers/DubboDocProviderImpl.java b/dubbo-api-docs/dubbo-api-docs-core/src/main/java/org/apache/dubbo/apidocs/core/providers/DubboDocProviderImpl.java
index 5f93bef..0bddd1c 100644
--- a/dubbo-api-docs/dubbo-api-docs-core/src/main/java/org/apache/dubbo/apidocs/core/providers/DubboDocProviderImpl.java
+++ b/dubbo-api-docs/dubbo-api-docs-core/src/main/java/org/apache/dubbo/apidocs/core/providers/DubboDocProviderImpl.java
@@ -18,16 +18,15 @@ package org.apache.dubbo.apidocs.core.providers;
 
 import org.apache.dubbo.apidocs.core.DubboApiDocsCache;
 import org.apache.dubbo.apidocs.core.beans.ModuleCacheItem;
+import org.apache.dubbo.common.logger.Logger;
+import org.apache.dubbo.common.logger.LoggerFactory;
 import org.apache.dubbo.config.annotation.DubboService;
 
-import lombok.extern.slf4j.Slf4j;
-
 import java.util.List;
 
 /**
  * The api implementation of Dubbo doc.
  */
-@Slf4j
 @DubboService
 public class DubboDocProviderImpl implements IDubboDocProvider {
 
diff --git a/dubbo-api-docs/dubbo-api-docs-core/src/main/java/org/apache/dubbo/apidocs/utils/ClassTypeUtil.java b/dubbo-api-docs/dubbo-api-docs-core/src/main/java/org/apache/dubbo/apidocs/utils/ClassTypeUtil.java
index 199b742..e9bc5d5 100644
--- a/dubbo-api-docs/dubbo-api-docs-core/src/main/java/org/apache/dubbo/apidocs/utils/ClassTypeUtil.java
+++ b/dubbo-api-docs/dubbo-api-docs-core/src/main/java/org/apache/dubbo/apidocs/utils/ClassTypeUtil.java
@@ -18,7 +18,6 @@ package org.apache.dubbo.apidocs.utils;
 
 import com.alibaba.fastjson.JSON;
 import com.alibaba.fastjson.serializer.SerializerFeature;
-import lombok.extern.slf4j.Slf4j;
 import org.apache.commons.lang3.StringUtils;
 import sun.reflect.generics.reflectiveObjects.ParameterizedTypeImpl;
 
@@ -29,13 +28,16 @@ import java.util.*;
 import java.util.concurrent.CompletableFuture;
 
 import org.apache.dubbo.apidocs.annotations.*;
+import org.apache.dubbo.common.logger.Logger;
+import org.apache.dubbo.common.logger.LoggerFactory;
 
 /**
  * Java class tool class, special for Dubbo doc.
  */
-@Slf4j
 public class ClassTypeUtil {
 
+    private static final Logger LOG = LoggerFactory.getLogger(ClassTypeUtil.class);
+
     /**
      * fastjson features
      */
@@ -77,7 +79,7 @@ public class ClassTypeUtil {
      */
     public static Object initClassTypeWithDefaultValue(Type genericType, Class<?> classType, int processCount) {
         if (processCount >= PROCESS_COUNT_MAX) {
-            log.warn("The depth of bean has exceeded 10 layers, the deeper layer will be ignored! " +
+            LOG.warn("The depth of bean has exceeded 10 layers, the deeper layer will be ignored! " +
                     "Please modify the parameter structure or check whether there is circular reference in bean!");
             return null;
         }
@@ -123,8 +125,8 @@ public class ClassTypeUtil {
                                     makeParameterizedType(actualTypeArguments[0].getTypeName()),
                                     makeClass(pt.getActualTypeArguments()[0].getTypeName()), processCount));
                         } else {
-                            log.warn("{}#{} generics are not supported temporarily. " +
-                                    "This property will be ignored", classType.getName(), field2.getName());
+                            LOG.warn(classType.getName() + "#" + field2.getName() + " generics are not supported temporarily. " +
+                                    "This property will be ignored");
                         }
                     } else {
                         result.put(field2.getName(), initClassTypeWithDefaultValue(field2.getGenericType(), field2.getType(), processCount));
@@ -172,7 +174,7 @@ public class ClassTypeUtil {
                     sb.append(getName.invoke(obj)).append("|");
                 }
             } catch (NoSuchMethodException | IllegalAccessException | InvocationTargetException e) {
-                log.error("", e);
+                LOG.error("", e);
             }
             return sb.toString();
         } else if (classType.isArray()) {
@@ -272,7 +274,7 @@ public class ClassTypeUtil {
             Type[] subTypes = makeSubClass(subTypeNamesArray);
             return ParameterizedTypeImpl.make(typeClass, subTypes, null);
         } catch (ClassNotFoundException e) {
-            log.warn("Exception getting generics in completabilefuture", e);
+            LOG.warn("Exception getting generics in completabilefuture", e);
             return null;
         }
     }
@@ -287,7 +289,7 @@ public class ClassTypeUtil {
                 return Class.forName(className.substring(0, className.indexOf("<")));
             }
         } catch (ClassNotFoundException e) {
-            log.warn("Exception getting generics in completabilefuture", e);
+            LOG.warn("Exception getting generics in completabilefuture", e);
             return null;
         }
     }
diff --git a/dubbo-api-docs/dubbo-api-docs-examples/examples-api/src/main/java/org/apache/dubbo/apidocs/examples/api/ISyncDemo.java b/dubbo-api-docs/dubbo-api-docs-examples/examples-api/src/main/java/org/apache/dubbo/apidocs/examples/api/ISyncDemo.java
index e1e8b40..64237dd 100644
--- a/dubbo-api-docs/dubbo-api-docs-examples/examples-api/src/main/java/org/apache/dubbo/apidocs/examples/api/ISyncDemo.java
+++ b/dubbo-api-docs/dubbo-api-docs-examples/examples-api/src/main/java/org/apache/dubbo/apidocs/examples/api/ISyncDemo.java
@@ -42,7 +42,6 @@ public interface ISyncDemo {
 
     /**
      * request and response parameters are Strings
-     * @Date 2020/2/4 0:02
      * @param: param1
      * @param: param2
      * @return java.lang.String
@@ -51,7 +50,6 @@ public interface ISyncDemo {
 
     /**
      * Without Dubbo doc annotation, no document will be generated
-     * @Date 2020/2/4 0:22
      * @param: param1
      * @return java.lang.String
      */
@@ -59,7 +57,6 @@ public interface ISyncDemo {
 
     /**
      * Nonparametric method with Dubbo doc annotation
-     * @Date 2020/2/4 0:02
      * @param:
      * @return java.lang.String
      */
diff --git a/dubbo-api-docs/dubbo-api-docs-examples/examples-api/src/main/java/org/apache/dubbo/apidocs/examples/params/DemoParamBean1.java b/dubbo-api-docs/dubbo-api-docs-examples/examples-api/src/main/java/org/apache/dubbo/apidocs/examples/params/DemoParamBean1.java
index f2b0c97..9eff493 100644
--- a/dubbo-api-docs/dubbo-api-docs-examples/examples-api/src/main/java/org/apache/dubbo/apidocs/examples/params/DemoParamBean1.java
+++ b/dubbo-api-docs/dubbo-api-docs-examples/examples-api/src/main/java/org/apache/dubbo/apidocs/examples/params/DemoParamBean1.java
@@ -18,17 +18,12 @@ package org.apache.dubbo.apidocs.examples.params;
 
 import org.apache.dubbo.apidocs.annotations.RequestParam;
 
-import lombok.Getter;
-import lombok.Setter;
-
 import java.util.List;
 import java.util.Map;
 
 /**
  * demo request bean.
  */
-@Getter
-@Setter
 public class DemoParamBean1 {
 
     @RequestParam(value = "Name", description = "说明测试说明测试说明测试说明测试说明测试说明测试说明测试说明测试说明测试" +
@@ -77,4 +72,116 @@ public class DemoParamBean1 {
     @RequestParam("Object")
     private Object obj1;
 
+    public String getName() {
+        return name;
+    }
+
+    public void setName(String name) {
+        this.name = name;
+    }
+
+    public Integer getAge() {
+        return age;
+    }
+
+    public void setAge(Integer age) {
+        this.age = age;
+    }
+
+    public Boolean getMan() {
+        return man;
+    }
+
+    public void setMan(Boolean man) {
+        this.man = man;
+    }
+
+    public List<DemoParamBean1SubBean1> getSubBean() {
+        return subBean;
+    }
+
+    public void setSubBean(List<DemoParamBean1SubBean1> subBean) {
+        this.subBean = subBean;
+    }
+
+    public Map<String, DemoParamBean1SubBean1> getSubBean2() {
+        return subBean2;
+    }
+
+    public void setSubBean2(Map<String, DemoParamBean1SubBean1> subBean2) {
+        this.subBean2 = subBean2;
+    }
+
+    public String[] getStrArray() {
+        return strArray;
+    }
+
+    public void setStrArray(String[] strArray) {
+        this.strArray = strArray;
+    }
+
+    public DemoParamBean1SubBean1[] getStrArray2() {
+        return strArray2;
+    }
+
+    public void setStrArray2(DemoParamBean1SubBean1[] strArray2) {
+        this.strArray2 = strArray2;
+    }
+
+    public TestEnum getTestEnum() {
+        return testEnum;
+    }
+
+    public void setTestEnum(TestEnum testEnum) {
+        this.testEnum = testEnum;
+    }
+
+    public DemoParamBean1SubBean1 getSubBean3() {
+        return subBean3;
+    }
+
+    public void setSubBean3(DemoParamBean1SubBean1 subBean3) {
+        this.subBean3 = subBean3;
+    }
+
+    public Map getMap1() {
+        return map1;
+    }
+
+    public void setMap1(Map map1) {
+        this.map1 = map1;
+    }
+
+    public Map<Object, Object> getMap2() {
+        return map2;
+    }
+
+    public void setMap2(Map<Object, Object> map2) {
+        this.map2 = map2;
+    }
+
+    public List getList1() {
+        return list1;
+    }
+
+    public void setList1(List list1) {
+        this.list1 = list1;
+    }
+
+    public List<Object> getList2() {
+        return list2;
+    }
+
+    public void setList2(List<Object> list2) {
+        this.list2 = list2;
+    }
+
+    public Object getObj1() {
+        return obj1;
+    }
+
+    public void setObj1(Object obj1) {
+        this.obj1 = obj1;
+    }
+
 }
diff --git a/dubbo-api-docs/dubbo-api-docs-examples/examples-api/src/main/java/org/apache/dubbo/apidocs/examples/params/DemoParamBean1SubBean1.java b/dubbo-api-docs/dubbo-api-docs-examples/examples-api/src/main/java/org/apache/dubbo/apidocs/examples/params/DemoParamBean1SubBean1.java
index 2ce694a..498316a 100644
--- a/dubbo-api-docs/dubbo-api-docs-examples/examples-api/src/main/java/org/apache/dubbo/apidocs/examples/params/DemoParamBean1SubBean1.java
+++ b/dubbo-api-docs/dubbo-api-docs-examples/examples-api/src/main/java/org/apache/dubbo/apidocs/examples/params/DemoParamBean1SubBean1.java
@@ -18,14 +18,9 @@ package org.apache.dubbo.apidocs.examples.params;
 
 import org.apache.dubbo.apidocs.annotations.RequestParam;
 
-import lombok.Getter;
-import lombok.Setter;
-
 /**
  * Attribute bean in DemoParamBean1.
  */
-@Getter
-@Setter
 public class DemoParamBean1SubBean1 {
 
     @RequestParam("Sub Name")
@@ -40,4 +35,28 @@ public class DemoParamBean1SubBean1 {
 //    @RequestParam("====bean")
 //    private DemoParamBean1 bean;
 
+
+    public String getSubName() {
+        return subName;
+    }
+
+    public void setSubName(String subName) {
+        this.subName = subName;
+    }
+
+    public Integer getSubAge() {
+        return subAge;
+    }
+
+    public void setSubAge(Integer subAge) {
+        this.subAge = subAge;
+    }
+
+    public TestEnum getTestEnum() {
+        return testEnum;
+    }
+
+    public void setTestEnum(TestEnum testEnum) {
+        this.testEnum = testEnum;
+    }
 }
diff --git a/dubbo-api-docs/dubbo-api-docs-examples/examples-api/src/main/java/org/apache/dubbo/apidocs/examples/params/DemoParamBean2.java b/dubbo-api-docs/dubbo-api-docs-examples/examples-api/src/main/java/org/apache/dubbo/apidocs/examples/params/DemoParamBean2.java
index 81a3312..4f35888 100644
--- a/dubbo-api-docs/dubbo-api-docs-examples/examples-api/src/main/java/org/apache/dubbo/apidocs/examples/params/DemoParamBean2.java
+++ b/dubbo-api-docs/dubbo-api-docs-examples/examples-api/src/main/java/org/apache/dubbo/apidocs/examples/params/DemoParamBean2.java
@@ -18,14 +18,9 @@ package org.apache.dubbo.apidocs.examples.params;
 
 import org.apache.dubbo.apidocs.annotations.RequestParam;
 
-import lombok.Getter;
-import lombok.Setter;
-
 /**
  * demo request bean 2.
  */
-@Getter
-@Setter
 public class DemoParamBean2 {
 
     @RequestParam(value = "Name 2", allowableValues = {"San Zhang", "Si Li"})
@@ -34,4 +29,19 @@ public class DemoParamBean2 {
     @RequestParam("Age 2")
     private Double age2;
 
+    public String getName2() {
+        return name2;
+    }
+
+    public void setName2(String name2) {
+        this.name2 = name2;
+    }
+
+    public Double getAge2() {
+        return age2;
+    }
+
+    public void setAge2(Double age2) {
+        this.age2 = age2;
+    }
 }
diff --git a/dubbo-api-docs/dubbo-api-docs-examples/examples-api/src/main/java/org/apache/dubbo/apidocs/examples/params/DemoParamBean3.java b/dubbo-api-docs/dubbo-api-docs-examples/examples-api/src/main/java/org/apache/dubbo/apidocs/examples/params/DemoParamBean3.java
index 5a5cf63..8037e5c 100644
--- a/dubbo-api-docs/dubbo-api-docs-examples/examples-api/src/main/java/org/apache/dubbo/apidocs/examples/params/DemoParamBean3.java
+++ b/dubbo-api-docs/dubbo-api-docs-examples/examples-api/src/main/java/org/apache/dubbo/apidocs/examples/params/DemoParamBean3.java
@@ -19,14 +19,9 @@ package org.apache.dubbo.apidocs.examples.params;
 import org.apache.dubbo.apidocs.annotations.RequestParam;
 import org.apache.dubbo.apidocs.annotations.ResponseProperty;
 
-import lombok.Getter;
-import lombok.Setter;
-
 /**
  * DemoParamBean3.
  */
-@Getter
-@Setter
 public class DemoParamBean3 {
 
     @RequestParam("a string")
@@ -37,4 +32,19 @@ public class DemoParamBean3 {
     @ResponseProperty("result a bean4")
     private DemoParamBean4 bean4;
 
+    public String getString() {
+        return string;
+    }
+
+    public void setString(String string) {
+        this.string = string;
+    }
+
+    public DemoParamBean4 getBean4() {
+        return bean4;
+    }
+
+    public void setBean4(DemoParamBean4 bean4) {
+        this.bean4 = bean4;
+    }
 }
diff --git a/dubbo-api-docs/dubbo-api-docs-examples/examples-api/src/main/java/org/apache/dubbo/apidocs/examples/params/DemoParamBean4.java b/dubbo-api-docs/dubbo-api-docs-examples/examples-api/src/main/java/org/apache/dubbo/apidocs/examples/params/DemoParamBean4.java
index 0cc6ea9..d2a89e0 100644
--- a/dubbo-api-docs/dubbo-api-docs-examples/examples-api/src/main/java/org/apache/dubbo/apidocs/examples/params/DemoParamBean4.java
+++ b/dubbo-api-docs/dubbo-api-docs-examples/examples-api/src/main/java/org/apache/dubbo/apidocs/examples/params/DemoParamBean4.java
@@ -19,18 +19,20 @@ package org.apache.dubbo.apidocs.examples.params;
 import org.apache.dubbo.apidocs.annotations.RequestParam;
 import org.apache.dubbo.apidocs.annotations.ResponseProperty;
 
-import lombok.Getter;
-import lombok.Setter;
-
 /**
  * DemoParamBean4.
  */
-@Getter
-@Setter
 public class DemoParamBean4 {
 
     @RequestParam("a string")
     @ResponseProperty("result a string")
     private String bean4Str;
 
+    public String getBean4Str() {
+        return bean4Str;
+    }
+
+    public void setBean4Str(String bean4Str) {
+        this.bean4Str = bean4Str;
+    }
 }
diff --git a/dubbo-api-docs/dubbo-api-docs-examples/examples-api/src/main/java/org/apache/dubbo/apidocs/examples/params/TestBean.java b/dubbo-api-docs/dubbo-api-docs-examples/examples-api/src/main/java/org/apache/dubbo/apidocs/examples/params/TestBean.java
index a655459..a5c151d 100644
--- a/dubbo-api-docs/dubbo-api-docs-examples/examples-api/src/main/java/org/apache/dubbo/apidocs/examples/params/TestBean.java
+++ b/dubbo-api-docs/dubbo-api-docs-examples/examples-api/src/main/java/org/apache/dubbo/apidocs/examples/params/TestBean.java
@@ -16,16 +16,19 @@
  */
 package org.apache.dubbo.apidocs.examples.params;
 
-import lombok.Getter;
-import lombok.Setter;
 
 /**
  * test.
  */
-@Getter
-@Setter
 public class TestBean {
 
     private DemoParamBean1 demoParamBean1;
 
+    public DemoParamBean1 getDemoParamBean1() {
+        return demoParamBean1;
+    }
+
+    public void setDemoParamBean1(DemoParamBean1 demoParamBean1) {
+        this.demoParamBean1 = demoParamBean1;
+    }
 }
diff --git a/dubbo-api-docs/dubbo-api-docs-examples/examples-api/src/main/java/org/apache/dubbo/apidocs/examples/responses/BaseResponse.java b/dubbo-api-docs/dubbo-api-docs-examples/examples-api/src/main/java/org/apache/dubbo/apidocs/examples/responses/BaseResponse.java
index e262827..57bc966 100644
--- a/dubbo-api-docs/dubbo-api-docs-examples/examples-api/src/main/java/org/apache/dubbo/apidocs/examples/responses/BaseResponse.java
+++ b/dubbo-api-docs/dubbo-api-docs-examples/examples-api/src/main/java/org/apache/dubbo/apidocs/examples/responses/BaseResponse.java
@@ -16,16 +16,10 @@
  */
 package org.apache.dubbo.apidocs.examples.responses;
 
-import lombok.Getter;
-import lombok.Setter;
-import lombok.ToString;
 
 /**
  * BaseResponse.
  */
-@Getter
-@Setter
-@ToString
 public class BaseResponse<T> implements java.io.Serializable {
 
     /**
@@ -43,4 +37,36 @@ public class BaseResponse<T> implements java.io.Serializable {
      */
     private T data;
 
+    public String getCode() {
+        return code;
+    }
+
+    public void setCode(String code) {
+        this.code = code;
+    }
+
+    public String getMessage() {
+        return message;
+    }
+
+    public void setMessage(String message) {
+        this.message = message;
+    }
+
+    public T getData() {
+        return data;
+    }
+
+    public void setData(T data) {
+        this.data = data;
+    }
+
+    @Override
+    public String toString() {
+        return "BaseResponse{" +
+                "code='" + code + '\'' +
+                ", message='" + message + '\'' +
+                ", data=" + data +
+                '}';
+    }
 }
diff --git a/dubbo-api-docs/dubbo-api-docs-examples/examples-api/src/main/java/org/apache/dubbo/apidocs/examples/responses/DemoRespBean1.java b/dubbo-api-docs/dubbo-api-docs-examples/examples-api/src/main/java/org/apache/dubbo/apidocs/examples/responses/DemoRespBean1.java
index 657b4b7..d51dc46 100644
--- a/dubbo-api-docs/dubbo-api-docs-examples/examples-api/src/main/java/org/apache/dubbo/apidocs/examples/responses/DemoRespBean1.java
+++ b/dubbo-api-docs/dubbo-api-docs-examples/examples-api/src/main/java/org/apache/dubbo/apidocs/examples/responses/DemoRespBean1.java
@@ -18,17 +18,12 @@ package org.apache.dubbo.apidocs.examples.responses;
 
 import org.apache.dubbo.apidocs.annotations.ResponseProperty;
 
-import lombok.Getter;
-import lombok.Setter;
-
 import java.util.List;
 import java.util.Map;
 
 /**
  * demo response bean 1.
  */
-@Getter
-@Setter
 public class DemoRespBean1 {
 
     @ResponseProperty("Response code")
@@ -55,4 +50,67 @@ public class DemoRespBean1 {
     @ResponseProperty("Object")
     private Object obj1;
 
+    public String getCode() {
+        return code;
+    }
+
+    public void setCode(String code) {
+        this.code = code;
+    }
+
+    public String getMessage() {
+        return message;
+    }
+
+    public void setMessage(String message) {
+        this.message = message;
+    }
+
+    public String getMessage2() {
+        return message2;
+    }
+
+    public void setMessage2(String message2) {
+        this.message2 = message2;
+    }
+
+    public Map getMap1() {
+        return map1;
+    }
+
+    public void setMap1(Map map1) {
+        this.map1 = map1;
+    }
+
+    public Map<Object, Object> getMap2() {
+        return map2;
+    }
+
+    public void setMap2(Map<Object, Object> map2) {
+        this.map2 = map2;
+    }
+
+    public List getList1() {
+        return list1;
+    }
+
+    public void setList1(List list1) {
+        this.list1 = list1;
+    }
+
+    public List<Object> getList2() {
+        return list2;
+    }
+
+    public void setList2(List<Object> list2) {
+        this.list2 = list2;
+    }
+
+    public Object getObj1() {
+        return obj1;
+    }
+
+    public void setObj1(Object obj1) {
+        this.obj1 = obj1;
+    }
 }
diff --git a/dubbo-api-docs/dubbo-api-docs-examples/examples-provider-sca/src/main/java/org/apache/dubbo/apidocs/examples/api/impl/SyncDemoImpl.java b/dubbo-api-docs/dubbo-api-docs-examples/examples-provider-sca/src/main/java/org/apache/dubbo/apidocs/examples/api/impl/SyncDemoImpl.java
index 877c57b..7368cee 100644
--- a/dubbo-api-docs/dubbo-api-docs-examples/examples-provider-sca/src/main/java/org/apache/dubbo/apidocs/examples/api/impl/SyncDemoImpl.java
+++ b/dubbo-api-docs/dubbo-api-docs-examples/examples-provider-sca/src/main/java/org/apache/dubbo/apidocs/examples/api/impl/SyncDemoImpl.java
@@ -28,7 +28,8 @@ import org.apache.dubbo.apidocs.examples.responses.BaseResponse;
 import org.apache.dubbo.apidocs.examples.responses.DemoRespBean1;
 import org.apache.dubbo.config.annotation.DubboService;
 
-import lombok.extern.slf4j.Slf4j;
+import org.slf4j.Logger;
+import org.slf4j.LoggerFactory;
 
 import java.util.List;
 import java.util.Map;
@@ -36,11 +37,12 @@ import java.util.Map;
 /**
  * Synchronous demo implementation.
  */
-@Slf4j
 @DubboService
 @ApiModule(value = "Synchronous demo", apiInterface = ISyncDemo.class)
 public class SyncDemoImpl implements ISyncDemo {
 
+    private static final Logger log = LoggerFactory.getLogger(SyncDemoImpl.class);
+
     @ApiDoc("request and response parameters are beans")
     @Override
     public DemoRespBean1 demoApi1(DemoParamBean1 param1, DemoParamBean2 param2) {
diff --git a/dubbo-api-docs/dubbo-api-docs-examples/examples-provider/src/main/java/org/apache/dubbo/apidocs/examples/api/impl/SyncDemoImpl.java b/dubbo-api-docs/dubbo-api-docs-examples/examples-provider/src/main/java/org/apache/dubbo/apidocs/examples/api/impl/SyncDemoImpl.java
index 0449688..8998566 100644
--- a/dubbo-api-docs/dubbo-api-docs-examples/examples-provider/src/main/java/org/apache/dubbo/apidocs/examples/api/impl/SyncDemoImpl.java
+++ b/dubbo-api-docs/dubbo-api-docs-examples/examples-provider/src/main/java/org/apache/dubbo/apidocs/examples/api/impl/SyncDemoImpl.java
@@ -16,8 +16,6 @@
  */
 package org.apache.dubbo.apidocs.examples.api.impl;
 
-import lombok.extern.slf4j.Slf4j;
-
 import org.apache.dubbo.apidocs.annotations.ApiDoc;
 import org.apache.dubbo.apidocs.annotations.ApiModule;
 import org.apache.dubbo.apidocs.annotations.RequestParam;
@@ -30,17 +28,21 @@ import org.apache.dubbo.apidocs.examples.responses.BaseResponse;
 import org.apache.dubbo.apidocs.examples.responses.DemoRespBean1;
 import org.apache.dubbo.config.annotation.DubboService;
 
+import org.slf4j.Logger;
+import org.slf4j.LoggerFactory;
+
 import java.util.List;
 import java.util.Map;
 
 /**
  * Synchronous demo implementation.
  */
-@Slf4j
 @DubboService
 @ApiModule(value = "Synchronous demo", apiInterface = ISyncDemo.class)
 public class SyncDemoImpl implements ISyncDemo {
 
+    private static final Logger log = LoggerFactory.getLogger(SyncDemoImpl.class);
+
     @ApiDoc("request and response parameters are beans")
     @Override
     public DemoRespBean1 demoApi1(DemoParamBean1 param1, DemoParamBean2 param2) {
diff --git a/dubbo-api-docs/dubbo-api-docs-ui-server/pom.xml b/dubbo-api-docs/dubbo-api-docs-ui-server/pom.xml
deleted file mode 100644
index 32a7230..0000000
--- a/dubbo-api-docs/dubbo-api-docs-ui-server/pom.xml
+++ /dev/null
@@ -1,280 +0,0 @@
-<?xml version="1.0" encoding="UTF-8"?>
-<!--
-  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.
- -->
-<project xmlns="http://maven.apache.org/POM/4.0.0" xmlns:xsi="http://www.w3.org/2001/XMLSchema-instance" xsi:schemaLocation="http://maven.apache.org/POM/4.0.0 http://maven.apache.org/xsd/maven-4.0.0.xsd">
-    <modelVersion>4.0.0</modelVersion>
-
-    <parent>
-        <groupId>org.apache.dubbo</groupId>
-        <artifactId>dubbo-api-docs</artifactId>
-        <version>${revision}</version>
-        <relativePath>../pom.xml</relativePath>
-    </parent>
-
-    <artifactId>dubbo-api-docs-ui-server</artifactId>
-    <packaging>jar</packaging>
-    <name>dubbo-api-docs-ui-server</name>
-    <description>Web ui, responsible for displaying doc and providing testing function</description>
-
-    <properties>
-    </properties>
-
-    <dependencyManagement>
-        <dependencies>
-            <dependency>
-                <groupId>org.springframework.boot</groupId>
-                <artifactId>spring-boot-starter-parent</artifactId>
-                <version>${spring-boot.version}</version>
-                <type>pom</type>
-                <scope>import</scope>
-            </dependency>
-        </dependencies>
-    </dependencyManagement>
-
-    <dependencies>
-
-        <!--
-        [Begin] Solve the spring fox problem temporarily
-        Spring fox relies on 1.2.0 but doesn't work. It works under 2.0.0
-        <dependency>
-            <groupId>org.springframework.plugin</groupId>
-            <artifactId>spring-plugin-core</artifactId>
-            <version>2.0.0.RELEASE</version>
-        </dependency>
-        <dependency>
-            <groupId>org.springframework.plugin</groupId>
-            <artifactId>spring-plugin-metadata</artifactId>
-            <version>2.0.0.RELEASE</version>
-        </dependency>
-        [End] Solve the spring fox problem temporarily -->
-
-        <dependency>
-            <groupId>org.springframework.boot</groupId>
-            <artifactId>spring-boot-starter-webflux</artifactId>
-            <exclusions>
-                <exclusion>
-                    <groupId>org.springframework.boot</groupId>
-                    <artifactId>spring-boot-starter-logging</artifactId>
-                </exclusion>
-            </exclusions>
-        </dependency>
-
-        <dependency>
-            <groupId>org.apache.logging.log4j</groupId>
-            <artifactId>log4j-1.2-api</artifactId>
-        </dependency>
-
-        <dependency>
-            <groupId>org.apache.logging.log4j</groupId>
-            <artifactId>log4j-slf4j-impl</artifactId>
-        </dependency>
-        <dependency>
-            <groupId>org.slf4j</groupId>
-            <artifactId>jcl-over-slf4j</artifactId>
-        </dependency>
-        <dependency>
-            <groupId>com.lmax</groupId>
-            <artifactId>disruptor</artifactId>
-        </dependency>
-
-        <dependency>
-            <groupId>org.apache.dubbo</groupId>
-            <artifactId>dubbo</artifactId>
-        </dependency>
-
-        <dependency>
-            <groupId>org.apache.dubbo</groupId>
-            <artifactId>dubbo-registry-nacos</artifactId>
-            <exclusions>
-                <exclusion>
-                    <artifactId>log4j</artifactId>
-                    <groupId>log4j</groupId>
-                </exclusion>
-                <exclusion>
-                    <groupId>org.apache.dubbo</groupId>
-                    <artifactId>dubbo-remoting-api</artifactId>
-                </exclusion>
-                <exclusion>
-                    <artifactId>dubbo-common</artifactId>
-                    <groupId>org.apache.dubbo</groupId>
-                </exclusion>
-            </exclusions>
-        </dependency>
-
-        <dependency>
-            <groupId>org.apache.dubbo</groupId>
-            <artifactId>dubbo-registry-consul</artifactId>
-        </dependency>
-
-        <dependency>
-            <groupId>org.apache.dubbo</groupId>
-            <artifactId>dubbo-registry-default</artifactId>
-        </dependency>
-
-        <dependency>
-            <groupId>org.apache.dubbo</groupId>
-            <artifactId>dubbo-registry-etcd3</artifactId>
-            <exclusions>
-                <exclusion>
-                    <artifactId>log4j</artifactId>
-                    <groupId>log4j</groupId>
-                </exclusion>
-                <exclusion>
-                    <groupId>org.apache.dubbo</groupId>
-                    <artifactId>dubbo-remoting-api</artifactId>
-                </exclusion>
-                <exclusion>
-                    <artifactId>dubbo-common</artifactId>
-                    <groupId>org.apache.dubbo</groupId>
-                </exclusion>
-            </exclusions>
-        </dependency>
-
-        <dependency>
-            <groupId>org.apache.dubbo</groupId>
-            <artifactId>dubbo-registry-multicast</artifactId>
-        </dependency>
-
-        <dependency>
-            <groupId>org.apache.dubbo</groupId>
-            <artifactId>dubbo-registry-multiple</artifactId>
-        </dependency>
-
-        <dependency>
-            <groupId>org.apache.dubbo</groupId>
-            <artifactId>dubbo-registry-redis</artifactId>
-            <exclusions>
-                <exclusion>
-                    <artifactId>log4j</artifactId>
-                    <groupId>log4j</groupId>
-                </exclusion>
-                <exclusion>
-                    <groupId>org.apache.dubbo</groupId>
-                    <artifactId>dubbo-remoting-api</artifactId>
-                </exclusion>
-                <exclusion>
-                    <artifactId>dubbo-common</artifactId>
-                    <groupId>org.apache.dubbo</groupId>
-                </exclusion>
-            </exclusions>
-        </dependency>
-
-        <dependency>
-            <groupId>org.apache.dubbo</groupId>
-            <artifactId>dubbo-registry-sofa</artifactId>
-        </dependency>
-
-        <dependency>
-            <groupId>org.apache.dubbo</groupId>
-            <artifactId>dubbo-registry-zookeeper</artifactId>
-            <exclusions>
-                <exclusion>
-                    <artifactId>slf4j-log4j12</artifactId>
-                    <groupId>org.slf4j</groupId>
-                </exclusion>
-                <exclusion>
-                    <artifactId>log4j</artifactId>
-                    <groupId>log4j</groupId>
-                </exclusion>
-                <exclusion>
-                    <groupId>org.apache.dubbo</groupId>
-                    <artifactId>dubbo-remoting-api</artifactId>
-                </exclusion>
-                <exclusion>
-                    <artifactId>dubbo-common</artifactId>
-                    <groupId>org.apache.dubbo</groupId>
-                </exclusion>
-            </exclusions>
-        </dependency>
-
-        <dependency>
-            <groupId>com.alibaba.nacos</groupId>
-            <artifactId>nacos-api</artifactId>
-            <scope>compile</scope>
-        </dependency>
-
-        <dependency>
-            <groupId>com.alibaba.nacos</groupId>
-            <artifactId>nacos-client</artifactId>
-        </dependency>
-
-        <dependency>
-            <groupId>io.springfox</groupId>
-            <artifactId>springfox-boot-starter</artifactId>
-        </dependency>
-
-        <dependency>
-            <groupId>commons-io</groupId>
-            <artifactId>commons-io</artifactId>
-        </dependency>
-
-        <dependency>
-            <groupId>commons-beanutils</groupId>
-            <artifactId>commons-beanutils</artifactId>
-        </dependency>
-
-        <dependency>
-            <groupId>org.apache.commons</groupId>
-            <artifactId>commons-collections4</artifactId>
-        </dependency>
-
-    </dependencies>
-
-    <profiles>
-        <profile>
-            <id>release-dubboApiDocs</id>
-            <build>
-                <finalName>dubbo-api-docs-ui-server</finalName>
-                <plugins>
-                    <plugin>
-                        <groupId>org.springframework.boot</groupId>
-                        <artifactId>spring-boot-maven-plugin</artifactId>
-                        <configuration>
-                            <mainClass>org.apache.dubbo.apidocs.DubboApiDocsUiServerApplication</mainClass>
-                            <layout>ZIP</layout>
-                        </configuration>
-                        <executions>
-                            <execution>
-                                <goals>
-                                    <goal>repackage</goal>
-                                </goals>
-                            </execution>
-                        </executions>
-                    </plugin>
-                    <plugin>
-                        <groupId>org.apache.maven.plugins</groupId>
-                        <artifactId>maven-jar-plugin</artifactId>
-                        <configuration>
-                            <archive>
-                                <manifest>
-                                    <addDefaultImplementationEntries>true</addDefaultImplementationEntries>
-                                    <addDefaultSpecificationEntries>true</addDefaultSpecificationEntries>
-                                </manifest>
-                            </archive>
-                            <excludes>
-                                <exclude>**/application.yml</exclude>
-                                <exclude>**/log4j2.xml</exclude>
-                                <exclude>**/rebel.xml</exclude>
-                            </excludes>
-                        </configuration>
-                    </plugin>
-                </plugins>
-            </build>
-        </profile>
-    </profiles>
-
-</project>
\ No newline at end of file
diff --git a/dubbo-api-docs/dubbo-api-docs-ui-server/src/main/java/org/apache/dubbo/apidocs/DubboApiDocsUiServerApplication.java b/dubbo-api-docs/dubbo-api-docs-ui-server/src/main/java/org/apache/dubbo/apidocs/DubboApiDocsUiServerApplication.java
deleted file mode 100644
index 8186ec1..0000000
--- a/dubbo-api-docs/dubbo-api-docs-ui-server/src/main/java/org/apache/dubbo/apidocs/DubboApiDocsUiServerApplication.java
+++ /dev/null
@@ -1,35 +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.apidocs;
-
-import org.springframework.boot.SpringApplication;
-import org.springframework.boot.autoconfigure.SpringBootApplication;
-import org.springframework.context.ConfigurableApplicationContext;
-
-
-/**
- * Start Dubbo doc ui server.
- */
-@SpringBootApplication
-public class DubboApiDocsUiServerApplication {
-
-
-    public static void main(String[] args) {
-        ConfigurableApplicationContext ctx = SpringApplication.run(DubboApiDocsUiServerApplication.class);
-    }
-
-}
diff --git a/dubbo-api-docs/dubbo-api-docs-ui-server/src/main/java/org/apache/dubbo/apidocs/cfg/SwaggerConfig.java b/dubbo-api-docs/dubbo-api-docs-ui-server/src/main/java/org/apache/dubbo/apidocs/cfg/SwaggerConfig.java
deleted file mode 100644
index 1b3e15b..0000000
--- a/dubbo-api-docs/dubbo-api-docs-ui-server/src/main/java/org/apache/dubbo/apidocs/cfg/SwaggerConfig.java
+++ /dev/null
@@ -1,60 +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.apidocs.cfg;
-
-
-import io.swagger.annotations.Api;
-import org.springframework.context.annotation.Bean;
-import org.springframework.context.annotation.Configuration;
-import springfox.documentation.builders.ApiInfoBuilder;
-import springfox.documentation.builders.PathSelectors;
-import springfox.documentation.builders.RequestHandlerSelectors;
-import springfox.documentation.service.*;
-import springfox.documentation.spi.DocumentationType;
-import springfox.documentation.spring.web.plugins.Docket;
-import springfox.documentation.swagger2.annotations.EnableSwagger2;
-import springfox.documentation.swagger2.annotations.EnableSwagger2WebFlux;
-
-/**
- * swagger config.
- */
-@Configuration
-@EnableSwagger2
-public class SwaggerConfig {
-
-    public static final String VERSION = "1.0.0";
-
-    protected ApiInfo apiInfo() {
-        return new ApiInfoBuilder().title("Dubbo API docs").description("&nbsp;")
-                .license("Apache 2.0")
-                .licenseUrl("http://www.apache.org/licenses/LICENSE-2.0.html")
-                .termsOfServiceUrl("").version(VERSION)
-                .build();
-    }
-
-    @Bean
-    public Docket customImplementationDevHelper() {
-        return new Docket(DocumentationType.SWAGGER_2)
-                .groupName("【Dubbo API docs】")
-                .select()
-                .paths(PathSelectors.ant("/**"))
-                .apis(RequestHandlerSelectors.withClassAnnotation(Api.class))
-                .build()
-                .apiInfo(apiInfo());
-    }
-    
-}
diff --git a/dubbo-api-docs/dubbo-api-docs-ui-server/src/main/java/org/apache/dubbo/apidocs/cfg/WebConfig.java b/dubbo-api-docs/dubbo-api-docs-ui-server/src/main/java/org/apache/dubbo/apidocs/cfg/WebConfig.java
deleted file mode 100644
index 6cbb26f..0000000
--- a/dubbo-api-docs/dubbo-api-docs-ui-server/src/main/java/org/apache/dubbo/apidocs/cfg/WebConfig.java
+++ /dev/null
@@ -1,40 +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.apidocs.cfg;
-
-import org.springframework.stereotype.Component;
-import org.springframework.web.server.ServerWebExchange;
-import org.springframework.web.server.WebFilter;
-import org.springframework.web.server.WebFilterChain;
-import reactor.core.publisher.Mono;
-
-/**
- * web config.
- */
-@Component
-public class WebConfig implements WebFilter {
-
-    @Override
-    public Mono<Void> filter(ServerWebExchange exchange, WebFilterChain chain) {
-        if (exchange.getRequest().getURI().getPath().equals("/")) {
-            return chain.filter(exchange.mutate().request(exchange.getRequest().mutate().path("/index.html").build()).build());
-        }
-
-        return chain.filter(exchange);
-    }
-
-}
diff --git a/dubbo-api-docs/dubbo-api-docs-ui-server/src/main/java/org/apache/dubbo/apidocs/controller/DubboApiDocsController.java b/dubbo-api-docs/dubbo-api-docs-ui-server/src/main/java/org/apache/dubbo/apidocs/controller/DubboApiDocsController.java
deleted file mode 100644
index 838cf8e..0000000
--- a/dubbo-api-docs/dubbo-api-docs-ui-server/src/main/java/org/apache/dubbo/apidocs/controller/DubboApiDocsController.java
+++ /dev/null
@@ -1,189 +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.apidocs.controller;
-
-import org.apache.dubbo.apidocs.controller.vo.ApiInfoRequest;
-import org.apache.dubbo.apidocs.controller.vo.CallDubboServiceRequest;
-import org.apache.dubbo.apidocs.controller.vo.CallDubboServiceRequestInterfaceParam;
-import org.apache.dubbo.apidocs.editor.CustomDateEditor;
-import org.apache.dubbo.apidocs.editor.CustomLocalDateEditor;
-import org.apache.dubbo.apidocs.editor.CustomLocalDateTimeEditor;
-import org.apache.dubbo.apidocs.utils.DubboGenericUtil;
-
-import com.alibaba.fastjson.JSON;
-import com.alibaba.fastjson.serializer.SimplePropertyPreFilter;
-import io.swagger.annotations.Api;
-import io.swagger.annotations.ApiOperation;
-import lombok.extern.slf4j.Slf4j;
-import org.apache.commons.collections4.CollectionUtils;
-import org.apache.commons.lang3.StringUtils;
-import org.springframework.beans.factory.annotation.Value;
-import org.springframework.beans.propertyeditors.StringTrimmerEditor;
-import org.springframework.web.bind.WebDataBinder;
-import org.springframework.web.bind.annotation.*;
-import reactor.core.publisher.Mono;
-
-import javax.annotation.PostConstruct;
-import java.time.LocalDate;
-import java.time.LocalDateTime;
-import java.util.*;
-import java.util.concurrent.CompletableFuture;
-
-/**
- * dubbo doc ui server api.
- */
-@Api(tags = {"dubbo doc ui server api"})
-@RestController
-@Slf4j
-@RequestMapping("/api")
-public class DubboApiDocsController {
-
-    private static final SimplePropertyPreFilter CLASS_NAME_PRE_FILTER = new SimplePropertyPreFilter(HashMap.class);
-    static {
-        // Remove the "class" attribute from the returned result
-        CLASS_NAME_PRE_FILTER.getExcludes().add("class");
-    }
-
-    /**
-     * retries for dubbo provider.
-     */
-    @Value("${dubbo.consumer.retries:2}")
-    private int retries;
-
-    /**
-     * timeout.
-     */
-    @Value("${dubbo.consumer.timeout:1000}")
-    private int timeout;
-
-    @InitBinder
-    public void initBinder(WebDataBinder binder) {
-        binder.registerCustomEditor(String.class, new StringTrimmerEditor(true));
-        binder.registerCustomEditor(Date.class, new CustomDateEditor());
-        binder.registerCustomEditor(LocalDate.class, new CustomLocalDateEditor());
-        binder.registerCustomEditor(LocalDateTime.class, new CustomLocalDateTimeEditor());
-    }
-
-    /**
-     * Set timeout and retries for {@link DubboGenericUtil}.
-     * 2020/11/14 20:26
-     */
-    @PostConstruct
-    public void setRetriesAndTimeout(){
-        DubboGenericUtil.setRetriesAndTimeout(retries, timeout);
-    }
-
-    @ApiOperation(value = "request dubbo api", notes = "request dubbo api", httpMethod = "POST", produces = "application/json")
-    @PostMapping("/requestDubbo")
-    public Mono<String> callDubboService(CallDubboServiceRequest dubboCfg, @RequestBody List<CallDubboServiceRequestInterfaceParam> methodParams){
-        String[] paramTypes = null;
-        Object[] paramValues = null;
-        if(CollectionUtils.isNotEmpty(methodParams)){
-            paramTypes = new String[methodParams.size()];
-            paramValues = new Object[methodParams.size()];
-            for(int i = 0; i < methodParams.size(); i++){
-                CallDubboServiceRequestInterfaceParam param = methodParams.get(i);
-                paramTypes[i] = param.getParamType();
-                Object paramValue = param.getParamValue();
-                if(isBaseType(param.getParamType()) && null != paramValue){
-                    if(paramValue instanceof Map){
-                        Map<?, ?> tempMap = (Map<?, ?>) paramValue;
-                        if(!tempMap.isEmpty()) {
-                            this.emptyString2Null(tempMap);
-                            paramValues[i] = tempMap.values().stream().findFirst().orElse(null);
-                        }
-                    } else {
-                        paramValues[i] = emptyString2Null(paramValue);
-                    }
-                } else {
-                    this.emptyString2Null(paramValue);
-                    paramValues[i] = paramValue;
-                }
-            }
-        }
-        if (null == paramTypes) {
-            paramTypes = new String[0];
-        }
-        if (null == paramValues) {
-            paramValues = new Object[0];
-        }
-        CompletableFuture<Object> future = DubboGenericUtil.invoke(dubboCfg.getRegistryCenterUrl(), dubboCfg.getInterfaceClassName(),
-                dubboCfg.getMethodName(), dubboCfg.isAsync(), paramTypes, paramValues);
-        return Mono.fromFuture(future).map( o -> JSON.toJSONString(o, CLASS_NAME_PRE_FILTER));
-    }
-
-    private Object emptyString2Null(Object paramValue){
-        if(null != paramValue) {
-            if (paramValue instanceof String && StringUtils.isBlank((String) paramValue)) {
-                return null;
-            } else if (paramValue instanceof Map) {
-                Map<String, Object> tempMap = (Map<String, Object>) paramValue;
-                tempMap.forEach((k, v) -> {
-                    if (v != null && v instanceof String && StringUtils.isBlank((String) v)) {
-                        tempMap.put(k, null);
-                    } else {
-                        this.emptyString2Null(v);
-                    }
-                });
-            }
-        }
-        return paramValue;
-    }
-
-    @ApiOperation(value = "Get basic information of all modules, excluding API parameter information", notes = "Get basic information of all modules, excluding API parameter information", httpMethod = "GET", produces = "application/json")
-    @GetMapping("/apiModuleList")
-    public Mono<String> apiModuleList(ApiInfoRequest apiInfoRequest){
-        CallDubboServiceRequest req = new CallDubboServiceRequest();
-        req.setRegistryCenterUrl("dubbo://" + apiInfoRequest.getDubboIp() + ":" + apiInfoRequest.getDubboPort());
-        req.setInterfaceClassName("org.apache.dubbo.apidocs.core.providers.IDubboDocProvider");
-        req.setMethodName("apiModuleList");
-        req.setAsync(false);
-        return callDubboService(req, null);
-    }
-
-    @ApiOperation(value = "Get the parameter information of the specified API", notes = "Get the parameter information of the specified API", httpMethod = "GET", produces = "application/json")
-    @GetMapping("/apiParamsResp")
-    public Mono<String> apiParamsResp(ApiInfoRequest apiInfoRequest){
-        CallDubboServiceRequest req = new CallDubboServiceRequest();
-        req.setRegistryCenterUrl("dubbo://" + apiInfoRequest.getDubboIp() + ":" + apiInfoRequest.getDubboPort());
-        req.setInterfaceClassName("org.apache.dubbo.apidocs.core.providers.IDubboDocProvider");
-        req.setMethodName("apiParamsResponseInfo");
-        req.setAsync(false);
-
-        List<CallDubboServiceRequestInterfaceParam> methodParams = new ArrayList<>(1);
-        CallDubboServiceRequestInterfaceParam param = new CallDubboServiceRequestInterfaceParam();
-        param.setParamType(String.class.getName());
-        param.setParamValue(apiInfoRequest.getApiName());
-        methodParams.add(param);
-        return callDubboService(req, methodParams);
-    }
-
-    private static boolean isBaseType(String typeStr) {
-        if ("java.lang.Integer".equals(typeStr) ||
-                "java.lang.Byte".equals(typeStr) ||
-                "java.lang.Long".equals(typeStr) ||
-                "java.lang.Double".equals(typeStr) ||
-                "java.lang.Float".equals(typeStr) ||
-                "java.lang.Character".equals(typeStr) ||
-                "java.lang.Short".equals(typeStr) ||
-                "java.lang.Boolean".equals(typeStr) ||
-                "java.lang.String".equals(typeStr)) {
-            return true;
-        }
-        return false;
-    }
-}
diff --git a/dubbo-api-docs/dubbo-api-docs-ui-server/src/main/java/org/apache/dubbo/apidocs/controller/vo/ApiInfoRequest.java b/dubbo-api-docs/dubbo-api-docs-ui-server/src/main/java/org/apache/dubbo/apidocs/controller/vo/ApiInfoRequest.java
deleted file mode 100644
index 5f37b4d..0000000
--- a/dubbo-api-docs/dubbo-api-docs-ui-server/src/main/java/org/apache/dubbo/apidocs/controller/vo/ApiInfoRequest.java
+++ /dev/null
@@ -1,39 +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.apidocs.controller.vo;
-
-import io.swagger.annotations.ApiParam;
-import lombok.Getter;
-import lombok.Setter;
-
-/**
- * Obtain the API module list and the request parameters of the API parameter information interface.
- */
-@Getter
-@Setter
-public class ApiInfoRequest {
-
-    @ApiParam(value = "IP of Dubbo provider", required = true)
-    private String dubboIp;
-
-    @ApiParam(value = "Port of Dubbo provider", required = true)
-    private String dubboPort;
-
-    @ApiParam(value = "API full name (interface class full name. Method name), which must be passed when getting API parameter information")
-    private String apiName;
-
-}
diff --git a/dubbo-api-docs/dubbo-api-docs-ui-server/src/main/java/org/apache/dubbo/apidocs/controller/vo/CallDubboServiceRequest.java b/dubbo-api-docs/dubbo-api-docs-ui-server/src/main/java/org/apache/dubbo/apidocs/controller/vo/CallDubboServiceRequest.java
deleted file mode 100644
index 741fdde..0000000
--- a/dubbo-api-docs/dubbo-api-docs-ui-server/src/main/java/org/apache/dubbo/apidocs/controller/vo/CallDubboServiceRequest.java
+++ /dev/null
@@ -1,43 +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.apidocs.controller.vo;
-
-import io.swagger.annotations.ApiParam;
-import lombok.Getter;
-import lombok.Setter;
-
-
-/**
- * Call Dubbo api to request parameters.
- */
-@Getter
-@Setter
-public class CallDubboServiceRequest {
-
-    @ApiParam(value = "Address of registration center, such as: nacos://127.0.0.1:8848", required = true)
-    private String registryCenterUrl;
-
-    @ApiParam(value = "Dubbo interface full package path", required = true)
-    private String interfaceClassName;
-
-    @ApiParam(value = "Method name of the service", required = true)
-    private String methodName;
-
-    @ApiParam(value = "Whether to call asynchronously, false by default")
-    private boolean async = false;
-
-}
diff --git a/dubbo-api-docs/dubbo-api-docs-ui-server/src/main/java/org/apache/dubbo/apidocs/controller/vo/CallDubboServiceRequestInterfaceParam.java b/dubbo-api-docs/dubbo-api-docs-ui-server/src/main/java/org/apache/dubbo/apidocs/controller/vo/CallDubboServiceRequestInterfaceParam.java
deleted file mode 100644
index 7b318ae..0000000
--- a/dubbo-api-docs/dubbo-api-docs-ui-server/src/main/java/org/apache/dubbo/apidocs/controller/vo/CallDubboServiceRequestInterfaceParam.java
+++ /dev/null
@@ -1,36 +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.apidocs.controller.vo;
-
-import io.swagger.annotations.ApiParam;
-import lombok.Getter;
-import lombok.Setter;
-
-/**
- * Parameters passed to duboo service api.
- */
-@Getter
-@Setter
-public class CallDubboServiceRequestInterfaceParam {
-
-    @ApiParam(value = "Parameter type (full package path), such as: java.lang.String", required = true)
-    private String paramType;
-
-    @ApiParam(value = "Parameter value", required = true)
-    private Object paramValue;
-
-}
diff --git a/dubbo-api-docs/dubbo-api-docs-ui-server/src/main/java/org/apache/dubbo/apidocs/editor/CustomDateEditor.java b/dubbo-api-docs/dubbo-api-docs-ui-server/src/main/java/org/apache/dubbo/apidocs/editor/CustomDateEditor.java
deleted file mode 100644
index c11efd1..0000000
--- a/dubbo-api-docs/dubbo-api-docs-ui-server/src/main/java/org/apache/dubbo/apidocs/editor/CustomDateEditor.java
+++ /dev/null
@@ -1,120 +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.apidocs.editor;
-
-import org.slf4j.Logger;
-import org.slf4j.LoggerFactory;
-import org.springframework.util.StringUtils;
-
-import java.beans.PropertyEditorSupport;
-import java.text.ParseException;
-import java.text.SimpleDateFormat;
-import java.util.Date;
-import java.util.regex.Pattern;
-
-/**
- * Date editor for controller.
- */
-public class CustomDateEditor extends PropertyEditorSupport {
-
-    protected Logger logger = LoggerFactory.getLogger(this.getClass());
-
-    @Override
-    public void setAsText(String text) throws IllegalArgumentException {
-        if (!StringUtils.hasText(text)) {
-            setValue(null);
-        } else {
-            setValue(this.dateAdapter(text));
-        }
-    }
-
-    @Override
-    public String getAsText() {
-        Date value = (Date) getValue();
-        SimpleDateFormat dateFormat = new SimpleDateFormat("yyyy-MM-dd HH:mm:ss");
-        return (value != null ? dateFormat.format(value) : "");
-    }
-
-    /**
-     * String to date adaptation method.
-     * 2020/11/14 20:59
-     * @param dateStr
-     * @return java.util.Date
-     */
-    public static Date dateAdapter(String dateStr) {
-        Date date = null;
-
-        if (!(null == dateStr || "".equals(dateStr))) {
-            try {
-                long timeLong = Long.parseLong(dateStr);
-                date = new Date(timeLong);
-
-                return date;
-            } catch (Exception e) {
-
-            }
-
-            if (dateStr.contains("CST")) {
-                date = new Date(dateStr);
-            } else if (dateStr.contains("Z")) {
-                dateStr = dateStr.replace("\"", "");
-                dateStr = dateStr.replace("Z", " UTC");
-                SimpleDateFormat utcFormat = new SimpleDateFormat("yyyy-MM-dd'T'HH:mm:ss.SSS Z");
-                try {
-                    date = utcFormat.parse(dateStr);
-                } catch (ParseException e) {
-                    e.printStackTrace();
-                }
-            } else {
-                dateStr = dateStr.replace("年", "-").replace("月", "-").replace("日", "").replaceAll("/", "-").replaceAll("\\.", "-").trim();
-                String fm = "";
-
-                // determine date format
-                if (Pattern.compile("^[0-9]{4}-[0-9]{2}-[0-9]{2}.*").matcher(dateStr).matches()) {
-                    fm = "yyyy-MM-dd";
-                } else if (Pattern.compile("^[0-9]{4}-[0-9]{1}-[0-9]+.*||^[0-9]{4}-[0-9]+-[0-9]{1}.*").matcher(dateStr).matches()) {
-                    fm = "yyyy-M-d";
-                } else if (Pattern.compile("^[0-9]{2}-[0-9]{2}-[0-9]{2}.*").matcher(dateStr).matches()) {
-                    fm = "yy-MM-dd";
-                } else if (Pattern.compile("^[0-9]{2}-[0-9]{1}-[0-9]+.*||^[0-9]{2}-[0-9]+-[0-9]{1}.*").matcher(dateStr).matches()) {
-                    fm = "yy-M-d";
-                }
-
-                // determine time format
-                if (Pattern.compile(".*[ ][0-9]{2}").matcher(dateStr).matches()) {
-                    fm += " HH";
-                } else if (Pattern.compile(".*[ ][0-9]{2}:[0-9]{2}").matcher(dateStr).matches()) {
-                    fm += " HH:mm";
-                } else if (Pattern.compile(".*[ ][0-9]{2}:[0-9]{2}:[0-9]{2}").matcher(dateStr).matches()) {
-                    fm += " HH:mm:ss";
-                } else if (Pattern.compile(".*[ ][0-9]{2}:[0-9]{2}:[0-9]{2}:[0-9]{0,3}").matcher(dateStr).matches()) {
-                    fm += " HH:mm:ss:sss";
-                }
-
-                if (!"".equals(fm)) {
-                    try {
-                        date = new SimpleDateFormat(fm).parse(dateStr);
-                    } catch (ParseException e) {
-                        throw new IllegalArgumentException(dateStr + " cannot be converted to date format!");
-                    }
-                }
-            }
-        }
-
-        return date;
-    }
-}
diff --git a/dubbo-api-docs/dubbo-api-docs-ui-server/src/main/java/org/apache/dubbo/apidocs/editor/CustomLocalDateEditor.java b/dubbo-api-docs/dubbo-api-docs-ui-server/src/main/java/org/apache/dubbo/apidocs/editor/CustomLocalDateEditor.java
deleted file mode 100644
index 291e98b..0000000
--- a/dubbo-api-docs/dubbo-api-docs-ui-server/src/main/java/org/apache/dubbo/apidocs/editor/CustomLocalDateEditor.java
+++ /dev/null
@@ -1,43 +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.apidocs.editor;
-
-
-import org.apache.dubbo.apidocs.utils.LocalDateTimeUtil;
-
-import java.beans.PropertyEditorSupport;
-import java.time.LocalDate;
-import java.time.format.DateTimeFormatter;
-
-/**
- * Localdate editor for controller.
- */
-public class CustomLocalDateEditor extends PropertyEditorSupport {
-
-    @Override
-    public void setAsText(String text) throws IllegalArgumentException {
-        setValue(LocalDateTimeUtil.formatToLD(text));
-    }
-    
-    @Override
-    public String getAsText() {
-        LocalDate date = (LocalDate)getValue();
-        return date.format(DateTimeFormatter.ofPattern("yyyy-MM-dd"));
-    }
-    
-    
-}
diff --git a/dubbo-api-docs/dubbo-api-docs-ui-server/src/main/java/org/apache/dubbo/apidocs/editor/CustomLocalDateTimeEditor.java b/dubbo-api-docs/dubbo-api-docs-ui-server/src/main/java/org/apache/dubbo/apidocs/editor/CustomLocalDateTimeEditor.java
deleted file mode 100644
index 5d5c84a..0000000
--- a/dubbo-api-docs/dubbo-api-docs-ui-server/src/main/java/org/apache/dubbo/apidocs/editor/CustomLocalDateTimeEditor.java
+++ /dev/null
@@ -1,43 +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.apidocs.editor;
-
-
-import org.apache.dubbo.apidocs.utils.LocalDateTimeUtil;
-
-import java.beans.PropertyEditorSupport;
-import java.time.LocalDateTime;
-import java.time.format.DateTimeFormatter;
-
-/**
- * LocalDateTime editor for controller.
- */
-public class CustomLocalDateTimeEditor extends PropertyEditorSupport {
-
-    @Override
-    public void setAsText(String text) throws IllegalArgumentException {
-        setValue(LocalDateTimeUtil.formatToLDT(text));
-    }
-    
-    @Override
-    public String getAsText() {
-	LocalDateTime date = (LocalDateTime)getValue();
-	return date.format(DateTimeFormatter.ofPattern("yyyy-MM-dd HH:mm:ss"));
-    }
-    
-    
-}
diff --git a/dubbo-api-docs/dubbo-api-docs-ui-server/src/main/java/org/apache/dubbo/apidocs/utils/DubboGenericUtil.java b/dubbo-api-docs/dubbo-api-docs-ui-server/src/main/java/org/apache/dubbo/apidocs/utils/DubboGenericUtil.java
deleted file mode 100644
index fac8fce..0000000
--- a/dubbo-api-docs/dubbo-api-docs-ui-server/src/main/java/org/apache/dubbo/apidocs/utils/DubboGenericUtil.java
+++ /dev/null
@@ -1,211 +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.apidocs.utils;
-
-import org.apache.dubbo.config.ApplicationConfig;
-import org.apache.dubbo.config.ReferenceConfig;
-import org.apache.dubbo.config.RegistryConfig;
-import org.apache.dubbo.rpc.service.GenericService;
-
-import org.apache.commons.lang3.StringUtils;
-
-import java.util.Map;
-import java.util.concurrent.CompletableFuture;
-import java.util.concurrent.ConcurrentHashMap;
-import java.util.concurrent.ExecutorService;
-import java.util.concurrent.Executors;
-
-/**
- * Dubbo operation related tool class.
- */
-public class DubboGenericUtil {
-
-    /**
-     * Current application information.
-     */
-    private static ApplicationConfig application;
-
-    /**
-     * Registry information cache.
-     */
-    private static Map<String, RegistryConfig> registryConfigCache;
-
-    /**
-     * Dubbo service interface proxy cache.
-     */
-    private static Map<String, ReferenceConfig<GenericService>> referenceCache;
-
-    private static final ExecutorService executor;
-
-    /**
-     * Default retries.
-     */
-    private static int retries = 2;
-
-    /**
-     * Default timeout.
-     */
-    private static int timeout = 1000;
-
-    static{
-        // T (number of threads) = N (number of server cores) * u (expected CPU utilization) * (1 + E (waiting time) / C (calculation time))
-        executor = Executors.newFixedThreadPool(Runtime.getRuntime().availableProcessors() * 40 * (1 + 5 / 2));
-        application = new ApplicationConfig();
-        application.setName("dubbo-api-docs");
-        registryConfigCache = new ConcurrentHashMap<>();
-        referenceCache = new ConcurrentHashMap<>();
-    }
-
-    public static void setRetriesAndTimeout(int retries, int timeout){
-        DubboGenericUtil.retries = retries;
-        DubboGenericUtil.timeout = timeout;
-    }
-
-    /**
-     * Get registry information.
-     * 2020/11/14 21:01
-     * @param address address Address of Registration Center
-     * @return org.apache.dubbo.config.RegistryConfig
-     */
-    private static RegistryConfig getRegistryConfig(String address) {
-        RegistryConfig registryConfig = registryConfigCache.get(address);
-        if (null == registryConfig) {
-            registryConfig = new RegistryConfig();
-            registryConfig.setAddress(address);
-            registryConfig.setRegister(false);
-            registryConfigCache.put(address, registryConfig);
-        }
-        return registryConfig;
-    }
-
-    /**
-     * remove cached registry information.
-     * 2020/11/20 17:36
-     * @param address Address of Registration Center
-     * @return void
-     */
-    private static void removeRegistryConfig(String address) {
-        registryConfigCache.remove(address);
-    }
-
-    /**
-     * Get proxy object for dubbo service.
-     * 2019/9/19 17:43
-     * @param: address  address Address of Registration Center
-     * @param: interfaceName  Interface full package path
-     * @return org.apache.dubbo.config.ReferenceConfig<org.apache.dubbo.rpc.service.GenericService>
-     */
-    private static ReferenceConfig<GenericService> getReferenceConfig(String address, String interfaceName) {
-        ReferenceConfig<GenericService> referenceConfig = referenceCache.get(address + "/" + interfaceName);
-        if (null == referenceConfig) {
-            referenceConfig = new ReferenceConfig<>();
-            referenceConfig.setRetries(retries);
-            referenceConfig.setTimeout(timeout);
-            referenceConfig.setApplication(application);
-            if(address.startsWith("dubbo")){
-                referenceConfig.setUrl(address);
-            } else {
-                referenceConfig.setRegistry(getRegistryConfig(address));
-            }
-            referenceConfig.setInterface(interfaceName);
-            // Declared as a generic interface
-            referenceConfig.setGeneric(true);
-            referenceCache.put(address + "/" + interfaceName, referenceConfig);
-        }
-        return referenceConfig;
-    }
-
-    /**
-     * remove cached proxy object.
-     * 2020/11/20 17:38
-     * @param address
-     * @param interfaceName
-     * @return void
-     */
-    private static void removeReferenceConfig(String address, String interfaceName) {
-        removeRegistryConfig(address);
-        referenceCache.remove(address + "/" + interfaceName);
-    }
-
-    /**
-     * Call duboo provider and return {@link CompletableFuture}.
-     * 2020/3/1 14:55
-     * @param: address
-     * @param: interfaceName
-     * @param: methodName
-     * @param: async  Whether the provider is asynchronous is to directly return the {@link CompletableFuture}
-     * returned by the provider, not to wrap it as {@link CompletableFuture}
-     * @param: paramTypes
-     * @param: paramValues
-     * @return java.util.concurrent.CompletableFuture<java.lang.Object>
-     */
-    public static CompletableFuture<Object> invoke(String address, String interfaceName,
-                                                  String methodName, boolean async, String[] paramTypes,
-                                                  Object[] paramValues) {
-        CompletableFuture future = null;
-        ReferenceConfig<GenericService> reference = getReferenceConfig(address, interfaceName);
-        if (null != reference) {
-            GenericService genericService = reference.get();
-            if (null != genericService) {
-                if (async) {
-                    future = genericService.$invokeAsync(methodName, paramTypes, paramValues);
-                } else {
-                    future = CompletableFuture.supplyAsync(() -> genericService.$invoke(methodName, paramTypes, paramValues), executor);
-                }
-            }
-            future.exceptionally(ex -> {
-                if (StringUtils.contains(ex.toString(), "Failed to invoke remote method")) {
-                    removeReferenceConfig(address, interfaceName);
-                }
-                return ex;
-            });
-        }
-        return future;
-    }
-
-    /**
-     * Synchronous call provider. The provider must provide synchronous api.
-     * 2020/3/1 14:58
-     * @param: address
-     * @param: interfaceName
-     * @param: methodName
-     * @param: paramTypes
-     * @param: paramValues
-     * @return java.lang.Object
-     */
-    public static Object invokeSync(String address, String interfaceName,
-                                                   String methodName, String[] paramTypes,
-                                                   Object[] paramValues) {
-        ReferenceConfig<GenericService> reference = getReferenceConfig(address, interfaceName);
-        if (null != reference) {
-            GenericService genericService = reference.get();
-            try {
-                if (null != genericService) {
-                    return genericService.$invoke(methodName, paramTypes, paramValues);
-                }
-            } catch (Exception ex) {
-                if (StringUtils.contains(ex.toString(), "Failed to invoke remote method")) {
-                    removeReferenceConfig(address, interfaceName);
-                } else {
-                    throw ex;
-                }
-            }
-        }
-        return null;
-    }
-
-}
diff --git a/dubbo-api-docs/dubbo-api-docs-ui-server/src/main/java/org/apache/dubbo/apidocs/utils/LocalDateTimeUtil.java b/dubbo-api-docs/dubbo-api-docs-ui-server/src/main/java/org/apache/dubbo/apidocs/utils/LocalDateTimeUtil.java
deleted file mode 100644
index 2568ac7..0000000
--- a/dubbo-api-docs/dubbo-api-docs-ui-server/src/main/java/org/apache/dubbo/apidocs/utils/LocalDateTimeUtil.java
+++ /dev/null
@@ -1,73 +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.apidocs.utils;
-
-import java.time.*;
-import java.time.format.DateTimeFormatter;
-import java.time.temporal.ChronoUnit;
-import java.time.temporal.TemporalUnit;
-import java.util.Date;
-
-
-/**
- * Date time tool class of LocalDateTime.
- */
-public class LocalDateTimeUtil {
-
-    /**
-     * Create a LocalDateTime based on the passed in string date and the corresponding format.
-     * @param dateStr
-     * @param dateFormatter
-     * @return
-     */
-    public static LocalDateTime formatToLDT(String dateStr, String dateFormatter) {
-        //yyyy-MM-dd HH:mm:ss
-        return LocalDateTime.parse(dateStr, DateTimeFormatter.ofPattern(dateFormatter));
-    }
-
-    /**
-     * Create LocalDateTime from a string in the format "yyyy-MM-dd HH:mm:ss".
-     * @param dateStr
-     * @return
-     */
-    public static LocalDateTime formatToLDT(String dateStr) {
-        return formatToLDT(dateStr, "yyyy-MM-dd HH:mm:ss");
-    }
-
-    /**
-     * Create a LocalDate based on the passed in string date and the corresponding format.
-     * @param dateStr
-     * @param dateFormatter
-     * @return
-     */
-    public static LocalDate formatToLD(String dateStr, String dateFormatter) {
-        return LocalDate.parse(dateStr, DateTimeFormatter.ofPattern(dateFormatter));
-    }
-
-    /**
-     * Create LocalDate from a string in the format "yyyy-MM-dd".
-     * @param dateStr
-     * @return
-     */
-    public static LocalDate formatToLD(String dateStr) {
-        return formatToLD(dateStr, "yyyy-MM-dd");
-    }
-
-
-
-
-}
diff --git a/dubbo-api-docs/dubbo-api-docs-ui-server/src/main/resources/application.yml b/dubbo-api-docs/dubbo-api-docs-ui-server/src/main/resources/application.yml
deleted file mode 100644
index 76231ff..0000000
--- a/dubbo-api-docs/dubbo-api-docs-ui-server/src/main/resources/application.yml
+++ /dev/null
@@ -1,11 +0,0 @@
-server:
-  port: 8888
-spring:
-  application:
-    name: dubbo-api-docs-ui-server
-dubbo:
-  reference:
-    heartbeat: 1000
-  consumer:
-    timeout: 10000
-    retries: 0
\ No newline at end of file
diff --git a/dubbo-api-docs/dubbo-api-docs-ui-server/src/main/resources/banner.txt b/dubbo-api-docs/dubbo-api-docs-ui-server/src/main/resources/banner.txt
deleted file mode 100644
index 86690cb..0000000
--- a/dubbo-api-docs/dubbo-api-docs-ui-server/src/main/resources/banner.txt
+++ /dev/null
@@ -1,7 +0,0 @@
-  _____        _     _                        _____ _____      _____
- |  __ \      | |   | |                 /\   |  __ \_   _|    |  __ \
- | |  | |_   _| |__ | |__   ___        /  \  | |__) || |      | |  | | ___   ___ ___
- | |  | | | | | '_ \| '_ \ / _ \      / /\ \ |  ___/ | |      | |  | |/ _ \ / __/ __|
- | |__| | |_| | |_) | |_) | (_) |    / ____ \| |    _| |_     | |__| | (_) | (__\__ \
- |_____/ \__,_|_.__/|_.__/ \___/    /_/    \_\_|   |_____|    |_____/ \___/ \___|___/
-
diff --git a/dubbo-api-docs/dubbo-api-docs-ui-server/src/main/resources/log4j2.xml b/dubbo-api-docs/dubbo-api-docs-ui-server/src/main/resources/log4j2.xml
deleted file mode 100644
index 8bd3515..0000000
--- a/dubbo-api-docs/dubbo-api-docs-ui-server/src/main/resources/log4j2.xml
+++ /dev/null
@@ -1,23 +0,0 @@
-<?xml version="1.0" encoding="UTF-8"?>
-<Configuration status="WARN" monitorInterval="600" shutdownHook="disable">
-    <Properties>
-        <Property name="logDir" value="/home/weihu/deploy/logs/dubbo-api-docs/" />
-        <Property name="genericPattern" value="[dubboDoc]-%d{yyyy-MM-dd HH:mm:ss.SSS} [%t] %-5level %logger{36} - %msg%n" />
-        <Property name="genericFilePattern" value="%d{yyyy-MM-dd HH:mm}-%i" />
-    </Properties>
-    <Appenders>
-        <Console name="consoleAppender" target="SYSTEM_OUT">
-            <PatternLayout pattern="${genericPattern}" />
-        </Console>
-
-    </Appenders>
-    <Loggers>
-        <asyncRoot level="INFO">
-            <AppenderRef ref="consoleAppender" />
-        </asyncRoot>
-
-        <logger name="org.springframework" level="ERROR" />
-        <logger name="com.alibaba" level="ERROR" />
-        <logger name="org.apache" level="ERROR" />
-    </Loggers>
-</Configuration>
diff --git a/dubbo-api-docs/dubbo-api-docs-ui-server/src/main/resources/static/css/index.css b/dubbo-api-docs/dubbo-api-docs-ui-server/src/main/resources/static/css/index.css
deleted file mode 100644
index 88e0239..0000000
--- a/dubbo-api-docs/dubbo-api-docs-ui-server/src/main/resources/static/css/index.css
+++ /dev/null
@@ -1 +0,0 @@
-.next-sr-only{position:absolute;width:1px;height:1px;padding:0;overflow:hidden;clip:rect(0,0,0,0);white-space:nowrap;border:0;margin:-1px}/*! normalize.css v7.0.0 | MIT License | github.com/necolas/normalize.css */html{line-height:1.15;-ms-text-size-adjust:100%;-webkit-text-size-adjust:100%}body{margin:0}article,aside,footer,header,nav,section{display:block}h1{font-size:2em;margin:.67em 0}figcaption,figure,main{display:block}figure{margin:1em 40px}hr{-webkit-box-sizing:content-box;box-si [...]
\ No newline at end of file
diff --git a/dubbo-api-docs/dubbo-api-docs-ui-server/src/main/resources/static/favicon.png b/dubbo-api-docs/dubbo-api-docs-ui-server/src/main/resources/static/favicon.png
deleted file mode 100644
index a2605c5..0000000
Binary files a/dubbo-api-docs/dubbo-api-docs-ui-server/src/main/resources/static/favicon.png and /dev/null differ
diff --git a/dubbo-api-docs/dubbo-api-docs-ui-server/src/main/resources/static/index.html b/dubbo-api-docs/dubbo-api-docs-ui-server/src/main/resources/static/index.html
deleted file mode 100644
index e1bf09d..0000000
--- a/dubbo-api-docs/dubbo-api-docs-ui-server/src/main/resources/static/index.html
+++ /dev/null
@@ -1,29 +0,0 @@
-<!DOCTYPE html>
-<!--
- * 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.
-  -->
-<html>
-  <head>
-    <meta charset="utf-8" />
-    <meta http-equiv="x-ua-compatible" content="ie=edge,chrome=1" />
-    <meta name="viewport" content="width=device-width" />
-    <title>Dubbo Doc</title>
-  <link rel="shortcut icon" href="./favicon.png"><link href="./css/index.css" rel="stylesheet"></head>
-
-  <body>
-    <div id="icestark-container"></div>
-  <script type="text/javascript" src="./js/index.js"></script></body>
-</html>
diff --git a/dubbo-api-docs/dubbo-api-docs-ui-server/src/main/resources/static/js/index.js b/dubbo-api-docs/dubbo-api-docs-ui-server/src/main/resources/static/js/index.js
deleted file mode 100644
index 6120326..0000000
--- a/dubbo-api-docs/dubbo-api-docs-ui-server/src/main/resources/static/js/index.js
+++ /dev/null
@@ -1,112 +0,0 @@
-!function(e){var t={};function n(r){if(t[r])return t[r].exports;var o=t[r]={i:r,l:!1,exports:{}};return e[r].call(o.exports,o,o.exports,n),o.l=!0,o.exports}n.m=e,n.c=t,n.d=function(e,t,r){n.o(e,t)||Object.defineProperty(e,t,{enumerable:!0,get:r})},n.r=function(e){"undefined"!=typeof Symbol&&Symbol.toStringTag&&Object.defineProperty(e,Symbol.toStringTag,{value:"Module"}),Object.defineProperty(e,"__esModule",{value:!0})},n.t=function(e,t){if(1&t&&(e=n(e)),8&t)return e;if(4&t&&"object"==typ [...]
-/*!
-  Copyright (c) 2017 Jed Watson.
-  Licensed under the MIT License (MIT), see
-  http://jedwatson.github.io/classnames
-*/!function(){"use strict";var n={}.hasOwnProperty;function a(){for(var e=[],t=0;t<arguments.length;t++){var r=arguments[t];if(r){var o=typeof r;if("string"===o||"number"===o)e.push(r);else if(Array.isArray(r)&&r.length){var i=a.apply(null,r);i&&e.push(i)}else if("object"===o)for(var s in r)n.call(r,s)&&r[s]&&e.push(s)}}return e.join(" ")}e.exports?(a.default=a,e.exports=a):void 0===(o=function(){return a}.apply(t,r=[]))||(e.exports=o)}()},function(e,t,n){"use strict";t.__esModule=!0,t.d [...]
-/*! *****************************************************************************
-Copyright (c) Microsoft Corporation.
-
-Permission to use, copy, modify, and/or distribute this software for any
-purpose with or without fee is hereby granted.
-
-THE SOFTWARE IS PROVIDED "AS IS" AND THE AUTHOR DISCLAIMS ALL WARRANTIES WITH
-REGARD TO THIS SOFTWARE INCLUDING ALL IMPLIED WARRANTIES OF MERCHANTABILITY
-AND FITNESS. IN NO EVENT SHALL THE AUTHOR BE LIABLE FOR ANY SPECIAL, DIRECT,
-INDIRECT, OR CONSEQUENTIAL DAMAGES OR ANY DAMAGES WHATSOEVER RESULTING FROM
-LOSS OF USE, DATA OR PROFITS, WHETHER IN AN ACTION OF CONTRACT, NEGLIGENCE OR
-OTHER TORTIOUS ACTION, ARISING OUT OF OR IN CONNECTION WITH THE USE OR
-PERFORMANCE OF THIS SOFTWARE.
-***************************************************************************** */
-var r=function(e,t){return(r=Object.setPrototypeOf||{__proto__:[]}instanceof Array&&function(e,t){e.__proto__=t}||function(e,t){for(var n in t)t.hasOwnProperty(n)&&(e[n]=t[n])})(e,t)};function o(e,t){function n(){this.constructor=e}r(e,t),e.prototype=null===t?Object.create(t):(n.prototype=t.prototype,new n)}var a=function(){return(a=Object.assign||function e(t){for(var n,r=1,o=arguments.length;r<o;r++)for(var a in n=arguments[r])Object.prototype.hasOwnProperty.call(n,a)&&(t[a]=n[a]);retu [...]
-/*!
- * jQuery JavaScript Library v3.5.1
- * https://jquery.com/
- *
- * Includes Sizzle.js
- * https://sizzlejs.com/
- *
- * Copyright JS Foundation and other contributors
- * Released under the MIT license
- * https://jquery.org/license
- *
- * Date: 2020-05-04T22:49Z
- */!function(t,n){"use strict";"object"==typeof e.exports?e.exports=t.document?n(t,!0):function(e){if(!e.document)throw new Error("jQuery requires a window with a document");return n(e)}:n(t)}("undefined"!=typeof window?window:this,(function(n,a){"use strict";var i=[],s=Object.getPrototypeOf,u=i.slice,l=i.flat?function(e){return i.flat.call(e)}:function(e){return i.concat.apply([],e)},c=i.push,f=i.indexOf,p={},d=p.toString,h=p.hasOwnProperty,v=h.toString,m=v.call(Object),y={},g=function  [...]
-/*!
- * Sizzle CSS Selector Engine v2.3.5
- * https://sizzlejs.com/
- *
- * Copyright JS Foundation and other contributors
- * Released under the MIT license
- * https://js.foundation/
- *
- * Date: 2020-03-14
- */
-function(e){var t,n,r,o,a,i,s,u,l,c,f,p,d,h,v,m,y,g,b,w="sizzle"+1*new Date,x=e.document,E=0,_=0,O=ue(),S=ue(),C=ue(),k=ue(),P=function(e,t){return e===t&&(f=!0),0},T={}.hasOwnProperty,j=[],A=j.pop,N=j.push,M=j.push,D=j.slice,R=function(e,t){for(var n=0,r=e.length;n<r;n++)if(e[n]===t)return n;return-1},L="checked|selected|async|autofocus|autoplay|controls|defer|disabled|hidden|ismap|loop|multiple|open|readonly|required|scoped",I="[\\x20\\t\\r\\n\\f]",F="(?:\\\\[\\da-fA-F]{1,6}"+I+"?|\\\\ [...]
-/*
-object-assign
-(c) Sindre Sorhus
-@license MIT
-*/var r=Object.getOwnPropertySymbols,o=Object.prototype.hasOwnProperty,a=Object.prototype.propertyIsEnumerable;function i(e){if(null==e)throw new TypeError("Object.assign cannot be called with null or undefined");return Object(e)}function s(){try{if(!Object.assign)return!1;var e=new String("abc"),t;if(e[5]="de","5"===Object.getOwnPropertyNames(e)[0])return!1;for(var n={},r=0;r<10;r++)n["_"+String.fromCharCode(r)]=r;if("0123456789"!==Object.getOwnPropertyNames(n).map((function(e){return n [...]
-/*!
- * cookie
- * Copyright(c) 2012-2014 Roman Shtylman
- * Copyright(c) 2015 Douglas Christopher Wilson
- * MIT Licensed
- */t.parse=s,t.serialize=u;var r=decodeURIComponent,o=encodeURIComponent,a=/; */,i=/^[\u0009\u0020-\u007e\u0080-\u00ff]+$/;function s(e,t){if("string"!=typeof e)throw new TypeError("argument str must be a string");for(var n={},o=t||{},i=e.split(a),s=o.decode||r,u=0;u<i.length;u++){var c=i[u],f=c.indexOf("=");if(!(f<0)){var p=c.substr(0,f).trim(),d=c.substr(++f,c.length).trim();'"'==d[0]&&(d=d.slice(1,-1)),null==n[p]&&(n[p]=l(d,s))}}return n}function u(e,t,n){var r=n||{},a=r.encode||o;if( [...]
-//! version : 2.29.1
-//! authors : Tim Wood, Iskren Chernev, Moment.js contributors
-//! license : MIT
-//! momentjs.com
-r=this,o=function(){"use strict";var t,r;function o(){return t.apply(null,arguments)}function a(e){t=e}function i(e){return e instanceof Array||"[object Array]"===Object.prototype.toString.call(e)}function s(e){return null!=e&&"[object Object]"===Object.prototype.toString.call(e)}function u(e,t){return Object.prototype.hasOwnProperty.call(e,t)}function l(e){if(Object.getOwnPropertyNames)return 0===Object.getOwnPropertyNames(e).length;var t;for(t in e)if(u(e,t))return!1;return!0}function  [...]
-//! moment.js
-o.version="2.29.1",a($n),o.fn=la,o.min=Qn,o.max=er,o.now=tr,o.utc=v,o.unix=ca,o.months=ya,o.isDate=p,o.locale=vn,o.invalid=b,o.duration=Pr,o.isMoment=O,o.weekdays=ba,o.parseZone=fa,o.localeData=gn,o.isDuration=sr,o.monthsShort=ga,o.weekdaysMin=xa,o.defineLocale=mn,o.updateLocale=yn,o.locales=bn,o.weekdaysShort=wa,o.normalizeUnits=oe,o.relativeTimeRounding=oi,o.relativeTimeThreshold=ai,o.calendarFormat=Ur,o.prototype=la,o.HTML5_FMT={DATETIME_LOCAL:"YYYY-MM-DDTHH:mm",DATETIME_LOCAL_SECONDS [...]
-//! moment.js locale configuration
-var t;return e.defineLocale("zh-cn",{months:"\u4e00\u6708_\u4e8c\u6708_\u4e09\u6708_\u56db\u6708_\u4e94\u6708_\u516d\u6708_\u4e03\u6708_\u516b\u6708_\u4e5d\u6708_\u5341\u6708_\u5341\u4e00\u6708_\u5341\u4e8c\u6708".split("_"),monthsShort:"1\u6708_2\u6708_3\u6708_4\u6708_5\u6708_6\u6708_7\u6708_8\u6708_9\u6708_10\u6708_11\u6708_12\u6708".split("_"),weekdays:"\u661f\u671f\u65e5_\u661f\u671f\u4e00_\u661f\u671f\u4e8c_\u661f\u671f\u4e09_\u661f\u671f\u56db_\u661f\u671f\u4e94_\u661f\u671f\u516d" [...]
-/** @license React v16.14.0
- * react.production.min.js
- *
- * Copyright (c) Facebook, Inc. and its affiliates.
- *
- * This source code is licensed under the MIT license found in the
- * LICENSE file in the root directory of this source tree.
- */var r=n(188),o="function"==typeof Symbol&&Symbol.for,a=o?Symbol.for("react.element"):60103,i=o?Symbol.for("react.portal"):60106,s=o?Symbol.for("react.fragment"):60107,u=o?Symbol.for("react.strict_mode"):60108,l=o?Symbol.for("react.profiler"):60114,c=o?Symbol.for("react.provider"):60109,f=o?Symbol.for("react.context"):60110,p=o?Symbol.for("react.forward_ref"):60112,d=o?Symbol.for("react.suspense"):60113,h=o?Symbol.for("react.memo"):60115,v=o?Symbol.for("react.lazy"):60116,m="function"= [...]
-/** @license React v16.14.0
- * react-dom.production.min.js
- *
- * Copyright (c) Facebook, Inc. and its affiliates.
- *
- * This source code is licensed under the MIT license found in the
- * LICENSE file in the root directory of this source tree.
- */var r=n(1),o=n(188),a=n(562);function i(e){for(var t="https://reactjs.org/docs/error-decoder.html?invariant="+e,n=1;n<arguments.length;n++)t+="&args[]="+encodeURIComponent(arguments[n]);return"Minified React error #"+e+"; visit "+t+" for the full message or use the non-minified dev environment for full errors and additional helpful warnings."}if(!r)throw Error(i(227));function s(e,t,n,r,o,a,i,s,u){var l=Array.prototype.slice.call(arguments,3);try{t.apply(n,l)}catch(e){this.onError(e)} [...]
-/** @license React v0.19.1
- * scheduler.production.min.js
- *
- * Copyright (c) Facebook, Inc. and its affiliates.
- *
- * This source code is licensed under the MIT license found in the
- * LICENSE file in the root directory of this source tree.
- */var r,o,a,i,s;if("undefined"==typeof window||"function"!=typeof MessageChannel){var u=null,l=null,c=function(){if(null!==u)try{var e=t.unstable_now();u(!0,e),u=null}catch(e){throw setTimeout(c,0),e}},f=Date.now();t.unstable_now=function(){return Date.now()-f},r=function(e){null!==u?setTimeout(r,0,e):(u=e,setTimeout(c,0))},o=function(e,t){l=setTimeout(e,t)},a=function(){clearTimeout(l)},i=function(){return!1},s=t.unstable_forceFrameRate=function(){}}else{var p=window.performance,d=wind [...]
-/** @license React v16.14.0
- * react-dom-server.browser.production.min.js
- *
- * Copyright (c) Facebook, Inc. and its affiliates.
- *
- * This source code is licensed under the MIT license found in the
- * LICENSE file in the root directory of this source tree.
- */var r=n(188),o=n(1);function a(e){for(var t="https://reactjs.org/docs/error-decoder.html?invariant="+e,n=1;n<arguments.length;n++)t+="&args[]="+encodeURIComponent(arguments[n]);return"Minified React error #"+e+"; visit "+t+" for the full message or use the non-minified dev environment for full errors and additional helpful warnings."}var i="function"==typeof Symbol&&Symbol.for,s=i?Symbol.for("react.portal"):60106,u=i?Symbol.for("react.fragment"):60107,l=i?Symbol.for("react.strict_mode [...]
-/*!
- * escape-html
- * Copyright(c) 2012-2013 TJ Holowaychuk
- * Copyright(c) 2015 Andreas Lubbe
- * Copyright(c) 2015 Tiancheng "Timothy" Gu
- * MIT Licensed
- */var r=/["'&<>]/;function o(e){var t=""+e,n=r.exec(t),o;if(!n)return t;var a="",i=0,s=0;for(i=n.index;i<t.length;i++){switch(t.charCodeAt(i)){case 34:o="&quot;";break;case 38:o="&amp;";break;case 39:o="&#39;";break;case 60:o="&lt;";break;case 62:o="&gt;";break;default:continue}s!==i&&(a+=t.substring(s,i)),s=i+1,a+=o}return s!==i?a+t.substring(s,i):a}e.exports=o},function(e,t,n){"use strict";t.decode=t.parse=n(598),t.encode=t.stringify=n(599)},function(e,t,n){"use strict";function r(e,t [...]
-/** @license React v16.13.1
- * react-is.production.min.js
- *
- * Copyright (c) Facebook, Inc. and its affiliates.
- *
- * This source code is licensed under the MIT license found in the
- * LICENSE file in the root directory of this source tree.
- */var r="function"==typeof Symbol&&Symbol.for,o=r?Symbol.for("react.element"):60103,a=r?Symbol.for("react.portal"):60106,i=r?Symbol.for("react.fragment"):60107,s=r?Symbol.for("react.strict_mode"):60108,u=r?Symbol.for("react.profiler"):60114,l=r?Symbol.for("react.provider"):60109,c=r?Symbol.for("react.context"):60110,f=r?Symbol.for("react.async_mode"):60111,p=r?Symbol.for("react.concurrent_mode"):60111,d=r?Symbol.for("react.forward_ref"):60112,h=r?Symbol.for("react.suspense"):60113,v=r?S [...]
\ No newline at end of file
diff --git a/dubbo-api-docs/dubbo-api-docs-ui/.editorconfig b/dubbo-api-docs/dubbo-api-docs-ui/.editorconfig
deleted file mode 100644
index 5760be5..0000000
--- a/dubbo-api-docs/dubbo-api-docs-ui/.editorconfig
+++ /dev/null
@@ -1,12 +0,0 @@
-# http://editorconfig.org
-root = true
-
-[*]
-indent_style = space
-indent_size = 2
-charset = utf-8
-trim_trailing_whitespace = true
-insert_final_newline = true
-
-[*.md]
-trim_trailing_whitespace = false
diff --git a/dubbo-api-docs/dubbo-api-docs-ui/.eslintignore b/dubbo-api-docs/dubbo-api-docs-ui/.eslintignore
deleted file mode 100644
index 3b437e6..0000000
--- a/dubbo-api-docs/dubbo-api-docs-ui/.eslintignore
+++ /dev/null
@@ -1,11 +0,0 @@
-# 忽略目录
-build/
-tests/
-demo/
-
-# node 覆盖率文件
-coverage/
-
-# 忽略文件
-**/*-min.js
-**/*.min.js
diff --git a/dubbo-api-docs/dubbo-api-docs-ui/.eslintrc.js b/dubbo-api-docs/dubbo-api-docs-ui/.eslintrc.js
deleted file mode 100644
index 54a71d5..0000000
--- a/dubbo-api-docs/dubbo-api-docs-ui/.eslintrc.js
+++ /dev/null
@@ -1,3 +0,0 @@
-const { eslint } = require('@ice/spec');
-
-module.exports = eslint;
\ No newline at end of file
diff --git a/dubbo-api-docs/dubbo-api-docs-ui/.gitignore b/dubbo-api-docs/dubbo-api-docs-ui/.gitignore
deleted file mode 100644
index 7c3f84e..0000000
--- a/dubbo-api-docs/dubbo-api-docs-ui/.gitignore
+++ /dev/null
@@ -1,16 +0,0 @@
-# dependencies
-/node_modules
-
-# production
-/build
-/dist
-
-# misc
-.idea/
-.happypack
-.DS_Store
-.ice
-
-npm-debug.log*
-yarn-debug.log*
-yarn-error.log*
diff --git a/dubbo-api-docs/dubbo-api-docs-ui/.prettierignore b/dubbo-api-docs/dubbo-api-docs-ui/.prettierignore
deleted file mode 100644
index f238d06..0000000
--- a/dubbo-api-docs/dubbo-api-docs-ui/.prettierignore
+++ /dev/null
@@ -1,9 +0,0 @@
-build/
-tests/
-demo/
-.ice/
-coverage/
-**/*-min.js
-**/*.min.js
-package-lock.json
-yarn.lock
\ No newline at end of file
diff --git a/dubbo-api-docs/dubbo-api-docs-ui/.prettierrc.js b/dubbo-api-docs/dubbo-api-docs-ui/.prettierrc.js
deleted file mode 100644
index 2d68f3f..0000000
--- a/dubbo-api-docs/dubbo-api-docs-ui/.prettierrc.js
+++ /dev/null
@@ -1,3 +0,0 @@
-const { prettier } = require('@ice/spec');
-
-module.exports = prettier;
diff --git a/dubbo-api-docs/dubbo-api-docs-ui/.stylelintignore b/dubbo-api-docs/dubbo-api-docs-ui/.stylelintignore
deleted file mode 100644
index 82af6f6..0000000
--- a/dubbo-api-docs/dubbo-api-docs-ui/.stylelintignore
+++ /dev/null
@@ -1,7 +0,0 @@
-# 忽略目录
-build/
-tests/
-demo/
-
-# node 覆盖率文件
-coverage/
diff --git a/dubbo-api-docs/dubbo-api-docs-ui/.stylelintrc.js b/dubbo-api-docs/dubbo-api-docs-ui/.stylelintrc.js
deleted file mode 100644
index eeb605b..0000000
--- a/dubbo-api-docs/dubbo-api-docs-ui/.stylelintrc.js
+++ /dev/null
@@ -1,3 +0,0 @@
-const { stylelint } = require('@ice/spec');
-
-module.exports = stylelint;
diff --git a/dubbo-api-docs/dubbo-api-docs-ui/README.md b/dubbo-api-docs/dubbo-api-docs-ui/README.md
deleted file mode 100644
index 8a340fb..0000000
--- a/dubbo-api-docs/dubbo-api-docs-ui/README.md
+++ /dev/null
@@ -1,14 +0,0 @@
-# ice-stark-layout
-
-## 使用
-
-- 启动调试服务: `npm start`
-- 构建 dist: `npm run build`
-
-## 目录结构
-
-- 应用配置: `src/app.js`
-- 路由配置: `src/routes.js`
-- 布局文件: `src/layouts`
-- 通用组件: `src/components`
-- 页面文件: `src/pages`
diff --git a/dubbo-api-docs/dubbo-api-docs-ui/build.json b/dubbo-api-docs/dubbo-api-docs-ui/build.json
deleted file mode 100644
index b2d2470..0000000
--- a/dubbo-api-docs/dubbo-api-docs-ui/build.json
+++ /dev/null
@@ -1,21 +0,0 @@
-{
-  "publicPath": "./",
-  "plugins": [
-    "build-plugin-icestark",
-    ["build-plugin-fusion", {
-      "themePackage": "@alifd/theme-design-pro",
-      "themeConfig": {
-        "nextPrefix": "next-icestark-"
-      }
-    }],
-    ["build-plugin-moment-locales", {
-      "locales": ["zh-cn"]
-    }]
-  ],
-  "proxy": {
-	  "/api/**": {
-      "enable": true,
-      "target": "http://localhost:8888"
-    }
-  }
-}
diff --git a/dubbo-api-docs/dubbo-api-docs-ui/package-lock.json b/dubbo-api-docs/dubbo-api-docs-ui/package-lock.json
deleted file mode 100644
index 23a69d1..0000000
--- a/dubbo-api-docs/dubbo-api-docs-ui/package-lock.json
+++ /dev/null
@@ -1,24011 +0,0 @@
-{
-  "name": "@icedesign/stark-layout-scaffold",
-  "version": "3.0.6",
-  "lockfileVersion": 1,
-  "requires": true,
-  "dependencies": {
-    "@ahooksjs/use-request": {
-      "version": "2.8.1",
-      "resolved": "https://registry.npm.taobao.org/@ahooksjs/use-request/download/@ahooksjs/use-request-2.8.1.tgz",
-      "integrity": "sha1-vwamM2jfGFm2t5qUZhLrDSiJq28=",
-      "dev": true,
-      "requires": {
-        "lodash.debounce": "^4.0.8",
-        "lodash.throttle": "^4.1.1"
-      }
-    },
-    "@alib/build-scripts": {
-      "version": "0.1.29",
-      "resolved": "https://registry.npm.taobao.org/@alib/build-scripts/download/@alib/build-scripts-0.1.29.tgz",
-      "integrity": "sha1-RreUu/XBA7gvAOXdnfGaWKdEJYE=",
-      "dev": true,
-      "requires": {
-        "address": "^1.1.0",
-        "camelcase": "^5.3.1",
-        "chalk": "^2.4.1",
-        "chokidar": "^3.3.1",
-        "commander": "^2.19.0",
-        "deepmerge": "^4.0.0",
-        "detect-port": "^1.3.0",
-        "fs-extra": "^8.1.0",
-        "jest": "^26.4.2",
-        "json5": "^2.1.3",
-        "lodash": "^4.17.15",
-        "npmlog": "^4.1.2",
-        "react-dev-utils": "^9.0.4",
-        "semver": "^7.3.2",
-        "webpack": "^4.27.1",
-        "webpack-dev-server": "^3.7.2",
-        "yargs-parser": "^14.0.0"
-      },
-      "dependencies": {
-        "camelcase": {
-          "version": "5.3.1",
-          "resolved": "https://registry.npm.taobao.org/camelcase/download/camelcase-5.3.1.tgz?cache=0&sync_timestamp=1603921882890&other_urls=https%3A%2F%2Fregistry.npm.taobao.org%2Fcamelcase%2Fdownload%2Fcamelcase-5.3.1.tgz",
-          "integrity": "sha1-48mzFWnhBoEd8kL3FXJaH0xJQyA=",
-          "dev": true
-        },
-        "commander": {
-          "version": "2.20.3",
-          "resolved": "https://registry.npm.taobao.org/commander/download/commander-2.20.3.tgz?cache=0&sync_timestamp=1603599627620&other_urls=https%3A%2F%2Fregistry.npm.taobao.org%2Fcommander%2Fdownload%2Fcommander-2.20.3.tgz",
-          "integrity": "sha1-/UhehMA+tIgcIHIrpIA16FMa6zM=",
-          "dev": true
-        },
-        "json5": {
-          "version": "2.1.3",
-          "resolved": "https://registry.npm.taobao.org/json5/download/json5-2.1.3.tgz",
-          "integrity": "sha1-ybD3+pIzv+WAf+ZvzzpWF+1ZfUM=",
-          "dev": true,
-          "requires": {
-            "minimist": "^1.2.5"
-          }
-        },
-        "yargs-parser": {
-          "version": "14.0.0",
-          "resolved": "https://registry.npm.taobao.org/yargs-parser/download/yargs-parser-14.0.0.tgz?cache=0&sync_timestamp=1604886694625&other_urls=https%3A%2F%2Fregistry.npm.taobao.org%2Fyargs-parser%2Fdownload%2Fyargs-parser-14.0.0.tgz",
-          "integrity": "sha1-QuJXd7BnGOyZ6sLDqYrT3nO2gY8=",
-          "dev": true,
-          "requires": {
-            "camelcase": "^5.0.0",
-            "decamelize": "^1.2.0"
-          }
-        }
-      }
-    },
-    "@alifd/field": {
-      "version": "1.4.5",
-      "resolved": "https://registry.npm.taobao.org/@alifd/field/download/@alifd/field-1.4.5.tgz",
-      "integrity": "sha1-Hh5eg8FDY31u/pLrkdzenginOp8=",
-      "requires": {
-        "@alifd/validate": "^1.2.0",
-        "prop-types": "^15.5.8"
-      }
-    },
-    "@alifd/fusion-collector": {
-      "version": "1.3.5",
-      "resolved": "https://registry.npm.taobao.org/@alifd/fusion-collector/download/@alifd/fusion-collector-1.3.5.tgz",
-      "integrity": "sha1-gUc5qFKla8MkmFLVHKfFinln9NY=",
-      "dev": true,
-      "requires": {
-        "@babel/runtime": "^7.8.4",
-        "glob": "^7.1.2",
-        "graceful-fs": "^4.1.11",
-        "ice-npm-utils": "^1.4.1",
-        "ini": "^1.3.5"
-      }
-    },
-    "@alifd/next": {
-      "version": "1.21.8",
-      "resolved": "https://registry.npm.taobao.org/@alifd/next/download/@alifd/next-1.21.8.tgz",
-      "integrity": "sha1-yQGzKFTL3pmqq42S5Oc1IEpB7nw=",
-      "requires": {
-        "@alifd/field": "~1.4.1",
-        "@alifd/validate": "~1.2.0",
-        "babel-runtime": "^6.26.0",
-        "classnames": "^2.2.3",
-        "hoist-non-react-statics": "^2.1.0",
-        "lodash.clonedeep": "^4.5.0",
-        "prop-types": "^15.6.0",
-        "react-lifecycles-compat": "^3.0.4",
-        "react-transition-group": "^2.2.1",
-        "shallow-element-equals": "^1.0.1"
-      }
-    },
-    "@alifd/theme-design-pro": {
-      "version": "0.6.2",
-      "resolved": "https://registry.npm.taobao.org/@alifd/theme-design-pro/download/@alifd/theme-design-pro-0.6.2.tgz",
-      "integrity": "sha1-qaoxJgIooS2NlfvwTog/d1oO5Fs=",
-      "requires": {
-        "@alifd/next": "~1.19.22"
-      },
-      "dependencies": {
-        "@alifd/field": {
-          "version": "1.3.5",
-          "resolved": "https://registry.npm.taobao.org/@alifd/field/download/@alifd/field-1.3.5.tgz",
-          "integrity": "sha1-uPNwuNnbwquirIX2pZiezVHzZnM=",
-          "requires": {
-            "@alifd/validate": "^1.1.3",
-            "prop-types": "^15.5.8"
-          }
-        },
-        "@alifd/next": {
-          "version": "1.19.31",
-          "resolved": "https://registry.npm.taobao.org/@alifd/next/download/@alifd/next-1.19.31.tgz",
-          "integrity": "sha1-5DFSQ3UK/28KWZUOcvneDS/NblQ=",
-          "requires": {
-            "@alifd/field": "~1.3.3",
-            "@alifd/validate": "~1.1.4",
-            "babel-runtime": "^6.26.0",
-            "classnames": "^2.2.3",
-            "hoist-non-react-statics": "^2.1.0",
-            "prop-types": "^15.6.0",
-            "react-lifecycles-compat": "^3.0.4",
-            "react-transition-group": "^2.2.1",
-            "shallow-element-equals": "^1.0.1"
-          }
-        },
-        "@alifd/validate": {
-          "version": "1.1.5",
-          "resolved": "https://registry.npm.taobao.org/@alifd/validate/download/@alifd/validate-1.1.5.tgz",
-          "integrity": "sha1-5EiWeFBRGCy5TbfsKzOpm0yGlDo="
-        }
-      }
-    },
-    "@alifd/validate": {
-      "version": "1.2.0",
-      "resolved": "https://registry.npm.taobao.org/@alifd/validate/download/@alifd/validate-1.2.0.tgz",
-      "integrity": "sha1-JS4K3STmTv1U/mEbqMZtAUfYUPY="
-    },
-    "@babel/code-frame": {
-      "version": "7.10.4",
-      "resolved": "https://registry.npm.taobao.org/@babel/code-frame/download/@babel/code-frame-7.10.4.tgz",
-      "integrity": "sha1-Fo2ho26Q2miujUnA8bSMfGJJITo=",
-      "dev": true,
-      "requires": {
-        "@babel/highlight": "^7.10.4"
-      }
-    },
-    "@babel/compat-data": {
-      "version": "7.12.5",
-      "resolved": "https://registry.npm.taobao.org/@babel/compat-data/download/@babel/compat-data-7.12.5.tgz?cache=0&sync_timestamp=1604441103552&other_urls=https%3A%2F%2Fregistry.npm.taobao.org%2F%40babel%2Fcompat-data%2Fdownload%2F%40babel%2Fcompat-data-7.12.5.tgz",
-      "integrity": "sha1-9W2wxLsbu/IhtOgTRaq0FB58sOk=",
-      "dev": true
-    },
-    "@babel/core": {
-      "version": "7.12.3",
-      "resolved": "https://registry.npm.taobao.org/@babel/core/download/@babel/core-7.12.3.tgz",
-      "integrity": "sha1-G0NohOHjv/b7EyjcArIIdZ3pKtg=",
-      "dev": true,
-      "requires": {
-        "@babel/code-frame": "^7.10.4",
-        "@babel/generator": "^7.12.1",
-        "@babel/helper-module-transforms": "^7.12.1",
-        "@babel/helpers": "^7.12.1",
-        "@babel/parser": "^7.12.3",
-        "@babel/template": "^7.10.4",
-        "@babel/traverse": "^7.12.1",
-        "@babel/types": "^7.12.1",
-        "convert-source-map": "^1.7.0",
-        "debug": "^4.1.0",
-        "gensync": "^1.0.0-beta.1",
-        "json5": "^2.1.2",
-        "lodash": "^4.17.19",
-        "resolve": "^1.3.2",
-        "semver": "^5.4.1",
-        "source-map": "^0.5.0"
-      },
-      "dependencies": {
-        "json5": {
-          "version": "2.1.3",
-          "resolved": "https://registry.npm.taobao.org/json5/download/json5-2.1.3.tgz",
-          "integrity": "sha1-ybD3+pIzv+WAf+ZvzzpWF+1ZfUM=",
-          "dev": true,
-          "requires": {
-            "minimist": "^1.2.5"
-          }
-        },
-        "semver": {
-          "version": "5.7.1",
-          "resolved": "https://registry.npm.taobao.org/semver/download/semver-5.7.1.tgz",
-          "integrity": "sha1-qVT5Ma66UI0we78Gnv8MAclhFvc=",
-          "dev": true
-        }
-      }
-    },
-    "@babel/generator": {
-      "version": "7.12.5",
-      "resolved": "https://registry.npm.taobao.org/@babel/generator/download/@babel/generator-7.12.5.tgz?cache=0&sync_timestamp=1604441076223&other_urls=https%3A%2F%2Fregistry.npm.taobao.org%2F%40babel%2Fgenerator%2Fdownload%2F%40babel%2Fgenerator-7.12.5.tgz",
-      "integrity": "sha1-osUN5ci21wirlb5eYFOTbBiEpN4=",
-      "dev": true,
-      "requires": {
-        "@babel/types": "^7.12.5",
-        "jsesc": "^2.5.1",
-        "source-map": "^0.5.0"
-      }
-    },
-    "@babel/helper-annotate-as-pure": {
-      "version": "7.10.4",
-      "resolved": "https://registry.npm.taobao.org/@babel/helper-annotate-as-pure/download/@babel/helper-annotate-as-pure-7.10.4.tgz?cache=0&sync_timestamp=1593522826156&other_urls=https%3A%2F%2Fregistry.npm.taobao.org%2F%40babel%2Fhelper-annotate-as-pure%2Fdownload%2F%40babel%2Fhelper-annotate-as-pure-7.10.4.tgz",
-      "integrity": "sha1-W/DUlaP3V6w72ki1vzs7ownHK6M=",
-      "dev": true,
-      "requires": {
-        "@babel/types": "^7.10.4"
-      }
-    },
-    "@babel/helper-builder-binary-assignment-operator-visitor": {
-      "version": "7.10.4",
-      "resolved": "https://registry.npm.taobao.org/@babel/helper-builder-binary-assignment-operator-visitor/download/@babel/helper-builder-binary-assignment-operator-visitor-7.10.4.tgz",
-      "integrity": "sha1-uwt18xv5jL+f8UPBrleLhydK4aM=",
-      "dev": true,
-      "requires": {
-        "@babel/helper-explode-assignable-expression": "^7.10.4",
-        "@babel/types": "^7.10.4"
-      }
-    },
-    "@babel/helper-builder-react-jsx": {
-      "version": "7.10.4",
-      "resolved": "https://registry.npm.taobao.org/@babel/helper-builder-react-jsx/download/@babel/helper-builder-react-jsx-7.10.4.tgz?cache=0&sync_timestamp=1593522969703&other_urls=https%3A%2F%2Fregistry.npm.taobao.org%2F%40babel%2Fhelper-builder-react-jsx%2Fdownload%2F%40babel%2Fhelper-builder-react-jsx-7.10.4.tgz",
-      "integrity": "sha1-gJXN2/+Fjm+pwyba7lSi8nMsHV0=",
-      "dev": true,
-      "requires": {
-        "@babel/helper-annotate-as-pure": "^7.10.4",
-        "@babel/types": "^7.10.4"
-      }
-    },
-    "@babel/helper-builder-react-jsx-experimental": {
-      "version": "7.12.4",
-      "resolved": "https://registry.npm.taobao.org/@babel/helper-builder-react-jsx-experimental/download/@babel/helper-builder-react-jsx-experimental-7.12.4.tgz",
-      "integrity": "sha1-VfwerVJCyqDKKHXcuO7W0xHlD0g=",
-      "dev": true,
-      "requires": {
-        "@babel/helper-annotate-as-pure": "^7.10.4",
-        "@babel/helper-module-imports": "^7.12.1",
-        "@babel/types": "^7.12.1"
-      }
-    },
-    "@babel/helper-compilation-targets": {
-      "version": "7.12.5",
-      "resolved": "https://registry.npm.taobao.org/@babel/helper-compilation-targets/download/@babel/helper-compilation-targets-7.12.5.tgz?cache=0&sync_timestamp=1604441105017&other_urls=https%3A%2F%2Fregistry.npm.taobao.org%2F%40babel%2Fhelper-compilation-targets%2Fdownload%2F%40babel%2Fhelper-compilation-targets-7.12.5.tgz",
-      "integrity": "sha1-y0cMdhmNtqJOnbyJhydWMeXSmDE=",
-      "dev": true,
-      "requires": {
-        "@babel/compat-data": "^7.12.5",
-        "@babel/helper-validator-option": "^7.12.1",
-        "browserslist": "^4.14.5",
-        "semver": "^5.5.0"
-      },
-      "dependencies": {
-        "semver": {
-          "version": "5.7.1",
-          "resolved": "https://registry.npm.taobao.org/semver/download/semver-5.7.1.tgz",
-          "integrity": "sha1-qVT5Ma66UI0we78Gnv8MAclhFvc=",
-          "dev": true
-        }
-      }
-    },
-    "@babel/helper-create-class-features-plugin": {
-      "version": "7.12.1",
-      "resolved": "https://registry.npm.taobao.org/@babel/helper-create-class-features-plugin/download/@babel/helper-create-class-features-plugin-7.12.1.tgz?cache=0&sync_timestamp=1602802060378&other_urls=https%3A%2F%2Fregistry.npm.taobao.org%2F%40babel%2Fhelper-create-class-features-plugin%2Fdownload%2F%40babel%2Fhelper-create-class-features-plugin-7.12.1.tgz",
-      "integrity": "sha1-PEWZj0Me3UqSFMXx060USKYTf24=",
-      "dev": true,
-      "requires": {
-        "@babel/helper-function-name": "^7.10.4",
-        "@babel/helper-member-expression-to-functions": "^7.12.1",
-        "@babel/helper-optimise-call-expression": "^7.10.4",
-        "@babel/helper-replace-supers": "^7.12.1",
-        "@babel/helper-split-export-declaration": "^7.10.4"
-      }
-    },
-    "@babel/helper-create-regexp-features-plugin": {
-      "version": "7.12.1",
-      "resolved": "https://registry.npm.taobao.org/@babel/helper-create-regexp-features-plugin/download/@babel/helper-create-regexp-features-plugin-7.12.1.tgz?cache=0&sync_timestamp=1602800231050&other_urls=https%3A%2F%2Fregistry.npm.taobao.org%2F%40babel%2Fhelper-create-regexp-features-plugin%2Fdownload%2F%40babel%2Fhelper-create-regexp-features-plugin-7.12.1.tgz",
-      "integrity": "sha1-GLEwLUZ3+dxHQP6MntlmgOKdN+g=",
-      "dev": true,
-      "requires": {
-        "@babel/helper-annotate-as-pure": "^7.10.4",
-        "@babel/helper-regex": "^7.10.4",
-        "regexpu-core": "^4.7.1"
-      }
-    },
-    "@babel/helper-define-map": {
-      "version": "7.10.5",
-      "resolved": "https://registry.npm.taobao.org/@babel/helper-define-map/download/@babel/helper-define-map-7.10.5.tgz",
-      "integrity": "sha1-tTwQ23imQIABUmkrEzkxR6y5uzA=",
-      "dev": true,
-      "requires": {
-        "@babel/helper-function-name": "^7.10.4",
-        "@babel/types": "^7.10.5",
-        "lodash": "^4.17.19"
-      }
-    },
-    "@babel/helper-explode-assignable-expression": {
-      "version": "7.12.1",
-      "resolved": "https://registry.npm.taobao.org/@babel/helper-explode-assignable-expression/download/@babel/helper-explode-assignable-expression-7.12.1.tgz?cache=0&sync_timestamp=1602800239433&other_urls=https%3A%2F%2Fregistry.npm.taobao.org%2F%40babel%2Fhelper-explode-assignable-expression%2Fdownload%2F%40babel%2Fhelper-explode-assignable-expression-7.12.1.tgz",
-      "integrity": "sha1-gAakZmlcSthqKl8vsVtfLDGtVjM=",
-      "dev": true,
-      "requires": {
-        "@babel/types": "^7.12.1"
-      }
-    },
-    "@babel/helper-function-name": {
-      "version": "7.10.4",
-      "resolved": "https://registry.npm.taobao.org/@babel/helper-function-name/download/@babel/helper-function-name-7.10.4.tgz?cache=0&sync_timestamp=1593522836308&other_urls=https%3A%2F%2Fregistry.npm.taobao.org%2F%40babel%2Fhelper-function-name%2Fdownload%2F%40babel%2Fhelper-function-name-7.10.4.tgz",
-      "integrity": "sha1-0tOyDFmtjEcRL6fSqUvAnV74Lxo=",
-      "dev": true,
-      "requires": {
-        "@babel/helper-get-function-arity": "^7.10.4",
-        "@babel/template": "^7.10.4",
-        "@babel/types": "^7.10.4"
-      }
-    },
-    "@babel/helper-get-function-arity": {
-      "version": "7.10.4",
-      "resolved": "https://registry.npm.taobao.org/@babel/helper-get-function-arity/download/@babel/helper-get-function-arity-7.10.4.tgz?cache=0&sync_timestamp=1593522827189&other_urls=https%3A%2F%2Fregistry.npm.taobao.org%2F%40babel%2Fhelper-get-function-arity%2Fdownload%2F%40babel%2Fhelper-get-function-arity-7.10.4.tgz",
-      "integrity": "sha1-mMHL6g4jMvM/mkZhuM4VBbLBm6I=",
-      "dev": true,
-      "requires": {
-        "@babel/types": "^7.10.4"
-      }
-    },
-    "@babel/helper-hoist-variables": {
-      "version": "7.10.4",
-      "resolved": "https://registry.npm.taobao.org/@babel/helper-hoist-variables/download/@babel/helper-hoist-variables-7.10.4.tgz?cache=0&sync_timestamp=1593522826778&other_urls=https%3A%2F%2Fregistry.npm.taobao.org%2F%40babel%2Fhelper-hoist-variables%2Fdownload%2F%40babel%2Fhelper-hoist-variables-7.10.4.tgz",
-      "integrity": "sha1-1JsAHR1aaMpeZgTdoBpil/fJOB4=",
-      "dev": true,
-      "requires": {
-        "@babel/types": "^7.10.4"
-      }
-    },
-    "@babel/helper-member-expression-to-functions": {
-      "version": "7.12.1",
-      "resolved": "https://registry.npm.taobao.org/@babel/helper-member-expression-to-functions/download/@babel/helper-member-expression-to-functions-7.12.1.tgz?cache=0&sync_timestamp=1602800239601&other_urls=https%3A%2F%2Fregistry.npm.taobao.org%2F%40babel%2Fhelper-member-expression-to-functions%2Fdownload%2F%40babel%2Fhelper-member-expression-to-functions-7.12.1.tgz",
-      "integrity": "sha1-+6Dy/P8/ugDm7LZku15uJuLWFlw=",
-      "dev": true,
-      "requires": {
-        "@babel/types": "^7.12.1"
-      }
-    },
-    "@babel/helper-module-imports": {
-      "version": "7.12.5",
-      "resolved": "https://registry.npm.taobao.org/@babel/helper-module-imports/download/@babel/helper-module-imports-7.12.5.tgz?cache=0&sync_timestamp=1604441076449&other_urls=https%3A%2F%2Fregistry.npm.taobao.org%2F%40babel%2Fhelper-module-imports%2Fdownload%2F%40babel%2Fhelper-module-imports-7.12.5.tgz",
-      "integrity": "sha1-G/wCKfeUmI927QpNTpCGCFC1Tfs=",
-      "dev": true,
-      "requires": {
-        "@babel/types": "^7.12.5"
-      }
-    },
-    "@babel/helper-module-transforms": {
-      "version": "7.12.1",
-      "resolved": "https://registry.npm.taobao.org/@babel/helper-module-transforms/download/@babel/helper-module-transforms-7.12.1.tgz?cache=0&sync_timestamp=1602802059560&other_urls=https%3A%2F%2Fregistry.npm.taobao.org%2F%40babel%2Fhelper-module-transforms%2Fdownload%2F%40babel%2Fhelper-module-transforms-7.12.1.tgz",
-      "integrity": "sha1-eVT+xx9bMsSOSzA7Q3w0RT/XJHw=",
-      "dev": true,
-      "requires": {
-        "@babel/helper-module-imports": "^7.12.1",
-        "@babel/helper-replace-supers": "^7.12.1",
-        "@babel/helper-simple-access": "^7.12.1",
-        "@babel/helper-split-export-declaration": "^7.11.0",
-        "@babel/helper-validator-identifier": "^7.10.4",
-        "@babel/template": "^7.10.4",
-        "@babel/traverse": "^7.12.1",
-        "@babel/types": "^7.12.1",
-        "lodash": "^4.17.19"
-      }
-    },
-    "@babel/helper-optimise-call-expression": {
-      "version": "7.10.4",
-      "resolved": "https://registry.npm.taobao.org/@babel/helper-optimise-call-expression/download/@babel/helper-optimise-call-expression-7.10.4.tgz?cache=0&sync_timestamp=1593522827576&other_urls=https%3A%2F%2Fregistry.npm.taobao.org%2F%40babel%2Fhelper-optimise-call-expression%2Fdownload%2F%40babel%2Fhelper-optimise-call-expression-7.10.4.tgz",
-      "integrity": "sha1-UNyWQT1ZT5lad5BZBbBYk813lnM=",
-      "dev": true,
-      "requires": {
-        "@babel/types": "^7.10.4"
-      }
-    },
-    "@babel/helper-plugin-utils": {
-      "version": "7.10.4",
-      "resolved": "https://registry.npm.taobao.org/@babel/helper-plugin-utils/download/@babel/helper-plugin-utils-7.10.4.tgz?cache=0&sync_timestamp=1593521148758&other_urls=https%3A%2F%2Fregistry.npm.taobao.org%2F%40babel%2Fhelper-plugin-utils%2Fdownload%2F%40babel%2Fhelper-plugin-utils-7.10.4.tgz",
-      "integrity": "sha1-L3WoMSadT2d95JmG3/WZJ1M883U=",
-      "dev": true
-    },
-    "@babel/helper-regex": {
-      "version": "7.10.5",
-      "resolved": "https://registry.npm.taobao.org/@babel/helper-regex/download/@babel/helper-regex-7.10.5.tgz?cache=0&sync_timestamp=1594751535064&other_urls=https%3A%2F%2Fregistry.npm.taobao.org%2F%40babel%2Fhelper-regex%2Fdownload%2F%40babel%2Fhelper-regex-7.10.5.tgz",
-      "integrity": "sha1-Mt+7eYmQc8QVVXBToZvQVarlCuA=",
-      "dev": true,
-      "requires": {
-        "lodash": "^4.17.19"
-      }
-    },
-    "@babel/helper-remap-async-to-generator": {
-      "version": "7.12.1",
-      "resolved": "https://registry.npm.taobao.org/@babel/helper-remap-async-to-generator/download/@babel/helper-remap-async-to-generator-7.12.1.tgz?cache=0&sync_timestamp=1602800240049&other_urls=https%3A%2F%2Fregistry.npm.taobao.org%2F%40babel%2Fhelper-remap-async-to-generator%2Fdownload%2F%40babel%2Fhelper-remap-async-to-generator-7.12.1.tgz",
-      "integrity": "sha1-jE27+RYxT2BH3AXmoiFwdCODR/0=",
-      "dev": true,
-      "requires": {
-        "@babel/helper-annotate-as-pure": "^7.10.4",
-        "@babel/helper-wrap-function": "^7.10.4",
-        "@babel/types": "^7.12.1"
-      }
-    },
-    "@babel/helper-replace-supers": {
-      "version": "7.12.5",
-      "resolved": "https://registry.npm.taobao.org/@babel/helper-replace-supers/download/@babel/helper-replace-supers-7.12.5.tgz",
-      "integrity": "sha1-8AmhdUO7u84WsGIGrnO2PT/KaNk=",
-      "dev": true,
-      "requires": {
-        "@babel/helper-member-expression-to-functions": "^7.12.1",
-        "@babel/helper-optimise-call-expression": "^7.10.4",
-        "@babel/traverse": "^7.12.5",
-        "@babel/types": "^7.12.5"
-      }
-    },
-    "@babel/helper-simple-access": {
-      "version": "7.12.1",
-      "resolved": "https://registry.npm.taobao.org/@babel/helper-simple-access/download/@babel/helper-simple-access-7.12.1.tgz?cache=0&sync_timestamp=1602802050087&other_urls=https%3A%2F%2Fregistry.npm.taobao.org%2F%40babel%2Fhelper-simple-access%2Fdownload%2F%40babel%2Fhelper-simple-access-7.12.1.tgz",
-      "integrity": "sha1-MkJ+WqYVR9OOsebq9f0UJv2tkTY=",
-      "dev": true,
-      "requires": {
-        "@babel/types": "^7.12.1"
-      }
-    },
-    "@babel/helper-skip-transparent-expression-wrappers": {
-      "version": "7.12.1",
-      "resolved": "https://registry.npm.taobao.org/@babel/helper-skip-transparent-expression-wrappers/download/@babel/helper-skip-transparent-expression-wrappers-7.12.1.tgz",
-      "integrity": "sha1-Ri3GOn5DWt6EaDhcY9K4TM5LPL8=",
-      "dev": true,
-      "requires": {
-        "@babel/types": "^7.12.1"
-      }
-    },
-    "@babel/helper-split-export-declaration": {
-      "version": "7.11.0",
-      "resolved": "https://registry.npm.taobao.org/@babel/helper-split-export-declaration/download/@babel/helper-split-export-declaration-7.11.0.tgz?cache=0&sync_timestamp=1596144786980&other_urls=https%3A%2F%2Fregistry.npm.taobao.org%2F%40babel%2Fhelper-split-export-declaration%2Fdownload%2F%40babel%2Fhelper-split-export-declaration-7.11.0.tgz",
-      "integrity": "sha1-+KSRJErPamdhWKxCBykRuoOtCZ8=",
-      "dev": true,
-      "requires": {
-        "@babel/types": "^7.11.0"
-      }
-    },
-    "@babel/helper-validator-identifier": {
-      "version": "7.10.4",
-      "resolved": "https://registry.npm.taobao.org/@babel/helper-validator-identifier/download/@babel/helper-validator-identifier-7.10.4.tgz",
-      "integrity": "sha1-p4x6clHgH2FlEtMbEK3PUq2l4NI=",
-      "dev": true
-    },
-    "@babel/helper-validator-option": {
-      "version": "7.12.1",
-      "resolved": "https://registry.npm.taobao.org/@babel/helper-validator-option/download/@babel/helper-validator-option-7.12.1.tgz?cache=0&sync_timestamp=1602801773085&other_urls=https%3A%2F%2Fregistry.npm.taobao.org%2F%40babel%2Fhelper-validator-option%2Fdownload%2F%40babel%2Fhelper-validator-option-7.12.1.tgz",
-      "integrity": "sha1-F1VnOAw+d9YP+YpUuwFf548heNk=",
-      "dev": true
-    },
-    "@babel/helper-wrap-function": {
-      "version": "7.12.3",
-      "resolved": "https://registry.npm.taobao.org/@babel/helper-wrap-function/download/@babel/helper-wrap-function-7.12.3.tgz",
-      "integrity": "sha1-MzIzn8TR+78cJ9eVjCfTRwjpkNk=",
-      "dev": true,
-      "requires": {
-        "@babel/helper-function-name": "^7.10.4",
-        "@babel/template": "^7.10.4",
-        "@babel/traverse": "^7.10.4",
-        "@babel/types": "^7.10.4"
-      }
-    },
-    "@babel/helpers": {
-      "version": "7.12.5",
-      "resolved": "https://registry.npm.taobao.org/@babel/helpers/download/@babel/helpers-7.12.5.tgz",
-      "integrity": "sha1-Ghukp2jZtYMQ7aUWxEmRP+ZHEW4=",
-      "dev": true,
-      "requires": {
-        "@babel/template": "^7.10.4",
-        "@babel/traverse": "^7.12.5",
-        "@babel/types": "^7.12.5"
-      }
-    },
-    "@babel/highlight": {
-      "version": "7.10.4",
-      "resolved": "https://registry.npm.taobao.org/@babel/highlight/download/@babel/highlight-7.10.4.tgz?cache=0&sync_timestamp=1593522818552&other_urls=https%3A%2F%2Fregistry.npm.taobao.org%2F%40babel%2Fhighlight%2Fdownload%2F%40babel%2Fhighlight-7.10.4.tgz",
-      "integrity": "sha1-fRvf1ldTU4+r5sOFls23bZrGAUM=",
-      "dev": true,
-      "requires": {
-        "@babel/helper-validator-identifier": "^7.10.4",
-        "chalk": "^2.0.0",
-        "js-tokens": "^4.0.0"
-      }
-    },
-    "@babel/parser": {
-      "version": "7.12.5",
-      "resolved": "https://registry.npm.taobao.org/@babel/parser/download/@babel/parser-7.12.5.tgz?cache=0&sync_timestamp=1604441237314&other_urls=https%3A%2F%2Fregistry.npm.taobao.org%2F%40babel%2Fparser%2Fdownload%2F%40babel%2Fparser-7.12.5.tgz",
-      "integrity": "sha1-tK8y3dRzwL+mQ71/8HKLjnG4HqA=",
-      "dev": true
-    },
-    "@babel/plugin-proposal-async-generator-functions": {
-      "version": "7.12.1",
-      "resolved": "https://registry.npm.taobao.org/@babel/plugin-proposal-async-generator-functions/download/@babel/plugin-proposal-async-generator-functions-7.12.1.tgz?cache=0&sync_timestamp=1602800241810&other_urls=https%3A%2F%2Fregistry.npm.taobao.org%2F%40babel%2Fplugin-proposal-async-generator-functions%2Fdownload%2F%40babel%2Fplugin-proposal-async-generator-functions-7.12.1.tgz",
-      "integrity": "sha1-3GwRcOJ9isqZ/2X0klvQaxyQVQ4=",
-      "dev": true,
-      "requires": {
-        "@babel/helper-plugin-utils": "^7.10.4",
-        "@babel/helper-remap-async-to-generator": "^7.12.1",
-        "@babel/plugin-syntax-async-generators": "^7.8.0"
-      }
-    },
-    "@babel/plugin-proposal-class-properties": {
-      "version": "7.12.1",
-      "resolved": "https://registry.npm.taobao.org/@babel/plugin-proposal-class-properties/download/@babel/plugin-proposal-class-properties-7.12.1.tgz?cache=0&sync_timestamp=1602802062562&other_urls=https%3A%2F%2Fregistry.npm.taobao.org%2F%40babel%2Fplugin-proposal-class-properties%2Fdownload%2F%40babel%2Fplugin-proposal-class-properties-7.12.1.tgz",
-      "integrity": "sha1-oIL/VB8qKaSCEGW4rdk0bAwW5d4=",
-      "dev": true,
-      "requires": {
-        "@babel/helper-create-class-features-plugin": "^7.12.1",
-        "@babel/helper-plugin-utils": "^7.10.4"
-      }
-    },
-    "@babel/plugin-proposal-decorators": {
-      "version": "7.12.1",
-      "resolved": "https://registry.npm.taobao.org/@babel/plugin-proposal-decorators/download/@babel/plugin-proposal-decorators-7.12.1.tgz?cache=0&sync_timestamp=1602800229034&other_urls=https%3A%2F%2Fregistry.npm.taobao.org%2F%40babel%2Fplugin-proposal-decorators%2Fdownload%2F%40babel%2Fplugin-proposal-decorators-7.12.1.tgz",
-      "integrity": "sha1-WScUOf7UFFRWxBBnRQVDruMy0V8=",
-      "dev": true,
-      "requires": {
-        "@babel/helper-create-class-features-plugin": "^7.12.1",
-        "@babel/helper-plugin-utils": "^7.10.4",
-        "@babel/plugin-syntax-decorators": "^7.12.1"
-      }
-    },
-    "@babel/plugin-proposal-do-expressions": {
-      "version": "7.12.1",
-      "resolved": "https://registry.npm.taobao.org/@babel/plugin-proposal-do-expressions/download/@babel/plugin-proposal-do-expressions-7.12.1.tgz?cache=0&sync_timestamp=1602806865634&other_urls=https%3A%2F%2Fregistry.npm.taobao.org%2F%40babel%2Fplugin-proposal-do-expressions%2Fdownload%2F%40babel%2Fplugin-proposal-do-expressions-7.12.1.tgz",
-      "integrity": "sha1-jX8bxTLYFoFHVVwm49uSLMDf0vg=",
-      "dev": true,
-      "requires": {
-        "@babel/helper-plugin-utils": "^7.10.4",
-        "@babel/plugin-syntax-do-expressions": "^7.12.1"
-      }
-    },
-    "@babel/plugin-proposal-dynamic-import": {
-      "version": "7.12.1",
-      "resolved": "https://registry.npm.taobao.org/@babel/plugin-proposal-dynamic-import/download/@babel/plugin-proposal-dynamic-import-7.12.1.tgz?cache=0&sync_timestamp=1602800231856&other_urls=https%3A%2F%2Fregistry.npm.taobao.org%2F%40babel%2Fplugin-proposal-dynamic-import%2Fdownload%2F%40babel%2Fplugin-proposal-dynamic-import-7.12.1.tgz",
-      "integrity": "sha1-Q+tcKjSH7NmMXI6otf22midJstw=",
-      "dev": true,
-      "requires": {
-        "@babel/helper-plugin-utils": "^7.10.4",
-        "@babel/plugin-syntax-dynamic-import": "^7.8.0"
-      }
-    },
-    "@babel/plugin-proposal-export-default-from": {
-      "version": "7.12.1",
-      "resolved": "https://registry.npm.taobao.org/@babel/plugin-proposal-export-default-from/download/@babel/plugin-proposal-export-default-from-7.12.1.tgz?cache=0&sync_timestamp=1602806866408&other_urls=https%3A%2F%2Fregistry.npm.taobao.org%2F%40babel%2Fplugin-proposal-export-default-from%2Fdownload%2F%40babel%2Fplugin-proposal-export-default-from-7.12.1.tgz",
-      "integrity": "sha1-xuYtZoqKvP4NKLgvVgOV/sthHFo=",
-      "dev": true,
-      "requires": {
-        "@babel/helper-plugin-utils": "^7.10.4",
-        "@babel/plugin-syntax-export-default-from": "^7.12.1"
-      }
-    },
-    "@babel/plugin-proposal-export-namespace-from": {
-      "version": "7.12.1",
-      "resolved": "https://registry.npm.taobao.org/@babel/plugin-proposal-export-namespace-from/download/@babel/plugin-proposal-export-namespace-from-7.12.1.tgz?cache=0&sync_timestamp=1602801775633&other_urls=https%3A%2F%2Fregistry.npm.taobao.org%2F%40babel%2Fplugin-proposal-export-namespace-from%2Fdownload%2F%40babel%2Fplugin-proposal-export-namespace-from-7.12.1.tgz",
-      "integrity": "sha1-i5uPN2stiPXdd05NJKXMLjZ5ttQ=",
-      "dev": true,
-      "requires": {
-        "@babel/helper-plugin-utils": "^7.10.4",
-        "@babel/plugin-syntax-export-namespace-from": "^7.8.3"
-      }
-    },
-    "@babel/plugin-proposal-function-bind": {
-      "version": "7.12.1",
-      "resolved": "https://registry.npm.taobao.org/@babel/plugin-proposal-function-bind/download/@babel/plugin-proposal-function-bind-7.12.1.tgz?cache=0&sync_timestamp=1602806866031&other_urls=https%3A%2F%2Fregistry.npm.taobao.org%2F%40babel%2Fplugin-proposal-function-bind%2Fdownload%2F%40babel%2Fplugin-proposal-function-bind-7.12.1.tgz",
-      "integrity": "sha1-i4kbQS/7yOj/P9TfZ7jUu+WUcAQ=",
-      "dev": true,
-      "requires": {
-        "@babel/helper-plugin-utils": "^7.10.4",
-        "@babel/plugin-syntax-function-bind": "^7.12.1"
-      }
-    },
-    "@babel/plugin-proposal-function-sent": {
-      "version": "7.12.1",
-      "resolved": "https://registry.npm.taobao.org/@babel/plugin-proposal-function-sent/download/@babel/plugin-proposal-function-sent-7.12.1.tgz",
-      "integrity": "sha1-jzAqqKtfAK9slKPhEI+jXRUxlRA=",
-      "dev": true,
-      "requires": {
-        "@babel/helper-plugin-utils": "^7.10.4",
-        "@babel/helper-wrap-function": "^7.10.4",
-        "@babel/plugin-syntax-function-sent": "^7.12.1"
-      }
-    },
-    "@babel/plugin-proposal-json-strings": {
-      "version": "7.12.1",
-      "resolved": "https://registry.npm.taobao.org/@babel/plugin-proposal-json-strings/download/@babel/plugin-proposal-json-strings-7.12.1.tgz?cache=0&sync_timestamp=1602800231781&other_urls=https%3A%2F%2Fregistry.npm.taobao.org%2F%40babel%2Fplugin-proposal-json-strings%2Fdownload%2F%40babel%2Fplugin-proposal-json-strings-7.12.1.tgz",
-      "integrity": "sha1-1FQjtRdxTu3VYhqd/cA/qfTrJBw=",
-      "dev": true,
-      "requires": {
-        "@babel/helper-plugin-utils": "^7.10.4",
-        "@babel/plugin-syntax-json-strings": "^7.8.0"
-      }
-    },
-    "@babel/plugin-proposal-logical-assignment-operators": {
-      "version": "7.12.1",
-      "resolved": "https://registry.npm.taobao.org/@babel/plugin-proposal-logical-assignment-operators/download/@babel/plugin-proposal-logical-assignment-operators-7.12.1.tgz?cache=0&sync_timestamp=1602801777850&other_urls=https%3A%2F%2Fregistry.npm.taobao.org%2F%40babel%2Fplugin-proposal-logical-assignment-operators%2Fdownload%2F%40babel%2Fplugin-proposal-logical-assignment-operators-7.12.1.tgz",
-      "integrity": "sha1-8sSQ024bPJZZJBA0pdLNUCY6J1E=",
-      "dev": true,
-      "requires": {
-        "@babel/helper-plugin-utils": "^7.10.4",
-        "@babel/plugin-syntax-logical-assignment-operators": "^7.10.4"
-      }
-    },
-    "@babel/plugin-proposal-nullish-coalescing-operator": {
-      "version": "7.12.1",
-      "resolved": "https://registry.npm.taobao.org/@babel/plugin-proposal-nullish-coalescing-operator/download/@babel/plugin-proposal-nullish-coalescing-operator-7.12.1.tgz?cache=0&sync_timestamp=1602800231580&other_urls=https%3A%2F%2Fregistry.npm.taobao.org%2F%40babel%2Fplugin-proposal-nullish-coalescing-operator%2Fdownload%2F%40babel%2Fplugin-proposal-nullish-coalescing-operator-7.12.1.tgz",
-      "integrity": "sha1-PtT/8xwBXn8/FGfxkNvlRc17BGw=",
-      "dev": true,
-      "requires": {
-        "@babel/helper-plugin-utils": "^7.10.4",
-        "@babel/plugin-syntax-nullish-coalescing-operator": "^7.8.0"
-      }
-    },
-    "@babel/plugin-proposal-numeric-separator": {
-      "version": "7.12.5",
-      "resolved": "https://registry.npm.taobao.org/@babel/plugin-proposal-numeric-separator/download/@babel/plugin-proposal-numeric-separator-7.12.5.tgz?cache=0&sync_timestamp=1604441516252&other_urls=https%3A%2F%2Fregistry.npm.taobao.org%2F%40babel%2Fplugin-proposal-numeric-separator%2Fdownload%2F%40babel%2Fplugin-proposal-numeric-separator-7.12.5.tgz",
-      "integrity": "sha1-sc51cVbUDtedWdRnyysVSlxBSbo=",
-      "dev": true,
-      "requires": {
-        "@babel/helper-plugin-utils": "^7.10.4",
-        "@babel/plugin-syntax-numeric-separator": "^7.10.4"
-      }
-    },
-    "@babel/plugin-proposal-object-rest-spread": {
-      "version": "7.12.1",
-      "resolved": "https://registry.npm.taobao.org/@babel/plugin-proposal-object-rest-spread/download/@babel/plugin-proposal-object-rest-spread-7.12.1.tgz?cache=0&sync_timestamp=1602800240952&other_urls=https%3A%2F%2Fregistry.npm.taobao.org%2F%40babel%2Fplugin-proposal-object-rest-spread%2Fdownload%2F%40babel%2Fplugin-proposal-object-rest-spread-7.12.1.tgz",
-      "integrity": "sha1-3vm9A86g+bcig9rA7CLSicdpEGk=",
-      "dev": true,
-      "requires": {
-        "@babel/helper-plugin-utils": "^7.10.4",
-        "@babel/plugin-syntax-object-rest-spread": "^7.8.0",
-        "@babel/plugin-transform-parameters": "^7.12.1"
-      }
-    },
-    "@babel/plugin-proposal-optional-catch-binding": {
-      "version": "7.12.1",
-      "resolved": "https://registry.npm.taobao.org/@babel/plugin-proposal-optional-catch-binding/download/@babel/plugin-proposal-optional-catch-binding-7.12.1.tgz?cache=0&sync_timestamp=1602800232182&other_urls=https%3A%2F%2Fregistry.npm.taobao.org%2F%40babel%2Fplugin-proposal-optional-catch-binding%2Fdownload%2F%40babel%2Fplugin-proposal-optional-catch-binding-7.12.1.tgz",
-      "integrity": "sha1-zMJCGvZNOq5QtVinHO3pKaWrKUI=",
-      "dev": true,
-      "requires": {
-        "@babel/helper-plugin-utils": "^7.10.4",
-        "@babel/plugin-syntax-optional-catch-binding": "^7.8.0"
-      }
-    },
-    "@babel/plugin-proposal-optional-chaining": {
-      "version": "7.12.1",
-      "resolved": "https://registry.npm.taobao.org/@babel/plugin-proposal-optional-chaining/download/@babel/plugin-proposal-optional-chaining-7.12.1.tgz?cache=0&sync_timestamp=1602800241914&other_urls=https%3A%2F%2Fregistry.npm.taobao.org%2F%40babel%2Fplugin-proposal-optional-chaining%2Fdownload%2F%40babel%2Fplugin-proposal-optional-chaining-7.12.1.tgz",
-      "integrity": "sha1-zOEiID/IoyeUKW/Dd8be2vQ2N5c=",
-      "dev": true,
-      "requires": {
-        "@babel/helper-plugin-utils": "^7.10.4",
-        "@babel/helper-skip-transparent-expression-wrappers": "^7.12.1",
-        "@babel/plugin-syntax-optional-chaining": "^7.8.0"
-      }
-    },
-    "@babel/plugin-proposal-pipeline-operator": {
-      "version": "7.12.1",
-      "resolved": "https://registry.npm.taobao.org/@babel/plugin-proposal-pipeline-operator/download/@babel/plugin-proposal-pipeline-operator-7.12.1.tgz?cache=0&sync_timestamp=1602806869343&other_urls=https%3A%2F%2Fregistry.npm.taobao.org%2F%40babel%2Fplugin-proposal-pipeline-operator%2Fdownload%2F%40babel%2Fplugin-proposal-pipeline-operator-7.12.1.tgz",
-      "integrity": "sha1-S9N3vH5b6S8i8cCLPzljY2vY9KE=",
-      "dev": true,
-      "requires": {
-        "@babel/helper-plugin-utils": "^7.10.4",
-        "@babel/plugin-syntax-pipeline-operator": "^7.12.1"
-      }
-    },
-    "@babel/plugin-proposal-private-methods": {
-      "version": "7.12.1",
-      "resolved": "https://registry.npm.taobao.org/@babel/plugin-proposal-private-methods/download/@babel/plugin-proposal-private-methods-7.12.1.tgz?cache=0&sync_timestamp=1602802060750&other_urls=https%3A%2F%2Fregistry.npm.taobao.org%2F%40babel%2Fplugin-proposal-private-methods%2Fdownload%2F%40babel%2Fplugin-proposal-private-methods-7.12.1.tgz",
-      "integrity": "sha1-hoFPbnohN0yYDBDTi0ST5wP0o4k=",
-      "dev": true,
-      "requires": {
-        "@babel/helper-create-class-features-plugin": "^7.12.1",
-        "@babel/helper-plugin-utils": "^7.10.4"
-      }
-    },
-    "@babel/plugin-proposal-throw-expressions": {
-      "version": "7.12.1",
-      "resolved": "https://registry.npm.taobao.org/@babel/plugin-proposal-throw-expressions/download/@babel/plugin-proposal-throw-expressions-7.12.1.tgz",
-      "integrity": "sha1-Wt9KvH80mi2lMuZjs2JR9gF8Qnk=",
-      "dev": true,
-      "requires": {
-        "@babel/helper-plugin-utils": "^7.10.4",
-        "@babel/plugin-syntax-throw-expressions": "^7.12.1"
-      }
-    },
-    "@babel/plugin-proposal-unicode-property-regex": {
-      "version": "7.12.1",
-      "resolved": "https://registry.npm.taobao.org/@babel/plugin-proposal-unicode-property-regex/download/@babel/plugin-proposal-unicode-property-regex-7.12.1.tgz?cache=0&sync_timestamp=1602800241079&other_urls=https%3A%2F%2Fregistry.npm.taobao.org%2F%40babel%2Fplugin-proposal-unicode-property-regex%2Fdownload%2F%40babel%2Fplugin-proposal-unicode-property-regex-7.12.1.tgz",
-      "integrity": "sha1-Khg5WNQXdluerjNPR3WOXWqC4HI=",
-      "dev": true,
-      "requires": {
-        "@babel/helper-create-regexp-features-plugin": "^7.12.1",
-        "@babel/helper-plugin-utils": "^7.10.4"
-      }
-    },
-    "@babel/plugin-syntax-async-generators": {
-      "version": "7.8.4",
-      "resolved": "https://registry.npm.taobao.org/@babel/plugin-syntax-async-generators/download/@babel/plugin-syntax-async-generators-7.8.4.tgz",
-      "integrity": "sha1-qYP7Gusuw/btBCohD2QOkOeG/g0=",
-      "dev": true,
-      "requires": {
-        "@babel/helper-plugin-utils": "^7.8.0"
-      }
-    },
-    "@babel/plugin-syntax-bigint": {
-      "version": "7.8.3",
-      "resolved": "https://registry.npm.taobao.org/@babel/plugin-syntax-bigint/download/@babel/plugin-syntax-bigint-7.8.3.tgz",
-      "integrity": "sha1-TJpvZp9dDN8bkKFnHpoUa+UwDOo=",
-      "dev": true,
-      "requires": {
-        "@babel/helper-plugin-utils": "^7.8.0"
-      }
-    },
-    "@babel/plugin-syntax-class-properties": {
-      "version": "7.12.1",
-      "resolved": "https://registry.npm.taobao.org/@babel/plugin-syntax-class-properties/download/@babel/plugin-syntax-class-properties-7.12.1.tgz?cache=0&sync_timestamp=1602800231971&other_urls=https%3A%2F%2Fregistry.npm.taobao.org%2F%40babel%2Fplugin-syntax-class-properties%2Fdownload%2F%40babel%2Fplugin-syntax-class-properties-7.12.1.tgz",
-      "integrity": "sha1-vLKXxTZueb663vUJVJzZOwTxmXg=",
-      "dev": true,
-      "requires": {
-        "@babel/helper-plugin-utils": "^7.10.4"
-      }
-    },
-    "@babel/plugin-syntax-decorators": {
-      "version": "7.12.1",
-      "resolved": "https://registry.npm.taobao.org/@babel/plugin-syntax-decorators/download/@babel/plugin-syntax-decorators-7.12.1.tgz?cache=0&sync_timestamp=1602800232071&other_urls=https%3A%2F%2Fregistry.npm.taobao.org%2F%40babel%2Fplugin-syntax-decorators%2Fdownload%2F%40babel%2Fplugin-syntax-decorators-7.12.1.tgz",
-      "integrity": "sha1-gai1NbKER2xBvm3gaFOogCuYxd0=",
-      "dev": true,
-      "requires": {
-        "@babel/helper-plugin-utils": "^7.10.4"
-      }
-    },
-    "@babel/plugin-syntax-do-expressions": {
-      "version": "7.12.1",
-      "resolved": "https://registry.npm.taobao.org/@babel/plugin-syntax-do-expressions/download/@babel/plugin-syntax-do-expressions-7.12.1.tgz?cache=0&sync_timestamp=1602806852526&other_urls=https%3A%2F%2Fregistry.npm.taobao.org%2F%40babel%2Fplugin-syntax-do-expressions%2Fdownload%2F%40babel%2Fplugin-syntax-do-expressions-7.12.1.tgz",
-      "integrity": "sha1-a4Pfq3lUC2aRK1WYYM5tS+T32WA=",
-      "dev": true,
-      "requires": {
-        "@babel/helper-plugin-utils": "^7.10.4"
-      }
-    },
-    "@babel/plugin-syntax-dynamic-import": {
-      "version": "7.8.3",
-      "resolved": "https://registry.npm.taobao.org/@babel/plugin-syntax-dynamic-import/download/@babel/plugin-syntax-dynamic-import-7.8.3.tgz",
-      "integrity": "sha1-Yr+Ysto80h1iYVT8lu5bPLaOrLM=",
-      "dev": true,
-      "requires": {
-        "@babel/helper-plugin-utils": "^7.8.0"
-      }
-    },
-    "@babel/plugin-syntax-export-default-from": {
-      "version": "7.12.1",
-      "resolved": "https://registry.npm.taobao.org/@babel/plugin-syntax-export-default-from/download/@babel/plugin-syntax-export-default-from-7.12.1.tgz?cache=0&sync_timestamp=1602806852333&other_urls=https%3A%2F%2Fregistry.npm.taobao.org%2F%40babel%2Fplugin-syntax-export-default-from%2Fdownload%2F%40babel%2Fplugin-syntax-export-default-from-7.12.1.tgz",
-      "integrity": "sha1-qesxiB9PmhEVo9LG1krD9gFrWp0=",
-      "dev": true,
-      "requires": {
-        "@babel/helper-plugin-utils": "^7.10.4"
-      }
-    },
-    "@babel/plugin-syntax-export-namespace-from": {
-      "version": "7.8.3",
-      "resolved": "https://registry.npm.taobao.org/@babel/plugin-syntax-export-namespace-from/download/@babel/plugin-syntax-export-namespace-from-7.8.3.tgz",
-      "integrity": "sha1-AolkqbqA28CUyRXEh618TnpmRlo=",
-      "dev": true,
-      "requires": {
-        "@babel/helper-plugin-utils": "^7.8.3"
-      }
-    },
-    "@babel/plugin-syntax-flow": {
-      "version": "7.12.1",
-      "resolved": "https://registry.npm.taobao.org/@babel/plugin-syntax-flow/download/@babel/plugin-syntax-flow-7.12.1.tgz",
-      "integrity": "sha1-p3Zw2avm1j6Kyt9MMbsetaUGu90=",
-      "dev": true,
-      "requires": {
-        "@babel/helper-plugin-utils": "^7.10.4"
-      }
-    },
-    "@babel/plugin-syntax-function-bind": {
-      "version": "7.12.1",
-      "resolved": "https://registry.npm.taobao.org/@babel/plugin-syntax-function-bind/download/@babel/plugin-syntax-function-bind-7.12.1.tgz?cache=0&sync_timestamp=1602806852726&other_urls=https%3A%2F%2Fregistry.npm.taobao.org%2F%40babel%2Fplugin-syntax-function-bind%2Fdownload%2F%40babel%2Fplugin-syntax-function-bind-7.12.1.tgz",
-      "integrity": "sha1-HhXaPlaMltq+IVefLWaCHbmKr8w=",
-      "dev": true,
-      "requires": {
-        "@babel/helper-plugin-utils": "^7.10.4"
-      }
-    },
-    "@babel/plugin-syntax-function-sent": {
-      "version": "7.12.1",
-      "resolved": "https://registry.npm.taobao.org/@babel/plugin-syntax-function-sent/download/@babel/plugin-syntax-function-sent-7.12.1.tgz",
-      "integrity": "sha1-tTVTBPCw+wyxvzFZA7980TYI6BE=",
-      "dev": true,
-      "requires": {
-        "@babel/helper-plugin-utils": "^7.10.4"
-      }
-    },
-    "@babel/plugin-syntax-import-meta": {
-      "version": "7.10.4",
-      "resolved": "https://registry.npm.taobao.org/@babel/plugin-syntax-import-meta/download/@babel/plugin-syntax-import-meta-7.10.4.tgz",
-      "integrity": "sha1-7mATSMNw+jNNIge+FYd3SWUh/VE=",
-      "dev": true,
-      "requires": {
-        "@babel/helper-plugin-utils": "^7.10.4"
-      }
-    },
-    "@babel/plugin-syntax-json-strings": {
-      "version": "7.8.3",
-      "resolved": "https://registry.npm.taobao.org/@babel/plugin-syntax-json-strings/download/@babel/plugin-syntax-json-strings-7.8.3.tgz",
-      "integrity": "sha1-AcohtmjNghjJ5kDLbdiMVBKyyWo=",
-      "dev": true,
-      "requires": {
-        "@babel/helper-plugin-utils": "^7.8.0"
-      }
-    },
-    "@babel/plugin-syntax-jsx": {
-      "version": "7.12.1",
-      "resolved": "https://registry.npm.taobao.org/@babel/plugin-syntax-jsx/download/@babel/plugin-syntax-jsx-7.12.1.tgz?cache=0&sync_timestamp=1602800233054&other_urls=https%3A%2F%2Fregistry.npm.taobao.org%2F%40babel%2Fplugin-syntax-jsx%2Fdownload%2F%40babel%2Fplugin-syntax-jsx-7.12.1.tgz",
-      "integrity": "sha1-nZ01fMgYqnrnk1kXwSV/Z2d6CSY=",
-      "dev": true,
-      "requires": {
-        "@babel/helper-plugin-utils": "^7.10.4"
-      }
-    },
-    "@babel/plugin-syntax-logical-assignment-operators": {
-      "version": "7.10.4",
-      "resolved": "https://registry.npm.taobao.org/@babel/plugin-syntax-logical-assignment-operators/download/@babel/plugin-syntax-logical-assignment-operators-7.10.4.tgz?cache=0&sync_timestamp=1593522961558&other_urls=https%3A%2F%2Fregistry.npm.taobao.org%2F%40babel%2Fplugin-syntax-logical-assignment-operators%2Fdownload%2F%40babel%2Fplugin-syntax-logical-assignment-operators-7.10.4.tgz",
-      "integrity": "sha1-ypHvRjA1MESLkGZSusLp/plB9pk=",
-      "dev": true,
-      "requires": {
-        "@babel/helper-plugin-utils": "^7.10.4"
-      }
-    },
-    "@babel/plugin-syntax-nullish-coalescing-operator": {
-      "version": "7.8.3",
-      "resolved": "https://registry.npm.taobao.org/@babel/plugin-syntax-nullish-coalescing-operator/download/@babel/plugin-syntax-nullish-coalescing-operator-7.8.3.tgz",
-      "integrity": "sha1-Fn7XA2iIYIH3S1w2xlqIwDtm0ak=",
-      "dev": true,
-      "requires": {
-        "@babel/helper-plugin-utils": "^7.8.0"
-      }
-    },
-    "@babel/plugin-syntax-numeric-separator": {
-      "version": "7.10.4",
-      "resolved": "https://registry.npm.taobao.org/@babel/plugin-syntax-numeric-separator/download/@babel/plugin-syntax-numeric-separator-7.10.4.tgz?cache=0&sync_timestamp=1593521806492&other_urls=https%3A%2F%2Fregistry.npm.taobao.org%2F%40babel%2Fplugin-syntax-numeric-separator%2Fdownload%2F%40babel%2Fplugin-syntax-numeric-separator-7.10.4.tgz",
-      "integrity": "sha1-ubBws+M1cM2f0Hun+pHA3Te5r5c=",
-      "dev": true,
-      "requires": {
-        "@babel/helper-plugin-utils": "^7.10.4"
-      }
-    },
-    "@babel/plugin-syntax-object-rest-spread": {
-      "version": "7.8.3",
-      "resolved": "https://registry.npm.taobao.org/@babel/plugin-syntax-object-rest-spread/download/@babel/plugin-syntax-object-rest-spread-7.8.3.tgz",
-      "integrity": "sha1-YOIl7cvZimQDMqLnLdPmbxr1WHE=",
-      "dev": true,
-      "requires": {
-        "@babel/helper-plugin-utils": "^7.8.0"
-      }
-    },
-    "@babel/plugin-syntax-optional-catch-binding": {
-      "version": "7.8.3",
-      "resolved": "https://registry.npm.taobao.org/@babel/plugin-syntax-optional-catch-binding/download/@babel/plugin-syntax-optional-catch-binding-7.8.3.tgz",
-      "integrity": "sha1-YRGiZbz7Ag6579D9/X0mQCue1sE=",
-      "dev": true,
-      "requires": {
-        "@babel/helper-plugin-utils": "^7.8.0"
-      }
-    },
-    "@babel/plugin-syntax-optional-chaining": {
-      "version": "7.8.3",
-      "resolved": "https://registry.npm.taobao.org/@babel/plugin-syntax-optional-chaining/download/@babel/plugin-syntax-optional-chaining-7.8.3.tgz",
-      "integrity": "sha1-T2nCq5UWfgGAzVM2YT+MV4j31Io=",
-      "dev": true,
-      "requires": {
-        "@babel/helper-plugin-utils": "^7.8.0"
-      }
-    },
-    "@babel/plugin-syntax-pipeline-operator": {
-      "version": "7.12.1",
-      "resolved": "https://registry.npm.taobao.org/@babel/plugin-syntax-pipeline-operator/download/@babel/plugin-syntax-pipeline-operator-7.12.1.tgz?cache=0&sync_timestamp=1602806853081&other_urls=https%3A%2F%2Fregistry.npm.taobao.org%2F%40babel%2Fplugin-syntax-pipeline-operator%2Fdownload%2F%40babel%2Fplugin-syntax-pipeline-operator-7.12.1.tgz",
-      "integrity": "sha1-YYbx1f64bTFakgpQVqhsmRv0t/Q=",
-      "dev": true,
-      "requires": {
-        "@babel/helper-plugin-utils": "^7.10.4"
-      }
-    },
-    "@babel/plugin-syntax-throw-expressions": {
-      "version": "7.12.1",
-      "resolved": "https://registry.npm.taobao.org/@babel/plugin-syntax-throw-expressions/download/@babel/plugin-syntax-throw-expressions-7.12.1.tgz",
-      "integrity": "sha1-/5ClesWZumhamSdMhmBNh4yUUJQ=",
-      "dev": true,
-      "requires": {
-        "@babel/helper-plugin-utils": "^7.10.4"
-      }
-    },
-    "@babel/plugin-syntax-top-level-await": {
-      "version": "7.12.1",
-      "resolved": "https://registry.npm.taobao.org/@babel/plugin-syntax-top-level-await/download/@babel/plugin-syntax-top-level-await-7.12.1.tgz?cache=0&sync_timestamp=1602800233145&other_urls=https%3A%2F%2Fregistry.npm.taobao.org%2F%40babel%2Fplugin-syntax-top-level-await%2Fdownload%2F%40babel%2Fplugin-syntax-top-level-await-7.12.1.tgz",
-      "integrity": "sha1-3WwLNXrBuxQtmFN0UKMZYl0T0qA=",
-      "dev": true,
-      "requires": {
-        "@babel/helper-plugin-utils": "^7.10.4"
-      }
-    },
-    "@babel/plugin-syntax-typescript": {
-      "version": "7.12.1",
-      "resolved": "https://registry.npm.taobao.org/@babel/plugin-syntax-typescript/download/@babel/plugin-syntax-typescript-7.12.1.tgz",
-      "integrity": "sha1-Rgup13B3ZTgDw90uZz921mtAKeU=",
-      "dev": true,
-      "requires": {
-        "@babel/helper-plugin-utils": "^7.10.4"
-      }
-    },
-    "@babel/plugin-transform-arrow-functions": {
-      "version": "7.12.1",
-      "resolved": "https://registry.npm.taobao.org/@babel/plugin-transform-arrow-functions/download/@babel/plugin-transform-arrow-functions-7.12.1.tgz?cache=0&sync_timestamp=1602800233566&other_urls=https%3A%2F%2Fregistry.npm.taobao.org%2F%40babel%2Fplugin-transform-arrow-functions%2Fdownload%2F%40babel%2Fplugin-transform-arrow-functions-7.12.1.tgz",
-      "integrity": "sha1-gIP/yGrI53f74ktZZ8SyUh88srM=",
-      "dev": true,
-      "requires": {
-        "@babel/helper-plugin-utils": "^7.10.4"
-      }
-    },
-    "@babel/plugin-transform-async-to-generator": {
-      "version": "7.12.1",
-      "resolved": "https://registry.npm.taobao.org/@babel/plugin-transform-async-to-generator/download/@babel/plugin-transform-async-to-generator-7.12.1.tgz?cache=0&sync_timestamp=1602800242155&other_urls=https%3A%2F%2Fregistry.npm.taobao.org%2F%40babel%2Fplugin-transform-async-to-generator%2Fdownload%2F%40babel%2Fplugin-transform-async-to-generator-7.12.1.tgz",
-      "integrity": "sha1-OEmknMKiLpdDy9a1KSbTAzcimvE=",
-      "dev": true,
-      "requires": {
-        "@babel/helper-module-imports": "^7.12.1",
-        "@babel/helper-plugin-utils": "^7.10.4",
-        "@babel/helper-remap-async-to-generator": "^7.12.1"
-      }
-    },
-    "@babel/plugin-transform-block-scoped-functions": {
-      "version": "7.12.1",
-      "resolved": "https://registry.npm.taobao.org/@babel/plugin-transform-block-scoped-functions/download/@babel/plugin-transform-block-scoped-functions-7.12.1.tgz?cache=0&sync_timestamp=1602800233803&other_urls=https%3A%2F%2Fregistry.npm.taobao.org%2F%40babel%2Fplugin-transform-block-scoped-functions%2Fdownload%2F%40babel%2Fplugin-transform-block-scoped-functions-7.12.1.tgz",
-      "integrity": "sha1-8qGjZb3itxEuCm3tkGf918B5Bdk=",
-      "dev": true,
-      "requires": {
-        "@babel/helper-plugin-utils": "^7.10.4"
-      }
-    },
-    "@babel/plugin-transform-block-scoping": {
-      "version": "7.12.1",
-      "resolved": "https://registry.npm.taobao.org/@babel/plugin-transform-block-scoping/download/@babel/plugin-transform-block-scoping-7.12.1.tgz?cache=0&sync_timestamp=1602800233459&other_urls=https%3A%2F%2Fregistry.npm.taobao.org%2F%40babel%2Fplugin-transform-block-scoping%2Fdownload%2F%40babel%2Fplugin-transform-block-scoping-7.12.1.tgz",
-      "integrity": "sha1-8O5yeHS0KiCKSKWGuEw9IiwrvvE=",
-      "dev": true,
-      "requires": {
-        "@babel/helper-plugin-utils": "^7.10.4"
-      }
-    },
-    "@babel/plugin-transform-classes": {
-      "version": "7.12.1",
-      "resolved": "https://registry.npm.taobao.org/@babel/plugin-transform-classes/download/@babel/plugin-transform-classes-7.12.1.tgz?cache=0&sync_timestamp=1602802059995&other_urls=https%3A%2F%2Fregistry.npm.taobao.org%2F%40babel%2Fplugin-transform-classes%2Fdownload%2F%40babel%2Fplugin-transform-classes-7.12.1.tgz",
-      "integrity": "sha1-ZeZQ/K3dPYjdzmfA+DSj1DajLbY=",
-      "dev": true,
-      "requires": {
-        "@babel/helper-annotate-as-pure": "^7.10.4",
-        "@babel/helper-define-map": "^7.10.4",
-        "@babel/helper-function-name": "^7.10.4",
-        "@babel/helper-optimise-call-expression": "^7.10.4",
-        "@babel/helper-plugin-utils": "^7.10.4",
-        "@babel/helper-replace-supers": "^7.12.1",
-        "@babel/helper-split-export-declaration": "^7.10.4",
-        "globals": "^11.1.0"
-      }
-    },
-    "@babel/plugin-transform-computed-properties": {
-      "version": "7.12.1",
-      "resolved": "https://registry.npm.taobao.org/@babel/plugin-transform-computed-properties/download/@babel/plugin-transform-computed-properties-7.12.1.tgz?cache=0&sync_timestamp=1602800233906&other_urls=https%3A%2F%2Fregistry.npm.taobao.org%2F%40babel%2Fplugin-transform-computed-properties%2Fdownload%2F%40babel%2Fplugin-transform-computed-properties-7.12.1.tgz",
-      "integrity": "sha1-1oz2ybf4OKikFEutvpdUHqCQSFI=",
-      "dev": true,
-      "requires": {
-        "@babel/helper-plugin-utils": "^7.10.4"
-      }
-    },
-    "@babel/plugin-transform-destructuring": {
-      "version": "7.12.1",
-      "resolved": "https://registry.npm.taobao.org/@babel/plugin-transform-destructuring/download/@babel/plugin-transform-destructuring-7.12.1.tgz?cache=0&sync_timestamp=1602800233701&other_urls=https%3A%2F%2Fregistry.npm.taobao.org%2F%40babel%2Fplugin-transform-destructuring%2Fdownload%2F%40babel%2Fplugin-transform-destructuring-7.12.1.tgz",
-      "integrity": "sha1-uaVw/g0KjUYBFkE8tPl+jgiy+Ec=",
-      "dev": true,
-      "requires": {
-        "@babel/helper-plugin-utils": "^7.10.4"
-      }
-    },
-    "@babel/plugin-transform-dotall-regex": {
-      "version": "7.12.1",
-      "resolved": "https://registry.npm.taobao.org/@babel/plugin-transform-dotall-regex/download/@babel/plugin-transform-dotall-regex-7.12.1.tgz?cache=0&sync_timestamp=1602800241190&other_urls=https%3A%2F%2Fregistry.npm.taobao.org%2F%40babel%2Fplugin-transform-dotall-regex%2Fdownload%2F%40babel%2Fplugin-transform-dotall-regex-7.12.1.tgz",
-      "integrity": "sha1-odFsFIYoF7ZAnApnjW+Tc8qc2XU=",
-      "dev": true,
-      "requires": {
-        "@babel/helper-create-regexp-features-plugin": "^7.12.1",
-        "@babel/helper-plugin-utils": "^7.10.4"
-      }
-    },
-    "@babel/plugin-transform-duplicate-keys": {
-      "version": "7.12.1",
-      "resolved": "https://registry.npm.taobao.org/@babel/plugin-transform-duplicate-keys/download/@babel/plugin-transform-duplicate-keys-7.12.1.tgz?cache=0&sync_timestamp=1602800235384&other_urls=https%3A%2F%2Fregistry.npm.taobao.org%2F%40babel%2Fplugin-transform-duplicate-keys%2Fdownload%2F%40babel%2Fplugin-transform-duplicate-keys-7.12.1.tgz",
-      "integrity": "sha1-dFZhuropWsBuaGgieXpp+6osoig=",
-      "dev": true,
-      "requires": {
-        "@babel/helper-plugin-utils": "^7.10.4"
-      }
-    },
-    "@babel/plugin-transform-exponentiation-operator": {
-      "version": "7.12.1",
-      "resolved": "https://registry.npm.taobao.org/@babel/plugin-transform-exponentiation-operator/download/@babel/plugin-transform-exponentiation-operator-7.12.1.tgz?cache=0&sync_timestamp=1602800235495&other_urls=https%3A%2F%2Fregistry.npm.taobao.org%2F%40babel%2Fplugin-transform-exponentiation-operator%2Fdownload%2F%40babel%2Fplugin-transform-exponentiation-operator-7.12.1.tgz",
-      "integrity": "sha1-sPLtNWuhvhQo7K8Sj/iiTwKDCuA=",
-      "dev": true,
-      "requires": {
-        "@babel/helper-builder-binary-assignment-operator-visitor": "^7.10.4",
-        "@babel/helper-plugin-utils": "^7.10.4"
-      }
-    },
-    "@babel/plugin-transform-flow-strip-types": {
-      "version": "7.12.1",
-      "resolved": "https://registry.npm.taobao.org/@babel/plugin-transform-flow-strip-types/download/@babel/plugin-transform-flow-strip-types-7.12.1.tgz",
-      "integrity": "sha1-hDDez6frKupUFO1KP6bhZSt9d8Q=",
-      "dev": true,
-      "requires": {
-        "@babel/helper-plugin-utils": "^7.10.4",
-        "@babel/plugin-syntax-flow": "^7.12.1"
-      }
-    },
-    "@babel/plugin-transform-for-of": {
-      "version": "7.12.1",
-      "resolved": "https://registry.npm.taobao.org/@babel/plugin-transform-for-of/download/@babel/plugin-transform-for-of-7.12.1.tgz?cache=0&sync_timestamp=1602800234012&other_urls=https%3A%2F%2Fregistry.npm.taobao.org%2F%40babel%2Fplugin-transform-for-of%2Fdownload%2F%40babel%2Fplugin-transform-for-of-7.12.1.tgz",
-      "integrity": "sha1-B2QPKIZ+0W+VEcmciIKR9WCSHPo=",
-      "dev": true,
-      "requires": {
-        "@babel/helper-plugin-utils": "^7.10.4"
-      }
-    },
-    "@babel/plugin-transform-function-name": {
-      "version": "7.12.1",
-      "resolved": "https://registry.npm.taobao.org/@babel/plugin-transform-function-name/download/@babel/plugin-transform-function-name-7.12.1.tgz?cache=0&sync_timestamp=1602800234134&other_urls=https%3A%2F%2Fregistry.npm.taobao.org%2F%40babel%2Fplugin-transform-function-name%2Fdownload%2F%40babel%2Fplugin-transform-function-name-7.12.1.tgz",
-      "integrity": "sha1-LsdiWMcP4IxtfaFUADpIBiDrpmc=",
-      "dev": true,
-      "requires": {
-        "@babel/helper-function-name": "^7.10.4",
-        "@babel/helper-plugin-utils": "^7.10.4"
-      }
-    },
-    "@babel/plugin-transform-literals": {
-      "version": "7.12.1",
-      "resolved": "https://registry.npm.taobao.org/@babel/plugin-transform-literals/download/@babel/plugin-transform-literals-7.12.1.tgz?cache=0&sync_timestamp=1602800235597&other_urls=https%3A%2F%2Fregistry.npm.taobao.org%2F%40babel%2Fplugin-transform-literals%2Fdownload%2F%40babel%2Fplugin-transform-literals-7.12.1.tgz",
-      "integrity": "sha1-1zuAOiazcBfd+dO7j03Fi/uAb1c=",
-      "dev": true,
-      "requires": {
-        "@babel/helper-plugin-utils": "^7.10.4"
-      }
-    },
-    "@babel/plugin-transform-member-expression-literals": {
-      "version": "7.12.1",
-      "resolved": "https://registry.npm.taobao.org/@babel/plugin-transform-member-expression-literals/download/@babel/plugin-transform-member-expression-literals-7.12.1.tgz?cache=0&sync_timestamp=1602800235819&other_urls=https%3A%2F%2Fregistry.npm.taobao.org%2F%40babel%2Fplugin-transform-member-expression-literals%2Fdownload%2F%40babel%2Fplugin-transform-member-expression-literals-7.12.1.tgz",
-      "integrity": "sha1-SWA4YC2vFRSmTUPY4Xy7J1Xgw60=",
-      "dev": true,
-      "requires": {
-        "@babel/helper-plugin-utils": "^7.10.4"
-      }
-    },
-    "@babel/plugin-transform-modules-amd": {
-      "version": "7.12.1",
-      "resolved": "https://registry.npm.taobao.org/@babel/plugin-transform-modules-amd/download/@babel/plugin-transform-modules-amd-7.12.1.tgz?cache=0&sync_timestamp=1602802064278&other_urls=https%3A%2F%2Fregistry.npm.taobao.org%2F%40babel%2Fplugin-transform-modules-amd%2Fdownload%2F%40babel%2Fplugin-transform-modules-amd-7.12.1.tgz",
-      "integrity": "sha1-MVQwCwJhhWZu67DA7X+EFf789vk=",
-      "dev": true,
-      "requires": {
-        "@babel/helper-module-transforms": "^7.12.1",
-        "@babel/helper-plugin-utils": "^7.10.4",
-        "babel-plugin-dynamic-import-node": "^2.3.3"
-      }
-    },
-    "@babel/plugin-transform-modules-commonjs": {
-      "version": "7.12.1",
-      "resolved": "https://registry.npm.taobao.org/@babel/plugin-transform-modules-commonjs/download/@babel/plugin-transform-modules-commonjs-7.12.1.tgz?cache=0&sync_timestamp=1602802063892&other_urls=https%3A%2F%2Fregistry.npm.taobao.org%2F%40babel%2Fplugin-transform-modules-commonjs%2Fdownload%2F%40babel%2Fplugin-transform-modules-commonjs-7.12.1.tgz",
-      "integrity": "sha1-+kAxJFQmNseGz5tGCg/7tIqG5kg=",
-      "dev": true,
-      "requires": {
-        "@babel/helper-module-transforms": "^7.12.1",
-        "@babel/helper-plugin-utils": "^7.10.4",
-        "@babel/helper-simple-access": "^7.12.1",
-        "babel-plugin-dynamic-import-node": "^2.3.3"
-      }
-    },
-    "@babel/plugin-transform-modules-systemjs": {
-      "version": "7.12.1",
-      "resolved": "https://registry.npm.taobao.org/@babel/plugin-transform-modules-systemjs/download/@babel/plugin-transform-modules-systemjs-7.12.1.tgz?cache=0&sync_timestamp=1602802063412&other_urls=https%3A%2F%2Fregistry.npm.taobao.org%2F%40babel%2Fplugin-transform-modules-systemjs%2Fdownload%2F%40babel%2Fplugin-transform-modules-systemjs-7.12.1.tgz",
-      "integrity": "sha1-Zj/qYg1ZPJPyFKRkzTmb9txoMIY=",
-      "dev": true,
-      "requires": {
-        "@babel/helper-hoist-variables": "^7.10.4",
-        "@babel/helper-module-transforms": "^7.12.1",
-        "@babel/helper-plugin-utils": "^7.10.4",
-        "@babel/helper-validator-identifier": "^7.10.4",
-        "babel-plugin-dynamic-import-node": "^2.3.3"
-      }
-    },
-    "@babel/plugin-transform-modules-umd": {
-      "version": "7.12.1",
-      "resolved": "https://registry.npm.taobao.org/@babel/plugin-transform-modules-umd/download/@babel/plugin-transform-modules-umd-7.12.1.tgz?cache=0&sync_timestamp=1602802064711&other_urls=https%3A%2F%2Fregistry.npm.taobao.org%2F%40babel%2Fplugin-transform-modules-umd%2Fdownload%2F%40babel%2Fplugin-transform-modules-umd-7.12.1.tgz",
-      "integrity": "sha1-61ohjWscaPPWIXuPosyC/sZUeQI=",
-      "dev": true,
-      "requires": {
-        "@babel/helper-module-transforms": "^7.12.1",
-        "@babel/helper-plugin-utils": "^7.10.4"
-      }
-    },
-    "@babel/plugin-transform-named-capturing-groups-regex": {
-      "version": "7.12.1",
-      "resolved": "https://registry.npm.taobao.org/@babel/plugin-transform-named-capturing-groups-regex/download/@babel/plugin-transform-named-capturing-groups-regex-7.12.1.tgz?cache=0&sync_timestamp=1602800241290&other_urls=https%3A%2F%2Fregistry.npm.taobao.org%2F%40babel%2Fplugin-transform-named-capturing-groups-regex%2Fdownload%2F%40babel%2Fplugin-transform-named-capturing-groups-regex-7.12.1.tgz",
-      "integrity": "sha1-tAf1yWvg2fX4hGdJf6grMKw+h1M=",
-      "dev": true,
-      "requires": {
-        "@babel/helper-create-regexp-features-plugin": "^7.12.1"
-      }
-    },
-    "@babel/plugin-transform-new-target": {
-      "version": "7.12.1",
-      "resolved": "https://registry.npm.taobao.org/@babel/plugin-transform-new-target/download/@babel/plugin-transform-new-target-7.12.1.tgz?cache=0&sync_timestamp=1602800235712&other_urls=https%3A%2F%2Fregistry.npm.taobao.org%2F%40babel%2Fplugin-transform-new-target%2Fdownload%2F%40babel%2Fplugin-transform-new-target-7.12.1.tgz",
-      "integrity": "sha1-gAc/Au4bstNlw0FkkOCFyVdZ3sA=",
-      "dev": true,
-      "requires": {
-        "@babel/helper-plugin-utils": "^7.10.4"
-      }
-    },
-    "@babel/plugin-transform-object-super": {
-      "version": "7.12.1",
-      "resolved": "https://registry.npm.taobao.org/@babel/plugin-transform-object-super/download/@babel/plugin-transform-object-super-7.12.1.tgz?cache=0&sync_timestamp=1602802058628&other_urls=https%3A%2F%2Fregistry.npm.taobao.org%2F%40babel%2Fplugin-transform-object-super%2Fdownload%2F%40babel%2Fplugin-transform-object-super-7.12.1.tgz",
-      "integrity": "sha1-TqCGlrjS5lhB0MdwZIKwSL7RBm4=",
-      "dev": true,
-      "requires": {
-        "@babel/helper-plugin-utils": "^7.10.4",
-        "@babel/helper-replace-supers": "^7.12.1"
-      }
-    },
-    "@babel/plugin-transform-parameters": {
-      "version": "7.12.1",
-      "resolved": "https://registry.npm.taobao.org/@babel/plugin-transform-parameters/download/@babel/plugin-transform-parameters-7.12.1.tgz?cache=0&sync_timestamp=1602800236149&other_urls=https%3A%2F%2Fregistry.npm.taobao.org%2F%40babel%2Fplugin-transform-parameters%2Fdownload%2F%40babel%2Fplugin-transform-parameters-7.12.1.tgz",
-      "integrity": "sha1-0uljsDh3FlDJIu/1k3mclthTJV0=",
-      "dev": true,
-      "requires": {
-        "@babel/helper-plugin-utils": "^7.10.4"
-      }
-    },
-    "@babel/plugin-transform-property-literals": {
-      "version": "7.12.1",
-      "resolved": "https://registry.npm.taobao.org/@babel/plugin-transform-property-literals/download/@babel/plugin-transform-property-literals-7.12.1.tgz?cache=0&sync_timestamp=1602800236036&other_urls=https%3A%2F%2Fregistry.npm.taobao.org%2F%40babel%2Fplugin-transform-property-literals%2Fdownload%2F%40babel%2Fplugin-transform-property-literals-7.12.1.tgz",
-      "integrity": "sha1-QbyBIA1zCrtEVquLP71VN7Wa3s0=",
-      "dev": true,
-      "requires": {
-        "@babel/helper-plugin-utils": "^7.10.4"
-      }
-    },
-    "@babel/plugin-transform-react-display-name": {
-      "version": "7.12.1",
-      "resolved": "https://registry.npm.taobao.org/@babel/plugin-transform-react-display-name/download/@babel/plugin-transform-react-display-name-7.12.1.tgz",
-      "integrity": "sha1-HLzQw7HWZIxVN0oi/JtrflNBwA0=",
-      "dev": true,
-      "requires": {
-        "@babel/helper-plugin-utils": "^7.10.4"
-      }
-    },
-    "@babel/plugin-transform-react-jsx": {
-      "version": "7.12.5",
-      "resolved": "https://registry.npm.taobao.org/@babel/plugin-transform-react-jsx/download/@babel/plugin-transform-react-jsx-7.12.5.tgz?cache=0&sync_timestamp=1604441239750&other_urls=https%3A%2F%2Fregistry.npm.taobao.org%2F%40babel%2Fplugin-transform-react-jsx%2Fdownload%2F%40babel%2Fplugin-transform-react-jsx-7.12.5.tgz",
-      "integrity": "sha1-Oe3g4wFZdwVhtpY74UPkCvO94Aw=",
-      "dev": true,
-      "requires": {
-        "@babel/helper-builder-react-jsx": "^7.10.4",
-        "@babel/helper-builder-react-jsx-experimental": "^7.12.1",
-        "@babel/helper-plugin-utils": "^7.10.4",
-        "@babel/plugin-syntax-jsx": "^7.12.1"
-      }
-    },
-    "@babel/plugin-transform-react-jsx-development": {
-      "version": "7.12.5",
-      "resolved": "https://registry.npm.taobao.org/@babel/plugin-transform-react-jsx-development/download/@babel/plugin-transform-react-jsx-development-7.12.5.tgz",
-      "integrity": "sha1-Z33luW2jEEMNbPt/7hahYDr6PVY=",
-      "dev": true,
-      "requires": {
-        "@babel/helper-builder-react-jsx-experimental": "^7.12.1",
-        "@babel/helper-plugin-utils": "^7.10.4",
-        "@babel/plugin-syntax-jsx": "^7.12.1"
-      }
-    },
-    "@babel/plugin-transform-react-jsx-self": {
-      "version": "7.12.1",
-      "resolved": "https://registry.npm.taobao.org/@babel/plugin-transform-react-jsx-self/download/@babel/plugin-transform-react-jsx-self-7.12.1.tgz",
-      "integrity": "sha1-70PLyioU8b0XgH2+Q3b/idcUzyg=",
-      "dev": true,
-      "requires": {
-        "@babel/helper-plugin-utils": "^7.10.4"
-      }
-    },
-    "@babel/plugin-transform-react-jsx-source": {
-      "version": "7.12.1",
-      "resolved": "https://registry.npm.taobao.org/@babel/plugin-transform-react-jsx-source/download/@babel/plugin-transform-react-jsx-source-7.12.1.tgz",
-      "integrity": "sha1-0H3mhj9GjaCAntz3mhqoziqComs=",
-      "dev": true,
-      "requires": {
-        "@babel/helper-plugin-utils": "^7.10.4"
-      }
-    },
-    "@babel/plugin-transform-react-pure-annotations": {
-      "version": "7.12.1",
-      "resolved": "https://registry.npm.taobao.org/@babel/plugin-transform-react-pure-annotations/download/@babel/plugin-transform-react-pure-annotations-7.12.1.tgz",
-      "integrity": "sha1-BdRvCrTRM5rFmt8goUYskbN6GkI=",
-      "dev": true,
-      "requires": {
-        "@babel/helper-annotate-as-pure": "^7.10.4",
-        "@babel/helper-plugin-utils": "^7.10.4"
-      }
-    },
-    "@babel/plugin-transform-regenerator": {
-      "version": "7.12.1",
-      "resolved": "https://registry.npm.taobao.org/@babel/plugin-transform-regenerator/download/@babel/plugin-transform-regenerator-7.12.1.tgz?cache=0&sync_timestamp=1602800236618&other_urls=https%3A%2F%2Fregistry.npm.taobao.org%2F%40babel%2Fplugin-transform-regenerator%2Fdownload%2F%40babel%2Fplugin-transform-regenerator-7.12.1.tgz",
-      "integrity": "sha1-Xwoo2EL2RiKB8GqWToi6jXq0l1M=",
-      "dev": true,
-      "requires": {
-        "regenerator-transform": "^0.14.2"
-      }
-    },
-    "@babel/plugin-transform-reserved-words": {
-      "version": "7.12.1",
-      "resolved": "https://registry.npm.taobao.org/@babel/plugin-transform-reserved-words/download/@babel/plugin-transform-reserved-words-7.12.1.tgz?cache=0&sync_timestamp=1602800236807&other_urls=https%3A%2F%2Fregistry.npm.taobao.org%2F%40babel%2Fplugin-transform-reserved-words%2Fdownload%2F%40babel%2Fplugin-transform-reserved-words-7.12.1.tgz",
-      "integrity": "sha1-b9/IzH7cxCs2p8EhiMZ4fIc63Ng=",
-      "dev": true,
-      "requires": {
-        "@babel/helper-plugin-utils": "^7.10.4"
-      }
-    },
-    "@babel/plugin-transform-runtime": {
-      "version": "7.12.1",
-      "resolved": "https://registry.npm.taobao.org/@babel/plugin-transform-runtime/download/@babel/plugin-transform-runtime-7.12.1.tgz?cache=0&sync_timestamp=1602800227616&other_urls=https%3A%2F%2Fregistry.npm.taobao.org%2F%40babel%2Fplugin-transform-runtime%2Fdownload%2F%40babel%2Fplugin-transform-runtime-7.12.1.tgz",
-      "integrity": "sha1-BLeSBX60YDif9qQZjjd2FOoee6U=",
-      "dev": true,
-      "requires": {
-        "@babel/helper-module-imports": "^7.12.1",
-        "@babel/helper-plugin-utils": "^7.10.4",
-        "resolve": "^1.8.1",
-        "semver": "^5.5.1"
-      },
-      "dependencies": {
-        "semver": {
-          "version": "5.7.1",
-          "resolved": "https://registry.npm.taobao.org/semver/download/semver-5.7.1.tgz",
-          "integrity": "sha1-qVT5Ma66UI0we78Gnv8MAclhFvc=",
-          "dev": true
-        }
-      }
-    },
-    "@babel/plugin-transform-shorthand-properties": {
-      "version": "7.12.1",
-      "resolved": "https://registry.npm.taobao.org/@babel/plugin-transform-shorthand-properties/download/@babel/plugin-transform-shorthand-properties-7.12.1.tgz?cache=0&sync_timestamp=1602800237133&other_urls=https%3A%2F%2Fregistry.npm.taobao.org%2F%40babel%2Fplugin-transform-shorthand-properties%2Fdownload%2F%40babel%2Fplugin-transform-shorthand-properties-7.12.1.tgz",
-      "integrity": "sha1-C/nKxVUPzgz98ENCD2YdZF/cdeM=",
-      "dev": true,
-      "requires": {
-        "@babel/helper-plugin-utils": "^7.10.4"
-      }
-    },
-    "@babel/plugin-transform-spread": {
-      "version": "7.12.1",
-      "resolved": "https://registry.npm.taobao.org/@babel/plugin-transform-spread/download/@babel/plugin-transform-spread-7.12.1.tgz?cache=0&sync_timestamp=1602800242265&other_urls=https%3A%2F%2Fregistry.npm.taobao.org%2F%40babel%2Fplugin-transform-spread%2Fdownload%2F%40babel%2Fplugin-transform-spread-7.12.1.tgz",
-      "integrity": "sha1-Un+fMRvk7H/cK3m7ife/iEs+Hh4=",
-      "dev": true,
-      "requires": {
-        "@babel/helper-plugin-utils": "^7.10.4",
-        "@babel/helper-skip-transparent-expression-wrappers": "^7.12.1"
-      }
-    },
-    "@babel/plugin-transform-sticky-regex": {
-      "version": "7.12.1",
-      "resolved": "https://registry.npm.taobao.org/@babel/plugin-transform-sticky-regex/download/@babel/plugin-transform-sticky-regex-7.12.1.tgz?cache=0&sync_timestamp=1602800237248&other_urls=https%3A%2F%2Fregistry.npm.taobao.org%2F%40babel%2Fplugin-transform-sticky-regex%2Fdownload%2F%40babel%2Fplugin-transform-sticky-regex-7.12.1.tgz",
-      "integrity": "sha1-XCTPUN45bTDpmvyNHHAOi84PXK8=",
-      "dev": true,
-      "requires": {
-        "@babel/helper-plugin-utils": "^7.10.4",
-        "@babel/helper-regex": "^7.10.4"
-      }
-    },
-    "@babel/plugin-transform-template-literals": {
-      "version": "7.12.1",
-      "resolved": "https://registry.npm.taobao.org/@babel/plugin-transform-template-literals/download/@babel/plugin-transform-template-literals-7.12.1.tgz?cache=0&sync_timestamp=1602800237453&other_urls=https%3A%2F%2Fregistry.npm.taobao.org%2F%40babel%2Fplugin-transform-template-literals%2Fdownload%2F%40babel%2Fplugin-transform-template-literals-7.12.1.tgz",
-      "integrity": "sha1-tD7ObtmnnAxxEZ9XbSme8J2UKEM=",
-      "dev": true,
-      "requires": {
-        "@babel/helper-plugin-utils": "^7.10.4"
-      }
-    },
-    "@babel/plugin-transform-typeof-symbol": {
-      "version": "7.12.1",
-      "resolved": "https://registry.npm.taobao.org/@babel/plugin-transform-typeof-symbol/download/@babel/plugin-transform-typeof-symbol-7.12.1.tgz?cache=0&sync_timestamp=1602800237638&other_urls=https%3A%2F%2Fregistry.npm.taobao.org%2F%40babel%2Fplugin-transform-typeof-symbol%2Fdownload%2F%40babel%2Fplugin-transform-typeof-symbol-7.12.1.tgz",
-      "integrity": "sha1-nKa+ND1CUS+8LmgjaoKuZLx694o=",
-      "dev": true,
-      "requires": {
-        "@babel/helper-plugin-utils": "^7.10.4"
-      }
-    },
-    "@babel/plugin-transform-typescript": {
-      "version": "7.12.1",
-      "resolved": "https://registry.npm.taobao.org/@babel/plugin-transform-typescript/download/@babel/plugin-transform-typescript-7.12.1.tgz?cache=0&sync_timestamp=1602802164420&other_urls=https%3A%2F%2Fregistry.npm.taobao.org%2F%40babel%2Fplugin-transform-typescript%2Fdownload%2F%40babel%2Fplugin-transform-typescript-7.12.1.tgz",
-      "integrity": "sha1-2SzAr1BNUQ4mp1Sn28LlyM2cerQ=",
-      "dev": true,
-      "requires": {
-        "@babel/helper-create-class-features-plugin": "^7.12.1",
-        "@babel/helper-plugin-utils": "^7.10.4",
-        "@babel/plugin-syntax-typescript": "^7.12.1"
-      }
-    },
-    "@babel/plugin-transform-unicode-escapes": {
-      "version": "7.12.1",
-      "resolved": "https://registry.npm.taobao.org/@babel/plugin-transform-unicode-escapes/download/@babel/plugin-transform-unicode-escapes-7.12.1.tgz?cache=0&sync_timestamp=1602800237534&other_urls=https%3A%2F%2Fregistry.npm.taobao.org%2F%40babel%2Fplugin-transform-unicode-escapes%2Fdownload%2F%40babel%2Fplugin-transform-unicode-escapes-7.12.1.tgz",
-      "integrity": "sha1-UjK5+BzLBwcLfDw2xnobePGEVwk=",
-      "dev": true,
-      "requires": {
-        "@babel/helper-plugin-utils": "^7.10.4"
-      }
-    },
-    "@babel/plugin-transform-unicode-regex": {
-      "version": "7.12.1",
-      "resolved": "https://registry.npm.taobao.org/@babel/plugin-transform-unicode-regex/download/@babel/plugin-transform-unicode-regex-7.12.1.tgz?cache=0&sync_timestamp=1602800241610&other_urls=https%3A%2F%2Fregistry.npm.taobao.org%2F%40babel%2Fplugin-transform-unicode-regex%2Fdownload%2F%40babel%2Fplugin-transform-unicode-regex-7.12.1.tgz",
-      "integrity": "sha1-zJZh9hOQ21xl4/66zO/Vxqw/rss=",
-      "dev": true,
-      "requires": {
-        "@babel/helper-create-regexp-features-plugin": "^7.12.1",
-        "@babel/helper-plugin-utils": "^7.10.4"
-      }
-    },
-    "@babel/preset-env": {
-      "version": "7.12.1",
-      "resolved": "https://registry.npm.taobao.org/@babel/preset-env/download/@babel/preset-env-7.12.1.tgz?cache=0&sync_timestamp=1602802054477&other_urls=https%3A%2F%2Fregistry.npm.taobao.org%2F%40babel%2Fpreset-env%2Fdownload%2F%40babel%2Fpreset-env-7.12.1.tgz",
-      "integrity": "sha1-nH5cqCoZ78hlOEu0mJFI0u5desI=",
-      "dev": true,
-      "requires": {
-        "@babel/compat-data": "^7.12.1",
-        "@babel/helper-compilation-targets": "^7.12.1",
-        "@babel/helper-module-imports": "^7.12.1",
-        "@babel/helper-plugin-utils": "^7.10.4",
-        "@babel/helper-validator-option": "^7.12.1",
-        "@babel/plugin-proposal-async-generator-functions": "^7.12.1",
-        "@babel/plugin-proposal-class-properties": "^7.12.1",
-        "@babel/plugin-proposal-dynamic-import": "^7.12.1",
-        "@babel/plugin-proposal-export-namespace-from": "^7.12.1",
-        "@babel/plugin-proposal-json-strings": "^7.12.1",
-        "@babel/plugin-proposal-logical-assignment-operators": "^7.12.1",
-        "@babel/plugin-proposal-nullish-coalescing-operator": "^7.12.1",
-        "@babel/plugin-proposal-numeric-separator": "^7.12.1",
-        "@babel/plugin-proposal-object-rest-spread": "^7.12.1",
-        "@babel/plugin-proposal-optional-catch-binding": "^7.12.1",
-        "@babel/plugin-proposal-optional-chaining": "^7.12.1",
-        "@babel/plugin-proposal-private-methods": "^7.12.1",
-        "@babel/plugin-proposal-unicode-property-regex": "^7.12.1",
-        "@babel/plugin-syntax-async-generators": "^7.8.0",
-        "@babel/plugin-syntax-class-properties": "^7.12.1",
-        "@babel/plugin-syntax-dynamic-import": "^7.8.0",
-        "@babel/plugin-syntax-export-namespace-from": "^7.8.3",
-        "@babel/plugin-syntax-json-strings": "^7.8.0",
-        "@babel/plugin-syntax-logical-assignment-operators": "^7.10.4",
-        "@babel/plugin-syntax-nullish-coalescing-operator": "^7.8.0",
-        "@babel/plugin-syntax-numeric-separator": "^7.10.4",
-        "@babel/plugin-syntax-object-rest-spread": "^7.8.0",
-        "@babel/plugin-syntax-optional-catch-binding": "^7.8.0",
-        "@babel/plugin-syntax-optional-chaining": "^7.8.0",
-        "@babel/plugin-syntax-top-level-await": "^7.12.1",
-        "@babel/plugin-transform-arrow-functions": "^7.12.1",
-        "@babel/plugin-transform-async-to-generator": "^7.12.1",
-        "@babel/plugin-transform-block-scoped-functions": "^7.12.1",
-        "@babel/plugin-transform-block-scoping": "^7.12.1",
-        "@babel/plugin-transform-classes": "^7.12.1",
-        "@babel/plugin-transform-computed-properties": "^7.12.1",
-        "@babel/plugin-transform-destructuring": "^7.12.1",
-        "@babel/plugin-transform-dotall-regex": "^7.12.1",
-        "@babel/plugin-transform-duplicate-keys": "^7.12.1",
-        "@babel/plugin-transform-exponentiation-operator": "^7.12.1",
-        "@babel/plugin-transform-for-of": "^7.12.1",
-        "@babel/plugin-transform-function-name": "^7.12.1",
-        "@babel/plugin-transform-literals": "^7.12.1",
-        "@babel/plugin-transform-member-expression-literals": "^7.12.1",
-        "@babel/plugin-transform-modules-amd": "^7.12.1",
-        "@babel/plugin-transform-modules-commonjs": "^7.12.1",
-        "@babel/plugin-transform-modules-systemjs": "^7.12.1",
-        "@babel/plugin-transform-modules-umd": "^7.12.1",
-        "@babel/plugin-transform-named-capturing-groups-regex": "^7.12.1",
-        "@babel/plugin-transform-new-target": "^7.12.1",
-        "@babel/plugin-transform-object-super": "^7.12.1",
-        "@babel/plugin-transform-parameters": "^7.12.1",
-        "@babel/plugin-transform-property-literals": "^7.12.1",
-        "@babel/plugin-transform-regenerator": "^7.12.1",
-        "@babel/plugin-transform-reserved-words": "^7.12.1",
-        "@babel/plugin-transform-shorthand-properties": "^7.12.1",
-        "@babel/plugin-transform-spread": "^7.12.1",
-        "@babel/plugin-transform-sticky-regex": "^7.12.1",
-        "@babel/plugin-transform-template-literals": "^7.12.1",
-        "@babel/plugin-transform-typeof-symbol": "^7.12.1",
-        "@babel/plugin-transform-unicode-escapes": "^7.12.1",
-        "@babel/plugin-transform-unicode-regex": "^7.12.1",
-        "@babel/preset-modules": "^0.1.3",
-        "@babel/types": "^7.12.1",
-        "core-js-compat": "^3.6.2",
-        "semver": "^5.5.0"
-      },
-      "dependencies": {
-        "semver": {
-          "version": "5.7.1",
-          "resolved": "https://registry.npm.taobao.org/semver/download/semver-5.7.1.tgz",
-          "integrity": "sha1-qVT5Ma66UI0we78Gnv8MAclhFvc=",
-          "dev": true
-        }
-      }
-    },
-    "@babel/preset-flow": {
-      "version": "7.12.1",
-      "resolved": "https://registry.npm.taobao.org/@babel/preset-flow/download/@babel/preset-flow-7.12.1.tgz",
-      "integrity": "sha1-GoHTdsWpVJ51NSo4iPjCc0Va6UA=",
-      "dev": true,
-      "requires": {
-        "@babel/helper-plugin-utils": "^7.10.4",
-        "@babel/plugin-transform-flow-strip-types": "^7.12.1"
-      }
-    },
-    "@babel/preset-modules": {
-      "version": "0.1.4",
-      "resolved": "https://registry.npm.taobao.org/@babel/preset-modules/download/@babel/preset-modules-0.1.4.tgz?cache=0&sync_timestamp=1598549645892&other_urls=https%3A%2F%2Fregistry.npm.taobao.org%2F%40babel%2Fpreset-modules%2Fdownload%2F%40babel%2Fpreset-modules-0.1.4.tgz",
-      "integrity": "sha1-Ni8raMZihClw/bXiVP/I/BwuQV4=",
-      "dev": true,
-      "requires": {
-        "@babel/helper-plugin-utils": "^7.0.0",
-        "@babel/plugin-proposal-unicode-property-regex": "^7.4.4",
-        "@babel/plugin-transform-dotall-regex": "^7.4.4",
-        "@babel/types": "^7.4.4",
-        "esutils": "^2.0.2"
-      }
-    },
-    "@babel/preset-react": {
-      "version": "7.12.5",
-      "resolved": "https://registry.npm.taobao.org/@babel/preset-react/download/@babel/preset-react-7.12.5.tgz",
-      "integrity": "sha1-1FYl9l1TYSB4pDhnxcZ1Dnh3LFY=",
-      "dev": true,
-      "requires": {
-        "@babel/helper-plugin-utils": "^7.10.4",
-        "@babel/plugin-transform-react-display-name": "^7.12.1",
-        "@babel/plugin-transform-react-jsx": "^7.12.5",
-        "@babel/plugin-transform-react-jsx-development": "^7.12.5",
-        "@babel/plugin-transform-react-jsx-self": "^7.12.1",
-        "@babel/plugin-transform-react-jsx-source": "^7.12.1",
-        "@babel/plugin-transform-react-pure-annotations": "^7.12.1"
-      }
-    },
-    "@babel/preset-typescript": {
-      "version": "7.12.1",
-      "resolved": "https://registry.npm.taobao.org/@babel/preset-typescript/download/@babel/preset-typescript-7.12.1.tgz?cache=0&sync_timestamp=1602801827867&other_urls=https%3A%2F%2Fregistry.npm.taobao.org%2F%40babel%2Fpreset-typescript%2Fdownload%2F%40babel%2Fpreset-typescript-7.12.1.tgz",
-      "integrity": "sha1-hkgLSDu5f3UDbohk/kBMx4LMMRs=",
-      "dev": true,
-      "requires": {
-        "@babel/helper-plugin-utils": "^7.10.4",
-        "@babel/plugin-transform-typescript": "^7.12.1"
-      }
-    },
-    "@babel/runtime": {
-      "version": "7.12.5",
-      "resolved": "https://registry.npm.taobao.org/@babel/runtime/download/@babel/runtime-7.12.5.tgz?cache=0&sync_timestamp=1604441104026&other_urls=https%3A%2F%2Fregistry.npm.taobao.org%2F%40babel%2Fruntime%2Fdownload%2F%40babel%2Fruntime-7.12.5.tgz",
-      "integrity": "sha1-QQ5+SHRB4bNgwpvnFdhw2bmFiC4=",
-      "requires": {
-        "regenerator-runtime": "^0.13.4"
-      },
-      "dependencies": {
-        "regenerator-runtime": {
-          "version": "0.13.7",
-          "resolved": "https://registry.npm.taobao.org/regenerator-runtime/download/regenerator-runtime-0.13.7.tgz?cache=0&other_urls=https%3A%2F%2Fregistry.npm.taobao.org%2Fregenerator-runtime%2Fdownload%2Fregenerator-runtime-0.13.7.tgz",
-          "integrity": "sha1-ysLazIoepnX+qrrriugziYrkb1U="
-        }
-      }
-    },
-    "@babel/runtime-corejs3": {
-      "version": "7.12.5",
-      "resolved": "https://registry.npm.taobao.org/@babel/runtime-corejs3/download/@babel/runtime-corejs3-7.12.5.tgz",
-      "integrity": "sha1-/+6R2g60xtrggHdOlLpgY2jkFPQ=",
-      "dev": true,
-      "requires": {
-        "core-js-pure": "^3.0.0",
-        "regenerator-runtime": "^0.13.4"
-      },
-      "dependencies": {
-        "regenerator-runtime": {
-          "version": "0.13.7",
-          "resolved": "https://registry.npm.taobao.org/regenerator-runtime/download/regenerator-runtime-0.13.7.tgz?cache=0&other_urls=https%3A%2F%2Fregistry.npm.taobao.org%2Fregenerator-runtime%2Fdownload%2Fregenerator-runtime-0.13.7.tgz",
-          "integrity": "sha1-ysLazIoepnX+qrrriugziYrkb1U=",
-          "dev": true
-        }
-      }
-    },
-    "@babel/template": {
-      "version": "7.10.4",
-      "resolved": "https://registry.npm.taobao.org/@babel/template/download/@babel/template-7.10.4.tgz?cache=0&sync_timestamp=1593522831608&other_urls=https%3A%2F%2Fregistry.npm.taobao.org%2F%40babel%2Ftemplate%2Fdownload%2F%40babel%2Ftemplate-7.10.4.tgz",
-      "integrity": "sha1-MlGZbEIA68cdGo/EBfupQPNrong=",
-      "dev": true,
-      "requires": {
-        "@babel/code-frame": "^7.10.4",
-        "@babel/parser": "^7.10.4",
-        "@babel/types": "^7.10.4"
-      }
-    },
-    "@babel/traverse": {
-      "version": "7.12.5",
-      "resolved": "https://registry.npm.taobao.org/@babel/traverse/download/@babel/traverse-7.12.5.tgz",
-      "integrity": "sha1-eKDGjI6KNeTKz9MduLswPVYG8JU=",
-      "dev": true,
-      "requires": {
-        "@babel/code-frame": "^7.10.4",
-        "@babel/generator": "^7.12.5",
-        "@babel/helper-function-name": "^7.10.4",
-        "@babel/helper-split-export-declaration": "^7.11.0",
-        "@babel/parser": "^7.12.5",
-        "@babel/types": "^7.12.5",
-        "debug": "^4.1.0",
-        "globals": "^11.1.0",
-        "lodash": "^4.17.19"
-      }
-    },
-    "@babel/types": {
-      "version": "7.12.6",
-      "resolved": "https://registry.npm.taobao.org/@babel/types/download/@babel/types-7.12.6.tgz?cache=0&sync_timestamp=1604486339981&other_urls=https%3A%2F%2Fregistry.npm.taobao.org%2F%40babel%2Ftypes%2Fdownload%2F%40babel%2Ftypes-7.12.6.tgz",
-      "integrity": "sha1-rg5V7xzOH7yIHNJvgjTrPmV+3JY=",
-      "dev": true,
-      "requires": {
-        "@babel/helper-validator-identifier": "^7.10.4",
-        "lodash": "^4.17.19",
-        "to-fast-properties": "^2.0.0"
-      }
-    },
-    "@bcoe/v8-coverage": {
-      "version": "0.2.3",
-      "resolved": "https://registry.npm.taobao.org/@bcoe/v8-coverage/download/@bcoe/v8-coverage-0.2.3.tgz",
-      "integrity": "sha1-daLotRy3WKdVPWgEpZMteqznXDk=",
-      "dev": true
-    },
-    "@builder/app-helpers": {
-      "version": "1.0.1",
-      "resolved": "https://registry.npm.taobao.org/@builder/app-helpers/download/@builder/app-helpers-1.0.1.tgz",
-      "integrity": "sha1-7u27x6NwCMkyGJebwDOF0VBMLak=",
-      "dev": true,
-      "requires": {
-        "fs-extra": "^8.1.0",
-        "lodash": "^4.17.20"
-      }
-    },
-    "@builder/user-config": {
-      "version": "0.1.1",
-      "resolved": "https://registry.npm.taobao.org/@builder/user-config/download/@builder/user-config-0.1.1.tgz",
-      "integrity": "sha1-21AHT9yPRdmhjnvfYMIJXula4j0=",
-      "dev": true,
-      "requires": {
-        "@alifd/fusion-collector": "^1.2.5",
-        "@babel/plugin-transform-runtime": "^7.6.2",
-        "@builder/app-helpers": "^1.0.0",
-        "add-asset-html-webpack-plugin": "^3.1.3",
-        "chalk": "^4.0.0",
-        "copy-webpack-plugin": "^5.0.4",
-        "core-js": "^3.3.1",
-        "debug": "^4.1.1",
-        "eslint-loader": "^4.0.0",
-        "eslint-reporting-webpack-plugin": "^0.1.0",
-        "fork-ts-checker-webpack-plugin": "^5.0.5",
-        "friendly-errors-webpack-plugin": "^1.7.0",
-        "fs-extra": "^8.1.0",
-        "loader-utils": "^2.0.0",
-        "lodash": "^4.17.15",
-        "mkcert": "^1.2.0",
-        "path-exists": "^4.0.0",
-        "postcss-plugin-rpx2vw": "^0.0.2",
-        "react-dev-utils": "^10.2.1",
-        "regenerator-runtime": "^0.13.3",
-        "webpack-bundle-analyzer": "^3.6.0",
-        "webpack-dev-mock": "^1.0.1",
-        "webpack-plugin-import": "^0.2.6"
-      },
-      "dependencies": {
-        "ansi-regex": {
-          "version": "5.0.0",
-          "resolved": "https://registry.npm.taobao.org/ansi-regex/download/ansi-regex-5.0.0.tgz",
-          "integrity": "sha1-OIU59VF5vzkznIGvMKZU1p+Hy3U=",
-          "dev": true
-        },
-        "ansi-styles": {
-          "version": "4.3.0",
-          "resolved": "https://registry.npm.taobao.org/ansi-styles/download/ansi-styles-4.3.0.tgz?cache=0&sync_timestamp=1601839122515&other_urls=https%3A%2F%2Fregistry.npm.taobao.org%2Fansi-styles%2Fdownload%2Fansi-styles-4.3.0.tgz",
-          "integrity": "sha1-7dgDYornHATIWuegkG7a00tkiTc=",
-          "dev": true,
-          "requires": {
-            "color-convert": "^2.0.1"
-          }
-        },
-        "browserslist": {
-          "version": "4.10.0",
-          "resolved": "https://registry.npm.taobao.org/browserslist/download/browserslist-4.10.0.tgz?cache=0&sync_timestamp=1604944989360&other_urls=https%3A%2F%2Fregistry.npm.taobao.org%2Fbrowserslist%2Fdownload%2Fbrowserslist-4.10.0.tgz",
-          "integrity": "sha1-8XlzeRPq8NK5jkkmrBymoVy8xqk=",
-          "dev": true,
-          "requires": {
-            "caniuse-lite": "^1.0.30001035",
-            "electron-to-chromium": "^1.3.378",
-            "node-releases": "^1.1.52",
-            "pkg-up": "^3.1.0"
-          }
-        },
-        "chalk": {
-          "version": "4.1.0",
-          "resolved": "https://registry.npm.taobao.org/chalk/download/chalk-4.1.0.tgz",
-          "integrity": "sha1-ThSHCmGNni7dl92DRf2dncMVZGo=",
-          "dev": true,
-          "requires": {
-            "ansi-styles": "^4.1.0",
-            "supports-color": "^7.1.0"
-          }
-        },
-        "cli-width": {
-          "version": "2.2.1",
-          "resolved": "https://registry.npm.taobao.org/cli-width/download/cli-width-2.2.1.tgz",
-          "integrity": "sha1-sEM9C06chH7xiGik7xb9X8gnHEg=",
-          "dev": true
-        },
-        "color-convert": {
-          "version": "2.0.1",
-          "resolved": "https://registry.npm.taobao.org/color-convert/download/color-convert-2.0.1.tgz",
-          "integrity": "sha1-ctOmjVmMm9s68q0ehPIdiWq9TeM=",
-          "dev": true,
-          "requires": {
-            "color-name": "~1.1.4"
-          }
-        },
-        "color-name": {
-          "version": "1.1.4",
-          "resolved": "https://registry.npm.taobao.org/color-name/download/color-name-1.1.4.tgz",
-          "integrity": "sha1-wqCah6y95pVD3m9j+jmVyCbFNqI=",
-          "dev": true
-        },
-        "copy-webpack-plugin": {
-          "version": "5.1.2",
-          "resolved": "https://registry.npm.taobao.org/copy-webpack-plugin/download/copy-webpack-plugin-5.1.2.tgz?cache=0&other_urls=https%3A%2F%2Fregistry.npm.taobao.org%2Fcopy-webpack-plugin%2Fdownload%2Fcopy-webpack-plugin-5.1.2.tgz",
-          "integrity": "sha1-ioieHcr6bJHGzUvhrRWPHTgjuuI=",
-          "dev": true,
-          "requires": {
-            "cacache": "^12.0.3",
-            "find-cache-dir": "^2.1.0",
-            "glob-parent": "^3.1.0",
-            "globby": "^7.1.1",
-            "is-glob": "^4.0.1",
-            "loader-utils": "^1.2.3",
-            "minimatch": "^3.0.4",
-            "normalize-path": "^3.0.0",
-            "p-limit": "^2.2.1",
-            "schema-utils": "^1.0.0",
-            "serialize-javascript": "^4.0.0",
-            "webpack-log": "^2.0.0"
-          },
-          "dependencies": {
-            "loader-utils": {
-              "version": "1.4.0",
-              "resolved": "https://registry.npm.taobao.org/loader-utils/download/loader-utils-1.4.0.tgz",
-              "integrity": "sha1-xXm140yzSxp07cbB+za/o3HVphM=",
-              "dev": true,
-              "requires": {
-                "big.js": "^5.2.2",
-                "emojis-list": "^3.0.0",
-                "json5": "^1.0.1"
-              }
-            }
-          }
-        },
-        "core-js": {
-          "version": "3.7.0",
-          "resolved": "https://registry.npm.taobao.org/core-js/download/core-js-3.7.0.tgz?cache=0&sync_timestamp=1604675498528&other_urls=https%3A%2F%2Fregistry.npm.taobao.org%2Fcore-js%2Fdownload%2Fcore-js-3.7.0.tgz",
-          "integrity": "sha1-sKdhoCSIV3r7+XF55Ggb9JVoUg8=",
-          "dev": true
-        },
-        "cosmiconfig": {
-          "version": "6.0.0",
-          "resolved": "https://registry.npm.taobao.org/cosmiconfig/download/cosmiconfig-6.0.0.tgz?cache=0&sync_timestamp=1596312863119&other_urls=https%3A%2F%2Fregistry.npm.taobao.org%2Fcosmiconfig%2Fdownload%2Fcosmiconfig-6.0.0.tgz",
-          "integrity": "sha1-2k/uhTxS9rHmk19BwaL8UL1KmYI=",
-          "dev": true,
-          "requires": {
-            "@types/parse-json": "^4.0.0",
-            "import-fresh": "^3.1.0",
-            "parse-json": "^5.0.0",
-            "path-type": "^4.0.0",
-            "yaml": "^1.7.2"
-          }
-        },
-        "cross-spawn": {
-          "version": "7.0.1",
-          "resolved": "https://registry.npm.taobao.org/cross-spawn/download/cross-spawn-7.0.1.tgz",
-          "integrity": "sha1-CrVihuD3wk4VPQTMKqAn5DqaXRQ=",
-          "dev": true,
-          "requires": {
-            "path-key": "^3.1.0",
-            "shebang-command": "^2.0.0",
-            "which": "^2.0.1"
-          }
-        },
-        "detect-port-alt": {
-          "version": "1.1.6",
-          "resolved": "https://registry.npm.taobao.org/detect-port-alt/download/detect-port-alt-1.1.6.tgz",
-          "integrity": "sha1-JHB96r6TLUo89iEwICfCsmZWgnU=",
-          "dev": true,
-          "requires": {
-            "address": "^1.0.1",
-            "debug": "^2.6.0"
-          },
-          "dependencies": {
-            "debug": {
-              "version": "2.6.9",
-              "resolved": "https://registry.npm.taobao.org/debug/download/debug-2.6.9.tgz?cache=0&sync_timestamp=1600502871403&other_urls=https%3A%2F%2Fregistry.npm.taobao.org%2Fdebug%2Fdownload%2Fdebug-2.6.9.tgz",
-              "integrity": "sha1-XRKFFd8TT/Mn6QpMk/Tgd6U2NB8=",
-              "dev": true,
-              "requires": {
-                "ms": "2.0.0"
-              }
-            }
-          }
-        },
-        "emoji-regex": {
-          "version": "8.0.0",
-          "resolved": "https://registry.npm.taobao.org/emoji-regex/download/emoji-regex-8.0.0.tgz?cache=0&sync_timestamp=1603212263242&other_urls=https%3A%2F%2Fregistry.npm.taobao.org%2Femoji-regex%2Fdownload%2Femoji-regex-8.0.0.tgz",
-          "integrity": "sha1-6Bj9ac5cz8tARZT4QpY79TFkzDc=",
-          "dev": true
-        },
-        "escape-string-regexp": {
-          "version": "2.0.0",
-          "resolved": "https://registry.npm.taobao.org/escape-string-regexp/download/escape-string-regexp-2.0.0.tgz?cache=0&sync_timestamp=1587627107924&other_urls=https%3A%2F%2Fregistry.npm.taobao.org%2Fescape-string-regexp%2Fdownload%2Fescape-string-regexp-2.0.0.tgz",
-          "integrity": "sha1-owME6Z2qMuI7L9IPUbq9B8/8o0Q=",
-          "dev": true
-        },
-        "filesize": {
-          "version": "6.0.1",
-          "resolved": "https://registry.npm.taobao.org/filesize/download/filesize-6.0.1.tgz",
-          "integrity": "sha1-+FC1CZCcfIb35FDqGQBsMcLtPS8=",
-          "dev": true
-        },
-        "find-up": {
-          "version": "4.1.0",
-          "resolved": "https://registry.npm.taobao.org/find-up/download/find-up-4.1.0.tgz?cache=0&sync_timestamp=1597169862146&other_urls=https%3A%2F%2Fregistry.npm.taobao.org%2Ffind-up%2Fdownload%2Ffind-up-4.1.0.tgz",
-          "integrity": "sha1-l6/n1s3AvFkoWEt8jXsW6KmqXRk=",
-          "dev": true,
-          "requires": {
-            "locate-path": "^5.0.0",
-            "path-exists": "^4.0.0"
-          }
-        },
-        "fork-ts-checker-webpack-plugin": {
-          "version": "5.2.1",
-          "resolved": "https://registry.npm.taobao.org/fork-ts-checker-webpack-plugin/download/fork-ts-checker-webpack-plugin-5.2.1.tgz",
-          "integrity": "sha1-eTJthpeXkG+osk4qvPlCH8gFRQ0=",
-          "dev": true,
-          "requires": {
-            "@babel/code-frame": "^7.8.3",
-            "@types/json-schema": "^7.0.5",
-            "chalk": "^4.1.0",
-            "cosmiconfig": "^6.0.0",
-            "deepmerge": "^4.2.2",
-            "fs-extra": "^9.0.0",
-            "memfs": "^3.1.2",
-            "minimatch": "^3.0.4",
-            "schema-utils": "2.7.0",
-            "semver": "^7.3.2",
-            "tapable": "^1.0.0"
-          },
-          "dependencies": {
-            "fs-extra": {
-              "version": "9.0.1",
-              "resolved": "https://registry.npm.taobao.org/fs-extra/download/fs-extra-9.0.1.tgz?cache=0&other_urls=https%3A%2F%2Fregistry.npm.taobao.org%2Ffs-extra%2Fdownload%2Ffs-extra-9.0.1.tgz",
-              "integrity": "sha1-kQ2gBiQ3ukw5/t2GPxZ1zP78ufw=",
-              "dev": true,
-              "requires": {
-                "at-least-node": "^1.0.0",
-                "graceful-fs": "^4.2.0",
-                "jsonfile": "^6.0.1",
-                "universalify": "^1.0.0"
-              }
-            },
-            "schema-utils": {
-              "version": "2.7.0",
-              "resolved": "https://registry.npm.taobao.org/schema-utils/download/schema-utils-2.7.0.tgz",
-              "integrity": "sha1-FxUfdtjq5n+793lgwzxnatn078c=",
-              "dev": true,
-              "requires": {
-                "@types/json-schema": "^7.0.4",
-                "ajv": "^6.12.2",
-                "ajv-keywords": "^3.4.1"
-              }
-            }
-          }
-        },
-        "globby": {
-          "version": "7.1.1",
-          "resolved": "https://registry.npm.taobao.org/globby/download/globby-7.1.1.tgz",
-          "integrity": "sha1-+yzP+UAfhgCUXfral0QMypcrhoA=",
-          "dev": true,
-          "requires": {
-            "array-union": "^1.0.1",
-            "dir-glob": "^2.0.0",
-            "glob": "^7.1.2",
-            "ignore": "^3.3.5",
-            "pify": "^3.0.0",
-            "slash": "^1.0.0"
-          }
-        },
-        "has-flag": {
-          "version": "4.0.0",
-          "resolved": "https://registry.npm.taobao.org/has-flag/download/has-flag-4.0.0.tgz?cache=0&sync_timestamp=1596294337050&other_urls=https%3A%2F%2Fregistry.npm.taobao.org%2Fhas-flag%2Fdownload%2Fhas-flag-4.0.0.tgz",
-          "integrity": "sha1-lEdx/ZyByBJlxNaUGGDaBrtZR5s=",
-          "dev": true
-        },
-        "ignore": {
-          "version": "3.3.10",
-          "resolved": "https://registry.npm.taobao.org/ignore/download/ignore-3.3.10.tgz",
-          "integrity": "sha1-Cpf7h2mG6AgcYxFg+PnziRV/AEM=",
-          "dev": true
-        },
-        "import-fresh": {
-          "version": "3.2.2",
-          "resolved": "https://registry.npm.taobao.org/import-fresh/download/import-fresh-3.2.2.tgz?cache=0&sync_timestamp=1604256056573&other_urls=https%3A%2F%2Fregistry.npm.taobao.org%2Fimport-fresh%2Fdownload%2Fimport-fresh-3.2.2.tgz",
-          "integrity": "sha1-/BKcFgxdaCNVB/QzGmuq0Ya9vD4=",
-          "dev": true,
-          "requires": {
-            "parent-module": "^1.0.0",
-            "resolve-from": "^4.0.0"
-          }
-        },
-        "inquirer": {
-          "version": "7.0.4",
-          "resolved": "https://registry.npm.taobao.org/inquirer/download/inquirer-7.0.4.tgz",
-          "integrity": "sha1-ma9b3kcVOryiP1x/ww2yR/OdpwM=",
-          "dev": true,
-          "requires": {
-            "ansi-escapes": "^4.2.1",
-            "chalk": "^2.4.2",
-            "cli-cursor": "^3.1.0",
-            "cli-width": "^2.0.0",
-            "external-editor": "^3.0.3",
-            "figures": "^3.0.0",
-            "lodash": "^4.17.15",
-            "mute-stream": "0.0.8",
-            "run-async": "^2.2.0",
-            "rxjs": "^6.5.3",
-            "string-width": "^4.1.0",
-            "strip-ansi": "^5.1.0",
-            "through": "^2.3.6"
-          },
-          "dependencies": {
-            "ansi-regex": {
-              "version": "4.1.0",
-              "resolved": "https://registry.npm.taobao.org/ansi-regex/download/ansi-regex-4.1.0.tgz",
-              "integrity": "sha1-i5+PCM8ay4Q3Vqg5yox+MWjFGZc=",
-              "dev": true
-            },
-            "ansi-styles": {
-              "version": "3.2.1",
-              "resolved": "https://registry.npm.taobao.org/ansi-styles/download/ansi-styles-3.2.1.tgz?cache=0&sync_timestamp=1601839122515&other_urls=https%3A%2F%2Fregistry.npm.taobao.org%2Fansi-styles%2Fdownload%2Fansi-styles-3.2.1.tgz",
-              "integrity": "sha1-QfuyAkPlCxK+DwS43tvwdSDOhB0=",
-              "dev": true,
-              "requires": {
-                "color-convert": "^1.9.0"
-              }
-            },
-            "chalk": {
-              "version": "2.4.2",
-              "resolved": "https://registry.npm.taobao.org/chalk/download/chalk-2.4.2.tgz",
-              "integrity": "sha1-zUJUFnelQzPPVBpJEIwUMrRMlCQ=",
-              "dev": true,
-              "requires": {
-                "ansi-styles": "^3.2.1",
-                "escape-string-regexp": "^1.0.5",
-                "supports-color": "^5.3.0"
-              }
-            },
-            "color-convert": {
-              "version": "1.9.3",
-              "resolved": "https://registry.npm.taobao.org/color-convert/download/color-convert-1.9.3.tgz",
-              "integrity": "sha1-u3GFBpDh8TZWfeYp0tVHHe2kweg=",
-              "dev": true,
-              "requires": {
-                "color-name": "1.1.3"
-              }
-            },
-            "color-name": {
-              "version": "1.1.3",
-              "resolved": "https://registry.npm.taobao.org/color-name/download/color-name-1.1.3.tgz",
-              "integrity": "sha1-p9BVi9icQveV3UIyj3QIMcpTvCU=",
-              "dev": true
-            },
-            "escape-string-regexp": {
-              "version": "1.0.5",
-              "resolved": "https://registry.npm.taobao.org/escape-string-regexp/download/escape-string-regexp-1.0.5.tgz?cache=0&sync_timestamp=1587627107924&other_urls=https%3A%2F%2Fregistry.npm.taobao.org%2Fescape-string-regexp%2Fdownload%2Fescape-string-regexp-1.0.5.tgz",
-              "integrity": "sha1-G2HAViGQqN/2rjuyzwIAyhMLhtQ=",
-              "dev": true
-            },
-            "has-flag": {
-              "version": "3.0.0",
-              "resolved": "https://registry.npm.taobao.org/has-flag/download/has-flag-3.0.0.tgz?cache=0&sync_timestamp=1596294337050&other_urls=https%3A%2F%2Fregistry.npm.taobao.org%2Fhas-flag%2Fdownload%2Fhas-flag-3.0.0.tgz",
-              "integrity": "sha1-tdRU3CGZriJWmfNGfloH87lVuv0=",
-              "dev": true
-            },
-            "strip-ansi": {
-              "version": "5.2.0",
-              "resolved": "https://registry.npm.taobao.org/strip-ansi/download/strip-ansi-5.2.0.tgz",
-              "integrity": "sha1-jJpTb+tq/JYr36WxBKUJHBrZwK4=",
-              "dev": true,
-              "requires": {
-                "ansi-regex": "^4.1.0"
-              }
-            },
-            "supports-color": {
-              "version": "5.5.0",
-              "resolved": "https://registry.npm.taobao.org/supports-color/download/supports-color-5.5.0.tgz?cache=0&sync_timestamp=1598611730985&other_urls=https%3A%2F%2Fregistry.npm.taobao.org%2Fsupports-color%2Fdownload%2Fsupports-color-5.5.0.tgz",
-              "integrity": "sha1-4uaaRKyHcveKHsCzW2id9lMO/I8=",
-              "dev": true,
-              "requires": {
-                "has-flag": "^3.0.0"
-              }
-            }
-          }
-        },
-        "is-fullwidth-code-point": {
-          "version": "3.0.0",
-          "resolved": "https://registry.npm.taobao.org/is-fullwidth-code-point/download/is-fullwidth-code-point-3.0.0.tgz",
-          "integrity": "sha1-8Rb4Bk/pCz94RKOJl8C3UFEmnx0=",
-          "dev": true
-        },
-        "jsonfile": {
-          "version": "6.1.0",
-          "resolved": "https://registry.npm.taobao.org/jsonfile/download/jsonfile-6.1.0.tgz?cache=0&sync_timestamp=1604161933968&other_urls=https%3A%2F%2Fregistry.npm.taobao.org%2Fjsonfile%2Fdownload%2Fjsonfile-6.1.0.tgz",
-          "integrity": "sha1-vFWyY0eTxnnsZAMJTrE2mKbsCq4=",
-          "dev": true,
-          "requires": {
-            "graceful-fs": "^4.1.6",
-            "universalify": "^2.0.0"
-          },
-          "dependencies": {
-            "universalify": {
-              "version": "2.0.0",
-              "resolved": "https://registry.npm.taobao.org/universalify/download/universalify-2.0.0.tgz?cache=0&sync_timestamp=1603180048005&other_urls=https%3A%2F%2Fregistry.npm.taobao.org%2Funiversalify%2Fdownload%2Funiversalify-2.0.0.tgz",
-              "integrity": "sha1-daSYTv7cSwiXXFrrc/Uw0C3yVxc=",
-              "dev": true
-            }
-          }
-        },
-        "loader-utils": {
-          "version": "2.0.0",
-          "resolved": "https://registry.npm.taobao.org/loader-utils/download/loader-utils-2.0.0.tgz",
-          "integrity": "sha1-5MrOW4FtQloWa18JfhDNErNgZLA=",
-          "dev": true,
-          "requires": {
-            "big.js": "^5.2.2",
-            "emojis-list": "^3.0.0",
-            "json5": "^2.1.2"
-          },
-          "dependencies": {
-            "json5": {
-              "version": "2.1.3",
-              "resolved": "https://registry.npm.taobao.org/json5/download/json5-2.1.3.tgz",
-              "integrity": "sha1-ybD3+pIzv+WAf+ZvzzpWF+1ZfUM=",
-              "dev": true,
-              "requires": {
-                "minimist": "^1.2.5"
-              }
-            }
-          }
-        },
-        "locate-path": {
-          "version": "5.0.0",
-          "resolved": "https://registry.npm.taobao.org/locate-path/download/locate-path-5.0.0.tgz",
-          "integrity": "sha1-Gvujlq/WdqbUJQTQpno6frn2KqA=",
-          "dev": true,
-          "requires": {
-            "p-locate": "^4.1.0"
-          }
-        },
-        "ms": {
-          "version": "2.0.0",
-          "resolved": "https://registry.npm.taobao.org/ms/download/ms-2.0.0.tgz",
-          "integrity": "sha1-VgiurfwAvmwpAd9fmGF4jeDVl8g=",
-          "dev": true
-        },
-        "open": {
-          "version": "7.3.0",
-          "resolved": "https://registry.npm.taobao.org/open/download/open-7.3.0.tgz?cache=0&sync_timestamp=1601376312546&other_urls=https%3A%2F%2Fregistry.npm.taobao.org%2Fopen%2Fdownload%2Fopen-7.3.0.tgz",
-          "integrity": "sha1-RUYf3uRkRPNkW24U6zypS4Lhvmk=",
-          "dev": true,
-          "requires": {
-            "is-docker": "^2.0.0",
-            "is-wsl": "^2.1.1"
-          }
-        },
-        "p-limit": {
-          "version": "2.3.0",
-          "resolved": "https://registry.npm.taobao.org/p-limit/download/p-limit-2.3.0.tgz",
-          "integrity": "sha1-PdM8ZHohT9//2DWTPrCG2g3CHbE=",
-          "dev": true,
-          "requires": {
-            "p-try": "^2.0.0"
-          }
-        },
-        "p-locate": {
-          "version": "4.1.0",
-          "resolved": "https://registry.npm.taobao.org/p-locate/download/p-locate-4.1.0.tgz?cache=0&sync_timestamp=1597081508945&other_urls=https%3A%2F%2Fregistry.npm.taobao.org%2Fp-locate%2Fdownload%2Fp-locate-4.1.0.tgz",
-          "integrity": "sha1-o0KLtwiLOmApL2aRkni3wpetTwc=",
-          "dev": true,
-          "requires": {
-            "p-limit": "^2.2.0"
-          }
-        },
-        "p-try": {
-          "version": "2.2.0",
-          "resolved": "https://registry.npm.taobao.org/p-try/download/p-try-2.2.0.tgz",
-          "integrity": "sha1-yyhoVA4xPWHeWPr741zpAE1VQOY=",
-          "dev": true
-        },
-        "parse-json": {
-          "version": "5.1.0",
-          "resolved": "https://registry.npm.taobao.org/parse-json/download/parse-json-5.1.0.tgz?cache=0&sync_timestamp=1598129247474&other_urls=https%3A%2F%2Fregistry.npm.taobao.org%2Fparse-json%2Fdownload%2Fparse-json-5.1.0.tgz",
-          "integrity": "sha1-+WCIzfJKj6qa6poAny2dlCyZlkY=",
-          "dev": true,
-          "requires": {
-            "@babel/code-frame": "^7.0.0",
-            "error-ex": "^1.3.1",
-            "json-parse-even-better-errors": "^2.3.0",
-            "lines-and-columns": "^1.1.6"
-          }
-        },
-        "path-exists": {
-          "version": "4.0.0",
-          "resolved": "https://registry.npm.taobao.org/path-exists/download/path-exists-4.0.0.tgz",
-          "integrity": "sha1-UTvb4tO5XXdi6METfvoZXGxhtbM=",
-          "dev": true
-        },
-        "path-key": {
-          "version": "3.1.1",
-          "resolved": "https://registry.npm.taobao.org/path-key/download/path-key-3.1.1.tgz",
-          "integrity": "sha1-WB9q3mWMu6ZaDTOA3ndTKVBU83U=",
-          "dev": true
-        },
-        "path-type": {
-          "version": "4.0.0",
-          "resolved": "https://registry.npm.taobao.org/path-type/download/path-type-4.0.0.tgz",
-          "integrity": "sha1-hO0BwKe6OAr+CdkKjBgNzZ0DBDs=",
-          "dev": true
-        },
-        "pify": {
-          "version": "3.0.0",
-          "resolved": "https://registry.npm.taobao.org/pify/download/pify-3.0.0.tgz",
-          "integrity": "sha1-5aSs0sEB/fPZpNB/DbxNtJ3SgXY=",
-          "dev": true
-        },
-        "react-dev-utils": {
-          "version": "10.2.1",
-          "resolved": "https://registry.npm.taobao.org/react-dev-utils/download/react-dev-utils-10.2.1.tgz?cache=0&sync_timestamp=1603462727689&other_urls=https%3A%2F%2Fregistry.npm.taobao.org%2Freact-dev-utils%2Fdownload%2Freact-dev-utils-10.2.1.tgz",
-          "integrity": "sha1-9t4yWuJfpNVG0J30uxvv3G3RnBk=",
-          "dev": true,
-          "requires": {
-            "@babel/code-frame": "7.8.3",
-            "address": "1.1.2",
-            "browserslist": "4.10.0",
-            "chalk": "2.4.2",
-            "cross-spawn": "7.0.1",
-            "detect-port-alt": "1.1.6",
-            "escape-string-regexp": "2.0.0",
-            "filesize": "6.0.1",
-            "find-up": "4.1.0",
-            "fork-ts-checker-webpack-plugin": "3.1.1",
-            "global-modules": "2.0.0",
-            "globby": "8.0.2",
-            "gzip-size": "5.1.1",
-            "immer": "1.10.0",
-            "inquirer": "7.0.4",
-            "is-root": "2.1.0",
-            "loader-utils": "1.2.3",
-            "open": "^7.0.2",
-            "pkg-up": "3.1.0",
-            "react-error-overlay": "^6.0.7",
-            "recursive-readdir": "2.2.2",
-            "shell-quote": "1.7.2",
-            "strip-ansi": "6.0.0",
-            "text-table": "0.2.0"
-          },
-          "dependencies": {
-            "@babel/code-frame": {
-              "version": "7.8.3",
-              "resolved": "https://registry.npm.taobao.org/@babel/code-frame/download/@babel/code-frame-7.8.3.tgz",
-              "integrity": "sha1-M+JZA9dIEYFTThLsCiXxa2/PQZ4=",
-              "dev": true,
-              "requires": {
-                "@babel/highlight": "^7.8.3"
-              }
-            },
-            "ansi-styles": {
-              "version": "3.2.1",
-              "resolved": "https://registry.npm.taobao.org/ansi-styles/download/ansi-styles-3.2.1.tgz?cache=0&sync_timestamp=1601839122515&other_urls=https%3A%2F%2Fregistry.npm.taobao.org%2Fansi-styles%2Fdownload%2Fansi-styles-3.2.1.tgz",
-              "integrity": "sha1-QfuyAkPlCxK+DwS43tvwdSDOhB0=",
-              "dev": true,
-              "requires": {
-                "color-convert": "^1.9.0"
-              }
-            },
-            "chalk": {
-              "version": "2.4.2",
-              "resolved": "https://registry.npm.taobao.org/chalk/download/chalk-2.4.2.tgz",
-              "integrity": "sha1-zUJUFnelQzPPVBpJEIwUMrRMlCQ=",
-              "dev": true,
-              "requires": {
-                "ansi-styles": "^3.2.1",
-                "escape-string-regexp": "^1.0.5",
-                "supports-color": "^5.3.0"
-              },
-              "dependencies": {
-                "escape-string-regexp": {
-                  "version": "1.0.5",
-                  "resolved": "https://registry.npm.taobao.org/escape-string-regexp/download/escape-string-regexp-1.0.5.tgz?cache=0&sync_timestamp=1587627107924&other_urls=https%3A%2F%2Fregistry.npm.taobao.org%2Fescape-string-regexp%2Fdownload%2Fescape-string-regexp-1.0.5.tgz",
-                  "integrity": "sha1-G2HAViGQqN/2rjuyzwIAyhMLhtQ=",
-                  "dev": true
-                }
-              }
-            },
-            "color-convert": {
-              "version": "1.9.3",
-              "resolved": "https://registry.npm.taobao.org/color-convert/download/color-convert-1.9.3.tgz",
-              "integrity": "sha1-u3GFBpDh8TZWfeYp0tVHHe2kweg=",
-              "dev": true,
-              "requires": {
-                "color-name": "1.1.3"
-              }
-            },
-            "color-name": {
-              "version": "1.1.3",
-              "resolved": "https://registry.npm.taobao.org/color-name/download/color-name-1.1.3.tgz",
-              "integrity": "sha1-p9BVi9icQveV3UIyj3QIMcpTvCU=",
-              "dev": true
-            },
-            "dir-glob": {
-              "version": "2.0.0",
-              "resolved": "https://registry.npm.taobao.org/dir-glob/download/dir-glob-2.0.0.tgz",
-              "integrity": "sha1-CyBdK2rvmCOMooZZioIE0p0KADQ=",
-              "dev": true,
-              "requires": {
-                "arrify": "^1.0.1",
-                "path-type": "^3.0.0"
-              }
-            },
-            "emojis-list": {
-              "version": "2.1.0",
-              "resolved": "https://registry.npm.taobao.org/emojis-list/download/emojis-list-2.1.0.tgz",
-              "integrity": "sha1-TapNnbAPmBmIDHn6RXrlsJof04k=",
-              "dev": true
-            },
-            "fork-ts-checker-webpack-plugin": {
-              "version": "3.1.1",
-              "resolved": "https://registry.npm.taobao.org/fork-ts-checker-webpack-plugin/download/fork-ts-checker-webpack-plugin-3.1.1.tgz",
-              "integrity": "sha1-oWQsDT5l9QwswXQunAqA9EH4axk=",
-              "dev": true,
-              "requires": {
-                "babel-code-frame": "^6.22.0",
-                "chalk": "^2.4.1",
-                "chokidar": "^3.3.0",
-                "micromatch": "^3.1.10",
-                "minimatch": "^3.0.4",
-                "semver": "^5.6.0",
-                "tapable": "^1.0.0",
-                "worker-rpc": "^0.1.0"
-              }
-            },
-            "globby": {
-              "version": "8.0.2",
-              "resolved": "https://registry.npm.taobao.org/globby/download/globby-8.0.2.tgz",
-              "integrity": "sha1-VpdhnM2VxSdduy1vqkIIfBqUHY0=",
-              "dev": true,
-              "requires": {
-                "array-union": "^1.0.1",
-                "dir-glob": "2.0.0",
-                "fast-glob": "^2.0.2",
-                "glob": "^7.1.2",
-                "ignore": "^3.3.5",
-                "pify": "^3.0.0",
-                "slash": "^1.0.0"
-              }
-            },
-            "has-flag": {
-              "version": "3.0.0",
-              "resolved": "https://registry.npm.taobao.org/has-flag/download/has-flag-3.0.0.tgz?cache=0&sync_timestamp=1596294337050&other_urls=https%3A%2F%2Fregistry.npm.taobao.org%2Fhas-flag%2Fdownload%2Fhas-flag-3.0.0.tgz",
-              "integrity": "sha1-tdRU3CGZriJWmfNGfloH87lVuv0=",
-              "dev": true
-            },
-            "loader-utils": {
-              "version": "1.2.3",
-              "resolved": "https://registry.npm.taobao.org/loader-utils/download/loader-utils-1.2.3.tgz",
-              "integrity": "sha1-H/XcaRHJ8KBiUxpMBLYJQGEIwsc=",
-              "dev": true,
-              "requires": {
-                "big.js": "^5.2.2",
-                "emojis-list": "^2.0.0",
-                "json5": "^1.0.1"
-              }
-            },
-            "path-type": {
-              "version": "3.0.0",
-              "resolved": "https://registry.npm.taobao.org/path-type/download/path-type-3.0.0.tgz",
-              "integrity": "sha1-zvMdyOCho7sNEFwM2Xzzv0f0428=",
-              "dev": true,
-              "requires": {
-                "pify": "^3.0.0"
-              }
-            },
-            "semver": {
-              "version": "5.7.1",
-              "resolved": "https://registry.npm.taobao.org/semver/download/semver-5.7.1.tgz",
-              "integrity": "sha1-qVT5Ma66UI0we78Gnv8MAclhFvc=",
-              "dev": true
-            },
-            "supports-color": {
-              "version": "5.5.0",
-              "resolved": "https://registry.npm.taobao.org/supports-color/download/supports-color-5.5.0.tgz?cache=0&sync_timestamp=1598611730985&other_urls=https%3A%2F%2Fregistry.npm.taobao.org%2Fsupports-color%2Fdownload%2Fsupports-color-5.5.0.tgz",
-              "integrity": "sha1-4uaaRKyHcveKHsCzW2id9lMO/I8=",
-              "dev": true,
-              "requires": {
-                "has-flag": "^3.0.0"
-              }
-            }
-          }
-        },
-        "regenerator-runtime": {
-          "version": "0.13.7",
-          "resolved": "https://registry.npm.taobao.org/regenerator-runtime/download/regenerator-runtime-0.13.7.tgz?cache=0&other_urls=https%3A%2F%2Fregistry.npm.taobao.org%2Fregenerator-runtime%2Fdownload%2Fregenerator-runtime-0.13.7.tgz",
-          "integrity": "sha1-ysLazIoepnX+qrrriugziYrkb1U=",
-          "dev": true
-        },
-        "shebang-command": {
-          "version": "2.0.0",
-          "resolved": "https://registry.npm.taobao.org/shebang-command/download/shebang-command-2.0.0.tgz",
-          "integrity": "sha1-zNCvT4g1+9wmW4JGGq8MNmY/NOo=",
-          "dev": true,
-          "requires": {
-            "shebang-regex": "^3.0.0"
-          }
-        },
-        "shebang-regex": {
-          "version": "3.0.0",
-          "resolved": "https://registry.npm.taobao.org/shebang-regex/download/shebang-regex-3.0.0.tgz",
-          "integrity": "sha1-rhbxZE2HPsrYQ7AwexQzYtTEIXI=",
-          "dev": true
-        },
-        "slash": {
-          "version": "1.0.0",
-          "resolved": "https://registry.npm.taobao.org/slash/download/slash-1.0.0.tgz",
-          "integrity": "sha1-xB8vbDn8FtHNF61LXYlhFK5HDVU=",
-          "dev": true
-        },
-        "string-width": {
-          "version": "4.2.0",
-          "resolved": "https://registry.npm.taobao.org/string-width/download/string-width-4.2.0.tgz",
-          "integrity": "sha1-lSGCxGzHssMT0VluYjmSvRY7crU=",
-          "dev": true,
-          "requires": {
-            "emoji-regex": "^8.0.0",
-            "is-fullwidth-code-point": "^3.0.0",
-            "strip-ansi": "^6.0.0"
-          }
-        },
-        "strip-ansi": {
-          "version": "6.0.0",
-          "resolved": "https://registry.npm.taobao.org/strip-ansi/download/strip-ansi-6.0.0.tgz",
-          "integrity": "sha1-CxVx3XZpzNTz4G4U7x7tJiJa5TI=",
-          "dev": true,
-          "requires": {
-            "ansi-regex": "^5.0.0"
-          }
-        },
-        "supports-color": {
-          "version": "7.2.0",
-          "resolved": "https://registry.npm.taobao.org/supports-color/download/supports-color-7.2.0.tgz?cache=0&sync_timestamp=1598611730985&other_urls=https%3A%2F%2Fregistry.npm.taobao.org%2Fsupports-color%2Fdownload%2Fsupports-color-7.2.0.tgz",
-          "integrity": "sha1-G33NyzK4E4gBs+R4umpRyqiWSNo=",
-          "dev": true,
-          "requires": {
-            "has-flag": "^4.0.0"
-          }
-        },
-        "universalify": {
-          "version": "1.0.0",
-          "resolved": "https://registry.npm.taobao.org/universalify/download/universalify-1.0.0.tgz?cache=0&sync_timestamp=1603180048005&other_urls=https%3A%2F%2Fregistry.npm.taobao.org%2Funiversalify%2Fdownload%2Funiversalify-1.0.0.tgz",
-          "integrity": "sha1-thodoXPoQ1sv48Z9Kbmt+FlL0W0=",
-          "dev": true
-        },
-        "which": {
-          "version": "2.0.2",
-          "resolved": "https://registry.npm.taobao.org/which/download/which-2.0.2.tgz",
-          "integrity": "sha1-fGqN0KY2oDJ+ELWckobu6T8/UbE=",
-          "dev": true,
-          "requires": {
-            "isexe": "^2.0.0"
-          }
-        }
-      }
-    },
-    "@cnakazawa/watch": {
-      "version": "1.0.4",
-      "resolved": "https://registry.npm.taobao.org/@cnakazawa/watch/download/@cnakazawa/watch-1.0.4.tgz",
-      "integrity": "sha1-+GSuhQBND8q29QvpFBxNo2jRZWo=",
-      "dev": true,
-      "requires": {
-        "exec-sh": "^0.3.2",
-        "minimist": "^1.2.0"
-      }
-    },
-    "@commitlint/config-conventional": {
-      "version": "8.3.4",
-      "resolved": "https://registry.npm.taobao.org/@commitlint/config-conventional/download/@commitlint/config-conventional-8.3.4.tgz",
-      "integrity": "sha1-/tE7NxFpBmOxdsH2s5wgWlZWGNI=",
-      "dev": true,
-      "requires": {
-        "conventional-changelog-conventionalcommits": "4.2.1"
-      }
-    },
-    "@formatjs/intl-unified-numberformat": {
-      "version": "3.3.7",
-      "resolved": "https://registry.npm.taobao.org/@formatjs/intl-unified-numberformat/download/@formatjs/intl-unified-numberformat-3.3.7.tgz",
-      "integrity": "sha1-mZWiRWiQgYjnFtgaHeW3ArLuAOI=",
-      "requires": {
-        "@formatjs/intl-utils": "^2.3.0"
-      }
-    },
-    "@formatjs/intl-utils": {
-      "version": "2.3.0",
-      "resolved": "https://registry.npm.taobao.org/@formatjs/intl-utils/download/@formatjs/intl-utils-2.3.0.tgz",
-      "integrity": "sha1-LcjFcETeA0DrU6e6YC5Zq/gNx5k="
-    },
-    "@ice/sandbox": {
-      "version": "1.0.6",
-      "resolved": "https://registry.npm.taobao.org/@ice/sandbox/download/@ice/sandbox-1.0.6.tgz",
-      "integrity": "sha1-z2kKdMJIA2j4eSQ9rOLAEHG5d7c=",
-      "dev": true
-    },
-    "@ice/spec": {
-      "version": "1.0.1",
-      "resolved": "https://registry.npm.taobao.org/@ice/spec/download/@ice/spec-1.0.1.tgz",
-      "integrity": "sha1-tlZSiJ7CdUwYnO1f8VuAbdtiK7M=",
-      "dev": true,
-      "requires": {
-        "@commitlint/config-conventional": "^8.1.0",
-        "@typescript-eslint/eslint-plugin": "^2.20.0",
-        "@typescript-eslint/parser": "^2.20.0",
-        "babel-eslint": "^10.0.2",
-        "eslint-config-airbnb": "^18.0.1",
-        "eslint-config-prettier": "^6.0.0",
-        "eslint-plugin-import": "^2.18.0",
-        "eslint-plugin-jsx-a11y": "^6.2.3",
-        "eslint-plugin-react": "^7.14.2",
-        "eslint-plugin-react-hooks": "^2.4.0",
-        "stylelint-config-css-modules": "^2.2.0",
-        "stylelint-config-prettier": "^8.0.1",
-        "stylelint-config-rational-order": "^0.1.2",
-        "stylelint-config-standard": "^20.0.0",
-        "stylelint-order": "^4.0.0",
-        "stylelint-scss": "^3.14.2"
-      }
-    },
-    "@ice/stark": {
-      "version": "1.6.0",
-      "resolved": "https://registry.npm.taobao.org/@ice/stark/download/@ice/stark-1.6.0.tgz",
-      "integrity": "sha1-IgWzShP9uygXb5e7g42Tlyl8mAo=",
-      "dev": true,
-      "requires": {
-        "@ice/sandbox": "^1.0.4",
-        "lodash.isequal": "^4.5.0",
-        "path-to-regexp": "^1.7.0",
-        "url-parse": "^1.1.9"
-      }
-    },
-    "@ice/stark-app": {
-      "version": "1.2.0",
-      "resolved": "https://registry.npm.taobao.org/@ice/stark-app/download/@ice/stark-app-1.2.0.tgz",
-      "integrity": "sha1-6GcqfazAfe4Ugm3AtTZjki4rn6Y=",
-      "dev": true
-    },
-    "@ice/store": {
-      "version": "1.4.2",
-      "resolved": "https://registry.npm.taobao.org/@ice/store/download/@ice/store-1.4.2.tgz",
-      "integrity": "sha1-t/EOSDic3/Bv14FFFHCL6cWG4AA=",
-      "dev": true,
-      "requires": {
-        "immer": "^6.0.2",
-        "lodash.isfunction": "^3.0.9",
-        "react-redux": "^7.2.0",
-        "redux": "^4.0.5",
-        "redux-thunk": "^2.3.0"
-      },
-      "dependencies": {
-        "immer": {
-          "version": "6.0.9",
-          "resolved": "https://registry.npm.taobao.org/immer/download/immer-6.0.9.tgz?cache=0&sync_timestamp=1603236351037&other_urls=https%3A%2F%2Fregistry.npm.taobao.org%2Fimmer%2Fdownload%2Fimmer-6.0.9.tgz",
-          "integrity": "sha1-ud1puOabOhI5HofbHj/1NdGyZIU=",
-          "dev": true
-        }
-      }
-    },
-    "@icedesign/container": {
-      "version": "1.0.5",
-      "resolved": "https://registry.npm.taobao.org/@icedesign/container/download/@icedesign/container-1.0.5.tgz",
-      "integrity": "sha1-hcV+fZXy5nGt3St3tqy5aItgHZ4=",
-      "requires": {
-        "@alifd/next": "^1.x",
-        "prop-types": "^15.5.8"
-      }
-    },
-    "@icedesign/skin": {
-      "version": "0.1.14",
-      "resolved": "https://registry.npm.taobao.org/@icedesign/skin/download/@icedesign/skin-0.1.14.tgz",
-      "integrity": "sha1-vo5i9Gelouq+efVN4jsJJegw2uI=",
-      "dev": true
-    },
-    "@istanbuljs/load-nyc-config": {
-      "version": "1.1.0",
-      "resolved": "https://registry.npm.taobao.org/@istanbuljs/load-nyc-config/download/@istanbuljs/load-nyc-config-1.1.0.tgz",
-      "integrity": "sha1-/T2x1Z7PfPEh6AZQu4ZxL5tV7O0=",
-      "dev": true,
-      "requires": {
-        "camelcase": "^5.3.1",
-        "find-up": "^4.1.0",
-        "get-package-type": "^0.1.0",
-        "js-yaml": "^3.13.1",
-        "resolve-from": "^5.0.0"
-      },
-      "dependencies": {
-        "camelcase": {
-          "version": "5.3.1",
-          "resolved": "https://registry.npm.taobao.org/camelcase/download/camelcase-5.3.1.tgz?cache=0&sync_timestamp=1603921882890&other_urls=https%3A%2F%2Fregistry.npm.taobao.org%2Fcamelcase%2Fdownload%2Fcamelcase-5.3.1.tgz",
-          "integrity": "sha1-48mzFWnhBoEd8kL3FXJaH0xJQyA=",
-          "dev": true
-        },
-        "find-up": {
-          "version": "4.1.0",
-          "resolved": "https://registry.npm.taobao.org/find-up/download/find-up-4.1.0.tgz?cache=0&sync_timestamp=1597169862146&other_urls=https%3A%2F%2Fregistry.npm.taobao.org%2Ffind-up%2Fdownload%2Ffind-up-4.1.0.tgz",
-          "integrity": "sha1-l6/n1s3AvFkoWEt8jXsW6KmqXRk=",
-          "dev": true,
-          "requires": {
-            "locate-path": "^5.0.0",
-            "path-exists": "^4.0.0"
-          }
-        },
-        "locate-path": {
-          "version": "5.0.0",
-          "resolved": "https://registry.npm.taobao.org/locate-path/download/locate-path-5.0.0.tgz",
-          "integrity": "sha1-Gvujlq/WdqbUJQTQpno6frn2KqA=",
-          "dev": true,
-          "requires": {
-            "p-locate": "^4.1.0"
-          }
-        },
-        "p-limit": {
-          "version": "2.3.0",
-          "resolved": "https://registry.npm.taobao.org/p-limit/download/p-limit-2.3.0.tgz",
-          "integrity": "sha1-PdM8ZHohT9//2DWTPrCG2g3CHbE=",
-          "dev": true,
-          "requires": {
-            "p-try": "^2.0.0"
-          }
-        },
-        "p-locate": {
-          "version": "4.1.0",
-          "resolved": "https://registry.npm.taobao.org/p-locate/download/p-locate-4.1.0.tgz?cache=0&sync_timestamp=1597081508945&other_urls=https%3A%2F%2Fregistry.npm.taobao.org%2Fp-locate%2Fdownload%2Fp-locate-4.1.0.tgz",
-          "integrity": "sha1-o0KLtwiLOmApL2aRkni3wpetTwc=",
-          "dev": true,
-          "requires": {
-            "p-limit": "^2.2.0"
-          }
-        },
-        "p-try": {
-          "version": "2.2.0",
-          "resolved": "https://registry.npm.taobao.org/p-try/download/p-try-2.2.0.tgz",
-          "integrity": "sha1-yyhoVA4xPWHeWPr741zpAE1VQOY=",
-          "dev": true
-        },
-        "path-exists": {
-          "version": "4.0.0",
-          "resolved": "https://registry.npm.taobao.org/path-exists/download/path-exists-4.0.0.tgz",
-          "integrity": "sha1-UTvb4tO5XXdi6METfvoZXGxhtbM=",
-          "dev": true
-        },
-        "resolve-from": {
-          "version": "5.0.0",
-          "resolved": "https://registry.npm.taobao.org/resolve-from/download/resolve-from-5.0.0.tgz",
-          "integrity": "sha1-w1IlhD3493bfIcV1V7wIfp39/Gk=",
-          "dev": true
-        }
-      }
-    },
-    "@istanbuljs/schema": {
-      "version": "0.1.2",
-      "resolved": "https://registry.npm.taobao.org/@istanbuljs/schema/download/@istanbuljs/schema-0.1.2.tgz",
-      "integrity": "sha1-JlIL8Jq+SlZEzVQU43ElqJVCQd0=",
-      "dev": true
-    },
-    "@jest/console": {
-      "version": "26.6.2",
-      "resolved": "https://registry.npm.taobao.org/@jest/console/download/@jest/console-26.6.2.tgz",
-      "integrity": "sha1-TgS8RkAUNYsDq0k3gF7jagrrmPI=",
-      "dev": true,
-      "requires": {
-        "@jest/types": "^26.6.2",
-        "@types/node": "*",
-        "chalk": "^4.0.0",
-        "jest-message-util": "^26.6.2",
-        "jest-util": "^26.6.2",
-        "slash": "^3.0.0"
-      },
-      "dependencies": {
-        "ansi-styles": {
-          "version": "4.3.0",
-          "resolved": "https://registry.npm.taobao.org/ansi-styles/download/ansi-styles-4.3.0.tgz?cache=0&sync_timestamp=1601839122515&other_urls=https%3A%2F%2Fregistry.npm.taobao.org%2Fansi-styles%2Fdownload%2Fansi-styles-4.3.0.tgz",
-          "integrity": "sha1-7dgDYornHATIWuegkG7a00tkiTc=",
-          "dev": true,
-          "requires": {
-            "color-convert": "^2.0.1"
-          }
-        },
-        "chalk": {
-          "version": "4.1.0",
-          "resolved": "https://registry.npm.taobao.org/chalk/download/chalk-4.1.0.tgz",
-          "integrity": "sha1-ThSHCmGNni7dl92DRf2dncMVZGo=",
-          "dev": true,
-          "requires": {
-            "ansi-styles": "^4.1.0",
-            "supports-color": "^7.1.0"
-          }
-        },
-        "color-convert": {
-          "version": "2.0.1",
-          "resolved": "https://registry.npm.taobao.org/color-convert/download/color-convert-2.0.1.tgz",
-          "integrity": "sha1-ctOmjVmMm9s68q0ehPIdiWq9TeM=",
-          "dev": true,
-          "requires": {
-            "color-name": "~1.1.4"
-          }
-        },
-        "color-name": {
-          "version": "1.1.4",
-          "resolved": "https://registry.npm.taobao.org/color-name/download/color-name-1.1.4.tgz",
-          "integrity": "sha1-wqCah6y95pVD3m9j+jmVyCbFNqI=",
-          "dev": true
-        },
-        "has-flag": {
-          "version": "4.0.0",
-          "resolved": "https://registry.npm.taobao.org/has-flag/download/has-flag-4.0.0.tgz?cache=0&sync_timestamp=1596294337050&other_urls=https%3A%2F%2Fregistry.npm.taobao.org%2Fhas-flag%2Fdownload%2Fhas-flag-4.0.0.tgz",
-          "integrity": "sha1-lEdx/ZyByBJlxNaUGGDaBrtZR5s=",
-          "dev": true
-        },
-        "slash": {
-          "version": "3.0.0",
-          "resolved": "https://registry.npm.taobao.org/slash/download/slash-3.0.0.tgz",
-          "integrity": "sha1-ZTm+hwwWWtvVJAIg2+Nh8bxNRjQ=",
-          "dev": true
-        },
-        "supports-color": {
-          "version": "7.2.0",
-          "resolved": "https://registry.npm.taobao.org/supports-color/download/supports-color-7.2.0.tgz?cache=0&sync_timestamp=1598611730985&other_urls=https%3A%2F%2Fregistry.npm.taobao.org%2Fsupports-color%2Fdownload%2Fsupports-color-7.2.0.tgz",
-          "integrity": "sha1-G33NyzK4E4gBs+R4umpRyqiWSNo=",
-          "dev": true,
-          "requires": {
-            "has-flag": "^4.0.0"
-          }
-        }
-      }
-    },
-    "@jest/core": {
-      "version": "26.6.3",
-      "resolved": "https://registry.npm.taobao.org/@jest/core/download/@jest/core-26.6.3.tgz?cache=0&sync_timestamp=1604468975323&other_urls=https%3A%2F%2Fregistry.npm.taobao.org%2F%40jest%2Fcore%2Fdownload%2F%40jest%2Fcore-26.6.3.tgz",
-      "integrity": "sha1-djn8s4M9dIpGVq2lS94ZMFHkX60=",
-      "dev": true,
-      "requires": {
-        "@jest/console": "^26.6.2",
-        "@jest/reporters": "^26.6.2",
-        "@jest/test-result": "^26.6.2",
-        "@jest/transform": "^26.6.2",
-        "@jest/types": "^26.6.2",
-        "@types/node": "*",
-        "ansi-escapes": "^4.2.1",
-        "chalk": "^4.0.0",
-        "exit": "^0.1.2",
-        "graceful-fs": "^4.2.4",
-        "jest-changed-files": "^26.6.2",
-        "jest-config": "^26.6.3",
-        "jest-haste-map": "^26.6.2",
-        "jest-message-util": "^26.6.2",
-        "jest-regex-util": "^26.0.0",
-        "jest-resolve": "^26.6.2",
-        "jest-resolve-dependencies": "^26.6.3",
-        "jest-runner": "^26.6.3",
-        "jest-runtime": "^26.6.3",
-        "jest-snapshot": "^26.6.2",
-        "jest-util": "^26.6.2",
-        "jest-validate": "^26.6.2",
-        "jest-watcher": "^26.6.2",
-        "micromatch": "^4.0.2",
-        "p-each-series": "^2.1.0",
-        "rimraf": "^3.0.0",
-        "slash": "^3.0.0",
-        "strip-ansi": "^6.0.0"
-      },
-      "dependencies": {
-        "ansi-regex": {
-          "version": "5.0.0",
-          "resolved": "https://registry.npm.taobao.org/ansi-regex/download/ansi-regex-5.0.0.tgz",
-          "integrity": "sha1-OIU59VF5vzkznIGvMKZU1p+Hy3U=",
-          "dev": true
-        },
-        "ansi-styles": {
-          "version": "4.3.0",
-          "resolved": "https://registry.npm.taobao.org/ansi-styles/download/ansi-styles-4.3.0.tgz?cache=0&sync_timestamp=1601839122515&other_urls=https%3A%2F%2Fregistry.npm.taobao.org%2Fansi-styles%2Fdownload%2Fansi-styles-4.3.0.tgz",
-          "integrity": "sha1-7dgDYornHATIWuegkG7a00tkiTc=",
-          "dev": true,
-          "requires": {
-            "color-convert": "^2.0.1"
-          }
-        },
-        "braces": {
-          "version": "3.0.2",
-          "resolved": "https://registry.npm.taobao.org/braces/download/braces-3.0.2.tgz",
-          "integrity": "sha1-NFThpGLujVmeI23zNs2epPiv4Qc=",
-          "dev": true,
-          "requires": {
-            "fill-range": "^7.0.1"
-          }
-        },
-        "chalk": {
-          "version": "4.1.0",
-          "resolved": "https://registry.npm.taobao.org/chalk/download/chalk-4.1.0.tgz",
-          "integrity": "sha1-ThSHCmGNni7dl92DRf2dncMVZGo=",
-          "dev": true,
-          "requires": {
-            "ansi-styles": "^4.1.0",
-            "supports-color": "^7.1.0"
-          }
-        },
-        "color-convert": {
-          "version": "2.0.1",
-          "resolved": "https://registry.npm.taobao.org/color-convert/download/color-convert-2.0.1.tgz",
-          "integrity": "sha1-ctOmjVmMm9s68q0ehPIdiWq9TeM=",
-          "dev": true,
-          "requires": {
-            "color-name": "~1.1.4"
-          }
-        },
-        "color-name": {
-          "version": "1.1.4",
-          "resolved": "https://registry.npm.taobao.org/color-name/download/color-name-1.1.4.tgz",
-          "integrity": "sha1-wqCah6y95pVD3m9j+jmVyCbFNqI=",
-          "dev": true
-        },
-        "fill-range": {
-          "version": "7.0.1",
-          "resolved": "https://registry.npm.taobao.org/fill-range/download/fill-range-7.0.1.tgz",
-          "integrity": "sha1-GRmmp8df44ssfHflGYU12prN2kA=",
-          "dev": true,
-          "requires": {
-            "to-regex-range": "^5.0.1"
-          }
-        },
-        "has-flag": {
-          "version": "4.0.0",
-          "resolved": "https://registry.npm.taobao.org/has-flag/download/has-flag-4.0.0.tgz?cache=0&sync_timestamp=1596294337050&other_urls=https%3A%2F%2Fregistry.npm.taobao.org%2Fhas-flag%2Fdownload%2Fhas-flag-4.0.0.tgz",
-          "integrity": "sha1-lEdx/ZyByBJlxNaUGGDaBrtZR5s=",
-          "dev": true
-        },
-        "is-number": {
-          "version": "7.0.0",
-          "resolved": "https://registry.npm.taobao.org/is-number/download/is-number-7.0.0.tgz",
-          "integrity": "sha1-dTU0W4lnNNX4DE0GxQlVUnoU8Ss=",
-          "dev": true
-        },
-        "micromatch": {
-          "version": "4.0.2",
-          "resolved": "https://registry.npm.taobao.org/micromatch/download/micromatch-4.0.2.tgz",
-          "integrity": "sha1-T8sJmb+fvC/L3SEvbWKbmlbDklk=",
-          "dev": true,
-          "requires": {
-            "braces": "^3.0.1",
-            "picomatch": "^2.0.5"
-          }
-        },
-        "rimraf": {
-          "version": "3.0.2",
-          "resolved": "https://registry.npm.taobao.org/rimraf/download/rimraf-3.0.2.tgz?cache=0&sync_timestamp=1587992602190&other_urls=https%3A%2F%2Fregistry.npm.taobao.org%2Frimraf%2Fdownload%2Frimraf-3.0.2.tgz",
-          "integrity": "sha1-8aVAK6YiCtUswSgrrBrjqkn9Bho=",
-          "dev": true,
-          "requires": {
-            "glob": "^7.1.3"
-          }
-        },
-        "slash": {
-          "version": "3.0.0",
-          "resolved": "https://registry.npm.taobao.org/slash/download/slash-3.0.0.tgz",
-          "integrity": "sha1-ZTm+hwwWWtvVJAIg2+Nh8bxNRjQ=",
-          "dev": true
-        },
-        "strip-ansi": {
-          "version": "6.0.0",
-          "resolved": "https://registry.npm.taobao.org/strip-ansi/download/strip-ansi-6.0.0.tgz",
-          "integrity": "sha1-CxVx3XZpzNTz4G4U7x7tJiJa5TI=",
-          "dev": true,
-          "requires": {
-            "ansi-regex": "^5.0.0"
-          }
-        },
-        "supports-color": {
-          "version": "7.2.0",
-          "resolved": "https://registry.npm.taobao.org/supports-color/download/supports-color-7.2.0.tgz?cache=0&sync_timestamp=1598611730985&other_urls=https%3A%2F%2Fregistry.npm.taobao.org%2Fsupports-color%2Fdownload%2Fsupports-color-7.2.0.tgz",
-          "integrity": "sha1-G33NyzK4E4gBs+R4umpRyqiWSNo=",
-          "dev": true,
-          "requires": {
-            "has-flag": "^4.0.0"
-          }
-        },
-        "to-regex-range": {
-          "version": "5.0.1",
-          "resolved": "https://registry.npm.taobao.org/to-regex-range/download/to-regex-range-5.0.1.tgz",
-          "integrity": "sha1-FkjESq58jZiKMmAY7XL1tN0DkuQ=",
-          "dev": true,
-          "requires": {
-            "is-number": "^7.0.0"
-          }
-        }
-      }
-    },
-    "@jest/environment": {
-      "version": "26.6.2",
-      "resolved": "https://registry.npm.taobao.org/@jest/environment/download/@jest/environment-26.6.2.tgz",
-      "integrity": "sha1-ujZMxy4iHnnMjwqZVVv111d8+Sw=",
-      "dev": true,
-      "requires": {
-        "@jest/fake-timers": "^26.6.2",
-        "@jest/types": "^26.6.2",
-        "@types/node": "*",
-        "jest-mock": "^26.6.2"
-      }
-    },
-    "@jest/fake-timers": {
-      "version": "26.6.2",
-      "resolved": "https://registry.npm.taobao.org/@jest/fake-timers/download/@jest/fake-timers-26.6.2.tgz",
-      "integrity": "sha1-RZwym89wzuSvTX4/PmeEgSNTWq0=",
-      "dev": true,
-      "requires": {
-        "@jest/types": "^26.6.2",
-        "@sinonjs/fake-timers": "^6.0.1",
-        "@types/node": "*",
-        "jest-message-util": "^26.6.2",
-        "jest-mock": "^26.6.2",
-        "jest-util": "^26.6.2"
-      }
-    },
-    "@jest/globals": {
-      "version": "26.6.2",
-      "resolved": "https://registry.npm.taobao.org/@jest/globals/download/@jest/globals-26.6.2.tgz?cache=0&sync_timestamp=1604321658564&other_urls=https%3A%2F%2Fregistry.npm.taobao.org%2F%40jest%2Fglobals%2Fdownload%2F%40jest%2Fglobals-26.6.2.tgz",
-      "integrity": "sha1-W2E7eKGqJlWukI66Y4zJaiDfcgo=",
-      "dev": true,
-      "requires": {
-        "@jest/environment": "^26.6.2",
-        "@jest/types": "^26.6.2",
-        "expect": "^26.6.2"
-      }
-    },
-    "@jest/reporters": {
-      "version": "26.6.2",
-      "resolved": "https://registry.npm.taobao.org/@jest/reporters/download/@jest/reporters-26.6.2.tgz",
-      "integrity": "sha1-H1GLmWN6Xxgwe9Ps+SdfaIKmZ/Y=",
-      "dev": true,
-      "requires": {
-        "@bcoe/v8-coverage": "^0.2.3",
-        "@jest/console": "^26.6.2",
-        "@jest/test-result": "^26.6.2",
-        "@jest/transform": "^26.6.2",
-        "@jest/types": "^26.6.2",
-        "chalk": "^4.0.0",
-        "collect-v8-coverage": "^1.0.0",
-        "exit": "^0.1.2",
-        "glob": "^7.1.2",
-        "graceful-fs": "^4.2.4",
-        "istanbul-lib-coverage": "^3.0.0",
-        "istanbul-lib-instrument": "^4.0.3",
-        "istanbul-lib-report": "^3.0.0",
-        "istanbul-lib-source-maps": "^4.0.0",
-        "istanbul-reports": "^3.0.2",
-        "jest-haste-map": "^26.6.2",
-        "jest-resolve": "^26.6.2",
-        "jest-util": "^26.6.2",
-        "jest-worker": "^26.6.2",
-        "node-notifier": "^8.0.0",
-        "slash": "^3.0.0",
-        "source-map": "^0.6.0",
-        "string-length": "^4.0.1",
-        "terminal-link": "^2.0.0",
-        "v8-to-istanbul": "^7.0.0"
-      },
-      "dependencies": {
-        "ansi-styles": {
-          "version": "4.3.0",
-          "resolved": "https://registry.npm.taobao.org/ansi-styles/download/ansi-styles-4.3.0.tgz?cache=0&sync_timestamp=1601839122515&other_urls=https%3A%2F%2Fregistry.npm.taobao.org%2Fansi-styles%2Fdownload%2Fansi-styles-4.3.0.tgz",
-          "integrity": "sha1-7dgDYornHATIWuegkG7a00tkiTc=",
-          "dev": true,
-          "requires": {
-            "color-convert": "^2.0.1"
-          }
-        },
-        "chalk": {
-          "version": "4.1.0",
-          "resolved": "https://registry.npm.taobao.org/chalk/download/chalk-4.1.0.tgz",
-          "integrity": "sha1-ThSHCmGNni7dl92DRf2dncMVZGo=",
-          "dev": true,
-          "requires": {
-            "ansi-styles": "^4.1.0",
-            "supports-color": "^7.1.0"
-          }
-        },
-        "color-convert": {
-          "version": "2.0.1",
-          "resolved": "https://registry.npm.taobao.org/color-convert/download/color-convert-2.0.1.tgz",
-          "integrity": "sha1-ctOmjVmMm9s68q0ehPIdiWq9TeM=",
-          "dev": true,
-          "requires": {
-            "color-name": "~1.1.4"
-          }
-        },
-        "color-name": {
-          "version": "1.1.4",
-          "resolved": "https://registry.npm.taobao.org/color-name/download/color-name-1.1.4.tgz",
-          "integrity": "sha1-wqCah6y95pVD3m9j+jmVyCbFNqI=",
-          "dev": true
-        },
-        "has-flag": {
-          "version": "4.0.0",
-          "resolved": "https://registry.npm.taobao.org/has-flag/download/has-flag-4.0.0.tgz?cache=0&sync_timestamp=1596294337050&other_urls=https%3A%2F%2Fregistry.npm.taobao.org%2Fhas-flag%2Fdownload%2Fhas-flag-4.0.0.tgz",
-          "integrity": "sha1-lEdx/ZyByBJlxNaUGGDaBrtZR5s=",
-          "dev": true
-        },
-        "slash": {
-          "version": "3.0.0",
-          "resolved": "https://registry.npm.taobao.org/slash/download/slash-3.0.0.tgz",
-          "integrity": "sha1-ZTm+hwwWWtvVJAIg2+Nh8bxNRjQ=",
-          "dev": true
-        },
-        "source-map": {
-          "version": "0.6.1",
-          "resolved": "https://registry.npm.taobao.org/source-map/download/source-map-0.6.1.tgz",
-          "integrity": "sha1-dHIq8y6WFOnCh6jQu95IteLxomM=",
-          "dev": true
-        },
-        "supports-color": {
-          "version": "7.2.0",
-          "resolved": "https://registry.npm.taobao.org/supports-color/download/supports-color-7.2.0.tgz?cache=0&sync_timestamp=1598611730985&other_urls=https%3A%2F%2Fregistry.npm.taobao.org%2Fsupports-color%2Fdownload%2Fsupports-color-7.2.0.tgz",
-          "integrity": "sha1-G33NyzK4E4gBs+R4umpRyqiWSNo=",
-          "dev": true,
-          "requires": {
-            "has-flag": "^4.0.0"
-          }
-        }
-      }
-    },
-    "@jest/source-map": {
-      "version": "26.6.2",
-      "resolved": "https://registry.npm.taobao.org/@jest/source-map/download/@jest/source-map-26.6.2.tgz?cache=0&sync_timestamp=1604319711726&other_urls=https%3A%2F%2Fregistry.npm.taobao.org%2F%40jest%2Fsource-map%2Fdownload%2F%40jest%2Fsource-map-26.6.2.tgz",
-      "integrity": "sha1-Ka9eHi4yTK/MyTbyGDCfVKtp1TU=",
-      "dev": true,
-      "requires": {
-        "callsites": "^3.0.0",
-        "graceful-fs": "^4.2.4",
-        "source-map": "^0.6.0"
-      },
-      "dependencies": {
-        "callsites": {
-          "version": "3.1.0",
-          "resolved": "https://registry.npm.taobao.org/callsites/download/callsites-3.1.0.tgz",
-          "integrity": "sha1-s2MKvYlDQy9Us/BRkjjjPNffL3M=",
-          "dev": true
-        },
-        "source-map": {
-          "version": "0.6.1",
-          "resolved": "https://registry.npm.taobao.org/source-map/download/source-map-0.6.1.tgz",
-          "integrity": "sha1-dHIq8y6WFOnCh6jQu95IteLxomM=",
-          "dev": true
-        }
-      }
-    },
-    "@jest/test-result": {
-      "version": "26.6.2",
-      "resolved": "https://registry.npm.taobao.org/@jest/test-result/download/@jest/test-result-26.6.2.tgz",
-      "integrity": "sha1-VdpYti3xNFdsyVR276X3lJ4/Xxg=",
-      "dev": true,
-      "requires": {
-        "@jest/console": "^26.6.2",
-        "@jest/types": "^26.6.2",
-        "@types/istanbul-lib-coverage": "^2.0.0",
-        "collect-v8-coverage": "^1.0.0"
-      }
-    },
-    "@jest/test-sequencer": {
-      "version": "26.6.3",
-      "resolved": "https://registry.npm.taobao.org/@jest/test-sequencer/download/@jest/test-sequencer-26.6.3.tgz?cache=0&sync_timestamp=1604469032027&other_urls=https%3A%2F%2Fregistry.npm.taobao.org%2F%40jest%2Ftest-sequencer%2Fdownload%2F%40jest%2Ftest-sequencer-26.6.3.tgz",
-      "integrity": "sha1-mOikUQCGOIbQdCBej/3Fp+tYKxc=",
-      "dev": true,
-      "requires": {
-        "@jest/test-result": "^26.6.2",
-        "graceful-fs": "^4.2.4",
-        "jest-haste-map": "^26.6.2",
-        "jest-runner": "^26.6.3",
-        "jest-runtime": "^26.6.3"
-      }
-    },
-    "@jest/transform": {
-      "version": "26.6.2",
-      "resolved": "https://registry.npm.taobao.org/@jest/transform/download/@jest/transform-26.6.2.tgz",
-      "integrity": "sha1-WsV8X6GtF7Kq6D5z5FgTiU3PLks=",
-      "dev": true,
-      "requires": {
-        "@babel/core": "^7.1.0",
-        "@jest/types": "^26.6.2",
-        "babel-plugin-istanbul": "^6.0.0",
-        "chalk": "^4.0.0",
-        "convert-source-map": "^1.4.0",
-        "fast-json-stable-stringify": "^2.0.0",
-        "graceful-fs": "^4.2.4",
-        "jest-haste-map": "^26.6.2",
-        "jest-regex-util": "^26.0.0",
-        "jest-util": "^26.6.2",
-        "micromatch": "^4.0.2",
-        "pirates": "^4.0.1",
-        "slash": "^3.0.0",
-        "source-map": "^0.6.1",
-        "write-file-atomic": "^3.0.0"
-      },
-      "dependencies": {
-        "ansi-styles": {
-          "version": "4.3.0",
-          "resolved": "https://registry.npm.taobao.org/ansi-styles/download/ansi-styles-4.3.0.tgz?cache=0&sync_timestamp=1601839122515&other_urls=https%3A%2F%2Fregistry.npm.taobao.org%2Fansi-styles%2Fdownload%2Fansi-styles-4.3.0.tgz",
-          "integrity": "sha1-7dgDYornHATIWuegkG7a00tkiTc=",
-          "dev": true,
-          "requires": {
-            "color-convert": "^2.0.1"
-          }
-        },
-        "braces": {
-          "version": "3.0.2",
-          "resolved": "https://registry.npm.taobao.org/braces/download/braces-3.0.2.tgz",
-          "integrity": "sha1-NFThpGLujVmeI23zNs2epPiv4Qc=",
-          "dev": true,
-          "requires": {
-            "fill-range": "^7.0.1"
-          }
-        },
-        "chalk": {
-          "version": "4.1.0",
-          "resolved": "https://registry.npm.taobao.org/chalk/download/chalk-4.1.0.tgz",
-          "integrity": "sha1-ThSHCmGNni7dl92DRf2dncMVZGo=",
-          "dev": true,
-          "requires": {
-            "ansi-styles": "^4.1.0",
-            "supports-color": "^7.1.0"
-          }
-        },
-        "color-convert": {
-          "version": "2.0.1",
-          "resolved": "https://registry.npm.taobao.org/color-convert/download/color-convert-2.0.1.tgz",
-          "integrity": "sha1-ctOmjVmMm9s68q0ehPIdiWq9TeM=",
-          "dev": true,
-          "requires": {
-            "color-name": "~1.1.4"
-          }
-        },
-        "color-name": {
-          "version": "1.1.4",
-          "resolved": "https://registry.npm.taobao.org/color-name/download/color-name-1.1.4.tgz",
-          "integrity": "sha1-wqCah6y95pVD3m9j+jmVyCbFNqI=",
-          "dev": true
-        },
-        "fill-range": {
-          "version": "7.0.1",
-          "resolved": "https://registry.npm.taobao.org/fill-range/download/fill-range-7.0.1.tgz",
-          "integrity": "sha1-GRmmp8df44ssfHflGYU12prN2kA=",
-          "dev": true,
-          "requires": {
-            "to-regex-range": "^5.0.1"
-          }
-        },
-        "has-flag": {
-          "version": "4.0.0",
-          "resolved": "https://registry.npm.taobao.org/has-flag/download/has-flag-4.0.0.tgz?cache=0&sync_timestamp=1596294337050&other_urls=https%3A%2F%2Fregistry.npm.taobao.org%2Fhas-flag%2Fdownload%2Fhas-flag-4.0.0.tgz",
-          "integrity": "sha1-lEdx/ZyByBJlxNaUGGDaBrtZR5s=",
-          "dev": true
-        },
-        "is-number": {
-          "version": "7.0.0",
-          "resolved": "https://registry.npm.taobao.org/is-number/download/is-number-7.0.0.tgz",
-          "integrity": "sha1-dTU0W4lnNNX4DE0GxQlVUnoU8Ss=",
-          "dev": true
-        },
-        "micromatch": {
-          "version": "4.0.2",
-          "resolved": "https://registry.npm.taobao.org/micromatch/download/micromatch-4.0.2.tgz",
-          "integrity": "sha1-T8sJmb+fvC/L3SEvbWKbmlbDklk=",
-          "dev": true,
-          "requires": {
-            "braces": "^3.0.1",
-            "picomatch": "^2.0.5"
-          }
-        },
-        "slash": {
-          "version": "3.0.0",
-          "resolved": "https://registry.npm.taobao.org/slash/download/slash-3.0.0.tgz",
-          "integrity": "sha1-ZTm+hwwWWtvVJAIg2+Nh8bxNRjQ=",
-          "dev": true
-        },
-        "source-map": {
-          "version": "0.6.1",
-          "resolved": "https://registry.npm.taobao.org/source-map/download/source-map-0.6.1.tgz",
-          "integrity": "sha1-dHIq8y6WFOnCh6jQu95IteLxomM=",
-          "dev": true
-        },
-        "supports-color": {
-          "version": "7.2.0",
-          "resolved": "https://registry.npm.taobao.org/supports-color/download/supports-color-7.2.0.tgz?cache=0&sync_timestamp=1598611730985&other_urls=https%3A%2F%2Fregistry.npm.taobao.org%2Fsupports-color%2Fdownload%2Fsupports-color-7.2.0.tgz",
-          "integrity": "sha1-G33NyzK4E4gBs+R4umpRyqiWSNo=",
-          "dev": true,
-          "requires": {
-            "has-flag": "^4.0.0"
-          }
-        },
-        "to-regex-range": {
-          "version": "5.0.1",
-          "resolved": "https://registry.npm.taobao.org/to-regex-range/download/to-regex-range-5.0.1.tgz",
-          "integrity": "sha1-FkjESq58jZiKMmAY7XL1tN0DkuQ=",
-          "dev": true,
-          "requires": {
-            "is-number": "^7.0.0"
-          }
-        }
-      }
-    },
-    "@jest/types": {
-      "version": "26.6.2",
-      "resolved": "https://registry.npm.taobao.org/@jest/types/download/@jest/types-26.6.2.tgz",
-      "integrity": "sha1-vvWlMgMOHYii9abZM/hOlyJu1I4=",
-      "dev": true,
-      "requires": {
-        "@types/istanbul-lib-coverage": "^2.0.0",
-        "@types/istanbul-reports": "^3.0.0",
-        "@types/node": "*",
-        "@types/yargs": "^15.0.0",
-        "chalk": "^4.0.0"
-      },
-      "dependencies": {
-        "ansi-styles": {
-          "version": "4.3.0",
-          "resolved": "https://registry.npm.taobao.org/ansi-styles/download/ansi-styles-4.3.0.tgz?cache=0&sync_timestamp=1601839122515&other_urls=https%3A%2F%2Fregistry.npm.taobao.org%2Fansi-styles%2Fdownload%2Fansi-styles-4.3.0.tgz",
-          "integrity": "sha1-7dgDYornHATIWuegkG7a00tkiTc=",
-          "dev": true,
-          "requires": {
-            "color-convert": "^2.0.1"
-          }
-        },
-        "chalk": {
-          "version": "4.1.0",
-          "resolved": "https://registry.npm.taobao.org/chalk/download/chalk-4.1.0.tgz",
-          "integrity": "sha1-ThSHCmGNni7dl92DRf2dncMVZGo=",
-          "dev": true,
-          "requires": {
-            "ansi-styles": "^4.1.0",
-            "supports-color": "^7.1.0"
-          }
-        },
-        "color-convert": {
-          "version": "2.0.1",
-          "resolved": "https://registry.npm.taobao.org/color-convert/download/color-convert-2.0.1.tgz",
-          "integrity": "sha1-ctOmjVmMm9s68q0ehPIdiWq9TeM=",
-          "dev": true,
-          "requires": {
-            "color-name": "~1.1.4"
-          }
-        },
-        "color-name": {
-          "version": "1.1.4",
-          "resolved": "https://registry.npm.taobao.org/color-name/download/color-name-1.1.4.tgz",
-          "integrity": "sha1-wqCah6y95pVD3m9j+jmVyCbFNqI=",
-          "dev": true
-        },
-        "has-flag": {
-          "version": "4.0.0",
-          "resolved": "https://registry.npm.taobao.org/has-flag/download/has-flag-4.0.0.tgz?cache=0&sync_timestamp=1596294337050&other_urls=https%3A%2F%2Fregistry.npm.taobao.org%2Fhas-flag%2Fdownload%2Fhas-flag-4.0.0.tgz",
-          "integrity": "sha1-lEdx/ZyByBJlxNaUGGDaBrtZR5s=",
-          "dev": true
-        },
-        "supports-color": {
-          "version": "7.2.0",
-          "resolved": "https://registry.npm.taobao.org/supports-color/download/supports-color-7.2.0.tgz?cache=0&sync_timestamp=1598611730985&other_urls=https%3A%2F%2Fregistry.npm.taobao.org%2Fsupports-color%2Fdownload%2Fsupports-color-7.2.0.tgz",
-          "integrity": "sha1-G33NyzK4E4gBs+R4umpRyqiWSNo=",
-          "dev": true,
-          "requires": {
-            "has-flag": "^4.0.0"
-          }
-        }
-      }
-    },
-    "@mrmlnc/readdir-enhanced": {
-      "version": "2.2.1",
-      "resolved": "https://registry.npm.taobao.org/@mrmlnc/readdir-enhanced/download/@mrmlnc/readdir-enhanced-2.2.1.tgz",
-      "integrity": "sha1-UkryQNGjYFJ7cwR17PoTRKpUDd4=",
-      "dev": true,
-      "requires": {
-        "call-me-maybe": "^1.0.1",
-        "glob-to-regexp": "^0.3.0"
-      }
-    },
-    "@nodelib/fs.scandir": {
-      "version": "2.1.3",
-      "resolved": "https://registry.npm.taobao.org/@nodelib/fs.scandir/download/@nodelib/fs.scandir-2.1.3.tgz",
-      "integrity": "sha1-Olgr21OATGum0UZXnEblITDPSjs=",
-      "dev": true,
-      "requires": {
-        "@nodelib/fs.stat": "2.0.3",
-        "run-parallel": "^1.1.9"
-      },
-      "dependencies": {
-        "@nodelib/fs.stat": {
-          "version": "2.0.3",
-          "resolved": "https://registry.npm.taobao.org/@nodelib/fs.stat/download/@nodelib/fs.stat-2.0.3.tgz",
-          "integrity": "sha1-NNxfTKu8cg9OYPdadH5+zWwXW9M=",
-          "dev": true
-        }
-      }
-    },
-    "@nodelib/fs.stat": {
-      "version": "1.1.3",
-      "resolved": "https://registry.npm.taobao.org/@nodelib/fs.stat/download/@nodelib/fs.stat-1.1.3.tgz",
-      "integrity": "sha1-K1o6s/kYzKSKjHVMCBaOPwPrphs=",
-      "dev": true
-    },
-    "@nodelib/fs.walk": {
-      "version": "1.2.4",
-      "resolved": "https://registry.npm.taobao.org/@nodelib/fs.walk/download/@nodelib/fs.walk-1.2.4.tgz",
-      "integrity": "sha1-ARuSAqcKY2bkNspcBlhEUoqwSXY=",
-      "dev": true,
-      "requires": {
-        "@nodelib/fs.scandir": "2.1.3",
-        "fastq": "^1.6.0"
-      }
-    },
-    "@npmcli/move-file": {
-      "version": "1.0.1",
-      "resolved": "https://registry.npm.taobao.org/@npmcli/move-file/download/@npmcli/move-file-1.0.1.tgz",
-      "integrity": "sha1-3hAwcNrA9IzknPZpPCOvWcD3BGQ=",
-      "dev": true,
-      "requires": {
-        "mkdirp": "^1.0.4"
-      },
-      "dependencies": {
-        "mkdirp": {
-          "version": "1.0.4",
-          "resolved": "https://registry.npm.taobao.org/mkdirp/download/mkdirp-1.0.4.tgz?cache=0&sync_timestamp=1587535418745&other_urls=https%3A%2F%2Fregistry.npm.taobao.org%2Fmkdirp%2Fdownload%2Fmkdirp-1.0.4.tgz",
-          "integrity": "sha1-PrXtYmInVteaXw4qIh3+utdcL34=",
-          "dev": true
-        }
-      }
-    },
-    "@sinonjs/commons": {
-      "version": "1.8.1",
-      "resolved": "https://registry.npm.taobao.org/@sinonjs/commons/download/@sinonjs/commons-1.8.1.tgz?cache=0&sync_timestamp=1594975802135&other_urls=https%3A%2F%2Fregistry.npm.taobao.org%2F%40sinonjs%2Fcommons%2Fdownload%2F%40sinonjs%2Fcommons-1.8.1.tgz",
-      "integrity": "sha1-598A+YogMyT23HzGBsrZ1KirIhc=",
-      "dev": true,
-      "requires": {
-        "type-detect": "4.0.8"
-      }
-    },
-    "@sinonjs/fake-timers": {
-      "version": "6.0.1",
-      "resolved": "https://registry.npm.taobao.org/@sinonjs/fake-timers/download/@sinonjs/fake-timers-6.0.1.tgz",
-      "integrity": "sha1-KTZ0/MsyYqx4LHqt/eyoaxDHXEA=",
-      "dev": true,
-      "requires": {
-        "@sinonjs/commons": "^1.7.0"
-      }
-    },
-    "@stylelint/postcss-css-in-js": {
-      "version": "0.37.2",
-      "resolved": "https://registry.npm.taobao.org/@stylelint/postcss-css-in-js/download/@stylelint/postcss-css-in-js-0.37.2.tgz",
-      "integrity": "sha1-flqErRgfQjSiSAgDQipHuHSa89I=",
-      "dev": true,
-      "requires": {
-        "@babel/core": ">=7.9.0"
-      }
-    },
-    "@stylelint/postcss-markdown": {
-      "version": "0.36.1",
-      "resolved": "https://registry.npm.taobao.org/@stylelint/postcss-markdown/download/@stylelint/postcss-markdown-0.36.1.tgz",
-      "integrity": "sha1-gpuH5sDxCAFFM9nXuYfcnvtmMug=",
-      "dev": true,
-      "requires": {
-        "remark": "^12.0.0",
-        "unist-util-find-all-after": "^3.0.1"
-      },
-      "dependencies": {
-        "is-buffer": {
-          "version": "2.0.5",
-          "resolved": "https://registry.npm.taobao.org/is-buffer/download/is-buffer-2.0.5.tgz?cache=0&sync_timestamp=1604429452232&other_urls=https%3A%2F%2Fregistry.npm.taobao.org%2Fis-buffer%2Fdownload%2Fis-buffer-2.0.5.tgz",
-          "integrity": "sha1-68JS5ADSL/jXf6CYiIIaJKZYwZE=",
-          "dev": true
-        },
-        "is-plain-obj": {
-          "version": "2.1.0",
-          "resolved": "https://registry.npm.taobao.org/is-plain-obj/download/is-plain-obj-2.1.0.tgz?cache=0&sync_timestamp=1602541991817&other_urls=https%3A%2F%2Fregistry.npm.taobao.org%2Fis-plain-obj%2Fdownload%2Fis-plain-obj-2.1.0.tgz",
-          "integrity": "sha1-ReQuN/zPH0Dajl927iFRWEDAkoc=",
-          "dev": true
-        },
-        "markdown-table": {
-          "version": "2.0.0",
-          "resolved": "https://registry.npm.taobao.org/markdown-table/download/markdown-table-2.0.0.tgz",
-          "integrity": "sha1-GUqQztJtMf51PYuUNEMCFMARhls=",
-          "dev": true,
-          "requires": {
-            "repeat-string": "^1.0.0"
-          }
-        },
-        "mdast-util-compact": {
-          "version": "2.0.1",
-          "resolved": "https://registry.npm.taobao.org/mdast-util-compact/download/mdast-util-compact-2.0.1.tgz",
-          "integrity": "sha1-yrxpovQxA2KDJvNbGs9zXVXJlJA=",
-          "dev": true,
-          "requires": {
-            "unist-util-visit": "^2.0.0"
-          }
-        },
-        "parse-entities": {
-          "version": "2.0.0",
-          "resolved": "https://registry.npm.taobao.org/parse-entities/download/parse-entities-2.0.0.tgz",
-          "integrity": "sha1-U8brW5MUofTsmfoP33zgHs2gy+g=",
-          "dev": true,
-          "requires": {
-            "character-entities": "^1.0.0",
-            "character-entities-legacy": "^1.0.0",
-            "character-reference-invalid": "^1.0.0",
-            "is-alphanumerical": "^1.0.0",
-            "is-decimal": "^1.0.0",
-            "is-hexadecimal": "^1.0.0"
-          }
-        },
-        "remark": {
-          "version": "12.0.1",
-          "resolved": "https://registry.npm.taobao.org/remark/download/remark-12.0.1.tgz?cache=0&sync_timestamp=1602663771669&other_urls=https%3A%2F%2Fregistry.npm.taobao.org%2Fremark%2Fdownload%2Fremark-12.0.1.tgz",
-          "integrity": "sha1-8d32jbe+ccorrQozzTZ4uGuccJ8=",
-          "dev": true,
-          "requires": {
-            "remark-parse": "^8.0.0",
-            "remark-stringify": "^8.0.0",
-            "unified": "^9.0.0"
-          }
-        },
-        "remark-parse": {
-          "version": "8.0.3",
-          "resolved": "https://registry.npm.taobao.org/remark-parse/download/remark-parse-8.0.3.tgz?cache=0&sync_timestamp=1602663568829&other_urls=https%3A%2F%2Fregistry.npm.taobao.org%2Fremark-parse%2Fdownload%2Fremark-parse-8.0.3.tgz",
-          "integrity": "sha1-nGKqOzW3mkhkVMaQRykGB19Ax+E=",
-          "dev": true,
-          "requires": {
-            "ccount": "^1.0.0",
-            "collapse-white-space": "^1.0.2",
-            "is-alphabetical": "^1.0.0",
-            "is-decimal": "^1.0.0",
-            "is-whitespace-character": "^1.0.0",
-            "is-word-character": "^1.0.0",
-            "markdown-escapes": "^1.0.0",
-            "parse-entities": "^2.0.0",
-            "repeat-string": "^1.5.4",
-            "state-toggle": "^1.0.0",
-            "trim": "0.0.1",
-            "trim-trailing-lines": "^1.0.0",
-            "unherit": "^1.0.4",
-            "unist-util-remove-position": "^2.0.0",
-            "vfile-location": "^3.0.0",
-            "xtend": "^4.0.1"
-          }
-        },
-        "remark-stringify": {
-          "version": "8.1.1",
-          "resolved": "https://registry.npm.taobao.org/remark-stringify/download/remark-stringify-8.1.1.tgz?cache=0&sync_timestamp=1602663716084&other_urls=https%3A%2F%2Fregistry.npm.taobao.org%2Fremark-stringify%2Fdownload%2Fremark-stringify-8.1.1.tgz",
-          "integrity": "sha1-4qncenv0TkahVex4mW24lngNjOU=",
-          "dev": true,
-          "requires": {
-            "ccount": "^1.0.0",
-            "is-alphanumeric": "^1.0.0",
-            "is-decimal": "^1.0.0",
-            "is-whitespace-character": "^1.0.0",
-            "longest-streak": "^2.0.1",
-            "markdown-escapes": "^1.0.0",
-            "markdown-table": "^2.0.0",
-            "mdast-util-compact": "^2.0.0",
-            "parse-entities": "^2.0.0",
-            "repeat-string": "^1.5.4",
-            "state-toggle": "^1.0.0",
-            "stringify-entities": "^3.0.0",
-            "unherit": "^1.0.4",
-            "xtend": "^4.0.1"
-          }
-        },
-        "stringify-entities": {
-          "version": "3.1.0",
-          "resolved": "https://registry.npm.taobao.org/stringify-entities/download/stringify-entities-3.1.0.tgz?cache=0&sync_timestamp=1603096784534&other_urls=https%3A%2F%2Fregistry.npm.taobao.org%2Fstringify-entities%2Fdownload%2Fstringify-entities-3.1.0.tgz",
-          "integrity": "sha1-uNP+rCVtn/zJ+h/v3PPKcFdu6QM=",
-          "dev": true,
-          "requires": {
-            "character-entities-html4": "^1.0.0",
-            "character-entities-legacy": "^1.0.0",
-            "xtend": "^4.0.0"
-          }
-        },
-        "unified": {
-          "version": "9.2.0",
-          "resolved": "https://registry.npm.taobao.org/unified/download/unified-9.2.0.tgz?cache=0&sync_timestamp=1598031761770&other_urls=https%3A%2F%2Fregistry.npm.taobao.org%2Funified%2Fdownload%2Funified-9.2.0.tgz",
-          "integrity": "sha1-Z6YsYnxAWJ7eu/YPU+39TYIgJ/g=",
-          "dev": true,
-          "requires": {
-            "bail": "^1.0.0",
-            "extend": "^3.0.0",
-            "is-buffer": "^2.0.0",
-            "is-plain-obj": "^2.0.0",
-            "trough": "^1.0.0",
-            "vfile": "^4.0.0"
-          }
-        },
-        "unist-util-find-all-after": {
-          "version": "3.0.2",
-          "resolved": "https://registry.npm.taobao.org/unist-util-find-all-after/download/unist-util-find-all-after-3.0.2.tgz",
-          "integrity": "sha1-/f7NFMW3rqXp7zjV4NX3dO61YfY=",
-          "dev": true,
-          "requires": {
-            "unist-util-is": "^4.0.0"
-          }
-        },
-        "unist-util-is": {
-          "version": "4.0.3",
-          "resolved": "https://registry.npm.taobao.org/unist-util-is/download/unist-util-is-4.0.3.tgz?cache=0&sync_timestamp=1604050976793&other_urls=https%3A%2F%2Fregistry.npm.taobao.org%2Funist-util-is%2Fdownload%2Funist-util-is-4.0.3.tgz",
-          "integrity": "sha1-6LRNtV/CDEN1KzNGwRY0TUXXyR0=",
-          "dev": true
-        },
-        "unist-util-remove-position": {
-          "version": "2.0.1",
-          "resolved": "https://registry.npm.taobao.org/unist-util-remove-position/download/unist-util-remove-position-2.0.1.tgz",
-          "integrity": "sha1-XRnKef26cSMBmZsrc1U8qPOzUsw=",
-          "dev": true,
-          "requires": {
-            "unist-util-visit": "^2.0.0"
-          }
-        },
-        "unist-util-visit": {
-          "version": "2.0.3",
-          "resolved": "https://registry.npm.taobao.org/unist-util-visit/download/unist-util-visit-2.0.3.tgz?cache=0&sync_timestamp=1594459284890&other_urls=https%3A%2F%2Fregistry.npm.taobao.org%2Funist-util-visit%2Fdownload%2Funist-util-visit-2.0.3.tgz",
-          "integrity": "sha1-w3A4kxRt9HIDu4qXla9H17lxIIw=",
-          "dev": true,
-          "requires": {
-            "@types/unist": "^2.0.0",
-            "unist-util-is": "^4.0.0",
-            "unist-util-visit-parents": "^3.0.0"
-          }
-        },
-        "unist-util-visit-parents": {
-          "version": "3.1.1",
-          "resolved": "https://registry.npm.taobao.org/unist-util-visit-parents/download/unist-util-visit-parents-3.1.1.tgz?cache=0&sync_timestamp=1603108482643&other_urls=https%3A%2F%2Fregistry.npm.taobao.org%2Funist-util-visit-parents%2Fdownload%2Funist-util-visit-parents-3.1.1.tgz",
-          "integrity": "sha1-ZabOaY94prD1aqDojxOAGIbNrvY=",
-          "dev": true,
-          "requires": {
-            "@types/unist": "^2.0.0",
-            "unist-util-is": "^4.0.0"
-          }
-        },
-        "vfile": {
-          "version": "4.2.0",
-          "resolved": "https://registry.npm.taobao.org/vfile/download/vfile-4.2.0.tgz?cache=0&sync_timestamp=1596111341065&other_urls=https%3A%2F%2Fregistry.npm.taobao.org%2Fvfile%2Fdownload%2Fvfile-4.2.0.tgz",
-          "integrity": "sha1-JseKyS63CBawHUVl4AO35loqDgE=",
-          "dev": true,
-          "requires": {
-            "@types/unist": "^2.0.0",
-            "is-buffer": "^2.0.0",
-            "replace-ext": "1.0.0",
-            "unist-util-stringify-position": "^2.0.0",
-            "vfile-message": "^2.0.0"
-          }
-        },
-        "vfile-location": {
-          "version": "3.2.0",
-          "resolved": "https://registry.npm.taobao.org/vfile-location/download/vfile-location-3.2.0.tgz?cache=0&sync_timestamp=1604225085911&other_urls=https%3A%2F%2Fregistry.npm.taobao.org%2Fvfile-location%2Fdownload%2Fvfile-location-3.2.0.tgz",
-          "integrity": "sha1-2OQfvL1AYGNmnr9sM9Vq6HIdDzw=",
-          "dev": true
-        }
-      }
-    },
-    "@types/babel__core": {
-      "version": "7.1.12",
-      "resolved": "https://registry.npm.taobao.org/@types/babel__core/download/@types/babel__core-7.1.12.tgz",
-      "integrity": "sha1-TY6eUesmVVKn5PH/IhmrYTO9+y0=",
-      "dev": true,
-      "requires": {
-        "@babel/parser": "^7.1.0",
-        "@babel/types": "^7.0.0",
-        "@types/babel__generator": "*",
-        "@types/babel__template": "*",
-        "@types/babel__traverse": "*"
-      }
-    },
-    "@types/babel__generator": {
-      "version": "7.6.2",
-      "resolved": "https://registry.npm.taobao.org/@types/babel__generator/download/@types/babel__generator-7.6.2.tgz?cache=0&other_urls=https%3A%2F%2Fregistry.npm.taobao.org%2F%40types%2Fbabel__generator%2Fdownload%2F%40types%2Fbabel__generator-7.6.2.tgz",
-      "integrity": "sha1-89cReOGHhY98ReMDgPjxt0FaEtg=",
-      "dev": true,
-      "requires": {
-        "@babel/types": "^7.0.0"
-      }
-    },
-    "@types/babel__template": {
-      "version": "7.4.0",
-      "resolved": "https://registry.npm.taobao.org/@types/babel__template/download/@types/babel__template-7.4.0.tgz",
-      "integrity": "sha1-DIiN1ws+6e67bk8gDoCdoAdiYr4=",
-      "dev": true,
-      "requires": {
-        "@babel/parser": "^7.1.0",
-        "@babel/types": "^7.0.0"
-      }
-    },
-    "@types/babel__traverse": {
-      "version": "7.0.15",
-      "resolved": "https://registry.npm.taobao.org/@types/babel__traverse/download/@types/babel__traverse-7.0.15.tgz",
-      "integrity": "sha1-255COJMetp74qrCtZSPU1MqjnQM=",
-      "dev": true,
-      "requires": {
-        "@babel/types": "^7.3.0"
-      }
-    },
-    "@types/cookie": {
-      "version": "0.3.3",
-      "resolved": "https://registry.npm.taobao.org/@types/cookie/download/@types/cookie-0.3.3.tgz?cache=0&sync_timestamp=1605053525369&other_urls=https%3A%2F%2Fregistry.npm.taobao.org%2F%40types%2Fcookie%2Fdownload%2F%40types%2Fcookie-0.3.3.tgz",
-      "integrity": "sha1-hbx0ungvt6o6UU0RdngysOO8aAM=",
-      "dev": true
-    },
-    "@types/eslint-visitor-keys": {
-      "version": "1.0.0",
-      "resolved": "https://registry.npm.taobao.org/@types/eslint-visitor-keys/download/@types/eslint-visitor-keys-1.0.0.tgz",
-      "integrity": "sha1-HuMNeVRMqE1o1LPNsK9PIFZj3S0=",
-      "dev": true
-    },
-    "@types/glob": {
-      "version": "7.1.3",
-      "resolved": "https://registry.npm.taobao.org/@types/glob/download/@types/glob-7.1.3.tgz?cache=0&sync_timestamp=1605053412496&other_urls=https%3A%2F%2Fregistry.npm.taobao.org%2F%40types%2Fglob%2Fdownload%2F%40types%2Fglob-7.1.3.tgz",
-      "integrity": "sha1-5rqA82t9qtLGhazZJmOC5omFwYM=",
-      "dev": true,
-      "requires": {
-        "@types/minimatch": "*",
-        "@types/node": "*"
-      }
-    },
-    "@types/graceful-fs": {
-      "version": "4.1.4",
-      "resolved": "https://registry.npm.taobao.org/@types/graceful-fs/download/@types/graceful-fs-4.1.4.tgz?cache=0&sync_timestamp=1605053615976&other_urls=https%3A%2F%2Fregistry.npm.taobao.org%2F%40types%2Fgraceful-fs%2Fdownload%2F%40types%2Fgraceful-fs-4.1.4.tgz",
-      "integrity": "sha1-T/n2QafG0aNQj/iLwxQbFSdy51M=",
-      "dev": true,
-      "requires": {
-        "@types/node": "*"
-      }
-    },
-    "@types/istanbul-lib-coverage": {
-      "version": "2.0.3",
-      "resolved": "https://registry.npm.taobao.org/@types/istanbul-lib-coverage/download/@types/istanbul-lib-coverage-2.0.3.tgz?cache=0&sync_timestamp=1605054056155&other_urls=https%3A%2F%2Fregistry.npm.taobao.org%2F%40types%2Fistanbul-lib-coverage%2Fdownload%2F%40types%2Fistanbul-lib-coverage-2.0.3.tgz",
-      "integrity": "sha1-S6jdtyAiH0MuRDvV+RF/0iz9R2I=",
-      "dev": true
-    },
-    "@types/istanbul-lib-report": {
-      "version": "3.0.0",
-      "resolved": "https://registry.npm.taobao.org/@types/istanbul-lib-report/download/@types/istanbul-lib-report-3.0.0.tgz?cache=0&sync_timestamp=1605054055971&other_urls=https%3A%2F%2Fregistry.npm.taobao.org%2F%40types%2Fistanbul-lib-report%2Fdownload%2F%40types%2Fistanbul-lib-report-3.0.0.tgz",
-      "integrity": "sha1-wUwk8Y6oGQwRjudWK3/5mjZVJoY=",
-      "dev": true,
-      "requires": {
-        "@types/istanbul-lib-coverage": "*"
-      }
-    },
-    "@types/istanbul-reports": {
-      "version": "3.0.0",
-      "resolved": "https://registry.npm.taobao.org/@types/istanbul-reports/download/@types/istanbul-reports-3.0.0.tgz?cache=0&sync_timestamp=1605054056153&other_urls=https%3A%2F%2Fregistry.npm.taobao.org%2F%40types%2Fistanbul-reports%2Fdownload%2F%40types%2Fistanbul-reports-3.0.0.tgz",
-      "integrity": "sha1-UIsTqjRPpJdiNOdd3cw0klc32CE=",
-      "dev": true,
-      "requires": {
-        "@types/istanbul-lib-report": "*"
-      }
-    },
-    "@types/json-schema": {
-      "version": "7.0.6",
-      "resolved": "https://registry.npm.taobao.org/@types/json-schema/download/@types/json-schema-7.0.6.tgz?cache=0&sync_timestamp=1605053861867&other_urls=https%3A%2F%2Fregistry.npm.taobao.org%2F%40types%2Fjson-schema%2Fdownload%2F%40types%2Fjson-schema-7.0.6.tgz",
-      "integrity": "sha1-9MfsQ+gbMZqYFRFQMXCfJph4kfA=",
-      "dev": true
-    },
-    "@types/json5": {
-      "version": "0.0.29",
-      "resolved": "https://registry.npm.taobao.org/@types/json5/download/@types/json5-0.0.29.tgz?cache=0&sync_timestamp=1605054241417&other_urls=https%3A%2F%2Fregistry.npm.taobao.org%2F%40types%2Fjson5%2Fdownload%2F%40types%2Fjson5-0.0.29.tgz",
-      "integrity": "sha1-7ihweulOEdK4J7y+UnC86n8+ce4=",
-      "dev": true
-    },
-    "@types/minimatch": {
-      "version": "3.0.3",
-      "resolved": "https://registry.npm.taobao.org/@types/minimatch/download/@types/minimatch-3.0.3.tgz",
-      "integrity": "sha1-PcoOPzOyAPx9ETnAzZbBJoyt/Z0=",
-      "dev": true
-    },
-    "@types/minimist": {
-      "version": "1.2.1",
-      "resolved": "https://registry.npm.taobao.org/@types/minimist/download/@types/minimist-1.2.1.tgz",
-      "integrity": "sha1-KD9mn/dte4Jg34q3pCYsyD2YglY=",
-      "dev": true
-    },
-    "@types/node": {
-      "version": "14.14.7",
-      "resolved": "https://registry.npm.taobao.org/@types/node/download/@types/node-14.14.7.tgz",
-      "integrity": "sha1-jqHo+OriQwz0QFZLmMbfzh7FlF0=",
-      "dev": true
-    },
-    "@types/normalize-package-data": {
-      "version": "2.4.0",
-      "resolved": "https://registry.npm.taobao.org/@types/normalize-package-data/download/@types/normalize-package-data-2.4.0.tgz?cache=0&sync_timestamp=1605054933259&other_urls=https%3A%2F%2Fregistry.npm.taobao.org%2F%40types%2Fnormalize-package-data%2Fdownload%2F%40types%2Fnormalize-package-data-2.4.0.tgz",
-      "integrity": "sha1-5IbQ2XOW15vu3QpuM/RTT/a0lz4=",
-      "dev": true
-    },
-    "@types/npmlog": {
-      "version": "4.1.2",
-      "resolved": "https://registry.npm.taobao.org/@types/npmlog/download/@types/npmlog-4.1.2.tgz?cache=0&sync_timestamp=1605055837348&other_urls=https%3A%2F%2Fregistry.npm.taobao.org%2F%40types%2Fnpmlog%2Fdownload%2F%40types%2Fnpmlog-4.1.2.tgz",
-      "integrity": "sha1-0HD+amt4dV0QkqPcSS00w9j4ccQ=",
-      "dev": true
-    },
-    "@types/parse-json": {
-      "version": "4.0.0",
-      "resolved": "https://registry.npm.taobao.org/@types/parse-json/download/@types/parse-json-4.0.0.tgz?cache=0&sync_timestamp=1605054934191&other_urls=https%3A%2F%2Fregistry.npm.taobao.org%2F%40types%2Fparse-json%2Fdownload%2F%40types%2Fparse-json-4.0.0.tgz",
-      "integrity": "sha1-L4u0QUNNFjs1+4/9zNcTiSf/uMA=",
-      "dev": true
-    },
-    "@types/prettier": {
-      "version": "2.1.5",
-      "resolved": "https://registry.npm.taobao.org/@types/prettier/download/@types/prettier-2.1.5.tgz",
-      "integrity": "sha1-tqs7uinha4IdhOCez63tRiuBawA=",
-      "dev": true
-    },
-    "@types/prop-types": {
-      "version": "15.7.3",
-      "resolved": "https://registry.npm.taobao.org/@types/prop-types/download/@types/prop-types-15.7.3.tgz?cache=0&sync_timestamp=1605055388480&other_urls=https%3A%2F%2Fregistry.npm.taobao.org%2F%40types%2Fprop-types%2Fdownload%2F%40types%2Fprop-types-15.7.3.tgz",
-      "integrity": "sha1-KrDV2i5YFflLC51LldHl8kOrLKc="
-    },
-    "@types/q": {
-      "version": "1.5.4",
-      "resolved": "https://registry.npm.taobao.org/@types/q/download/@types/q-1.5.4.tgz?cache=0&sync_timestamp=1605055096527&other_urls=https%3A%2F%2Fregistry.npm.taobao.org%2F%40types%2Fq%2Fdownload%2F%40types%2Fq-1.5.4.tgz",
-      "integrity": "sha1-FZJUFOCtLNdlv+9YhC9+JqesyyQ=",
-      "dev": true
-    },
-    "@types/react": {
-      "version": "16.9.56",
-      "resolved": "https://registry.npm.taobao.org/@types/react/download/@types/react-16.9.56.tgz?cache=0&sync_timestamp=1604651654114&other_urls=https%3A%2F%2Fregistry.npm.taobao.org%2F%40types%2Freact%2Fdownload%2F%40types%2Freact-16.9.56.tgz",
-      "integrity": "sha1-6iWEe1PFvsBkkzCV/DZrFGLirfA=",
-      "requires": {
-        "@types/prop-types": "*",
-        "csstype": "^3.0.2"
-      }
-    },
-    "@types/react-dom": {
-      "version": "16.9.9",
-      "resolved": "https://registry.npm.taobao.org/@types/react-dom/download/@types/react-dom-16.9.9.tgz?cache=0&sync_timestamp=1605055329509&other_urls=https%3A%2F%2Fregistry.npm.taobao.org%2F%40types%2Freact-dom%2Fdownload%2F%40types%2Freact-dom-16.9.9.tgz",
-      "integrity": "sha1-0tCm9yCgIGNpzL7/91K6N7lYMTY=",
-      "requires": {
-        "@types/react": "*"
-      }
-    },
-    "@types/stack-utils": {
-      "version": "2.0.0",
-      "resolved": "https://registry.npm.taobao.org/@types/stack-utils/download/@types/stack-utils-2.0.0.tgz",
-      "integrity": "sha1-cDZkC04hzC8lmugmzoQ9J32tjP8=",
-      "dev": true
-    },
-    "@types/unist": {
-      "version": "2.0.3",
-      "resolved": "https://registry.npm.taobao.org/@types/unist/download/@types/unist-2.0.3.tgz",
-      "integrity": "sha1-nAiGeYdvN061mD8VDUeHqm+zLX4=",
-      "dev": true
-    },
-    "@types/url-parse": {
-      "version": "1.4.3",
-      "resolved": "https://registry.npm.taobao.org/@types/url-parse/download/@types/url-parse-1.4.3.tgz?cache=0&sync_timestamp=1605057382227&other_urls=https%3A%2F%2Fregistry.npm.taobao.org%2F%40types%2Furl-parse%2Fdownload%2F%40types%2Furl-parse-1.4.3.tgz",
-      "integrity": "sha1-+6SdkPg0lRywAKZ07+49byCWgyk=",
-      "dev": true
-    },
-    "@types/vfile": {
-      "version": "3.0.2",
-      "resolved": "https://registry.npm.taobao.org/@types/vfile/download/@types/vfile-3.0.2.tgz",
-      "integrity": "sha1-GcGM0jLfEc5vpq2AJZvIbDZrCbk=",
-      "dev": true,
-      "requires": {
-        "@types/node": "*",
-        "@types/unist": "*",
-        "@types/vfile-message": "*"
-      }
-    },
-    "@types/vfile-message": {
-      "version": "2.0.0",
-      "resolved": "https://registry.npm.taobao.org/@types/vfile-message/download/@types/vfile-message-2.0.0.tgz",
-      "integrity": "sha1-aQ5Grw/fwfn6rgDNBJzIiJV5J9U=",
-      "dev": true,
-      "requires": {
-        "vfile-message": "*"
-      }
-    },
-    "@types/yargs": {
-      "version": "15.0.9",
-      "resolved": "https://registry.npm.taobao.org/@types/yargs/download/@types/yargs-15.0.9.tgz?cache=0&sync_timestamp=1605057458388&other_urls=https%3A%2F%2Fregistry.npm.taobao.org%2F%40types%2Fyargs%2Fdownload%2F%40types%2Fyargs-15.0.9.tgz",
-      "integrity": "sha1-UkzXmY/oEM2wLyYQG2mczNFW/xk=",
-      "dev": true,
-      "requires": {
-        "@types/yargs-parser": "*"
-      }
-    },
-    "@types/yargs-parser": {
-      "version": "15.0.0",
-      "resolved": "https://registry.npm.taobao.org/@types/yargs-parser/download/@types/yargs-parser-15.0.0.tgz?cache=0&sync_timestamp=1605057457263&other_urls=https%3A%2F%2Fregistry.npm.taobao.org%2F%40types%2Fyargs-parser%2Fdownload%2F%40types%2Fyargs-parser-15.0.0.tgz",
-      "integrity": "sha1-yz+fdBhp4gzOMw/765JxWQSDiC0=",
-      "dev": true
-    },
-    "@typescript-eslint/eslint-plugin": {
-      "version": "2.34.0",
-      "resolved": "https://registry.npm.taobao.org/@typescript-eslint/eslint-plugin/download/@typescript-eslint/eslint-plugin-2.34.0.tgz",
-      "integrity": "sha1-b4zopGx96kpvHRcdK7j7rm2sK+k=",
-      "dev": true,
-      "requires": {
-        "@typescript-eslint/experimental-utils": "2.34.0",
-        "functional-red-black-tree": "^1.0.1",
-        "regexpp": "^3.0.0",
-        "tsutils": "^3.17.1"
-      }
-    },
-    "@typescript-eslint/experimental-utils": {
-      "version": "2.34.0",
-      "resolved": "https://registry.npm.taobao.org/@typescript-eslint/experimental-utils/download/@typescript-eslint/experimental-utils-2.34.0.tgz?cache=0&sync_timestamp=1605227301184&other_urls=https%3A%2F%2Fregistry.npm.taobao.org%2F%40typescript-eslint%2Fexperimental-utils%2Fdownload%2F%40typescript-eslint%2Fexperimental-utils-2.34.0.tgz",
-      "integrity": "sha1-01JLZEzbQO687KZ/jPPkzJyPmA8=",
-      "dev": true,
-      "requires": {
-        "@types/json-schema": "^7.0.3",
-        "@typescript-eslint/typescript-estree": "2.34.0",
-        "eslint-scope": "^5.0.0",
-        "eslint-utils": "^2.0.0"
-      }
-    },
-    "@typescript-eslint/parser": {
-      "version": "2.34.0",
-      "resolved": "https://registry.npm.taobao.org/@typescript-eslint/parser/download/@typescript-eslint/parser-2.34.0.tgz",
-      "integrity": "sha1-UCUmMMoxloVCDpo5ygX+GFola8g=",
-      "dev": true,
-      "requires": {
-        "@types/eslint-visitor-keys": "^1.0.0",
-        "@typescript-eslint/experimental-utils": "2.34.0",
-        "@typescript-eslint/typescript-estree": "2.34.0",
-        "eslint-visitor-keys": "^1.1.0"
-      }
-    },
-    "@typescript-eslint/typescript-estree": {
-      "version": "2.34.0",
-      "resolved": "https://registry.npm.taobao.org/@typescript-eslint/typescript-estree/download/@typescript-eslint/typescript-estree-2.34.0.tgz?cache=0&sync_timestamp=1605227303561&other_urls=https%3A%2F%2Fregistry.npm.taobao.org%2F%40typescript-eslint%2Ftypescript-estree%2Fdownload%2F%40typescript-eslint%2Ftypescript-estree-2.34.0.tgz",
-      "integrity": "sha1-FK62NTs57wcyzH8bgoUpSTfPN9U=",
-      "dev": true,
-      "requires": {
-        "debug": "^4.1.1",
-        "eslint-visitor-keys": "^1.1.0",
-        "glob": "^7.1.6",
-        "is-glob": "^4.0.1",
-        "lodash": "^4.17.15",
-        "semver": "^7.3.2",
-        "tsutils": "^3.17.1"
-      }
-    },
-    "@webassemblyjs/ast": {
-      "version": "1.9.0",
-      "resolved": "https://registry.npm.taobao.org/@webassemblyjs/ast/download/@webassemblyjs/ast-1.9.0.tgz?cache=0&sync_timestamp=1601756233286&other_urls=https%3A%2F%2Fregistry.npm.taobao.org%2F%40webassemblyjs%2Fast%2Fdownload%2F%40webassemblyjs%2Fast-1.9.0.tgz",
-      "integrity": "sha1-vYUGBLQEJFmlpBzX0zjL7Wle2WQ=",
-      "dev": true,
-      "requires": {
-        "@webassemblyjs/helper-module-context": "1.9.0",
-        "@webassemblyjs/helper-wasm-bytecode": "1.9.0",
-        "@webassemblyjs/wast-parser": "1.9.0"
-      }
-    },
-    "@webassemblyjs/floating-point-hex-parser": {
-      "version": "1.9.0",
-      "resolved": "https://registry.npm.taobao.org/@webassemblyjs/floating-point-hex-parser/download/@webassemblyjs/floating-point-hex-parser-1.9.0.tgz?cache=0&sync_timestamp=1601756232132&other_urls=https%3A%2F%2Fregistry.npm.taobao.org%2F%40webassemblyjs%2Ffloating-point-hex-parser%2Fdownload%2F%40webassemblyjs%2Ffloating-point-hex-parser-1.9.0.tgz",
-      "integrity": "sha1-PD07Jxvd/ITesA9xNEQ4MR1S/7Q=",
-      "dev": true
-    },
-    "@webassemblyjs/helper-api-error": {
-      "version": "1.9.0",
-      "resolved": "https://registry.npm.taobao.org/@webassemblyjs/helper-api-error/download/@webassemblyjs/helper-api-error-1.9.0.tgz?cache=0&sync_timestamp=1601756232631&other_urls=https%3A%2F%2Fregistry.npm.taobao.org%2F%40webassemblyjs%2Fhelper-api-error%2Fdownload%2F%40webassemblyjs%2Fhelper-api-error-1.9.0.tgz",
-      "integrity": "sha1-ID9nbjM7lsnaLuqzzO8zxFkotqI=",
-      "dev": true
-    },
-    "@webassemblyjs/helper-buffer": {
-      "version": "1.9.0",
-      "resolved": "https://registry.npm.taobao.org/@webassemblyjs/helper-buffer/download/@webassemblyjs/helper-buffer-1.9.0.tgz?cache=0&sync_timestamp=1601756248143&other_urls=https%3A%2F%2Fregistry.npm.taobao.org%2F%40webassemblyjs%2Fhelper-buffer%2Fdownload%2F%40webassemblyjs%2Fhelper-buffer-1.9.0.tgz",
-      "integrity": "sha1-oUQtJpxf6yP8vJ73WdrDVH8p3gA=",
-      "dev": true
-    },
-    "@webassemblyjs/helper-code-frame": {
-      "version": "1.9.0",
-      "resolved": "https://registry.npm.taobao.org/@webassemblyjs/helper-code-frame/download/@webassemblyjs/helper-code-frame-1.9.0.tgz?cache=0&sync_timestamp=1601756233909&other_urls=https%3A%2F%2Fregistry.npm.taobao.org%2F%40webassemblyjs%2Fhelper-code-frame%2Fdownload%2F%40webassemblyjs%2Fhelper-code-frame-1.9.0.tgz",
-      "integrity": "sha1-ZH+Iks0gQ6gqwMjF51w28dkVnyc=",
-      "dev": true,
-      "requires": {
-        "@webassemblyjs/wast-printer": "1.9.0"
-      }
-    },
-    "@webassemblyjs/helper-fsm": {
-      "version": "1.9.0",
-      "resolved": "https://registry.npm.taobao.org/@webassemblyjs/helper-fsm/download/@webassemblyjs/helper-fsm-1.9.0.tgz?cache=0&sync_timestamp=1601756231939&other_urls=https%3A%2F%2Fregistry.npm.taobao.org%2F%40webassemblyjs%2Fhelper-fsm%2Fdownload%2F%40webassemblyjs%2Fhelper-fsm-1.9.0.tgz",
-      "integrity": "sha1-wFJWtxJEIUZx9LCOwQitY7cO3bg=",
-      "dev": true
-    },
-    "@webassemblyjs/helper-module-context": {
-      "version": "1.9.0",
-      "resolved": "https://registry.npm.taobao.org/@webassemblyjs/helper-module-context/download/@webassemblyjs/helper-module-context-1.9.0.tgz?cache=0&sync_timestamp=1601756234776&other_urls=https%3A%2F%2Fregistry.npm.taobao.org%2F%40webassemblyjs%2Fhelper-module-context%2Fdownload%2F%40webassemblyjs%2Fhelper-module-context-1.9.0.tgz",
-      "integrity": "sha1-JdiIS3aDmHGgimxvgGw5ee9xLwc=",
-      "dev": true,
-      "requires": {
-        "@webassemblyjs/ast": "1.9.0"
-      }
-    },
-    "@webassemblyjs/helper-wasm-bytecode": {
-      "version": "1.9.0",
-      "resolved": "https://registry.npm.taobao.org/@webassemblyjs/helper-wasm-bytecode/download/@webassemblyjs/helper-wasm-bytecode-1.9.0.tgz?cache=0&sync_timestamp=1601756232301&other_urls=https%3A%2F%2Fregistry.npm.taobao.org%2F%40webassemblyjs%2Fhelper-wasm-bytecode%2Fdownload%2F%40webassemblyjs%2Fhelper-wasm-bytecode-1.9.0.tgz",
-      "integrity": "sha1-T+2L6sm4wU+MWLcNEk1UndH+V5A=",
-      "dev": true
-    },
-    "@webassemblyjs/helper-wasm-section": {
-      "version": "1.9.0",
-      "resolved": "https://registry.npm.taobao.org/@webassemblyjs/helper-wasm-section/download/@webassemblyjs/helper-wasm-section-1.9.0.tgz?cache=0&sync_timestamp=1601756234204&other_urls=https%3A%2F%2Fregistry.npm.taobao.org%2F%40webassemblyjs%2Fhelper-wasm-section%2Fdownload%2F%40webassemblyjs%2Fhelper-wasm-section-1.9.0.tgz",
-      "integrity": "sha1-WkE41aYpK6GLBMWuSXF+QWeWU0Y=",
-      "dev": true,
-      "requires": {
-        "@webassemblyjs/ast": "1.9.0",
-        "@webassemblyjs/helper-buffer": "1.9.0",
-        "@webassemblyjs/helper-wasm-bytecode": "1.9.0",
-        "@webassemblyjs/wasm-gen": "1.9.0"
-      }
-    },
-    "@webassemblyjs/ieee754": {
-      "version": "1.9.0",
-      "resolved": "https://registry.npm.taobao.org/@webassemblyjs/ieee754/download/@webassemblyjs/ieee754-1.9.0.tgz?cache=0&sync_timestamp=1601756232741&other_urls=https%3A%2F%2Fregistry.npm.taobao.org%2F%40webassemblyjs%2Fieee754%2Fdownload%2F%40webassemblyjs%2Fieee754-1.9.0.tgz",
-      "integrity": "sha1-Fceg+6roP7JhQ7us9tbfFwKtOeQ=",
-      "dev": true,
-      "requires": {
-        "@xtuc/ieee754": "^1.2.0"
-      }
-    },
-    "@webassemblyjs/leb128": {
-      "version": "1.9.0",
-      "resolved": "https://registry.npm.taobao.org/@webassemblyjs/leb128/download/@webassemblyjs/leb128-1.9.0.tgz?cache=0&sync_timestamp=1601756232514&other_urls=https%3A%2F%2Fregistry.npm.taobao.org%2F%40webassemblyjs%2Fleb128%2Fdownload%2F%40webassemblyjs%2Fleb128-1.9.0.tgz",
-      "integrity": "sha1-8Zygt2ptxVYjoJz/p2noOPoeHJU=",
-      "dev": true,
-      "requires": {
-        "@xtuc/long": "4.2.2"
-      }
-    },
-    "@webassemblyjs/utf8": {
-      "version": "1.9.0",
-      "resolved": "https://registry.npm.taobao.org/@webassemblyjs/utf8/download/@webassemblyjs/utf8-1.9.0.tgz?cache=0&sync_timestamp=1601756233013&other_urls=https%3A%2F%2Fregistry.npm.taobao.org%2F%40webassemblyjs%2Futf8%2Fdownload%2F%40webassemblyjs%2Futf8-1.9.0.tgz",
-      "integrity": "sha1-BNM7Y2945qaBMifoJAL3Y3tiKas=",
-      "dev": true
-    },
-    "@webassemblyjs/wasm-edit": {
-      "version": "1.9.0",
-      "resolved": "https://registry.npm.taobao.org/@webassemblyjs/wasm-edit/download/@webassemblyjs/wasm-edit-1.9.0.tgz?cache=0&sync_timestamp=1601756233442&other_urls=https%3A%2F%2Fregistry.npm.taobao.org%2F%40webassemblyjs%2Fwasm-edit%2Fdownload%2F%40webassemblyjs%2Fwasm-edit-1.9.0.tgz",
-      "integrity": "sha1-P+bXnT8PkiGDqoYALELdJWz+6c8=",
-      "dev": true,
-      "requires": {
-        "@webassemblyjs/ast": "1.9.0",
-        "@webassemblyjs/helper-buffer": "1.9.0",
-        "@webassemblyjs/helper-wasm-bytecode": "1.9.0",
-        "@webassemblyjs/helper-wasm-section": "1.9.0",
-        "@webassemblyjs/wasm-gen": "1.9.0",
-        "@webassemblyjs/wasm-opt": "1.9.0",
-        "@webassemblyjs/wasm-parser": "1.9.0",
-        "@webassemblyjs/wast-printer": "1.9.0"
-      }
-    },
-    "@webassemblyjs/wasm-gen": {
-      "version": "1.9.0",
-      "resolved": "https://registry.npm.taobao.org/@webassemblyjs/wasm-gen/download/@webassemblyjs/wasm-gen-1.9.0.tgz?cache=0&sync_timestamp=1601756234341&other_urls=https%3A%2F%2Fregistry.npm.taobao.org%2F%40webassemblyjs%2Fwasm-gen%2Fdownload%2F%40webassemblyjs%2Fwasm-gen-1.9.0.tgz",
-      "integrity": "sha1-ULxw7Gje2OJ2OwGhQYv0NJGnpJw=",
-      "dev": true,
-      "requires": {
-        "@webassemblyjs/ast": "1.9.0",
-        "@webassemblyjs/helper-wasm-bytecode": "1.9.0",
-        "@webassemblyjs/ieee754": "1.9.0",
-        "@webassemblyjs/leb128": "1.9.0",
-        "@webassemblyjs/utf8": "1.9.0"
-      }
-    },
-    "@webassemblyjs/wasm-opt": {
-      "version": "1.9.0",
-      "resolved": "https://registry.npm.taobao.org/@webassemblyjs/wasm-opt/download/@webassemblyjs/wasm-opt-1.9.0.tgz?cache=0&sync_timestamp=1601756233142&other_urls=https%3A%2F%2Fregistry.npm.taobao.org%2F%40webassemblyjs%2Fwasm-opt%2Fdownload%2F%40webassemblyjs%2Fwasm-opt-1.9.0.tgz",
-      "integrity": "sha1-IhEYHlsxMmRDzIES658LkChyGmE=",
-      "dev": true,
-      "requires": {
-        "@webassemblyjs/ast": "1.9.0",
-        "@webassemblyjs/helper-buffer": "1.9.0",
-        "@webassemblyjs/wasm-gen": "1.9.0",
-        "@webassemblyjs/wasm-parser": "1.9.0"
-      }
-    },
-    "@webassemblyjs/wasm-parser": {
-      "version": "1.9.0",
-      "resolved": "https://registry.npm.taobao.org/@webassemblyjs/wasm-parser/download/@webassemblyjs/wasm-parser-1.9.0.tgz?cache=0&sync_timestamp=1601756233776&other_urls=https%3A%2F%2Fregistry.npm.taobao.org%2F%40webassemblyjs%2Fwasm-parser%2Fdownload%2F%40webassemblyjs%2Fwasm-parser-1.9.0.tgz",
-      "integrity": "sha1-nUjkSCbfSmWYKUqmyHRp1kL/9l4=",
-      "dev": true,
-      "requires": {
-        "@webassemblyjs/ast": "1.9.0",
-        "@webassemblyjs/helper-api-error": "1.9.0",
-        "@webassemblyjs/helper-wasm-bytecode": "1.9.0",
-        "@webassemblyjs/ieee754": "1.9.0",
-        "@webassemblyjs/leb128": "1.9.0",
-        "@webassemblyjs/utf8": "1.9.0"
-      }
-    },
-    "@webassemblyjs/wast-parser": {
-      "version": "1.9.0",
-      "resolved": "https://registry.npm.taobao.org/@webassemblyjs/wast-parser/download/@webassemblyjs/wast-parser-1.9.0.tgz?cache=0&sync_timestamp=1601756234653&other_urls=https%3A%2F%2Fregistry.npm.taobao.org%2F%40webassemblyjs%2Fwast-parser%2Fdownload%2F%40webassemblyjs%2Fwast-parser-1.9.0.tgz",
-      "integrity": "sha1-MDERXXmsW9JhVWzsw/qQo+9FGRQ=",
-      "dev": true,
-      "requires": {
-        "@webassemblyjs/ast": "1.9.0",
-        "@webassemblyjs/floating-point-hex-parser": "1.9.0",
-        "@webassemblyjs/helper-api-error": "1.9.0",
-        "@webassemblyjs/helper-code-frame": "1.9.0",
-        "@webassemblyjs/helper-fsm": "1.9.0",
-        "@xtuc/long": "4.2.2"
-      }
-    },
-    "@webassemblyjs/wast-printer": {
-      "version": "1.9.0",
-      "resolved": "https://registry.npm.taobao.org/@webassemblyjs/wast-printer/download/@webassemblyjs/wast-printer-1.9.0.tgz?cache=0&sync_timestamp=1601756233564&other_urls=https%3A%2F%2Fregistry.npm.taobao.org%2F%40webassemblyjs%2Fwast-printer%2Fdownload%2F%40webassemblyjs%2Fwast-printer-1.9.0.tgz",
-      "integrity": "sha1-STXVTIX+9jewDOn1I3dFHQDUeJk=",
-      "dev": true,
-      "requires": {
-        "@webassemblyjs/ast": "1.9.0",
-        "@webassemblyjs/wast-parser": "1.9.0",
-        "@xtuc/long": "4.2.2"
-      }
-    },
-    "@xtuc/ieee754": {
-      "version": "1.2.0",
-      "resolved": "https://registry.npm.taobao.org/@xtuc/ieee754/download/@xtuc/ieee754-1.2.0.tgz",
-      "integrity": "sha1-7vAUoxRa5Hehy8AM0eVSM23Ot5A=",
-      "dev": true
-    },
-    "@xtuc/long": {
-      "version": "4.2.2",
-      "resolved": "https://registry.npm.taobao.org/@xtuc/long/download/@xtuc/long-4.2.2.tgz",
-      "integrity": "sha1-0pHGpOl5ibXGHZrPOWrk/hM6cY0=",
-      "dev": true
-    },
-    "abab": {
-      "version": "2.0.5",
-      "resolved": "https://registry.npm.taobao.org/abab/download/abab-2.0.5.tgz?cache=0&sync_timestamp=1599850200902&other_urls=https%3A%2F%2Fregistry.npm.taobao.org%2Fabab%2Fdownload%2Fabab-2.0.5.tgz",
-      "integrity": "sha1-wLZ4+zLWD8EhnHhNaoJv44Wut5o=",
-      "dev": true
-    },
-    "abbrev": {
-      "version": "1.1.1",
-      "resolved": "https://registry.npm.taobao.org/abbrev/download/abbrev-1.1.1.tgz",
-      "integrity": "sha1-+PLIh60Qv2f2NPAFtph/7TF5qsg=",
-      "dev": true
-    },
-    "accepts": {
-      "version": "1.3.7",
-      "resolved": "https://registry.npm.taobao.org/accepts/download/accepts-1.3.7.tgz",
-      "integrity": "sha1-UxvHJlF6OytB+FACHGzBXqq1B80=",
-      "dev": true,
-      "requires": {
-        "mime-types": "~2.1.24",
-        "negotiator": "0.6.2"
-      }
-    },
-    "acorn": {
-      "version": "7.4.1",
-      "resolved": "https://registry.npm.taobao.org/acorn/download/acorn-7.4.1.tgz",
-      "integrity": "sha1-/q7SVZc9LndVW4PbwIhRpsY1IPo=",
-      "dev": true
-    },
-    "acorn-globals": {
-      "version": "6.0.0",
-      "resolved": "https://registry.npm.taobao.org/acorn-globals/download/acorn-globals-6.0.0.tgz",
-      "integrity": "sha1-Rs3Tnw+P8IqHZhm1X1rIptx3C0U=",
-      "dev": true,
-      "requires": {
-        "acorn": "^7.1.1",
-        "acorn-walk": "^7.1.1"
-      }
-    },
-    "acorn-jsx": {
-      "version": "5.3.1",
-      "resolved": "https://registry.npm.taobao.org/acorn-jsx/download/acorn-jsx-5.3.1.tgz",
-      "integrity": "sha1-/IZh4Rt6wVOcR9v+oucrOvNNJns=",
-      "dev": true
-    },
-    "acorn-walk": {
-      "version": "7.2.0",
-      "resolved": "https://registry.npm.taobao.org/acorn-walk/download/acorn-walk-7.2.0.tgz?cache=0&sync_timestamp=1597235826369&other_urls=https%3A%2F%2Fregistry.npm.taobao.org%2Facorn-walk%2Fdownload%2Facorn-walk-7.2.0.tgz",
-      "integrity": "sha1-DeiJpgEgOQmw++B7iTjcIdLpZ7w=",
-      "dev": true
-    },
-    "add-asset-html-webpack-plugin": {
-      "version": "3.1.3",
-      "resolved": "https://registry.npm.taobao.org/add-asset-html-webpack-plugin/download/add-asset-html-webpack-plugin-3.1.3.tgz",
-      "integrity": "sha1-vsd9yBgmRKWKDuvK59H56xYtr98=",
-      "dev": true,
-      "requires": {
-        "globby": "^9.0.0",
-        "micromatch": "^3.1.3",
-        "p-each-series": "^1.0.0"
-      },
-      "dependencies": {
-        "p-each-series": {
-          "version": "1.0.0",
-          "resolved": "https://registry.npm.taobao.org/p-each-series/download/p-each-series-1.0.0.tgz",
-          "integrity": "sha1-kw89Et0fUOdDRFeiLNbwSsatf3E=",
-          "dev": true,
-          "requires": {
-            "p-reduce": "^1.0.0"
-          }
-        }
-      }
-    },
-    "address": {
-      "version": "1.1.2",
-      "resolved": "https://registry.npm.taobao.org/address/download/address-1.1.2.tgz",
-      "integrity": "sha1-vxEWycdYxRt6kz0pa3LCIe2UKLY=",
-      "dev": true
-    },
-    "aggregate-error": {
-      "version": "3.1.0",
-      "resolved": "https://registry.npm.taobao.org/aggregate-error/download/aggregate-error-3.1.0.tgz?cache=0&sync_timestamp=1598049934879&other_urls=https%3A%2F%2Fregistry.npm.taobao.org%2Faggregate-error%2Fdownload%2Faggregate-error-3.1.0.tgz",
-      "integrity": "sha1-kmcP9Q9TWb23o+DUDQ7DDFc3aHo=",
-      "dev": true,
-      "requires": {
-        "clean-stack": "^2.0.0",
-        "indent-string": "^4.0.0"
-      },
-      "dependencies": {
-        "indent-string": {
-          "version": "4.0.0",
-          "resolved": "https://registry.npm.taobao.org/indent-string/download/indent-string-4.0.0.tgz",
-          "integrity": "sha1-Yk+PRJfWGbLZdoUx1Y9BIoVNclE=",
-          "dev": true
-        }
-      }
-    },
-    "ajv": {
-      "version": "6.12.6",
-      "resolved": "https://registry.npm.taobao.org/ajv/download/ajv-6.12.6.tgz?cache=0&sync_timestamp=1604996837320&other_urls=https%3A%2F%2Fregistry.npm.taobao.org%2Fajv%2Fdownload%2Fajv-6.12.6.tgz",
-      "integrity": "sha1-uvWmLoArB9l3A0WG+MO69a3ybfQ=",
-      "dev": true,
-      "requires": {
-        "fast-deep-equal": "^3.1.1",
-        "fast-json-stable-stringify": "^2.0.0",
-        "json-schema-traverse": "^0.4.1",
-        "uri-js": "^4.2.2"
-      }
-    },
-    "ajv-errors": {
-      "version": "1.0.1",
-      "resolved": "https://registry.npm.taobao.org/ajv-errors/download/ajv-errors-1.0.1.tgz",
-      "integrity": "sha1-81mGrOuRr63sQQL72FAUlQzvpk0=",
-      "dev": true
-    },
-    "ajv-keywords": {
-      "version": "3.5.2",
-      "resolved": "https://registry.npm.taobao.org/ajv-keywords/download/ajv-keywords-3.5.2.tgz?cache=0&sync_timestamp=1604565104795&other_urls=https%3A%2F%2Fregistry.npm.taobao.org%2Fajv-keywords%2Fdownload%2Fajv-keywords-3.5.2.tgz",
-      "integrity": "sha1-MfKdpatuANHC0yms97WSlhTVAU0=",
-      "dev": true
-    },
-    "alphanum-sort": {
-      "version": "1.0.2",
-      "resolved": "https://registry.npm.taobao.org/alphanum-sort/download/alphanum-sort-1.0.2.tgz",
-      "integrity": "sha1-l6ERlkmyEa0zaR2fn0hqjsn74KM=",
-      "dev": true
-    },
-    "amdefine": {
-      "version": "1.0.1",
-      "resolved": "https://registry.npm.taobao.org/amdefine/download/amdefine-1.0.1.tgz",
-      "integrity": "sha1-SlKCrBZHKek2Gbz9OtFR+BfOkfU=",
-      "dev": true
-    },
-    "ansi-colors": {
-      "version": "3.2.4",
-      "resolved": "https://registry.npm.taobao.org/ansi-colors/download/ansi-colors-3.2.4.tgz",
-      "integrity": "sha1-46PaS/uubIapwoViXeEkojQCb78=",
-      "dev": true
-    },
-    "ansi-escapes": {
-      "version": "4.3.1",
-      "resolved": "https://registry.npm.taobao.org/ansi-escapes/download/ansi-escapes-4.3.1.tgz",
-      "integrity": "sha1-pcR8xDGB8fOP/XB2g3cA05VSKmE=",
-      "dev": true,
-      "requires": {
-        "type-fest": "^0.11.0"
-      },
-      "dependencies": {
-        "type-fest": {
-          "version": "0.11.0",
-          "resolved": "https://registry.npm.taobao.org/type-fest/download/type-fest-0.11.0.tgz?cache=0&sync_timestamp=1605191548126&other_urls=https%3A%2F%2Fregistry.npm.taobao.org%2Ftype-fest%2Fdownload%2Ftype-fest-0.11.0.tgz",
-          "integrity": "sha1-l6vwhyMQ/tiKXEZrJWgVdhReM/E=",
-          "dev": true
-        }
-      }
-    },
-    "ansi-html": {
-      "version": "0.0.7",
-      "resolved": "https://registry.npm.taobao.org/ansi-html/download/ansi-html-0.0.7.tgz",
-      "integrity": "sha1-gTWEAhliqenm/QOflA0S9WynhZ4=",
-      "dev": true
-    },
-    "ansi-regex": {
-      "version": "4.1.0",
-      "resolved": "https://registry.npm.taobao.org/ansi-regex/download/ansi-regex-4.1.0.tgz",
-      "integrity": "sha1-i5+PCM8ay4Q3Vqg5yox+MWjFGZc=",
-      "dev": true
-    },
-    "ansi-styles": {
-      "version": "3.2.1",
-      "resolved": "https://registry.npm.taobao.org/ansi-styles/download/ansi-styles-3.2.1.tgz?cache=0&sync_timestamp=1601839122515&other_urls=https%3A%2F%2Fregistry.npm.taobao.org%2Fansi-styles%2Fdownload%2Fansi-styles-3.2.1.tgz",
-      "integrity": "sha1-QfuyAkPlCxK+DwS43tvwdSDOhB0=",
-      "dev": true,
-      "requires": {
-        "color-convert": "^1.9.0"
-      }
-    },
-    "anymatch": {
-      "version": "3.1.1",
-      "resolved": "https://registry.npm.taobao.org/anymatch/download/anymatch-3.1.1.tgz",
-      "integrity": "sha1-xV7PAhheJGklk5kxDBc84xIzsUI=",
-      "dev": true,
-      "requires": {
-        "normalize-path": "^3.0.0",
-        "picomatch": "^2.0.4"
-      }
-    },
-    "append-field": {
-      "version": "1.0.0",
-      "resolved": "https://registry.npm.taobao.org/append-field/download/append-field-1.0.0.tgz",
-      "integrity": "sha1-HjRA6RXwsSA9I3SOeO3XubW0PlY=",
-      "dev": true
-    },
-    "aproba": {
-      "version": "1.2.0",
-      "resolved": "https://registry.npm.taobao.org/aproba/download/aproba-1.2.0.tgz",
-      "integrity": "sha1-aALmJk79GMeQobDVF/DyYnvyyUo=",
-      "dev": true
-    },
-    "are-we-there-yet": {
-      "version": "1.1.5",
-      "resolved": "https://registry.npm.taobao.org/are-we-there-yet/download/are-we-there-yet-1.1.5.tgz",
-      "integrity": "sha1-SzXClE8GKov82mZBB2A1D+nd/CE=",
-      "dev": true,
-      "requires": {
-        "delegates": "^1.0.0",
-        "readable-stream": "^2.0.6"
-      },
-      "dependencies": {
-        "readable-stream": {
-          "version": "2.3.7",
-          "resolved": "https://registry.npm.taobao.org/readable-stream/download/readable-stream-2.3.7.tgz",
-          "integrity": "sha1-Hsoc9xGu+BTAT2IlKjamL2yyO1c=",
-          "dev": true,
-          "requires": {
-            "core-util-is": "~1.0.0",
-            "inherits": "~2.0.3",
-            "isarray": "~1.0.0",
-            "process-nextick-args": "~2.0.0",
-            "safe-buffer": "~5.1.1",
-            "string_decoder": "~1.1.1",
-            "util-deprecate": "~1.0.1"
-          }
-        },
-        "safe-buffer": {
-          "version": "5.1.2",
-          "resolved": "https://registry.npm.taobao.org/safe-buffer/download/safe-buffer-5.1.2.tgz",
-          "integrity": "sha1-mR7GnSluAxN0fVm9/St0XDX4go0=",
-          "dev": true
-        },
-        "string_decoder": {
-          "version": "1.1.1",
-          "resolved": "https://registry.npm.taobao.org/string_decoder/download/string_decoder-1.1.1.tgz",
-          "integrity": "sha1-nPFhG6YmhdcDCunkujQUnDrwP8g=",
-          "dev": true,
-          "requires": {
-            "safe-buffer": "~5.1.0"
-          }
-        }
-      }
-    },
-    "argparse": {
-      "version": "1.0.10",
-      "resolved": "https://registry.npm.taobao.org/argparse/download/argparse-1.0.10.tgz",
-      "integrity": "sha1-vNZ5HqWuCXJeF+WtmIE0zUCz2RE=",
-      "dev": true,
-      "requires": {
-        "sprintf-js": "~1.0.2"
-      }
-    },
-    "aria-query": {
-      "version": "4.2.2",
-      "resolved": "https://registry.npm.taobao.org/aria-query/download/aria-query-4.2.2.tgz?cache=0&other_urls=https%3A%2F%2Fregistry.npm.taobao.org%2Faria-query%2Fdownload%2Faria-query-4.2.2.tgz",
-      "integrity": "sha1-DSymyazrVriXfp/tau1+FbvS+Ds=",
-      "dev": true,
-      "requires": {
-        "@babel/runtime": "^7.10.2",
-        "@babel/runtime-corejs3": "^7.10.2"
-      }
-    },
-    "arr-diff": {
-      "version": "4.0.0",
-      "resolved": "https://registry.npm.taobao.org/arr-diff/download/arr-diff-4.0.0.tgz",
-      "integrity": "sha1-1kYQdP6/7HHn4VI1dhoyml3HxSA=",
-      "dev": true
-    },
-    "arr-flatten": {
-      "version": "1.1.0",
-      "resolved": "https://registry.npm.taobao.org/arr-flatten/download/arr-flatten-1.1.0.tgz",
-      "integrity": "sha1-NgSLv/TntH4TZkQxbJlmnqWukfE=",
-      "dev": true
-    },
-    "arr-union": {
-      "version": "3.1.0",
-      "resolved": "https://registry.npm.taobao.org/arr-union/download/arr-union-3.1.0.tgz",
-      "integrity": "sha1-45sJrqne+Gao8gbiiK9jkZuuOcQ=",
-      "dev": true
-    },
-    "array-find-index": {
-      "version": "1.0.2",
-      "resolved": "https://registry.npm.taobao.org/array-find-index/download/array-find-index-1.0.2.tgz",
-      "integrity": "sha1-3wEKoSh+Fku9pvlyOwqWoexBh6E=",
-      "dev": true
-    },
-    "array-flatten": {
-      "version": "2.1.2",
-      "resolved": "https://registry.npm.taobao.org/array-flatten/download/array-flatten-2.1.2.tgz",
-      "integrity": "sha1-JO+AoowaiTYX4hSbDG0NeIKTsJk=",
-      "dev": true
-    },
-    "array-ify": {
-      "version": "1.0.0",
-      "resolved": "https://registry.npm.taobao.org/array-ify/download/array-ify-1.0.0.tgz",
-      "integrity": "sha1-nlKHYrSpBmrRY6aWKjZEGOlibs4=",
-      "dev": true
-    },
-    "array-includes": {
-      "version": "3.1.1",
-      "resolved": "https://registry.npm.taobao.org/array-includes/download/array-includes-3.1.1.tgz",
-      "integrity": "sha1-zdZ+aFK9+cEhVGB4ZzIlXtJFk0g=",
-      "dev": true,
-      "requires": {
-        "define-properties": "^1.1.3",
-        "es-abstract": "^1.17.0",
-        "is-string": "^1.0.5"
-      }
-    },
-    "array-union": {
-      "version": "1.0.2",
-      "resolved": "https://registry.npm.taobao.org/array-union/download/array-union-1.0.2.tgz",
-      "integrity": "sha1-mjRBDk9OPaI96jdb5b5w8kd47Dk=",
-      "dev": true,
-      "requires": {
-        "array-uniq": "^1.0.1"
-      }
-    },
-    "array-uniq": {
-      "version": "1.0.3",
-      "resolved": "https://registry.npm.taobao.org/array-uniq/download/array-uniq-1.0.3.tgz",
-      "integrity": "sha1-r2rId6Jcx/dOBYiUdThY39sk/bY=",
-      "dev": true
-    },
-    "array-unique": {
-      "version": "0.3.2",
-      "resolved": "https://registry.npm.taobao.org/array-unique/download/array-unique-0.3.2.tgz",
-      "integrity": "sha1-qJS3XUvE9s1nnvMkSp/Y9Gri1Cg=",
-      "dev": true
-    },
-    "array.prototype.flat": {
-      "version": "1.2.3",
-      "resolved": "https://registry.npm.taobao.org/array.prototype.flat/download/array.prototype.flat-1.2.3.tgz",
-      "integrity": "sha1-DegrQmsDGNv9uUAInjiwQ9N/bHs=",
-      "dev": true,
-      "requires": {
-        "define-properties": "^1.1.3",
-        "es-abstract": "^1.17.0-next.1"
-      }
-    },
-    "array.prototype.flatmap": {
-      "version": "1.2.3",
-      "resolved": "https://registry.npm.taobao.org/array.prototype.flatmap/download/array.prototype.flatmap-1.2.3.tgz",
-      "integrity": "sha1-HBP4SheFZgQt1j3kQURA25Ii5EM=",
-      "dev": true,
-      "requires": {
-        "define-properties": "^1.1.3",
-        "es-abstract": "^1.17.0-next.1",
-        "function-bind": "^1.1.1"
-      }
-    },
-    "arrify": {
-      "version": "1.0.1",
-      "resolved": "https://registry.npm.taobao.org/arrify/download/arrify-1.0.1.tgz",
-      "integrity": "sha1-iYUI2iIm84DfkEcoRWhJwVAaSw0=",
-      "dev": true
-    },
-    "asap": {
-      "version": "2.0.6",
-      "resolved": "https://registry.npm.taobao.org/asap/download/asap-2.0.6.tgz",
-      "integrity": "sha1-5QNHYR1+aQlDIIu9r+vLwvuGbUY="
-    },
-    "asn1": {
-      "version": "0.2.4",
-      "resolved": "https://registry.npm.taobao.org/asn1/download/asn1-0.2.4.tgz",
-      "integrity": "sha1-jSR136tVO7M+d7VOWeiAu4ziMTY=",
-      "dev": true,
-      "requires": {
-        "safer-buffer": "~2.1.0"
-      }
-    },
-    "asn1.js": {
-      "version": "5.4.1",
-      "resolved": "https://registry.npm.taobao.org/asn1.js/download/asn1.js-5.4.1.tgz",
-      "integrity": "sha1-EamAuE67kXgc41sP3C7ilON4Pwc=",
-      "dev": true,
-      "requires": {
-        "bn.js": "^4.0.0",
-        "inherits": "^2.0.1",
-        "minimalistic-assert": "^1.0.0",
-        "safer-buffer": "^2.1.0"
-      },
-      "dependencies": {
-        "bn.js": {
-          "version": "4.11.9",
-          "resolved": "https://registry.npm.taobao.org/bn.js/download/bn.js-4.11.9.tgz",
-          "integrity": "sha1-JtVWgpRY+dHoH8SJUkk9C6NQeCg=",
-          "dev": true
-        }
-      }
-    },
-    "assert": {
-      "version": "1.5.0",
-      "resolved": "https://registry.npm.taobao.org/assert/download/assert-1.5.0.tgz?cache=0&sync_timestamp=1586265311434&other_urls=https%3A%2F%2Fregistry.npm.taobao.org%2Fassert%2Fdownload%2Fassert-1.5.0.tgz",
-      "integrity": "sha1-VcEJqvbgrv2z3EtxJAxwv1dLGOs=",
-      "dev": true,
-      "requires": {
-        "object-assign": "^4.1.1",
-        "util": "0.10.3"
-      },
-      "dependencies": {
-        "inherits": {
-          "version": "2.0.1",
-          "resolved": "https://registry.npm.taobao.org/inherits/download/inherits-2.0.1.tgz",
-          "integrity": "sha1-sX0I0ya0Qj5Wjv9xn5GwscvfafE=",
-          "dev": true
-        },
-        "util": {
-          "version": "0.10.3",
-          "resolved": "https://registry.npm.taobao.org/util/download/util-0.10.3.tgz",
-          "integrity": "sha1-evsa/lCAUkZInj23/g7TeTNqwPk=",
-          "dev": true,
-          "requires": {
-            "inherits": "2.0.1"
-          }
-        }
-      }
-    },
-    "assert-plus": {
-      "version": "1.0.0",
-      "resolved": "https://registry.npm.taobao.org/assert-plus/download/assert-plus-1.0.0.tgz",
-      "integrity": "sha1-8S4PPF13sLHN2RRpQuTpbB5N1SU=",
-      "dev": true
-    },
-    "assign-symbols": {
-      "version": "1.0.0",
-      "resolved": "https://registry.npm.taobao.org/assign-symbols/download/assign-symbols-1.0.0.tgz",
-      "integrity": "sha1-WWZ/QfrdTyDMvCu5a41Pf3jsA2c=",
-      "dev": true
-    },
-    "ast-types-flow": {
-      "version": "0.0.7",
-      "resolved": "https://registry.npm.taobao.org/ast-types-flow/download/ast-types-flow-0.0.7.tgz",
-      "integrity": "sha1-9wtzXGvKGlycItmCw+Oef+ujva0=",
-      "dev": true
-    },
-    "astral-regex": {
-      "version": "1.0.0",
-      "resolved": "https://registry.npm.taobao.org/astral-regex/download/astral-regex-1.0.0.tgz",
-      "integrity": "sha1-bIw/uCfdQ+45GPJ7gngqt2WKb9k=",
-      "dev": true
-    },
-    "async": {
-      "version": "2.6.3",
-      "resolved": "https://registry.npm.taobao.org/async/download/async-2.6.3.tgz",
-      "integrity": "sha1-1yYl4jRKNlbjo61Pp0n6gymdgv8=",
-      "dev": true,
-      "requires": {
-        "lodash": "^4.17.14"
-      }
-    },
-    "async-each": {
-      "version": "1.0.3",
-      "resolved": "https://registry.npm.taobao.org/async-each/download/async-each-1.0.3.tgz",
-      "integrity": "sha1-tyfb+H12UWAvBvTUrDh/R9kbDL8=",
-      "dev": true
-    },
-    "async-foreach": {
-      "version": "0.1.3",
-      "resolved": "https://registry.npm.taobao.org/async-foreach/download/async-foreach-0.1.3.tgz",
-      "integrity": "sha1-NhIfhFwFeBct5Bmpfb6x0W7DRUI=",
-      "dev": true
-    },
-    "async-limiter": {
-      "version": "1.0.1",
-      "resolved": "https://registry.npm.taobao.org/async-limiter/download/async-limiter-1.0.1.tgz",
-      "integrity": "sha1-3TeelPDbgxCwgpH51kwyCXZmF/0=",
-      "dev": true
-    },
-    "asynckit": {
-      "version": "0.4.0",
-      "resolved": "https://registry.npm.taobao.org/asynckit/download/asynckit-0.4.0.tgz",
-      "integrity": "sha1-x57Zf380y48robyXkLzDZkdLS3k=",
-      "dev": true
-    },
-    "at-least-node": {
-      "version": "1.0.0",
-      "resolved": "https://registry.npm.taobao.org/at-least-node/download/at-least-node-1.0.0.tgz",
-      "integrity": "sha1-YCzUtG6EStTv/JKoARo8RuAjjcI=",
-      "dev": true
-    },
-    "atob": {
-      "version": "2.1.2",
-      "resolved": "https://registry.npm.taobao.org/atob/download/atob-2.1.2.tgz",
-      "integrity": "sha1-bZUX654DDSQ2ZmZR6GvZ9vE1M8k=",
-      "dev": true
-    },
-    "autoprefixer": {
-      "version": "9.8.6",
-      "resolved": "https://registry.npm.taobao.org/autoprefixer/download/autoprefixer-9.8.6.tgz",
-      "integrity": "sha1-O3NZTKG/kmYyDFrPFYjXTep0IQ8=",
-      "dev": true,
-      "requires": {
-        "browserslist": "^4.12.0",
-        "caniuse-lite": "^1.0.30001109",
-        "colorette": "^1.2.1",
-        "normalize-range": "^0.1.2",
-        "num2fraction": "^1.2.2",
-        "postcss": "^7.0.32",
-        "postcss-value-parser": "^4.1.0"
-      },
-      "dependencies": {
-        "postcss-value-parser": {
-          "version": "4.1.0",
-          "resolved": "https://registry.npm.taobao.org/postcss-value-parser/download/postcss-value-parser-4.1.0.tgz",
-          "integrity": "sha1-RD9qIM7WSBor2k+oUypuVdeJoss=",
-          "dev": true
-        }
-      }
-    },
-    "aws-sign2": {
-      "version": "0.7.0",
-      "resolved": "https://registry.npm.taobao.org/aws-sign2/download/aws-sign2-0.7.0.tgz",
-      "integrity": "sha1-tG6JCTSpWR8tL2+G1+ap8bP+dqg=",
-      "dev": true
-    },
-    "aws4": {
-      "version": "1.11.0",
-      "resolved": "https://registry.npm.taobao.org/aws4/download/aws4-1.11.0.tgz?cache=0&sync_timestamp=1604101210422&other_urls=https%3A%2F%2Fregistry.npm.taobao.org%2Faws4%2Fdownload%2Faws4-1.11.0.tgz",
-      "integrity": "sha1-1h9G2DslGSUOJ4Ta9bCUeai0HFk=",
-      "dev": true
-    },
-    "axe-core": {
-      "version": "4.0.2",
-      "resolved": "https://registry.npm.taobao.org/axe-core/download/axe-core-4.0.2.tgz",
-      "integrity": "sha1-x89zeDeKUfzSctPAlmgAKkmQscs=",
-      "dev": true
-    },
-    "axios": {
-      "version": "0.19.2",
-      "resolved": "https://registry.npm.taobao.org/axios/download/axios-0.19.2.tgz?cache=0&sync_timestamp=1603468716105&other_urls=https%3A%2F%2Fregistry.npm.taobao.org%2Faxios%2Fdownload%2Faxios-0.19.2.tgz",
-      "integrity": "sha1-PqNsXYgY0NX4qKl6bTa4bNwAyyc=",
-      "dev": true,
-      "requires": {
-        "follow-redirects": "1.5.10"
-      },
-      "dependencies": {
-        "debug": {
-          "version": "3.1.0",
-          "resolved": "https://registry.npm.taobao.org/debug/download/debug-3.1.0.tgz?cache=0&sync_timestamp=1600502871403&other_urls=https%3A%2F%2Fregistry.npm.taobao.org%2Fdebug%2Fdownload%2Fdebug-3.1.0.tgz",
-          "integrity": "sha1-W7WgZyYotkFJVmuhaBnmFRjGcmE=",
-          "dev": true,
-          "requires": {
-            "ms": "2.0.0"
-          }
-        },
-        "follow-redirects": {
-          "version": "1.5.10",
-          "resolved": "https://registry.npm.taobao.org/follow-redirects/download/follow-redirects-1.5.10.tgz?cache=0&sync_timestamp=1597057988030&other_urls=https%3A%2F%2Fregistry.npm.taobao.org%2Ffollow-redirects%2Fdownload%2Ffollow-redirects-1.5.10.tgz",
-          "integrity": "sha1-e3qfmuov3/NnhqlP9kPtB/T/Xio=",
-          "dev": true,
-          "requires": {
-            "debug": "=3.1.0"
-          }
-        },
-        "ms": {
-          "version": "2.0.0",
-          "resolved": "https://registry.npm.taobao.org/ms/download/ms-2.0.0.tgz",
-          "integrity": "sha1-VgiurfwAvmwpAd9fmGF4jeDVl8g=",
-          "dev": true
-        }
-      }
-    },
-    "axobject-query": {
-      "version": "2.2.0",
-      "resolved": "https://registry.npm.taobao.org/axobject-query/download/axobject-query-2.2.0.tgz?cache=0&sync_timestamp=1592784810338&other_urls=https%3A%2F%2Fregistry.npm.taobao.org%2Faxobject-query%2Fdownload%2Faxobject-query-2.2.0.tgz",
-      "integrity": "sha1-lD1H4QwLcEqkInXiDt83ImSJib4=",
-      "dev": true
-    },
-    "babel-code-frame": {
-      "version": "6.26.0",
-      "resolved": "https://registry.npm.taobao.org/babel-code-frame/download/babel-code-frame-6.26.0.tgz",
-      "integrity": "sha1-Y/1D99weO7fONZR9uP42mj9Yx0s=",
-      "dev": true,
-      "requires": {
-        "chalk": "^1.1.3",
-        "esutils": "^2.0.2",
-        "js-tokens": "^3.0.2"
-      },
-      "dependencies": {
-        "ansi-regex": {
-          "version": "2.1.1",
-          "resolved": "https://registry.npm.taobao.org/ansi-regex/download/ansi-regex-2.1.1.tgz",
-          "integrity": "sha1-w7M6te42DYbg5ijwRorn7yfWVN8=",
-          "dev": true
-        },
-        "ansi-styles": {
-          "version": "2.2.1",
-          "resolved": "https://registry.npm.taobao.org/ansi-styles/download/ansi-styles-2.2.1.tgz?cache=0&sync_timestamp=1601839122515&other_urls=https%3A%2F%2Fregistry.npm.taobao.org%2Fansi-styles%2Fdownload%2Fansi-styles-2.2.1.tgz",
-          "integrity": "sha1-tDLdM1i2NM914eRmQ2gkBTPB3b4=",
-          "dev": true
-        },
-        "chalk": {
-          "version": "1.1.3",
-          "resolved": "https://registry.npm.taobao.org/chalk/download/chalk-1.1.3.tgz",
-          "integrity": "sha1-qBFcVeSnAv5NFQq9OHKCKn4J/Jg=",
-          "dev": true,
-          "requires": {
-            "ansi-styles": "^2.2.1",
-            "escape-string-regexp": "^1.0.2",
-            "has-ansi": "^2.0.0",
-            "strip-ansi": "^3.0.0",
-            "supports-color": "^2.0.0"
-          }
-        },
-        "js-tokens": {
-          "version": "3.0.2",
-          "resolved": "https://registry.npm.taobao.org/js-tokens/download/js-tokens-3.0.2.tgz",
-          "integrity": "sha1-mGbfOVECEw449/mWvOtlRDIJwls=",
-          "dev": true
-        },
-        "strip-ansi": {
-          "version": "3.0.1",
-          "resolved": "https://registry.npm.taobao.org/strip-ansi/download/strip-ansi-3.0.1.tgz",
-          "integrity": "sha1-ajhfuIU9lS1f8F0Oiq+UJ43GPc8=",
-          "dev": true,
-          "requires": {
-            "ansi-regex": "^2.0.0"
-          }
-        },
-        "supports-color": {
-          "version": "2.0.0",
-          "resolved": "https://registry.npm.taobao.org/supports-color/download/supports-color-2.0.0.tgz?cache=0&sync_timestamp=1598611730985&other_urls=https%3A%2F%2Fregistry.npm.taobao.org%2Fsupports-color%2Fdownload%2Fsupports-color-2.0.0.tgz",
-          "integrity": "sha1-U10EXOa2Nj+kARcIRimZXp3zJMc=",
-          "dev": true
-        }
-      }
-    },
-    "babel-eslint": {
-      "version": "10.1.0",
-      "resolved": "https://registry.npm.taobao.org/babel-eslint/download/babel-eslint-10.1.0.tgz",
-      "integrity": "sha1-aWjlaKkQt4+zd5zdi2rC9HmUMjI=",
-      "dev": true,
-      "requires": {
-        "@babel/code-frame": "^7.0.0",
-        "@babel/parser": "^7.7.0",
-        "@babel/traverse": "^7.7.0",
-        "@babel/types": "^7.7.0",
-        "eslint-visitor-keys": "^1.0.0",
-        "resolve": "^1.12.0"
-      }
-    },
-    "babel-jest": {
-      "version": "26.6.3",
-      "resolved": "https://registry.npm.taobao.org/babel-jest/download/babel-jest-26.6.3.tgz",
-      "integrity": "sha1-2H0lywA3V3oMifguV1XF0pPAEFY=",
-      "dev": true,
-      "requires": {
-        "@jest/transform": "^26.6.2",
-        "@jest/types": "^26.6.2",
-        "@types/babel__core": "^7.1.7",
-        "babel-plugin-istanbul": "^6.0.0",
-        "babel-preset-jest": "^26.6.2",
-        "chalk": "^4.0.0",
-        "graceful-fs": "^4.2.4",
-        "slash": "^3.0.0"
-      },
-      "dependencies": {
-        "ansi-styles": {
-          "version": "4.3.0",
-          "resolved": "https://registry.npm.taobao.org/ansi-styles/download/ansi-styles-4.3.0.tgz?cache=0&sync_timestamp=1601839122515&other_urls=https%3A%2F%2Fregistry.npm.taobao.org%2Fansi-styles%2Fdownload%2Fansi-styles-4.3.0.tgz",
-          "integrity": "sha1-7dgDYornHATIWuegkG7a00tkiTc=",
-          "dev": true,
-          "requires": {
-            "color-convert": "^2.0.1"
-          }
-        },
-        "chalk": {
-          "version": "4.1.0",
-          "resolved": "https://registry.npm.taobao.org/chalk/download/chalk-4.1.0.tgz",
-          "integrity": "sha1-ThSHCmGNni7dl92DRf2dncMVZGo=",
-          "dev": true,
-          "requires": {
-            "ansi-styles": "^4.1.0",
-            "supports-color": "^7.1.0"
-          }
-        },
-        "color-convert": {
-          "version": "2.0.1",
-          "resolved": "https://registry.npm.taobao.org/color-convert/download/color-convert-2.0.1.tgz",
-          "integrity": "sha1-ctOmjVmMm9s68q0ehPIdiWq9TeM=",
-          "dev": true,
-          "requires": {
-            "color-name": "~1.1.4"
-          }
-        },
-        "color-name": {
-          "version": "1.1.4",
-          "resolved": "https://registry.npm.taobao.org/color-name/download/color-name-1.1.4.tgz",
-          "integrity": "sha1-wqCah6y95pVD3m9j+jmVyCbFNqI=",
-          "dev": true
-        },
-        "has-flag": {
-          "version": "4.0.0",
-          "resolved": "https://registry.npm.taobao.org/has-flag/download/has-flag-4.0.0.tgz?cache=0&sync_timestamp=1596294337050&other_urls=https%3A%2F%2Fregistry.npm.taobao.org%2Fhas-flag%2Fdownload%2Fhas-flag-4.0.0.tgz",
-          "integrity": "sha1-lEdx/ZyByBJlxNaUGGDaBrtZR5s=",
-          "dev": true
-        },
-        "slash": {
-          "version": "3.0.0",
-          "resolved": "https://registry.npm.taobao.org/slash/download/slash-3.0.0.tgz",
-          "integrity": "sha1-ZTm+hwwWWtvVJAIg2+Nh8bxNRjQ=",
-          "dev": true
-        },
-        "supports-color": {
-          "version": "7.2.0",
-          "resolved": "https://registry.npm.taobao.org/supports-color/download/supports-color-7.2.0.tgz?cache=0&sync_timestamp=1598611730985&other_urls=https%3A%2F%2Fregistry.npm.taobao.org%2Fsupports-color%2Fdownload%2Fsupports-color-7.2.0.tgz",
-          "integrity": "sha1-G33NyzK4E4gBs+R4umpRyqiWSNo=",
-          "dev": true,
-          "requires": {
-            "has-flag": "^4.0.0"
-          }
-        }
-      }
-    },
-    "babel-loader": {
-      "version": "8.2.1",
-      "resolved": "https://registry.npm.taobao.org/babel-loader/download/babel-loader-8.2.1.tgz?cache=0&sync_timestamp=1605043056908&other_urls=https%3A%2F%2Fregistry.npm.taobao.org%2Fbabel-loader%2Fdownload%2Fbabel-loader-8.2.1.tgz",
-      "integrity": "sha1-5TMTJUZ36G8nU29QcdgH4B0k7AA=",
-      "dev": true,
-      "requires": {
-        "find-cache-dir": "^2.1.0",
-        "loader-utils": "^1.4.0",
-        "make-dir": "^2.1.0",
-        "pify": "^4.0.1",
-        "schema-utils": "^2.6.5"
-      },
-      "dependencies": {
-        "make-dir": {
-          "version": "2.1.0",
-          "resolved": "https://registry.npm.taobao.org/make-dir/download/make-dir-2.1.0.tgz",
-          "integrity": "sha1-XwMQ4YuL6JjMBwCSlaMK5B6R5vU=",
-          "dev": true,
-          "requires": {
-            "pify": "^4.0.1",
-            "semver": "^5.6.0"
-          }
-        },
-        "pify": {
-          "version": "4.0.1",
-          "resolved": "https://registry.npm.taobao.org/pify/download/pify-4.0.1.tgz",
-          "integrity": "sha1-SyzSXFDVmHNcUCkiJP2MbfQeMjE=",
-          "dev": true
-        },
-        "schema-utils": {
-          "version": "2.7.1",
-          "resolved": "https://registry.npm.taobao.org/schema-utils/download/schema-utils-2.7.1.tgz",
-          "integrity": "sha1-HKTzLRskxZDCA7jnpQvw6kzTlNc=",
-          "dev": true,
-          "requires": {
-            "@types/json-schema": "^7.0.5",
-            "ajv": "^6.12.4",
-            "ajv-keywords": "^3.5.2"
-          }
-        },
-        "semver": {
-          "version": "5.7.1",
-          "resolved": "https://registry.npm.taobao.org/semver/download/semver-5.7.1.tgz",
-          "integrity": "sha1-qVT5Ma66UI0we78Gnv8MAclhFvc=",
-          "dev": true
-        }
-      }
-    },
-    "babel-plugin-dynamic-import-node": {
-      "version": "2.3.3",
-      "resolved": "https://registry.npm.taobao.org/babel-plugin-dynamic-import-node/download/babel-plugin-dynamic-import-node-2.3.3.tgz",
-      "integrity": "sha1-hP2hnJduxcbe/vV/lCez3vZuF6M=",
-      "dev": true,
-      "requires": {
-        "object.assign": "^4.1.0"
-      }
-    },
-    "babel-plugin-import": {
-      "version": "1.13.1",
-      "resolved": "https://registry.npm.taobao.org/babel-plugin-import/download/babel-plugin-import-1.13.1.tgz",
-      "integrity": "sha1-9s8ay3bFzjZrriZjrRK9iUMW2Ns=",
-      "dev": true,
-      "requires": {
-        "@babel/helper-module-imports": "^7.0.0",
-        "@babel/runtime": "^7.0.0"
-      }
-    },
-    "babel-plugin-istanbul": {
-      "version": "6.0.0",
-      "resolved": "https://registry.npm.taobao.org/babel-plugin-istanbul/download/babel-plugin-istanbul-6.0.0.tgz",
-      "integrity": "sha1-4VnM3Jr5XgtXDHW0Vzt8NNZx12U=",
-      "dev": true,
-      "requires": {
-        "@babel/helper-plugin-utils": "^7.0.0",
-        "@istanbuljs/load-nyc-config": "^1.0.0",
-        "@istanbuljs/schema": "^0.1.2",
-        "istanbul-lib-instrument": "^4.0.0",
-        "test-exclude": "^6.0.0"
-      }
-    },
-    "babel-plugin-jest-hoist": {
-      "version": "26.6.2",
-      "resolved": "https://registry.npm.taobao.org/babel-plugin-jest-hoist/download/babel-plugin-jest-hoist-26.6.2.tgz?cache=0&sync_timestamp=1604319713233&other_urls=https%3A%2F%2Fregistry.npm.taobao.org%2Fbabel-plugin-jest-hoist%2Fdownload%2Fbabel-plugin-jest-hoist-26.6.2.tgz",
-      "integrity": "sha1-gYW9AwNI0lTG192XQ1Xmoosh5i0=",
-      "dev": true,
-      "requires": {
-        "@babel/template": "^7.3.3",
-        "@babel/types": "^7.3.3",
-        "@types/babel__core": "^7.0.0",
-        "@types/babel__traverse": "^7.0.6"
-      }
-    },
-    "babel-plugin-module-resolver": {
-      "version": "4.0.0",
-      "resolved": "https://registry.npm.taobao.org/babel-plugin-module-resolver/download/babel-plugin-module-resolver-4.0.0.tgz",
-      "integrity": "sha1-jzo9nUgofcHTsNVZUROtq9NqhH8=",
-      "dev": true,
-      "requires": {
-        "find-babel-config": "^1.2.0",
-        "glob": "^7.1.6",
-        "pkg-up": "^3.1.0",
-        "reselect": "^4.0.0",
-        "resolve": "^1.13.1"
-      }
-    },
-    "babel-preset-current-node-syntax": {
-      "version": "1.0.0",
-      "resolved": "https://registry.npm.taobao.org/babel-preset-current-node-syntax/download/babel-preset-current-node-syntax-1.0.0.tgz?cache=0&sync_timestamp=1604147849036&other_urls=https%3A%2F%2Fregistry.npm.taobao.org%2Fbabel-preset-current-node-syntax%2Fdownload%2Fbabel-preset-current-node-syntax-1.0.0.tgz",
-      "integrity": "sha1-z1/u8pVRJTRxz6gvyOD1Bj3wenc=",
-      "dev": true,
-      "requires": {
-        "@babel/plugin-syntax-async-generators": "^7.8.4",
-        "@babel/plugin-syntax-bigint": "^7.8.3",
-        "@babel/plugin-syntax-class-properties": "^7.8.3",
-        "@babel/plugin-syntax-import-meta": "^7.8.3",
-        "@babel/plugin-syntax-json-strings": "^7.8.3",
-        "@babel/plugin-syntax-logical-assignment-operators": "^7.8.3",
-        "@babel/plugin-syntax-nullish-coalescing-operator": "^7.8.3",
-        "@babel/plugin-syntax-numeric-separator": "^7.8.3",
-        "@babel/plugin-syntax-object-rest-spread": "^7.8.3",
-        "@babel/plugin-syntax-optional-catch-binding": "^7.8.3",
-        "@babel/plugin-syntax-optional-chaining": "^7.8.3",
-        "@babel/plugin-syntax-top-level-await": "^7.8.3"
-      }
-    },
-    "babel-preset-jest": {
-      "version": "26.6.2",
-      "resolved": "https://registry.npm.taobao.org/babel-preset-jest/download/babel-preset-jest-26.6.2.tgz?cache=0&sync_timestamp=1604319712402&other_urls=https%3A%2F%2Fregistry.npm.taobao.org%2Fbabel-preset-jest%2Fdownload%2Fbabel-preset-jest-26.6.2.tgz",
-      "integrity": "sha1-dHhysRcd8DIlJCZYaIHWLTF5j+4=",
-      "dev": true,
-      "requires": {
-        "babel-plugin-jest-hoist": "^26.6.2",
-        "babel-preset-current-node-syntax": "^1.0.0"
-      }
-    },
-    "babel-runtime": {
-      "version": "6.26.0",
-      "resolved": "https://registry.npm.taobao.org/babel-runtime/download/babel-runtime-6.26.0.tgz",
-      "integrity": "sha1-llxwWGaOgrVde/4E/yM3vItWR/4=",
-      "requires": {
-        "core-js": "^2.4.0",
-        "regenerator-runtime": "^0.11.0"
-      }
-    },
-    "bail": {
-      "version": "1.0.5",
-      "resolved": "https://registry.npm.taobao.org/bail/download/bail-1.0.5.tgz",
-      "integrity": "sha1-tvoTNASjksvB+MS/Y/WVM1Hnp3Y=",
-      "dev": true
-    },
-    "balanced-match": {
-      "version": "1.0.0",
-      "resolved": "https://registry.npm.taobao.org/balanced-match/download/balanced-match-1.0.0.tgz",
-      "integrity": "sha1-ibTRmasr7kneFk6gK4nORi1xt2c=",
-      "dev": true
-    },
-    "base": {
-      "version": "0.11.2",
-      "resolved": "https://registry.npm.taobao.org/base/download/base-0.11.2.tgz",
-      "integrity": "sha1-e95c7RRbbVUakNuH+DxVi060io8=",
-      "dev": true,
-      "requires": {
-        "cache-base": "^1.0.1",
-        "class-utils": "^0.3.5",
-        "component-emitter": "^1.2.1",
-        "define-property": "^1.0.0",
-        "isobject": "^3.0.1",
-        "mixin-deep": "^1.2.0",
-        "pascalcase": "^0.1.1"
-      },
-      "dependencies": {
-        "define-property": {
-          "version": "1.0.0",
-          "resolved": "https://registry.npm.taobao.org/define-property/download/define-property-1.0.0.tgz",
-          "integrity": "sha1-dp66rz9KY6rTr56NMEybvnm/sOY=",
-          "dev": true,
-          "requires": {
-            "is-descriptor": "^1.0.0"
-          }
-        },
-        "is-accessor-descriptor": {
-          "version": "1.0.0",
-          "resolved": "https://registry.npm.taobao.org/is-accessor-descriptor/download/is-accessor-descriptor-1.0.0.tgz",
-          "integrity": "sha1-FpwvbT3x+ZJhgHI2XJsOofaHhlY=",
-          "dev": true,
-          "requires": {
-            "kind-of": "^6.0.0"
-          }
-        },
-        "is-data-descriptor": {
-          "version": "1.0.0",
-          "resolved": "https://registry.npm.taobao.org/is-data-descriptor/download/is-data-descriptor-1.0.0.tgz",
-          "integrity": "sha1-2Eh2Mh0Oet0DmQQGq7u9NrqSaMc=",
-          "dev": true,
-          "requires": {
-            "kind-of": "^6.0.0"
-          }
-        },
-        "is-descriptor": {
-          "version": "1.0.2",
-          "resolved": "https://registry.npm.taobao.org/is-descriptor/download/is-descriptor-1.0.2.tgz",
-          "integrity": "sha1-OxWXRqZmBLBPjIFSS6NlxfFNhuw=",
-          "dev": true,
-          "requires": {
-            "is-accessor-descriptor": "^1.0.0",
-            "is-data-descriptor": "^1.0.0",
-            "kind-of": "^6.0.2"
-          }
-        }
-      }
-    },
-    "base16": {
-      "version": "1.0.0",
-      "resolved": "https://registry.npm.taobao.org/base16/download/base16-1.0.0.tgz",
-      "integrity": "sha1-4pf2DX7BAUp6lxo568ipjAtoHnA="
-    },
-    "base64-js": {
-      "version": "1.5.1",
-      "resolved": "https://registry.npm.taobao.org/base64-js/download/base64-js-1.5.1.tgz?cache=0&other_urls=https%3A%2F%2Fregistry.npm.taobao.org%2Fbase64-js%2Fdownload%2Fbase64-js-1.5.1.tgz",
-      "integrity": "sha1-GxtEAWClv3rUC2UPCVljSBkDkwo=",
-      "dev": true
-    },
-    "batch": {
-      "version": "0.6.1",
-      "resolved": "https://registry.npm.taobao.org/batch/download/batch-0.6.1.tgz",
-      "integrity": "sha1-3DQxT05nkxgJP8dgJyUl+UvyXBY=",
-      "dev": true
-    },
-    "bcrypt-pbkdf": {
-      "version": "1.0.2",
-      "resolved": "https://registry.npm.taobao.org/bcrypt-pbkdf/download/bcrypt-pbkdf-1.0.2.tgz",
-      "integrity": "sha1-pDAdOJtqQ/m2f/PKEaP2Y342Dp4=",
-      "dev": true,
-      "requires": {
-        "tweetnacl": "^0.14.3"
-      }
-    },
-    "bfj": {
-      "version": "6.1.2",
-      "resolved": "https://registry.npm.taobao.org/bfj/download/bfj-6.1.2.tgz",
-      "integrity": "sha1-MlyGGoIryzWKQceKM7jm4ght3n8=",
-      "dev": true,
-      "requires": {
-        "bluebird": "^3.5.5",
-        "check-types": "^8.0.3",
-        "hoopy": "^0.1.4",
-        "tryer": "^1.0.1"
-      }
-    },
-    "big.js": {
-      "version": "5.2.2",
-      "resolved": "https://registry.npm.taobao.org/big.js/download/big.js-5.2.2.tgz",
-      "integrity": "sha1-ZfCvOC9Xi83HQr2cKB6cstd2gyg=",
-      "dev": true
-    },
-    "binary-extensions": {
-      "version": "2.1.0",
-      "resolved": "https://registry.npm.taobao.org/binary-extensions/download/binary-extensions-2.1.0.tgz?cache=0&sync_timestamp=1593261309792&other_urls=https%3A%2F%2Fregistry.npm.taobao.org%2Fbinary-extensions%2Fdownload%2Fbinary-extensions-2.1.0.tgz",
-      "integrity": "sha1-MPpAyef+B9vIlWeM0ocCTeokHdk=",
-      "dev": true
-    },
-    "bindings": {
-      "version": "1.5.0",
-      "resolved": "https://registry.npm.taobao.org/bindings/download/bindings-1.5.0.tgz",
-      "integrity": "sha1-EDU8npRTNLwFEabZCzj7x8nFBN8=",
-      "dev": true,
-      "optional": true,
-      "requires": {
-        "file-uri-to-path": "1.0.0"
-      }
-    },
-    "block-stream": {
-      "version": "0.0.9",
-      "resolved": "https://registry.npm.taobao.org/block-stream/download/block-stream-0.0.9.tgz",
-      "integrity": "sha1-E+v+d4oDIFz+A3UUgeu0szAMEmo=",
-      "dev": true,
-      "requires": {
-        "inherits": "~2.0.0"
-      }
-    },
-    "bluebird": {
-      "version": "3.7.2",
-      "resolved": "https://registry.npm.taobao.org/bluebird/download/bluebird-3.7.2.tgz?cache=0&sync_timestamp=1586263933818&other_urls=https%3A%2F%2Fregistry.npm.taobao.org%2Fbluebird%2Fdownload%2Fbluebird-3.7.2.tgz",
-      "integrity": "sha1-nyKcFb4nJFT/qXOs4NvueaGww28=",
-      "dev": true
-    },
-    "bn.js": {
-      "version": "5.1.3",
-      "resolved": "https://registry.npm.taobao.org/bn.js/download/bn.js-5.1.3.tgz",
-      "integrity": "sha1-vsoAVAj2Quvr6oCwQrTRjSrA7ms=",
-      "dev": true
-    },
-    "body-parser": {
-      "version": "1.19.0",
-      "resolved": "https://registry.npm.taobao.org/body-parser/download/body-parser-1.19.0.tgz",
-      "integrity": "sha1-lrJwnlfJxOCab9Zqj9l5hE9p8Io=",
-      "dev": true,
-      "requires": {
-        "bytes": "3.1.0",
-        "content-type": "~1.0.4",
-        "debug": "2.6.9",
-        "depd": "~1.1.2",
-        "http-errors": "1.7.2",
-        "iconv-lite": "0.4.24",
-        "on-finished": "~2.3.0",
-        "qs": "6.7.0",
-        "raw-body": "2.4.0",
-        "type-is": "~1.6.17"
-      },
-      "dependencies": {
-        "bytes": {
-          "version": "3.1.0",
-          "resolved": "https://registry.npm.taobao.org/bytes/download/bytes-3.1.0.tgz",
-          "integrity": "sha1-9s95M6Ng4FiPqf3oVlHNx/gF0fY=",
-          "dev": true
-        },
-        "debug": {
-          "version": "2.6.9",
-          "resolved": "https://registry.npm.taobao.org/debug/download/debug-2.6.9.tgz?cache=0&sync_timestamp=1600502871403&other_urls=https%3A%2F%2Fregistry.npm.taobao.org%2Fdebug%2Fdownload%2Fdebug-2.6.9.tgz",
-          "integrity": "sha1-XRKFFd8TT/Mn6QpMk/Tgd6U2NB8=",
-          "dev": true,
-          "requires": {
-            "ms": "2.0.0"
-          }
-        },
-        "iconv-lite": {
-          "version": "0.4.24",
-          "resolved": "https://registry.npm.taobao.org/iconv-lite/download/iconv-lite-0.4.24.tgz",
-          "integrity": "sha1-ICK0sl+93CHS9SSXSkdKr+czkIs=",
-          "dev": true,
-          "requires": {
-            "safer-buffer": ">= 2.1.2 < 3"
-          }
-        },
-        "ms": {
-          "version": "2.0.0",
-          "resolved": "https://registry.npm.taobao.org/ms/download/ms-2.0.0.tgz",
-          "integrity": "sha1-VgiurfwAvmwpAd9fmGF4jeDVl8g=",
-          "dev": true
-        },
-        "qs": {
-          "version": "6.7.0",
-          "resolved": "https://registry.npm.taobao.org/qs/download/qs-6.7.0.tgz",
-          "integrity": "sha1-QdwaAV49WB8WIXdr4xr7KHapsbw=",
-          "dev": true
-        }
-      }
-    },
-    "bonjour": {
-      "version": "3.5.0",
-      "resolved": "https://registry.npm.taobao.org/bonjour/download/bonjour-3.5.0.tgz",
-      "integrity": "sha1-jokKGD2O6aI5OzhExpGkK897yfU=",
-      "dev": true,
-      "requires": {
-        "array-flatten": "^2.1.0",
-        "deep-equal": "^1.0.1",
-        "dns-equal": "^1.0.0",
-        "dns-txt": "^2.0.2",
-        "multicast-dns": "^6.0.1",
-        "multicast-dns-service-types": "^1.1.0"
-      }
-    },
-    "boolbase": {
-      "version": "1.0.0",
-      "resolved": "https://registry.npm.taobao.org/boolbase/download/boolbase-1.0.0.tgz",
-      "integrity": "sha1-aN/1++YMUes3cl6p4+0xDcwed24=",
-      "dev": true
-    },
-    "brace-expansion": {
-      "version": "1.1.11",
-      "resolved": "https://registry.npm.taobao.org/brace-expansion/download/brace-expansion-1.1.11.tgz?cache=0&sync_timestamp=1601898189928&other_urls=https%3A%2F%2Fregistry.npm.taobao.org%2Fbrace-expansion%2Fdownload%2Fbrace-expansion-1.1.11.tgz",
-      "integrity": "sha1-PH/L9SnYcibz0vUrlm/1Jx60Qd0=",
-      "dev": true,
-      "requires": {
-        "balanced-match": "^1.0.0",
-        "concat-map": "0.0.1"
-      }
-    },
-    "braces": {
-      "version": "2.3.2",
-      "resolved": "https://registry.npm.taobao.org/braces/download/braces-2.3.2.tgz",
-      "integrity": "sha1-WXn9PxTNUxVl5fot8av/8d+u5yk=",
-      "dev": true,
-      "requires": {
-        "arr-flatten": "^1.1.0",
-        "array-unique": "^0.3.2",
-        "extend-shallow": "^2.0.1",
-        "fill-range": "^4.0.0",
-        "isobject": "^3.0.1",
-        "repeat-element": "^1.1.2",
-        "snapdragon": "^0.8.1",
-        "snapdragon-node": "^2.0.1",
-        "split-string": "^3.0.2",
-        "to-regex": "^3.0.1"
-      },
-      "dependencies": {
-        "extend-shallow": {
-          "version": "2.0.1",
-          "resolved": "https://registry.npm.taobao.org/extend-shallow/download/extend-shallow-2.0.1.tgz",
-          "integrity": "sha1-Ua99YUrZqfYQ6huvu5idaxxWiQ8=",
-          "dev": true,
-          "requires": {
-            "is-extendable": "^0.1.0"
-          }
-        }
-      }
-    },
-    "brorand": {
-      "version": "1.1.0",
-      "resolved": "https://registry.npm.taobao.org/brorand/download/brorand-1.1.0.tgz",
-      "integrity": "sha1-EsJe/kCkXjwyPrhnWgoM5XsiNx8=",
-      "dev": true
-    },
-    "browser-process-hrtime": {
-      "version": "1.0.0",
-      "resolved": "https://registry.npm.taobao.org/browser-process-hrtime/download/browser-process-hrtime-1.0.0.tgz",
-      "integrity": "sha1-PJtLfXgsgSHlbxAQbYTA0P/JRiY=",
-      "dev": true
-    },
-    "browserify-aes": {
-      "version": "1.2.0",
-      "resolved": "https://registry.npm.taobao.org/browserify-aes/download/browserify-aes-1.2.0.tgz",
-      "integrity": "sha1-Mmc0ZC9APavDADIJhTu3CtQo70g=",
-      "dev": true,
-      "requires": {
-        "buffer-xor": "^1.0.3",
-        "cipher-base": "^1.0.0",
-        "create-hash": "^1.1.0",
-        "evp_bytestokey": "^1.0.3",
-        "inherits": "^2.0.1",
-        "safe-buffer": "^5.0.1"
-      }
-    },
-    "browserify-cipher": {
-      "version": "1.0.1",
-      "resolved": "https://registry.npm.taobao.org/browserify-cipher/download/browserify-cipher-1.0.1.tgz",
-      "integrity": "sha1-jWR0wbhwv9q807z8wZNKEOlPFfA=",
-      "dev": true,
-      "requires": {
-        "browserify-aes": "^1.0.4",
-        "browserify-des": "^1.0.0",
-        "evp_bytestokey": "^1.0.0"
-      }
-    },
-    "browserify-des": {
-      "version": "1.0.2",
-      "resolved": "https://registry.npm.taobao.org/browserify-des/download/browserify-des-1.0.2.tgz",
-      "integrity": "sha1-OvTx9Zg5QDVy8cZiBDdfen9wPpw=",
-      "dev": true,
-      "requires": {
-        "cipher-base": "^1.0.1",
-        "des.js": "^1.0.0",
-        "inherits": "^2.0.1",
-        "safe-buffer": "^5.1.2"
-      }
-    },
-    "browserify-rsa": {
-      "version": "4.1.0",
-      "resolved": "https://registry.npm.taobao.org/browserify-rsa/download/browserify-rsa-4.1.0.tgz",
-      "integrity": "sha1-sv0Gtbda4pf3zi3GUfkY9b4VjI0=",
-      "dev": true,
-      "requires": {
-        "bn.js": "^5.0.0",
-        "randombytes": "^2.0.1"
-      }
-    },
-    "browserify-sign": {
-      "version": "4.2.1",
-      "resolved": "https://registry.npm.taobao.org/browserify-sign/download/browserify-sign-4.2.1.tgz",
-      "integrity": "sha1-6vSt1G3VS+O7OzbAzxWrvrp5VsM=",
-      "dev": true,
-      "requires": {
-        "bn.js": "^5.1.1",
-        "browserify-rsa": "^4.0.1",
-        "create-hash": "^1.2.0",
-        "create-hmac": "^1.1.7",
-        "elliptic": "^6.5.3",
-        "inherits": "^2.0.4",
-        "parse-asn1": "^5.1.5",
-        "readable-stream": "^3.6.0",
-        "safe-buffer": "^5.2.0"
-      }
-    },
-    "browserify-zlib": {
-      "version": "0.2.0",
-      "resolved": "https://registry.npm.taobao.org/browserify-zlib/download/browserify-zlib-0.2.0.tgz",
-      "integrity": "sha1-KGlFnZqjviRf6P4sofRuLn9U1z8=",
-      "dev": true,
-      "requires": {
-        "pako": "~1.0.5"
-      }
-    },
-    "browserslist": {
-      "version": "4.14.7",
-      "resolved": "https://registry.npm.taobao.org/browserslist/download/browserslist-4.14.7.tgz?cache=0&sync_timestamp=1604944989360&other_urls=https%3A%2F%2Fregistry.npm.taobao.org%2Fbrowserslist%2Fdownload%2Fbrowserslist-4.14.7.tgz",
-      "integrity": "sha1-wHHBs2IsHC55B5mje7CUc6Q1HLY=",
-      "dev": true,
-      "requires": {
-        "caniuse-lite": "^1.0.30001157",
-        "colorette": "^1.2.1",
-        "electron-to-chromium": "^1.3.591",
-        "escalade": "^3.1.1",
-        "node-releases": "^1.1.66"
-      }
-    },
-    "bser": {
-      "version": "2.1.1",
-      "resolved": "https://registry.npm.taobao.org/bser/download/bser-2.1.1.tgz",
-      "integrity": "sha1-5nh9og7OnQeZhTPP2d5vXDj0vAU=",
-      "dev": true,
-      "requires": {
-        "node-int64": "^0.4.0"
-      }
-    },
-    "buffer": {
-      "version": "4.9.2",
-      "resolved": "https://registry.npm.taobao.org/buffer/download/buffer-4.9.2.tgz?cache=0&sync_timestamp=1604959484032&other_urls=https%3A%2F%2Fregistry.npm.taobao.org%2Fbuffer%2Fdownload%2Fbuffer-4.9.2.tgz",
-      "integrity": "sha1-Iw6tNEACmIZEhBqwJEr4xEu+Pvg=",
-      "dev": true,
-      "requires": {
-        "base64-js": "^1.0.2",
-        "ieee754": "^1.1.4",
-        "isarray": "^1.0.0"
-      }
-    },
-    "buffer-from": {
-      "version": "1.1.1",
-      "resolved": "https://registry.npm.taobao.org/buffer-from/download/buffer-from-1.1.1.tgz",
-      "integrity": "sha1-MnE7wCj3XAL9txDXx7zsHyxgcO8=",
-      "dev": true
-    },
-    "buffer-indexof": {
-      "version": "1.1.1",
-      "resolved": "https://registry.npm.taobao.org/buffer-indexof/download/buffer-indexof-1.1.1.tgz",
-      "integrity": "sha1-Uvq8xqYG0aADAoAmSO9o9jnaJow=",
-      "dev": true
-    },
-    "buffer-xor": {
-      "version": "1.0.3",
-      "resolved": "https://registry.npm.taobao.org/buffer-xor/download/buffer-xor-1.0.3.tgz",
-      "integrity": "sha1-JuYe0UIvtw3ULm42cp7VHYVf6Nk=",
-      "dev": true
-    },
-    "build-plugin-app-core": {
-      "version": "0.1.23",
-      "resolved": "https://registry.npm.taobao.org/build-plugin-app-core/download/build-plugin-app-core-0.1.23.tgz",
-      "integrity": "sha1-cbiqu2MYpdi9gqnpMuKaupusfa0=",
-      "dev": true,
-      "requires": {
-        "chalk": "^4.0.0",
-        "chokidar": "^3.4.1",
-        "create-app-shared": "^0.1.14",
-        "ejs": "^3.0.1",
-        "fs-extra": "^8.1.0",
-        "globby": "^11.0.0",
-        "history": "^4.9.0",
-        "miniapp-history": "^0.1.0",
-        "miniapp-renderer": "^0.1.4",
-        "prettier": "^2.0.2",
-        "query-string": "^6.13.1",
-        "rax-app-renderer": "^0.1.4",
-        "rax-use-router": "^3.0.0",
-        "react-app-renderer": "0.1.10",
-        "universal-env": "^3.0.0"
-      },
-      "dependencies": {
-        "@nodelib/fs.stat": {
-          "version": "2.0.3",
-          "resolved": "https://registry.npm.taobao.org/@nodelib/fs.stat/download/@nodelib/fs.stat-2.0.3.tgz",
-          "integrity": "sha1-NNxfTKu8cg9OYPdadH5+zWwXW9M=",
-          "dev": true
-        },
-        "ansi-styles": {
-          "version": "4.3.0",
-          "resolved": "https://registry.npm.taobao.org/ansi-styles/download/ansi-styles-4.3.0.tgz?cache=0&sync_timestamp=1601839122515&other_urls=https%3A%2F%2Fregistry.npm.taobao.org%2Fansi-styles%2Fdownload%2Fansi-styles-4.3.0.tgz",
-          "integrity": "sha1-7dgDYornHATIWuegkG7a00tkiTc=",
-          "dev": true,
-          "requires": {
-            "color-convert": "^2.0.1"
-          }
-        },
-        "array-union": {
-          "version": "2.1.0",
-          "resolved": "https://registry.npm.taobao.org/array-union/download/array-union-2.1.0.tgz",
-          "integrity": "sha1-t5hCCtvrHego2ErNii4j0+/oXo0=",
-          "dev": true
-        },
-        "braces": {
-          "version": "3.0.2",
-          "resolved": "https://registry.npm.taobao.org/braces/download/braces-3.0.2.tgz",
-          "integrity": "sha1-NFThpGLujVmeI23zNs2epPiv4Qc=",
-          "dev": true,
-          "requires": {
-            "fill-range": "^7.0.1"
-          }
-        },
-        "chalk": {
-          "version": "4.1.0",
-          "resolved": "https://registry.npm.taobao.org/chalk/download/chalk-4.1.0.tgz",
-          "integrity": "sha1-ThSHCmGNni7dl92DRf2dncMVZGo=",
-          "dev": true,
-          "requires": {
-            "ansi-styles": "^4.1.0",
-            "supports-color": "^7.1.0"
-          }
-        },
-        "color-convert": {
-          "version": "2.0.1",
-          "resolved": "https://registry.npm.taobao.org/color-convert/download/color-convert-2.0.1.tgz",
-          "integrity": "sha1-ctOmjVmMm9s68q0ehPIdiWq9TeM=",
-          "dev": true,
-          "requires": {
-            "color-name": "~1.1.4"
-          }
-        },
-        "color-name": {
-          "version": "1.1.4",
-          "resolved": "https://registry.npm.taobao.org/color-name/download/color-name-1.1.4.tgz",
-          "integrity": "sha1-wqCah6y95pVD3m9j+jmVyCbFNqI=",
-          "dev": true
-        },
-        "dir-glob": {
-          "version": "3.0.1",
-          "resolved": "https://registry.npm.taobao.org/dir-glob/download/dir-glob-3.0.1.tgz",
-          "integrity": "sha1-Vtv3PZkqSpO6FYT0U0Bj/S5BcX8=",
-          "dev": true,
-          "requires": {
-            "path-type": "^4.0.0"
-          }
-        },
-        "fast-glob": {
-          "version": "3.2.4",
-          "resolved": "https://registry.npm.taobao.org/fast-glob/download/fast-glob-3.2.4.tgz?cache=0&sync_timestamp=1592290372789&other_urls=https%3A%2F%2Fregistry.npm.taobao.org%2Ffast-glob%2Fdownload%2Ffast-glob-3.2.4.tgz",
-          "integrity": "sha1-0grvv5lXk4Pn88xmUpFYybmFVNM=",
-          "dev": true,
-          "requires": {
-            "@nodelib/fs.stat": "^2.0.2",
-            "@nodelib/fs.walk": "^1.2.3",
-            "glob-parent": "^5.1.0",
-            "merge2": "^1.3.0",
-            "micromatch": "^4.0.2",
-            "picomatch": "^2.2.1"
-          }
-        },
-        "fill-range": {
-          "version": "7.0.1",
-          "resolved": "https://registry.npm.taobao.org/fill-range/download/fill-range-7.0.1.tgz",
-          "integrity": "sha1-GRmmp8df44ssfHflGYU12prN2kA=",
-          "dev": true,
-          "requires": {
-            "to-regex-range": "^5.0.1"
-          }
-        },
-        "glob-parent": {
-          "version": "5.1.1",
-          "resolved": "https://registry.npm.taobao.org/glob-parent/download/glob-parent-5.1.1.tgz",
-          "integrity": "sha1-tsHvQXxOVmPqSY8cRa+saRa7wik=",
-          "dev": true,
-          "requires": {
-            "is-glob": "^4.0.1"
-          }
-        },
-        "globby": {
-          "version": "11.0.1",
-          "resolved": "https://registry.npm.taobao.org/globby/download/globby-11.0.1.tgz",
-          "integrity": "sha1-mivxB6Bo8//qvEmtcCx57ejP01c=",
-          "dev": true,
-          "requires": {
-            "array-union": "^2.1.0",
-            "dir-glob": "^3.0.1",
-            "fast-glob": "^3.1.1",
-            "ignore": "^5.1.4",
-            "merge2": "^1.3.0",
-            "slash": "^3.0.0"
-          }
-        },
-        "has-flag": {
-          "version": "4.0.0",
-          "resolved": "https://registry.npm.taobao.org/has-flag/download/has-flag-4.0.0.tgz?cache=0&sync_timestamp=1596294337050&other_urls=https%3A%2F%2Fregistry.npm.taobao.org%2Fhas-flag%2Fdownload%2Fhas-flag-4.0.0.tgz",
-          "integrity": "sha1-lEdx/ZyByBJlxNaUGGDaBrtZR5s=",
-          "dev": true
-        },
-        "is-number": {
-          "version": "7.0.0",
-          "resolved": "https://registry.npm.taobao.org/is-number/download/is-number-7.0.0.tgz",
-          "integrity": "sha1-dTU0W4lnNNX4DE0GxQlVUnoU8Ss=",
-          "dev": true
-        },
-        "micromatch": {
-          "version": "4.0.2",
-          "resolved": "https://registry.npm.taobao.org/micromatch/download/micromatch-4.0.2.tgz",
-          "integrity": "sha1-T8sJmb+fvC/L3SEvbWKbmlbDklk=",
-          "dev": true,
-          "requires": {
-            "braces": "^3.0.1",
-            "picomatch": "^2.0.5"
-          }
-        },
-        "path-type": {
-          "version": "4.0.0",
-          "resolved": "https://registry.npm.taobao.org/path-type/download/path-type-4.0.0.tgz",
-          "integrity": "sha1-hO0BwKe6OAr+CdkKjBgNzZ0DBDs=",
-          "dev": true
-        },
-        "slash": {
-          "version": "3.0.0",
-          "resolved": "https://registry.npm.taobao.org/slash/download/slash-3.0.0.tgz",
-          "integrity": "sha1-ZTm+hwwWWtvVJAIg2+Nh8bxNRjQ=",
-          "dev": true
-        },
-        "supports-color": {
-          "version": "7.2.0",
-          "resolved": "https://registry.npm.taobao.org/supports-color/download/supports-color-7.2.0.tgz?cache=0&sync_timestamp=1598611730985&other_urls=https%3A%2F%2Fregistry.npm.taobao.org%2Fsupports-color%2Fdownload%2Fsupports-color-7.2.0.tgz",
-          "integrity": "sha1-G33NyzK4E4gBs+R4umpRyqiWSNo=",
-          "dev": true,
-          "requires": {
-            "has-flag": "^4.0.0"
-          }
-        },
-        "to-regex-range": {
-          "version": "5.0.1",
-          "resolved": "https://registry.npm.taobao.org/to-regex-range/download/to-regex-range-5.0.1.tgz",
-          "integrity": "sha1-FkjESq58jZiKMmAY7XL1tN0DkuQ=",
-          "dev": true,
-          "requires": {
-            "is-number": "^7.0.0"
-          }
-        }
-      }
-    },
-    "build-plugin-fusion": {
-      "version": "0.1.8",
-      "resolved": "https://registry.npm.taobao.org/build-plugin-fusion/download/build-plugin-fusion-0.1.8.tgz",
-      "integrity": "sha1-JVUBeV5/tHp/y1YVPalLBGihwyw=",
-      "dev": true,
-      "requires": {
-        "babel-plugin-import": "^1.11.2",
-        "babel-plugin-module-resolver": "^4.0.0",
-        "find-root": "^1.1.0",
-        "ice-skin-loader": "^0.3.0-0",
-        "lodash": "^4.17.15",
-        "postcss": "^7.0.32",
-        "postcss-plugin-rpx2vw": "^0.0.2",
-        "resolve-sass-import": "^0.1.0",
-        "semver": "^6.1.0",
-        "webpack-plugin-import": "^0.2.5",
-        "webpack-sources": "^1.3.0"
-      },
-      "dependencies": {
-        "semver": {
-          "version": "6.3.0",
-          "resolved": "https://registry.npm.taobao.org/semver/download/semver-6.3.0.tgz",
-          "integrity": "sha1-7gpkyK9ejO6mdoexM3YeG+y9HT0=",
-          "dev": true
-        }
-      }
-    },
-    "build-plugin-ice-config": {
-      "version": "1.7.1",
-      "resolved": "https://registry.npm.taobao.org/build-plugin-ice-config/download/build-plugin-ice-config-1.7.1.tgz",
-      "integrity": "sha1-vLMLxnV19KUDh9Bl9NTDc2wwoWM=",
-      "dev": true,
-      "requires": {
-        "fs-extra": "^8.1.0"
-      }
-    },
-    "build-plugin-ice-helpers": {
-      "version": "1.7.1",
-      "resolved": "https://registry.npm.taobao.org/build-plugin-ice-helpers/download/build-plugin-ice-helpers-1.7.1.tgz",
-      "integrity": "sha1-i4cpu3bE1IziChXNGEtI+8+30fs=",
-      "dev": true,
-      "requires": {
-        "@types/cookie": "^0.3.3",
-        "@types/url-parse": "^1.4.3",
-        "cookie": "^0.4.0",
-        "fs-extra": "^8.1.0",
-        "url-parse": "^1.4.7"
-      },
-      "dependencies": {
-        "cookie": {
-          "version": "0.4.1",
-          "resolved": "https://registry.npm.taobao.org/cookie/download/cookie-0.4.1.tgz?cache=0&sync_timestamp=1587525998658&other_urls=https%3A%2F%2Fregistry.npm.taobao.org%2Fcookie%2Fdownload%2Fcookie-0.4.1.tgz",
-          "integrity": "sha1-r9cT/ibr0hupXOth+agRblClN9E=",
-          "dev": true
-        }
-      }
-    },
-    "build-plugin-ice-logger": {
-      "version": "1.7.2",
-      "resolved": "https://registry.npm.taobao.org/build-plugin-ice-logger/download/build-plugin-ice-logger-1.7.2.tgz",
-      "integrity": "sha1-wdgmoHBhAqdI5OSh+bfAckJ3GGY=",
-      "dev": true,
-      "requires": {
-        "fs-extra": "^8.1.0",
-        "loglevel": "^1.6.6"
-      }
-    },
-    "build-plugin-ice-mpa": {
-      "version": "1.7.1",
-      "resolved": "https://registry.npm.taobao.org/build-plugin-ice-mpa/download/build-plugin-ice-mpa-1.7.1.tgz",
-      "integrity": "sha1-TEmVlIgmfOgVtMjG8Bazg+HgazM=",
-      "dev": true,
-      "requires": {
-        "fs-extra": "^8.1.0"
-      }
-    },
-    "build-plugin-ice-request": {
-      "version": "1.7.2",
-      "resolved": "https://registry.npm.taobao.org/build-plugin-ice-request/download/build-plugin-ice-request-1.7.2.tgz",
-      "integrity": "sha1-gNEERdIKc64+/sgkRLw9lfGEdT0=",
-      "dev": true,
-      "requires": {
-        "@ahooksjs/use-request": "^2.0.0",
-        "axios": "^0.19.2",
-        "fs-extra": "^8.1.0"
-      }
-    },
-    "build-plugin-ice-router": {
-      "version": "1.7.5",
-      "resolved": "https://registry.npm.taobao.org/build-plugin-ice-router/download/build-plugin-ice-router-1.7.5.tgz",
-      "integrity": "sha1-ff0ekvUyGe4X+VUAUwD/E5TKB8k=",
-      "dev": true,
-      "requires": {
-        "fs-extra": "^8.1.0",
-        "glob": "^7.1.6",
-        "history": "^4.10.1",
-        "query-string": "^6.12.1",
-        "react": "^16.12.0",
-        "react-dom": "^16.12.0",
-        "react-router-dom": "^5.1.2"
-      }
-    },
-    "build-plugin-ice-ssr": {
-      "version": "1.7.6",
-      "resolved": "https://registry.npm.taobao.org/build-plugin-ice-ssr/download/build-plugin-ice-ssr-1.7.6.tgz",
-      "integrity": "sha1-e9TYbHFvH2BeImfNbCB+hdOMYQ0=",
-      "dev": true,
-      "requires": {
-        "build-scripts-config": "^0.1.6",
-        "chalk": "^4.0.0",
-        "cheerio": "^1.0.0-rc.3",
-        "ejs": "^3.0.1",
-        "fs-extra": "^8.1.0",
-        "html-minifier": "^4.0.0",
-        "parseurl": "^1.3.3"
-      },
-      "dependencies": {
-        "ansi-styles": {
-          "version": "4.3.0",
-          "resolved": "https://registry.npm.taobao.org/ansi-styles/download/ansi-styles-4.3.0.tgz?cache=0&sync_timestamp=1601839122515&other_urls=https%3A%2F%2Fregistry.npm.taobao.org%2Fansi-styles%2Fdownload%2Fansi-styles-4.3.0.tgz",
-          "integrity": "sha1-7dgDYornHATIWuegkG7a00tkiTc=",
-          "dev": true,
-          "requires": {
-            "color-convert": "^2.0.1"
-          }
-        },
-        "chalk": {
-          "version": "4.1.0",
-          "resolved": "https://registry.npm.taobao.org/chalk/download/chalk-4.1.0.tgz",
-          "integrity": "sha1-ThSHCmGNni7dl92DRf2dncMVZGo=",
-          "dev": true,
-          "requires": {
-            "ansi-styles": "^4.1.0",
-            "supports-color": "^7.1.0"
-          }
-        },
-        "color-convert": {
-          "version": "2.0.1",
-          "resolved": "https://registry.npm.taobao.org/color-convert/download/color-convert-2.0.1.tgz",
-          "integrity": "sha1-ctOmjVmMm9s68q0ehPIdiWq9TeM=",
-          "dev": true,
-          "requires": {
-            "color-name": "~1.1.4"
-          }
-        },
-        "color-name": {
-          "version": "1.1.4",
-          "resolved": "https://registry.npm.taobao.org/color-name/download/color-name-1.1.4.tgz",
-          "integrity": "sha1-wqCah6y95pVD3m9j+jmVyCbFNqI=",
-          "dev": true
-        },
-        "has-flag": {
-          "version": "4.0.0",
-          "resolved": "https://registry.npm.taobao.org/has-flag/download/has-flag-4.0.0.tgz?cache=0&sync_timestamp=1596294337050&other_urls=https%3A%2F%2Fregistry.npm.taobao.org%2Fhas-flag%2Fdownload%2Fhas-flag-4.0.0.tgz",
-          "integrity": "sha1-lEdx/ZyByBJlxNaUGGDaBrtZR5s=",
-          "dev": true
-        },
-        "supports-color": {
-          "version": "7.2.0",
-          "resolved": "https://registry.npm.taobao.org/supports-color/download/supports-color-7.2.0.tgz?cache=0&sync_timestamp=1598611730985&other_urls=https%3A%2F%2Fregistry.npm.taobao.org%2Fsupports-color%2Fdownload%2Fsupports-color-7.2.0.tgz",
-          "integrity": "sha1-G33NyzK4E4gBs+R4umpRyqiWSNo=",
-          "dev": true,
-          "requires": {
-            "has-flag": "^4.0.0"
-          }
-        }
-      }
-    },
-    "build-plugin-ice-store": {
-      "version": "1.7.8",
-      "resolved": "https://registry.npm.taobao.org/build-plugin-ice-store/download/build-plugin-ice-store-1.7.8.tgz",
-      "integrity": "sha1-XXk7lFvgWu+fA2ZmuVi1ffod3LM=",
-      "dev": true,
-      "requires": {
-        "@ice/store": "^1.3.1",
-        "ejs": "^3.0.2",
-        "enhanced-resolve": "^4.3.0",
-        "fs-extra": "^8.1.0",
-        "fs-readdir-recursive": "^1.1.0",
-        "loader-utils": "^2.0.0",
-        "prettier": "^2.0.4",
-        "rax-redux": "^1.0.0"
-      },
-      "dependencies": {
-        "json5": {
-          "version": "2.1.3",
-          "resolved": "https://registry.npm.taobao.org/json5/download/json5-2.1.3.tgz",
-          "integrity": "sha1-ybD3+pIzv+WAf+ZvzzpWF+1ZfUM=",
-          "dev": true,
-          "requires": {
-            "minimist": "^1.2.5"
-          }
-        },
-        "loader-utils": {
-          "version": "2.0.0",
-          "resolved": "https://registry.npm.taobao.org/loader-utils/download/loader-utils-2.0.0.tgz",
-          "integrity": "sha1-5MrOW4FtQloWa18JfhDNErNgZLA=",
-          "dev": true,
-          "requires": {
-            "big.js": "^5.2.2",
-            "emojis-list": "^3.0.0",
-            "json5": "^2.1.2"
-          }
-        }
-      }
-    },
-    "build-plugin-icestark": {
-      "version": "1.7.2",
-      "resolved": "https://registry.npm.taobao.org/build-plugin-icestark/download/build-plugin-icestark-1.7.2.tgz",
-      "integrity": "sha1-34oaL95xR8eQsxup2H8p6uuKNGY=",
-      "dev": true,
-      "requires": {
-        "@ice/stark": "^1.3.1",
-        "@ice/stark-app": "^1.2.0",
-        "fs-extra": "^8.1.0",
-        "glob": "^7.1.6"
-      }
-    },
-    "build-plugin-miniapp": {
-      "version": "0.1.7",
-      "resolved": "https://registry.npm.taobao.org/build-plugin-miniapp/download/build-plugin-miniapp-0.1.7.tgz",
-      "integrity": "sha1-9gtn1tDUgKf5OWHH8pwv5yS98y0=",
-      "dev": true,
-      "requires": {
-        "miniapp-builder-shared": "^0.1.1",
-        "miniapp-runtime-config": "^0.1.1"
-      }
-    },
-    "build-plugin-moment-locales": {
-      "version": "0.1.0",
-      "resolved": "https://registry.npm.taobao.org/build-plugin-moment-locales/download/build-plugin-moment-locales-0.1.0.tgz",
-      "integrity": "sha1-ipy7+DMBt5J6IatHHRru3/+rZ2Q=",
-      "dev": true
-    },
-    "build-plugin-react-app": {
-      "version": "1.7.10",
-      "resolved": "https://registry.npm.taobao.org/build-plugin-react-app/download/build-plugin-react-app-1.7.10.tgz",
-      "integrity": "sha1-9dG0NCuAGfQCooxZF3Dzn/6QZFM=",
-      "dev": true,
-      "requires": {
-        "@builder/app-helpers": "^1.0.0",
-        "@builder/user-config": "^0.1.0",
-        "build-scripts-config": "^0.1.0",
-        "chalk": "^4.0.0",
-        "copy-webpack-plugin": "^5.0.4",
-        "core-js": "^3.7.0",
-        "debug": "^4.1.1",
-        "fs-extra": "^8.1.0",
-        "html-webpack-plugin": "^3.2.0",
-        "lodash": "^4.17.15",
-        "mkcert": "^1.2.0",
-        "path-exists": "^4.0.0",
-        "postcss-plugin-rpx2vw": "^0.0.2",
-        "react-dev-utils": "^10.2.1",
-        "webpack-plugin-import": "^0.2.6"
-      },
-      "dependencies": {
-        "@babel/code-frame": {
-          "version": "7.8.3",
-          "resolved": "https://registry.npm.taobao.org/@babel/code-frame/download/@babel/code-frame-7.8.3.tgz",
-          "integrity": "sha1-M+JZA9dIEYFTThLsCiXxa2/PQZ4=",
-          "dev": true,
-          "requires": {
-            "@babel/highlight": "^7.8.3"
-          }
-        },
-        "ansi-regex": {
-          "version": "5.0.0",
-          "resolved": "https://registry.npm.taobao.org/ansi-regex/download/ansi-regex-5.0.0.tgz",
-          "integrity": "sha1-OIU59VF5vzkznIGvMKZU1p+Hy3U=",
-          "dev": true
-        },
-        "ansi-styles": {
-          "version": "4.3.0",
-          "resolved": "https://registry.npm.taobao.org/ansi-styles/download/ansi-styles-4.3.0.tgz?cache=0&sync_timestamp=1601839122515&other_urls=https%3A%2F%2Fregistry.npm.taobao.org%2Fansi-styles%2Fdownload%2Fansi-styles-4.3.0.tgz",
-          "integrity": "sha1-7dgDYornHATIWuegkG7a00tkiTc=",
-          "dev": true,
-          "requires": {
-            "color-convert": "^2.0.1"
-          }
-        },
-        "browserslist": {
-          "version": "4.10.0",
-          "resolved": "https://registry.npm.taobao.org/browserslist/download/browserslist-4.10.0.tgz?cache=0&sync_timestamp=1604944989360&other_urls=https%3A%2F%2Fregistry.npm.taobao.org%2Fbrowserslist%2Fdownload%2Fbrowserslist-4.10.0.tgz",
-          "integrity": "sha1-8XlzeRPq8NK5jkkmrBymoVy8xqk=",
-          "dev": true,
-          "requires": {
-            "caniuse-lite": "^1.0.30001035",
-            "electron-to-chromium": "^1.3.378",
-            "node-releases": "^1.1.52",
-            "pkg-up": "^3.1.0"
-          }
-        },
-        "chalk": {
-          "version": "4.1.0",
-          "resolved": "https://registry.npm.taobao.org/chalk/download/chalk-4.1.0.tgz",
-          "integrity": "sha1-ThSHCmGNni7dl92DRf2dncMVZGo=",
-          "dev": true,
-          "requires": {
-            "ansi-styles": "^4.1.0",
-            "supports-color": "^7.1.0"
-          }
-        },
-        "cli-width": {
-          "version": "2.2.1",
-          "resolved": "https://registry.npm.taobao.org/cli-width/download/cli-width-2.2.1.tgz",
-          "integrity": "sha1-sEM9C06chH7xiGik7xb9X8gnHEg=",
-          "dev": true
-        },
-        "color-convert": {
-          "version": "2.0.1",
-          "resolved": "https://registry.npm.taobao.org/color-convert/download/color-convert-2.0.1.tgz",
-          "integrity": "sha1-ctOmjVmMm9s68q0ehPIdiWq9TeM=",
-          "dev": true,
-          "requires": {
-            "color-name": "~1.1.4"
-          }
-        },
-        "color-name": {
-          "version": "1.1.4",
-          "resolved": "https://registry.npm.taobao.org/color-name/download/color-name-1.1.4.tgz",
-          "integrity": "sha1-wqCah6y95pVD3m9j+jmVyCbFNqI=",
-          "dev": true
-        },
-        "copy-webpack-plugin": {
-          "version": "5.1.2",
-          "resolved": "https://registry.npm.taobao.org/copy-webpack-plugin/download/copy-webpack-plugin-5.1.2.tgz?cache=0&other_urls=https%3A%2F%2Fregistry.npm.taobao.org%2Fcopy-webpack-plugin%2Fdownload%2Fcopy-webpack-plugin-5.1.2.tgz",
-          "integrity": "sha1-ioieHcr6bJHGzUvhrRWPHTgjuuI=",
-          "dev": true,
-          "requires": {
-            "cacache": "^12.0.3",
-            "find-cache-dir": "^2.1.0",
-            "glob-parent": "^3.1.0",
-            "globby": "^7.1.1",
-            "is-glob": "^4.0.1",
-            "loader-utils": "^1.2.3",
-            "minimatch": "^3.0.4",
-            "normalize-path": "^3.0.0",
-            "p-limit": "^2.2.1",
-            "schema-utils": "^1.0.0",
-            "serialize-javascript": "^4.0.0",
-            "webpack-log": "^2.0.0"
-          }
-        },
-        "core-js": {
-          "version": "3.7.0",
-          "resolved": "https://registry.npm.taobao.org/core-js/download/core-js-3.7.0.tgz?cache=0&sync_timestamp=1604675498528&other_urls=https%3A%2F%2Fregistry.npm.taobao.org%2Fcore-js%2Fdownload%2Fcore-js-3.7.0.tgz",
-          "integrity": "sha1-sKdhoCSIV3r7+XF55Ggb9JVoUg8=",
-          "dev": true
-        },
-        "cross-spawn": {
-          "version": "7.0.1",
-          "resolved": "https://registry.npm.taobao.org/cross-spawn/download/cross-spawn-7.0.1.tgz",
-          "integrity": "sha1-CrVihuD3wk4VPQTMKqAn5DqaXRQ=",
-          "dev": true,
-          "requires": {
-            "path-key": "^3.1.0",
-            "shebang-command": "^2.0.0",
-            "which": "^2.0.1"
-          }
-        },
-        "detect-port-alt": {
-          "version": "1.1.6",
-          "resolved": "https://registry.npm.taobao.org/detect-port-alt/download/detect-port-alt-1.1.6.tgz",
-          "integrity": "sha1-JHB96r6TLUo89iEwICfCsmZWgnU=",
-          "dev": true,
-          "requires": {
-            "address": "^1.0.1",
-            "debug": "^2.6.0"
-          },
-          "dependencies": {
-            "debug": {
-              "version": "2.6.9",
-              "resolved": "https://registry.npm.taobao.org/debug/download/debug-2.6.9.tgz?cache=0&sync_timestamp=1600502871403&other_urls=https%3A%2F%2Fregistry.npm.taobao.org%2Fdebug%2Fdownload%2Fdebug-2.6.9.tgz",
-              "integrity": "sha1-XRKFFd8TT/Mn6QpMk/Tgd6U2NB8=",
-              "dev": true,
-              "requires": {
-                "ms": "2.0.0"
-              }
-            }
-          }
-        },
-        "emoji-regex": {
-          "version": "8.0.0",
-          "resolved": "https://registry.npm.taobao.org/emoji-regex/download/emoji-regex-8.0.0.tgz?cache=0&sync_timestamp=1603212263242&other_urls=https%3A%2F%2Fregistry.npm.taobao.org%2Femoji-regex%2Fdownload%2Femoji-regex-8.0.0.tgz",
-          "integrity": "sha1-6Bj9ac5cz8tARZT4QpY79TFkzDc=",
-          "dev": true
-        },
-        "emojis-list": {
-          "version": "2.1.0",
-          "resolved": "https://registry.npm.taobao.org/emojis-list/download/emojis-list-2.1.0.tgz",
-          "integrity": "sha1-TapNnbAPmBmIDHn6RXrlsJof04k=",
-          "dev": true
-        },
-        "escape-string-regexp": {
-          "version": "2.0.0",
-          "resolved": "https://registry.npm.taobao.org/escape-string-regexp/download/escape-string-regexp-2.0.0.tgz?cache=0&sync_timestamp=1587627107924&other_urls=https%3A%2F%2Fregistry.npm.taobao.org%2Fescape-string-regexp%2Fdownload%2Fescape-string-regexp-2.0.0.tgz",
-          "integrity": "sha1-owME6Z2qMuI7L9IPUbq9B8/8o0Q=",
-          "dev": true
-        },
-        "filesize": {
-          "version": "6.0.1",
-          "resolved": "https://registry.npm.taobao.org/filesize/download/filesize-6.0.1.tgz",
-          "integrity": "sha1-+FC1CZCcfIb35FDqGQBsMcLtPS8=",
-          "dev": true
-        },
-        "find-up": {
-          "version": "4.1.0",
-          "resolved": "https://registry.npm.taobao.org/find-up/download/find-up-4.1.0.tgz?cache=0&sync_timestamp=1597169862146&other_urls=https%3A%2F%2Fregistry.npm.taobao.org%2Ffind-up%2Fdownload%2Ffind-up-4.1.0.tgz",
-          "integrity": "sha1-l6/n1s3AvFkoWEt8jXsW6KmqXRk=",
-          "dev": true,
-          "requires": {
-            "locate-path": "^5.0.0",
-            "path-exists": "^4.0.0"
-          }
-        },
-        "fork-ts-checker-webpack-plugin": {
-          "version": "3.1.1",
-          "resolved": "https://registry.npm.taobao.org/fork-ts-checker-webpack-plugin/download/fork-ts-checker-webpack-plugin-3.1.1.tgz",
-          "integrity": "sha1-oWQsDT5l9QwswXQunAqA9EH4axk=",
-          "dev": true,
-          "requires": {
-            "babel-code-frame": "^6.22.0",
-            "chalk": "^2.4.1",
-            "chokidar": "^3.3.0",
-            "micromatch": "^3.1.10",
-            "minimatch": "^3.0.4",
-            "semver": "^5.6.0",
-            "tapable": "^1.0.0",
-            "worker-rpc": "^0.1.0"
-          },
-          "dependencies": {
-            "ansi-styles": {
-              "version": "3.2.1",
-              "resolved": "https://registry.npm.taobao.org/ansi-styles/download/ansi-styles-3.2.1.tgz?cache=0&sync_timestamp=1601839122515&other_urls=https%3A%2F%2Fregistry.npm.taobao.org%2Fansi-styles%2Fdownload%2Fansi-styles-3.2.1.tgz",
-              "integrity": "sha1-QfuyAkPlCxK+DwS43tvwdSDOhB0=",
-              "dev": true,
-              "requires": {
-                "color-convert": "^1.9.0"
-              }
-            },
-            "chalk": {
-              "version": "2.4.2",
-              "resolved": "https://registry.npm.taobao.org/chalk/download/chalk-2.4.2.tgz",
-              "integrity": "sha1-zUJUFnelQzPPVBpJEIwUMrRMlCQ=",
-              "dev": true,
-              "requires": {
-                "ansi-styles": "^3.2.1",
-                "escape-string-regexp": "^1.0.5",
-                "supports-color": "^5.3.0"
-              }
-            },
-            "color-convert": {
-              "version": "1.9.3",
-              "resolved": "https://registry.npm.taobao.org/color-convert/download/color-convert-1.9.3.tgz",
-              "integrity": "sha1-u3GFBpDh8TZWfeYp0tVHHe2kweg=",
-              "dev": true,
-              "requires": {
-                "color-name": "1.1.3"
-              }
-            },
-            "color-name": {
-              "version": "1.1.3",
-              "resolved": "https://registry.npm.taobao.org/color-name/download/color-name-1.1.3.tgz",
-              "integrity": "sha1-p9BVi9icQveV3UIyj3QIMcpTvCU=",
-              "dev": true
-            },
-            "escape-string-regexp": {
-              "version": "1.0.5",
-              "resolved": "https://registry.npm.taobao.org/escape-string-regexp/download/escape-string-regexp-1.0.5.tgz?cache=0&sync_timestamp=1587627107924&other_urls=https%3A%2F%2Fregistry.npm.taobao.org%2Fescape-string-regexp%2Fdownload%2Fescape-string-regexp-1.0.5.tgz",
-              "integrity": "sha1-G2HAViGQqN/2rjuyzwIAyhMLhtQ=",
-              "dev": true
-            },
-            "has-flag": {
-              "version": "3.0.0",
-              "resolved": "https://registry.npm.taobao.org/has-flag/download/has-flag-3.0.0.tgz?cache=0&sync_timestamp=1596294337050&other_urls=https%3A%2F%2Fregistry.npm.taobao.org%2Fhas-flag%2Fdownload%2Fhas-flag-3.0.0.tgz",
-              "integrity": "sha1-tdRU3CGZriJWmfNGfloH87lVuv0=",
-              "dev": true
-            },
-            "supports-color": {
-              "version": "5.5.0",
-              "resolved": "https://registry.npm.taobao.org/supports-color/download/supports-color-5.5.0.tgz?cache=0&sync_timestamp=1598611730985&other_urls=https%3A%2F%2Fregistry.npm.taobao.org%2Fsupports-color%2Fdownload%2Fsupports-color-5.5.0.tgz",
-              "integrity": "sha1-4uaaRKyHcveKHsCzW2id9lMO/I8=",
-              "dev": true,
-              "requires": {
-                "has-flag": "^3.0.0"
-              }
-            }
-          }
-        },
-        "globby": {
-          "version": "7.1.1",
-          "resolved": "https://registry.npm.taobao.org/globby/download/globby-7.1.1.tgz",
-          "integrity": "sha1-+yzP+UAfhgCUXfral0QMypcrhoA=",
-          "dev": true,
-          "requires": {
-            "array-union": "^1.0.1",
-            "dir-glob": "^2.0.0",
-            "glob": "^7.1.2",
-            "ignore": "^3.3.5",
-            "pify": "^3.0.0",
-            "slash": "^1.0.0"
-          }
-        },
-        "has-flag": {
-          "version": "4.0.0",
-          "resolved": "https://registry.npm.taobao.org/has-flag/download/has-flag-4.0.0.tgz?cache=0&sync_timestamp=1596294337050&other_urls=https%3A%2F%2Fregistry.npm.taobao.org%2Fhas-flag%2Fdownload%2Fhas-flag-4.0.0.tgz",
-          "integrity": "sha1-lEdx/ZyByBJlxNaUGGDaBrtZR5s=",
-          "dev": true
-        },
-        "ignore": {
-          "version": "3.3.10",
-          "resolved": "https://registry.npm.taobao.org/ignore/download/ignore-3.3.10.tgz",
-          "integrity": "sha1-Cpf7h2mG6AgcYxFg+PnziRV/AEM=",
-          "dev": true
-        },
-        "inquirer": {
-          "version": "7.0.4",
-          "resolved": "https://registry.npm.taobao.org/inquirer/download/inquirer-7.0.4.tgz",
-          "integrity": "sha1-ma9b3kcVOryiP1x/ww2yR/OdpwM=",
-          "dev": true,
-          "requires": {
-            "ansi-escapes": "^4.2.1",
-            "chalk": "^2.4.2",
-            "cli-cursor": "^3.1.0",
-            "cli-width": "^2.0.0",
-            "external-editor": "^3.0.3",
-            "figures": "^3.0.0",
-            "lodash": "^4.17.15",
-            "mute-stream": "0.0.8",
-            "run-async": "^2.2.0",
-            "rxjs": "^6.5.3",
-            "string-width": "^4.1.0",
-            "strip-ansi": "^5.1.0",
-            "through": "^2.3.6"
-          },
-          "dependencies": {
-            "ansi-regex": {
-              "version": "4.1.0",
-              "resolved": "https://registry.npm.taobao.org/ansi-regex/download/ansi-regex-4.1.0.tgz",
-              "integrity": "sha1-i5+PCM8ay4Q3Vqg5yox+MWjFGZc=",
-              "dev": true
-            },
-            "ansi-styles": {
-              "version": "3.2.1",
-              "resolved": "https://registry.npm.taobao.org/ansi-styles/download/ansi-styles-3.2.1.tgz?cache=0&sync_timestamp=1601839122515&other_urls=https%3A%2F%2Fregistry.npm.taobao.org%2Fansi-styles%2Fdownload%2Fansi-styles-3.2.1.tgz",
-              "integrity": "sha1-QfuyAkPlCxK+DwS43tvwdSDOhB0=",
-              "dev": true,
-              "requires": {
-                "color-convert": "^1.9.0"
-              }
-            },
-            "chalk": {
-              "version": "2.4.2",
-              "resolved": "https://registry.npm.taobao.org/chalk/download/chalk-2.4.2.tgz",
-              "integrity": "sha1-zUJUFnelQzPPVBpJEIwUMrRMlCQ=",
-              "dev": true,
-              "requires": {
-                "ansi-styles": "^3.2.1",
-                "escape-string-regexp": "^1.0.5",
-                "supports-color": "^5.3.0"
-              }
-            },
-            "color-convert": {
-              "version": "1.9.3",
-              "resolved": "https://registry.npm.taobao.org/color-convert/download/color-convert-1.9.3.tgz",
-              "integrity": "sha1-u3GFBpDh8TZWfeYp0tVHHe2kweg=",
-              "dev": true,
-              "requires": {
-                "color-name": "1.1.3"
-              }
-            },
-            "color-name": {
-              "version": "1.1.3",
-              "resolved": "https://registry.npm.taobao.org/color-name/download/color-name-1.1.3.tgz",
-              "integrity": "sha1-p9BVi9icQveV3UIyj3QIMcpTvCU=",
-              "dev": true
-            },
-            "escape-string-regexp": {
-              "version": "1.0.5",
-              "resolved": "https://registry.npm.taobao.org/escape-string-regexp/download/escape-string-regexp-1.0.5.tgz?cache=0&sync_timestamp=1587627107924&other_urls=https%3A%2F%2Fregistry.npm.taobao.org%2Fescape-string-regexp%2Fdownload%2Fescape-string-regexp-1.0.5.tgz",
-              "integrity": "sha1-G2HAViGQqN/2rjuyzwIAyhMLhtQ=",
-              "dev": true
-            },
-            "has-flag": {
-              "version": "3.0.0",
-              "resolved": "https://registry.npm.taobao.org/has-flag/download/has-flag-3.0.0.tgz?cache=0&sync_timestamp=1596294337050&other_urls=https%3A%2F%2Fregistry.npm.taobao.org%2Fhas-flag%2Fdownload%2Fhas-flag-3.0.0.tgz",
-              "integrity": "sha1-tdRU3CGZriJWmfNGfloH87lVuv0=",
-              "dev": true
-            },
-            "strip-ansi": {
-              "version": "5.2.0",
-              "resolved": "https://registry.npm.taobao.org/strip-ansi/download/strip-ansi-5.2.0.tgz",
-              "integrity": "sha1-jJpTb+tq/JYr36WxBKUJHBrZwK4=",
-              "dev": true,
-              "requires": {
-                "ansi-regex": "^4.1.0"
-              }
-            },
-            "supports-color": {
-              "version": "5.5.0",
-              "resolved": "https://registry.npm.taobao.org/supports-color/download/supports-color-5.5.0.tgz?cache=0&sync_timestamp=1598611730985&other_urls=https%3A%2F%2Fregistry.npm.taobao.org%2Fsupports-color%2Fdownload%2Fsupports-color-5.5.0.tgz",
-              "integrity": "sha1-4uaaRKyHcveKHsCzW2id9lMO/I8=",
-              "dev": true,
-              "requires": {
-                "has-flag": "^3.0.0"
-              }
-            }
-          }
-        },
-        "is-fullwidth-code-point": {
-          "version": "3.0.0",
-          "resolved": "https://registry.npm.taobao.org/is-fullwidth-code-point/download/is-fullwidth-code-point-3.0.0.tgz",
-          "integrity": "sha1-8Rb4Bk/pCz94RKOJl8C3UFEmnx0=",
-          "dev": true
-        },
-        "locate-path": {
-          "version": "5.0.0",
-          "resolved": "https://registry.npm.taobao.org/locate-path/download/locate-path-5.0.0.tgz",
-          "integrity": "sha1-Gvujlq/WdqbUJQTQpno6frn2KqA=",
-          "dev": true,
-          "requires": {
-            "p-locate": "^4.1.0"
-          }
-        },
-        "ms": {
-          "version": "2.0.0",
-          "resolved": "https://registry.npm.taobao.org/ms/download/ms-2.0.0.tgz",
-          "integrity": "sha1-VgiurfwAvmwpAd9fmGF4jeDVl8g=",
-          "dev": true
-        },
-        "open": {
-          "version": "7.3.0",
-          "resolved": "https://registry.npm.taobao.org/open/download/open-7.3.0.tgz?cache=0&sync_timestamp=1601376312546&other_urls=https%3A%2F%2Fregistry.npm.taobao.org%2Fopen%2Fdownload%2Fopen-7.3.0.tgz",
-          "integrity": "sha1-RUYf3uRkRPNkW24U6zypS4Lhvmk=",
-          "dev": true,
-          "requires": {
-            "is-docker": "^2.0.0",
-            "is-wsl": "^2.1.1"
-          }
-        },
-        "p-limit": {
-          "version": "2.3.0",
-          "resolved": "https://registry.npm.taobao.org/p-limit/download/p-limit-2.3.0.tgz",
-          "integrity": "sha1-PdM8ZHohT9//2DWTPrCG2g3CHbE=",
-          "dev": true,
-          "requires": {
-            "p-try": "^2.0.0"
-          }
-        },
-        "p-locate": {
-          "version": "4.1.0",
-          "resolved": "https://registry.npm.taobao.org/p-locate/download/p-locate-4.1.0.tgz?cache=0&sync_timestamp=1597081508945&other_urls=https%3A%2F%2Fregistry.npm.taobao.org%2Fp-locate%2Fdownload%2Fp-locate-4.1.0.tgz",
-          "integrity": "sha1-o0KLtwiLOmApL2aRkni3wpetTwc=",
-          "dev": true,
-          "requires": {
-            "p-limit": "^2.2.0"
-          }
-        },
-        "p-try": {
-          "version": "2.2.0",
-          "resolved": "https://registry.npm.taobao.org/p-try/download/p-try-2.2.0.tgz",
-          "integrity": "sha1-yyhoVA4xPWHeWPr741zpAE1VQOY=",
-          "dev": true
-        },
-        "path-exists": {
-          "version": "4.0.0",
-          "resolved": "https://registry.npm.taobao.org/path-exists/download/path-exists-4.0.0.tgz",
-          "integrity": "sha1-UTvb4tO5XXdi6METfvoZXGxhtbM=",
-          "dev": true
-        },
-        "path-key": {
-          "version": "3.1.1",
-          "resolved": "https://registry.npm.taobao.org/path-key/download/path-key-3.1.1.tgz",
-          "integrity": "sha1-WB9q3mWMu6ZaDTOA3ndTKVBU83U=",
-          "dev": true
-        },
-        "path-type": {
-          "version": "3.0.0",
-          "resolved": "https://registry.npm.taobao.org/path-type/download/path-type-3.0.0.tgz",
-          "integrity": "sha1-zvMdyOCho7sNEFwM2Xzzv0f0428=",
-          "dev": true,
-          "requires": {
-            "pify": "^3.0.0"
-          }
-        },
-        "pify": {
-          "version": "3.0.0",
-          "resolved": "https://registry.npm.taobao.org/pify/download/pify-3.0.0.tgz",
-          "integrity": "sha1-5aSs0sEB/fPZpNB/DbxNtJ3SgXY=",
-          "dev": true
-        },
-        "react-dev-utils": {
-          "version": "10.2.1",
-          "resolved": "https://registry.npm.taobao.org/react-dev-utils/download/react-dev-utils-10.2.1.tgz?cache=0&sync_timestamp=1603462727689&other_urls=https%3A%2F%2Fregistry.npm.taobao.org%2Freact-dev-utils%2Fdownload%2Freact-dev-utils-10.2.1.tgz",
-          "integrity": "sha1-9t4yWuJfpNVG0J30uxvv3G3RnBk=",
-          "dev": true,
-          "requires": {
-            "@babel/code-frame": "7.8.3",
-            "address": "1.1.2",
-            "browserslist": "4.10.0",
-            "chalk": "2.4.2",
-            "cross-spawn": "7.0.1",
-            "detect-port-alt": "1.1.6",
-            "escape-string-regexp": "2.0.0",
-            "filesize": "6.0.1",
-            "find-up": "4.1.0",
-            "fork-ts-checker-webpack-plugin": "3.1.1",
-            "global-modules": "2.0.0",
-            "globby": "8.0.2",
-            "gzip-size": "5.1.1",
-            "immer": "1.10.0",
-            "inquirer": "7.0.4",
-            "is-root": "2.1.0",
-            "loader-utils": "1.2.3",
-            "open": "^7.0.2",
-            "pkg-up": "3.1.0",
-            "react-error-overlay": "^6.0.7",
-            "recursive-readdir": "2.2.2",
-            "shell-quote": "1.7.2",
-            "strip-ansi": "6.0.0",
-            "text-table": "0.2.0"
-          },
-          "dependencies": {
-            "ansi-styles": {
-              "version": "3.2.1",
-              "resolved": "https://registry.npm.taobao.org/ansi-styles/download/ansi-styles-3.2.1.tgz?cache=0&sync_timestamp=1601839122515&other_urls=https%3A%2F%2Fregistry.npm.taobao.org%2Fansi-styles%2Fdownload%2Fansi-styles-3.2.1.tgz",
-              "integrity": "sha1-QfuyAkPlCxK+DwS43tvwdSDOhB0=",
-              "dev": true,
-              "requires": {
-                "color-convert": "^1.9.0"
-              }
-            },
-            "chalk": {
-              "version": "2.4.2",
-              "resolved": "https://registry.npm.taobao.org/chalk/download/chalk-2.4.2.tgz",
-              "integrity": "sha1-zUJUFnelQzPPVBpJEIwUMrRMlCQ=",
-              "dev": true,
-              "requires": {
-                "ansi-styles": "^3.2.1",
-                "escape-string-regexp": "^1.0.5",
-                "supports-color": "^5.3.0"
-              },
-              "dependencies": {
-                "escape-string-regexp": {
-                  "version": "1.0.5",
-                  "resolved": "https://registry.npm.taobao.org/escape-string-regexp/download/escape-string-regexp-1.0.5.tgz?cache=0&sync_timestamp=1587627107924&other_urls=https%3A%2F%2Fregistry.npm.taobao.org%2Fescape-string-regexp%2Fdownload%2Fescape-string-regexp-1.0.5.tgz",
-                  "integrity": "sha1-G2HAViGQqN/2rjuyzwIAyhMLhtQ=",
-                  "dev": true
-                }
-              }
-            },
-            "color-convert": {
-              "version": "1.9.3",
-              "resolved": "https://registry.npm.taobao.org/color-convert/download/color-convert-1.9.3.tgz",
-              "integrity": "sha1-u3GFBpDh8TZWfeYp0tVHHe2kweg=",
-              "dev": true,
-              "requires": {
-                "color-name": "1.1.3"
-              }
-            },
-            "color-name": {
-              "version": "1.1.3",
-              "resolved": "https://registry.npm.taobao.org/color-name/download/color-name-1.1.3.tgz",
-              "integrity": "sha1-p9BVi9icQveV3UIyj3QIMcpTvCU=",
-              "dev": true
-            },
-            "dir-glob": {
-              "version": "2.0.0",
-              "resolved": "https://registry.npm.taobao.org/dir-glob/download/dir-glob-2.0.0.tgz",
-              "integrity": "sha1-CyBdK2rvmCOMooZZioIE0p0KADQ=",
-              "dev": true,
-              "requires": {
-                "arrify": "^1.0.1",
-                "path-type": "^3.0.0"
-              }
-            },
-            "globby": {
-              "version": "8.0.2",
-              "resolved": "https://registry.npm.taobao.org/globby/download/globby-8.0.2.tgz",
-              "integrity": "sha1-VpdhnM2VxSdduy1vqkIIfBqUHY0=",
-              "dev": true,
-              "requires": {
-                "array-union": "^1.0.1",
-                "dir-glob": "2.0.0",
-                "fast-glob": "^2.0.2",
-                "glob": "^7.1.2",
-                "ignore": "^3.3.5",
-                "pify": "^3.0.0",
-                "slash": "^1.0.0"
-              }
-            },
-            "has-flag": {
-              "version": "3.0.0",
-              "resolved": "https://registry.npm.taobao.org/has-flag/download/has-flag-3.0.0.tgz?cache=0&sync_timestamp=1596294337050&other_urls=https%3A%2F%2Fregistry.npm.taobao.org%2Fhas-flag%2Fdownload%2Fhas-flag-3.0.0.tgz",
-              "integrity": "sha1-tdRU3CGZriJWmfNGfloH87lVuv0=",
-              "dev": true
-            },
-            "loader-utils": {
-              "version": "1.2.3",
-              "resolved": "https://registry.npm.taobao.org/loader-utils/download/loader-utils-1.2.3.tgz",
-              "integrity": "sha1-H/XcaRHJ8KBiUxpMBLYJQGEIwsc=",
-              "dev": true,
-              "requires": {
-                "big.js": "^5.2.2",
-                "emojis-list": "^2.0.0",
-                "json5": "^1.0.1"
-              }
-            },
-            "supports-color": {
-              "version": "5.5.0",
-              "resolved": "https://registry.npm.taobao.org/supports-color/download/supports-color-5.5.0.tgz?cache=0&sync_timestamp=1598611730985&other_urls=https%3A%2F%2Fregistry.npm.taobao.org%2Fsupports-color%2Fdownload%2Fsupports-color-5.5.0.tgz",
-              "integrity": "sha1-4uaaRKyHcveKHsCzW2id9lMO/I8=",
-              "dev": true,
-              "requires": {
-                "has-flag": "^3.0.0"
-              }
-            }
-          }
-        },
-        "semver": {
-          "version": "5.7.1",
-          "resolved": "https://registry.npm.taobao.org/semver/download/semver-5.7.1.tgz",
-          "integrity": "sha1-qVT5Ma66UI0we78Gnv8MAclhFvc=",
-          "dev": true
-        },
-        "shebang-command": {
-          "version": "2.0.0",
-          "resolved": "https://registry.npm.taobao.org/shebang-command/download/shebang-command-2.0.0.tgz",
-          "integrity": "sha1-zNCvT4g1+9wmW4JGGq8MNmY/NOo=",
-          "dev": true,
-          "requires": {
-            "shebang-regex": "^3.0.0"
-          }
-        },
-        "shebang-regex": {
-          "version": "3.0.0",
-          "resolved": "https://registry.npm.taobao.org/shebang-regex/download/shebang-regex-3.0.0.tgz",
-          "integrity": "sha1-rhbxZE2HPsrYQ7AwexQzYtTEIXI=",
-          "dev": true
-        },
-        "slash": {
-          "version": "1.0.0",
-          "resolved": "https://registry.npm.taobao.org/slash/download/slash-1.0.0.tgz",
-          "integrity": "sha1-xB8vbDn8FtHNF61LXYlhFK5HDVU=",
-          "dev": true
-        },
-        "string-width": {
-          "version": "4.2.0",
-          "resolved": "https://registry.npm.taobao.org/string-width/download/string-width-4.2.0.tgz",
-          "integrity": "sha1-lSGCxGzHssMT0VluYjmSvRY7crU=",
-          "dev": true,
-          "requires": {
-            "emoji-regex": "^8.0.0",
-            "is-fullwidth-code-point": "^3.0.0",
-            "strip-ansi": "^6.0.0"
-          }
-        },
-        "strip-ansi": {
-          "version": "6.0.0",
-          "resolved": "https://registry.npm.taobao.org/strip-ansi/download/strip-ansi-6.0.0.tgz",
-          "integrity": "sha1-CxVx3XZpzNTz4G4U7x7tJiJa5TI=",
-          "dev": true,
-          "requires": {
-            "ansi-regex": "^5.0.0"
-          }
-        },
-        "supports-color": {
-          "version": "7.2.0",
-          "resolved": "https://registry.npm.taobao.org/supports-color/download/supports-color-7.2.0.tgz?cache=0&sync_timestamp=1598611730985&other_urls=https%3A%2F%2Fregistry.npm.taobao.org%2Fsupports-color%2Fdownload%2Fsupports-color-7.2.0.tgz",
-          "integrity": "sha1-G33NyzK4E4gBs+R4umpRyqiWSNo=",
-          "dev": true,
-          "requires": {
-            "has-flag": "^4.0.0"
-          }
-        },
-        "which": {
-          "version": "2.0.2",
... 19551 lines suppressed ...


[dubbo-spi-extensions] 10/39: move some extension unit tests to here.

Posted by li...@apache.org.
This is an automated email from the ASF dual-hosted git repository.

liujun pushed a commit to branch 2.7.x
in repository https://gitbox.apache.org/repos/asf/dubbo-spi-extensions.git

commit a463413bf7ad58d52fe766d99ed4128becd5418a
Author: ken.lj <ke...@gmail.com>
AuthorDate: Thu Sep 3 14:07:55 2020 +0800

    move some extension unit tests to here.
---
 .../com/alibaba/dubbo/remoting/p2p/Networker.java  |  22 +
 .../rpc/protocol/thrift/ClassNameGenerator.java    |  22 +
 dubbo-test/pom.xml                                 |  42 +-
 .../apache/dubbo/config/AbstractConfigTest.java    | 927 +++++++++++++++++++++
 .../dubbo/config/AbstractInterfaceConfigTest.java  | 354 ++++++++
 .../dubbo/config/AbstractMethodConfigTest.java     | 126 +++
 .../dubbo/config/AbstractReferenceConfigTest.java  | 212 +++++
 .../dubbo/config/AbstractServiceConfigTest.java    | 184 ++++
 .../apache/dubbo/config/ApplicationConfigTest.java | 217 +++++
 .../apache/dubbo/config/ArgumentConfigTest.java    |  63 ++
 .../dubbo/config/ConfigCenterConfigTest.java       |  44 +
 .../apache/dubbo/config/ConsumerConfigTest.java    |  81 ++
 .../org/apache/dubbo/config/MethodConfigTest.java  | 240 ++++++
 .../org/apache/dubbo/config/ModuleConfigTest.java  | 104 +++
 .../org/apache/dubbo/config/MonitorConfigTest.java | 107 +++
 .../apache/dubbo/config/ProtocolConfigTest.java    | 204 +++++
 .../apache/dubbo/config/ProviderConfigTest.java    | 219 +++++
 .../apache/dubbo/config/ReferenceConfigTest.java   | 159 ++++
 .../apache/dubbo/config/RegistryConfigTest.java    | 190 +++++
 .../org/apache/dubbo/config/ServiceConfigTest.java | 264 ++++++
 .../test/java/org/apache/dubbo/config/api/Box.java |  23 +
 .../org/apache/dubbo/config/api/DemoException.java |  42 +
 .../org/apache/dubbo/config/api/DemoService.java   |  37 +
 .../java/org/apache/dubbo/config/api/Greeting.java |  24 +
 .../java/org/apache/dubbo/config/api/User.java     |  65 ++
 .../ConsulDubboServiceConsumerBootstrap.java       |  52 ++
 .../ConsulDubboServiceProviderBootstrap.java       |  42 +
 .../dubbo/config/bootstrap/DubboBootstrapTest.java | 154 ++++
 .../bootstrap/DubboServiceConsumerBootstrap.java   |  58 ++
 .../bootstrap/DubboServiceProviderBootstrap.java   |  95 +++
 .../DubboServiceProviderMinimumBootstrap.java      |  38 +
 .../apache/dubbo/config/bootstrap/EchoService.java |  31 +
 .../dubbo/config/bootstrap/EchoServiceImpl.java    |  36 +
 .../EtcdDubboServiceConsumerBootstrap.java         |  51 ++
 .../EtcdDubboServiceProviderBootstrap.java         |  94 +++
 .../NacosDubboServiceConsumerBootstrap.java        |  56 ++
 .../NacosDubboServiceProviderBootstrap.java        |  51 ++
 .../ZookeeperDubboServiceConsumerBootstrap.java    |  55 ++
 .../ZookeeperDubboServiceProviderBootstrap.java    |  43 +
 .../bootstrap/builders/AbstractBuilderTest.java    | 126 +++
 .../builders/AbstractInterfaceBuilderTest.java     | 311 +++++++
 .../builders/AbstractMethodBuilderTest.java        | 196 +++++
 .../builders/AbstractReferenceBuilderTest.java     | 151 ++++
 .../builders/AbstractServiceBuilderTest.java       | 245 ++++++
 .../bootstrap/builders/ApplicationBuilderTest.java | 255 ++++++
 .../bootstrap/builders/ArgumentBuilderTest.java    |  63 ++
 .../builders/ConfigCenterBuilderTest.java          | 169 ++++
 .../bootstrap/builders/ConsumerBuilderTest.java    |  95 +++
 .../builders/MetadataReportBuilderTest.java        | 151 ++++
 .../bootstrap/builders/MethodBuilderTest.java      | 189 +++++
 .../bootstrap/builders/ModuleBuilderTest.java      | 112 +++
 .../bootstrap/builders/MonitorBuilderTest.java     | 135 +++
 .../bootstrap/builders/ProtocolBuilderTest.java    | 338 ++++++++
 .../bootstrap/builders/ProviderBuilderTest.java    | 227 +++++
 .../bootstrap/builders/ReferenceBuilderTest.java   | 125 +++
 .../bootstrap/builders/RegistryBuilderTest.java    | 256 ++++++
 .../bootstrap/builders/ServiceBuilderTest.java     | 131 +++
 .../DubboInterfaceConsumerBootstrap.java           |  57 ++
 .../apache/dubbo/config/bootstrap/rest/User.java   |  77 ++
 .../dubbo/config/bootstrap/rest/UserService.java   |  45 +
 .../config/bootstrap/rest/UserServiceImpl.java     |  32 +
 .../apache/dubbo/config/cache/CacheService.java    |  26 +
 .../dubbo/config/cache/CacheServiceImpl.java       |  32 +
 .../org/apache/dubbo/config/cache/CacheTest.java   | 140 ++++
 .../config/consumer/DemoActionByAnnotation.java    |  35 +
 .../dubbo/config/consumer/DemoActionBySetter.java  |  36 +
 .../dubbo/config/consumer/DemoInterceptor.java     |  31 +
 .../PublishingServiceDefinitionListenerTest.java   |  94 +++
 .../DelegateProviderMetaDataInvokerTest.java       |  60 ++
 .../apache/dubbo/config/mock/GreetingLocal1.java   |  21 +
 .../apache/dubbo/config/mock/GreetingLocal2.java   |  26 +
 .../apache/dubbo/config/mock/GreetingLocal3.java   |  32 +
 .../apache/dubbo/config/mock/GreetingMock1.java    |  20 +
 .../apache/dubbo/config/mock/GreetingMock2.java    |  29 +
 .../org/apache/dubbo/config/mock/MockCluster.java  |  29 +
 .../org/apache/dubbo/config/mock/MockCodec.java    |  37 +
 .../apache/dubbo/config/mock/MockDispatcher.java   |  29 +
 .../apache/dubbo/config/mock/MockExchanger.java    |  37 +
 .../dubbo/config/mock/MockExporterListener.java    |  34 +
 .../org/apache/dubbo/config/mock/MockFilter.java   |  30 +
 .../dubbo/config/mock/MockInvokerListener.java     |  33 +
 .../apache/dubbo/config/mock/MockLoadBalance.java  |  32 +
 .../org/apache/dubbo/config/mock/MockProtocol.java |  89 ++
 .../apache/dubbo/config/mock/MockProtocol2.java    |  48 ++
 .../apache/dubbo/config/mock/MockProxyFactory.java |  39 +
 .../org/apache/dubbo/config/mock/MockRegistry.java | 110 +++
 .../dubbo/config/mock/MockRegistryFactory.java     |  37 +
 .../dubbo/config/mock/MockRegistryFactory2.java    |  31 +
 .../dubbo/config/mock/MockStatusChecker.java       |  28 +
 .../dubbo/config/mock/MockTelnetHandler.java       |  29 +
 .../apache/dubbo/config/mock/MockThreadPool.java   |  30 +
 .../apache/dubbo/config/mock/MockTransporter.java  |  42 +
 .../apache/dubbo/config/mock/TestProxyFactory.java |  33 +
 .../config/provider/impl/DemoServiceImpl.java      |  51 ++
 .../config/url/ExporterSideConfigUrlTest.java      | 102 +++
 .../dubbo/config/url/InvokerSideConfigUrlTest.java | 217 +++++
 .../dubbo/config/url/RpcConfigGetSetProxy.java     | 166 ++++
 .../org/apache/dubbo/config/url/UrlTestBase.java   | 202 +++++
 .../dubbo/config/utils/MockReferenceConfig.java    |  59 ++
 .../config/utils/ReferenceConfigCacheTest.java     | 151 ++++
 .../dubbo/config/utils/XxxMockReferenceConfig.java |  59 ++
 .../dubbo/config/utils/service/FooService.java     |  23 +
 .../dubbo/config/utils/service/FooServiceImpl.java |  23 +
 .../dubbo/config/utils/service/XxxService.java     |  23 +
 .../dubbo/config/utils/service/XxxServiceImpl.java |  23 +
 .../metadata/MetadataServiceExporterTest.java      |  42 +
 .../org.apache.dubbo.common.status.StatusChecker   |  18 +
 .../org.apache.dubbo.common.threadpool.ThreadPool  |  18 +
 .../org.apache.dubbo.registry.RegistryFactory      |   2 +
 .../services/org.apache.dubbo.remoting.Codec       |  18 +
 .../services/org.apache.dubbo.remoting.Dispatcher  |  18 +
 .../services/org.apache.dubbo.remoting.Transporter |  18 +
 .../org.apache.dubbo.remoting.exchange.Exchanger   |  18 +
 .../org.apache.dubbo.remoting.telnet.TelnetHandler |  18 +
 .../services/org.apache.dubbo.rpc.ExporterListener |  18 +
 .../META-INF/services/org.apache.dubbo.rpc.Filter  |   1 +
 .../services/org.apache.dubbo.rpc.InvokerListener  |   1 +
 .../services/org.apache.dubbo.rpc.Protocol         |   2 +
 .../services/org.apache.dubbo.rpc.ProxyFactory     |   2 +
 .../services/org.apache.dubbo.rpc.cluster.Cluster  |   1 +
 .../org.apache.dubbo.rpc.cluster.LoadBalance       |   1 +
 dubbo-test/src/test/resources/dubbo.properties     |   2 +
 dubbo-test/src/test/resources/log4j.xml            |  28 +
 pom.xml                                            |  74 ++
 124 files changed, 11071 insertions(+), 1 deletion(-)

diff --git a/dubbo-spi-remoting/dubbo-remoting-p2p/src/main/java/com/alibaba/dubbo/remoting/p2p/Networker.java b/dubbo-spi-remoting/dubbo-remoting-p2p/src/main/java/com/alibaba/dubbo/remoting/p2p/Networker.java
new file mode 100644
index 0000000..a2f9f41
--- /dev/null
+++ b/dubbo-spi-remoting/dubbo-remoting-p2p/src/main/java/com/alibaba/dubbo/remoting/p2p/Networker.java
@@ -0,0 +1,22 @@
+/*
+ * 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 com.alibaba.dubbo.remoting.p2p;
+
+@Deprecated
+public interface Networker extends org.apache.dubbo.remoting.p2p.Networker {
+}
diff --git a/dubbo-spi-rpc/dubbo-rpc-thrift/src/main/java/com/alibaba/dubbo/rpc/protocol/thrift/ClassNameGenerator.java b/dubbo-spi-rpc/dubbo-rpc-thrift/src/main/java/com/alibaba/dubbo/rpc/protocol/thrift/ClassNameGenerator.java
new file mode 100644
index 0000000..dec29d3
--- /dev/null
+++ b/dubbo-spi-rpc/dubbo-rpc-thrift/src/main/java/com/alibaba/dubbo/rpc/protocol/thrift/ClassNameGenerator.java
@@ -0,0 +1,22 @@
+/*
+ * 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 com.alibaba.dubbo.rpc.protocol.thrift;
+
+@Deprecated
+public interface ClassNameGenerator extends org.apache.dubbo.rpc.protocol.thrift.ClassNameGenerator {
+}
diff --git a/dubbo-test/pom.xml b/dubbo-test/pom.xml
index 66720dc..9b688b6 100644
--- a/dubbo-test/pom.xml
+++ b/dubbo-test/pom.xml
@@ -26,14 +26,48 @@
 
     <artifactId>dubbo-test</artifactId>
 
+    <properties>
+        <skip_maven_deploy>true</skip_maven_deploy>
+    </properties>
+
     <dependencies>
         <dependency>
             <groupId>org.apache.dubbo</groupId>
+            <artifactId>dubbo-config-api</artifactId>
+            <version>${project.parent.version}</version>
+        </dependency>
+        <dependency>
+            <groupId>org.apache.dubbo</groupId>
+            <artifactId>dubbo-registry-api</artifactId>
+            <version>${project.parent.version}</version>
+        </dependency>
+        <dependency>
+            <groupId>org.apache.dubbo</groupId>
+            <artifactId>dubbo-metadata-api</artifactId>
+            <version>${project.parent.version}</version>
+        </dependency>
+        <dependency>
+            <groupId>org.apache.dubbo</groupId>
+            <artifactId>dubbo-monitor-api</artifactId>
+            <version>${project.parent.version}</version>
+        </dependency>
+        <dependency>
+            <groupId>org.apache.dubbo</groupId>
+            <artifactId>dubbo-remoting-api</artifactId>
+            <version>${project.parent.version}</version>
+        </dependency>
+        <dependency>
+            <groupId>org.apache.dubbo</groupId>
+            <artifactId>dubbo-rpc-injvm</artifactId>
+            <version>${project.parent.version}</version>
+        </dependency>
+
+        <dependency>
+            <groupId>org.apache.dubbo</groupId>
             <artifactId>dubbo-rpc-dubbo</artifactId>
             <version>${project.parent.version}</version>
             <scope>test</scope>
         </dependency>
-
         <dependency>
             <groupId>org.apache.dubbo</groupId>
             <artifactId>dubbo-rpc-rest</artifactId>
@@ -190,6 +224,12 @@
             <version>${project.parent.version}</version>
             <scope>test</scope>
         </dependency>
+        <dependency>
+            <groupId>org.apache.dubbo</groupId>
+            <artifactId>dubbo-filter-cache</artifactId>
+            <version>${project.parent.version}</version>
+            <scope>test</scope>
+        </dependency>
     </dependencies>
 
     <build>
diff --git a/dubbo-test/src/test/java/org/apache/dubbo/config/AbstractConfigTest.java b/dubbo-test/src/test/java/org/apache/dubbo/config/AbstractConfigTest.java
new file mode 100644
index 0000000..041cd75
--- /dev/null
+++ b/dubbo-test/src/test/java/org/apache/dubbo/config/AbstractConfigTest.java
@@ -0,0 +1,927 @@
+/*
+ * 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;
+
+import org.apache.dubbo.common.utils.ConfigUtils;
+import org.apache.dubbo.config.api.Greeting;
+import org.apache.dubbo.config.support.Parameter;
+import org.apache.dubbo.config.utils.ConfigValidationUtils;
+import org.apache.dubbo.rpc.model.ApplicationModel;
+
+import org.hamcrest.Matchers;
+import org.junit.jupiter.api.Assertions;
+import org.junit.jupiter.api.Test;
+
+import java.lang.annotation.ElementType;
+import java.lang.annotation.Retention;
+import java.lang.annotation.RetentionPolicy;
+import java.lang.annotation.Target;
+import java.lang.reflect.Field;
+import java.util.Collections;
+import java.util.HashMap;
+import java.util.Map;
+import java.util.Properties;
+
+import static org.hamcrest.MatcherAssert.assertThat;
+import static org.junit.jupiter.api.Assertions.assertTrue;
+import static org.junit.jupiter.api.Assertions.fail;
+
+public class AbstractConfigTest {
+
+    //FIXME
+    /*@Test
+    public void testAppendProperties1() throws Exception {
+        try {
+            System.setProperty("dubbo.properties.i", "1");
+            System.setProperty("dubbo.properties.c", "c");
+            System.setProperty("dubbo.properties.b", "2");
+            System.setProperty("dubbo.properties.d", "3");
+            System.setProperty("dubbo.properties.f", "4");
+            System.setProperty("dubbo.properties.l", "5");
+            System.setProperty("dubbo.properties.s", "6");
+            System.setProperty("dubbo.properties.str", "dubbo");
+            System.setProperty("dubbo.properties.bool", "true");
+            PropertiesConfig config = new PropertiesConfig();
+            AbstractConfig.appendProperties(config);
+            Assertions.assertEquals(1, config.getI());
+            Assertions.assertEquals('c', config.getC());
+            Assertions.assertEquals((byte) 0x02, config.getB());
+            Assertions.assertEquals(3d, config.getD());
+            Assertions.assertEquals(4f, config.getF());
+            Assertions.assertEquals(5L, config.getL());
+            Assertions.assertEquals(6, config.getS());
+            Assertions.assertEquals("dubbo", config.getStr());
+            Assertions.assertTrue(config.isBool());
+        } finally {
+            System.clearProperty("dubbo.properties.i");
+            System.clearProperty("dubbo.properties.c");
+            System.clearProperty("dubbo.properties.b");
+            System.clearProperty("dubbo.properties.d");
+            System.clearProperty("dubbo.properties.f");
+            System.clearProperty("dubbo.properties.l");
+            System.clearProperty("dubbo.properties.s");
+            System.clearProperty("dubbo.properties.str");
+            System.clearProperty("dubbo.properties.bool");
+        }
+    }
+
+    @Test
+    public void testAppendProperties2() throws Exception {
+        try {
+            System.setProperty("dubbo.properties.two.i", "2");
+            PropertiesConfig config = new PropertiesConfig("two");
+            AbstractConfig.appendProperties(config);
+            Assertions.assertEquals(2, config.getI());
+        } finally {
+            System.clearProperty("dubbo.properties.two.i");
+        }
+    }
+
+    @Test
+    public void testAppendProperties3() throws Exception {
+        try {
+            Properties p = new Properties();
+            p.put("dubbo.properties.str", "dubbo");
+            ConfigUtils.setProperties(p);
+            PropertiesConfig config = new PropertiesConfig();
+            AbstractConfig.appendProperties(config);
+            Assertions.assertEquals("dubbo", config.getStr());
+        } finally {
+            System.clearProperty(Constants.DUBBO_PROPERTIES_KEY);
+            ConfigUtils.setProperties(null);
+        }
+    }*/
+
+    @Test
+    public void testAppendParameters1() throws Exception {
+        Map<String, String> parameters = new HashMap<String, String>();
+        parameters.put("num", "ONE");
+        AbstractConfig.appendParameters(parameters, new ParameterConfig(1, "hello/world", 30, "password"), "prefix");
+        Assertions.assertEquals("one", parameters.get("prefix.key.1"));
+        Assertions.assertEquals("two", parameters.get("prefix.key.2"));
+        Assertions.assertEquals("ONE,1", parameters.get("prefix.num"));
+        Assertions.assertEquals("hello%2Fworld", parameters.get("prefix.naming"));
+        Assertions.assertEquals("30", parameters.get("prefix.age"));
+        Assertions.assertTrue(parameters.containsKey("prefix.key-2"));
+        Assertions.assertTrue(parameters.containsKey("prefix.key.2"));
+        Assertions.assertFalse(parameters.containsKey("prefix.secret"));
+    }
+
+    @Test
+    public void testAppendParameters2() throws Exception {
+        Assertions.assertThrows(IllegalStateException.class, () -> {
+            Map<String, String> parameters = new HashMap<String, String>();
+            AbstractConfig.appendParameters(parameters, new ParameterConfig());
+        });
+    }
+
+    @Test
+    public void testAppendParameters3() throws Exception {
+        Map<String, String> parameters = new HashMap<String, String>();
+        AbstractConfig.appendParameters(parameters, null);
+        assertTrue(parameters.isEmpty());
+    }
+
+    @Test
+    public void testAppendParameters4() throws Exception {
+        Map<String, String> parameters = new HashMap<String, String>();
+        AbstractConfig.appendParameters(parameters, new ParameterConfig(1, "hello/world", 30, "password"));
+        Assertions.assertEquals("one", parameters.get("key.1"));
+        Assertions.assertEquals("two", parameters.get("key.2"));
+        Assertions.assertEquals("1", parameters.get("num"));
+        Assertions.assertEquals("hello%2Fworld", parameters.get("naming"));
+        Assertions.assertEquals("30", parameters.get("age"));
+    }
+
+    @Test
+    public void testAppendAttributes1() throws Exception {
+        Map<String, Object> parameters = new HashMap<String, Object>();
+        AbstractConfig.appendAttributes(parameters, new AttributeConfig('l', true, (byte) 0x01), "prefix");
+        Assertions.assertEquals('l', parameters.get("prefix.let"));
+        Assertions.assertEquals(true, parameters.get("prefix.activate"));
+        Assertions.assertFalse(parameters.containsKey("prefix.flag"));
+    }
+
+    @Test
+    public void testAppendAttributes2() throws Exception {
+        Map<String, Object> parameters = new HashMap<String, Object>();
+        AbstractConfig.appendAttributes(parameters, new AttributeConfig('l', true, (byte) 0x01));
+        Assertions.assertEquals('l', parameters.get("let"));
+        Assertions.assertEquals(true, parameters.get("activate"));
+        Assertions.assertFalse(parameters.containsKey("flag"));
+    }
+
+    @Test
+    public void checkExtension() throws Exception {
+        Assertions.assertThrows(IllegalStateException.class, () -> ConfigValidationUtils.checkExtension(Greeting.class, "hello", "world"));
+    }
+
+    @Test
+    public void checkMultiExtension1() throws Exception {
+        Assertions.assertThrows(IllegalStateException.class, () -> ConfigValidationUtils.checkMultiExtension(Greeting.class, "hello", "default,world"));
+    }
+
+    @Test
+    public void checkMultiExtension2() throws Exception {
+        Assertions.assertThrows(IllegalStateException.class, () -> ConfigValidationUtils.checkMultiExtension(Greeting.class, "hello", "default,-world"));
+    }
+
+    @Test
+    public void checkLength() throws Exception {
+        Assertions.assertThrows(IllegalStateException.class, () -> {
+            StringBuilder builder = new StringBuilder();
+            for (int i = 0; i <= 200; i++) {
+                builder.append("a");
+            }
+            ConfigValidationUtils.checkLength("hello", builder.toString());
+        });
+    }
+
+    @Test
+    public void checkPathLength() throws Exception {
+        Assertions.assertThrows(IllegalStateException.class, () -> {
+            StringBuilder builder = new StringBuilder();
+            for (int i = 0; i <= 200; i++) {
+                builder.append("a");
+            }
+            ConfigValidationUtils.checkPathLength("hello", builder.toString());
+        });
+    }
+
+    @Test
+    public void checkName() throws Exception {
+        Assertions.assertThrows(IllegalStateException.class, () -> ConfigValidationUtils.checkName("hello", "world%"));
+    }
+
+    @Test
+    public void checkNameHasSymbol() throws Exception {
+        try {
+            ConfigValidationUtils.checkNameHasSymbol("hello", ":*,/ -0123\tabcdABCD");
+            ConfigValidationUtils.checkNameHasSymbol("mock", "force:return world");
+        } catch (Exception e) {
+            fail("the value should be legal.");
+        }
+    }
+
+    @Test
+    public void checkKey() throws Exception {
+        try {
+            ConfigValidationUtils.checkKey("hello", "*,-0123abcdABCD");
+        } catch (Exception e) {
+            fail("the value should be legal.");
+        }
+    }
+
+    @Test
+    public void checkMultiName() throws Exception {
+        try {
+            ConfigValidationUtils.checkMultiName("hello", ",-._0123abcdABCD");
+        } catch (Exception e) {
+            fail("the value should be legal.");
+        }
+    }
+
+    @Test
+    public void checkPathName() throws Exception {
+        try {
+            ConfigValidationUtils.checkPathName("hello", "/-$._0123abcdABCD");
+        } catch (Exception e) {
+            fail("the value should be legal.");
+        }
+    }
+
+    @Test
+    public void checkMethodName() throws Exception {
+        try {
+            ConfigValidationUtils.checkMethodName("hello", "abcdABCD0123abcd");
+        } catch (Exception e) {
+            fail("the value should be legal.");
+        }
+
+        try {
+            ConfigValidationUtils.checkMethodName("hello", "0a");
+            fail("the value should be illegal.");
+        } catch (Exception e) {
+            // ignore
+        }
+    }
+
+    @Test
+    public void checkParameterName() throws Exception {
+        Map<String, String> parameters = Collections.singletonMap("hello", ":*,/-._0123abcdABCD");
+        try {
+            ConfigValidationUtils.checkParameterName(parameters);
+        } catch (Exception e) {
+            fail("the value should be legal.");
+        }
+    }
+
+    @Test
+    @Config(interfaceClass = Greeting.class, filter = {"f1, f2"}, listener = {"l1, l2"},
+            parameters = {"k1", "v1", "k2", "v2"})
+    public void appendAnnotation() throws Exception {
+        Config config = getClass().getMethod("appendAnnotation").getAnnotation(Config.class);
+        AnnotationConfig annotationConfig = new AnnotationConfig();
+        annotationConfig.appendAnnotation(Config.class, config);
+        Assertions.assertSame(Greeting.class, annotationConfig.getInterface());
+        Assertions.assertEquals("f1, f2", annotationConfig.getFilter());
+        Assertions.assertEquals("l1, l2", annotationConfig.getListener());
+        Assertions.assertEquals(2, annotationConfig.getParameters().size());
+        Assertions.assertEquals("v1", annotationConfig.getParameters().get("k1"));
+        Assertions.assertEquals("v2", annotationConfig.getParameters().get("k2"));
+        assertThat(annotationConfig.toString(), Matchers.containsString("filter=\"f1, f2\" "));
+        assertThat(annotationConfig.toString(), Matchers.containsString("listener=\"l1, l2\" "));
+    }
+
+    @Test
+    public void testRefreshAll() {
+        try {
+            OverrideConfig overrideConfig = new OverrideConfig();
+            overrideConfig.setAddress("override-config://127.0.0.1:2181");
+            overrideConfig.setProtocol("override-config");
+            overrideConfig.setEscape("override-config://");
+            overrideConfig.setExclude("override-config");
+
+            Map<String, String> external = new HashMap<>();
+            external.put("dubbo.override.address", "external://127.0.0.1:2181");
+            // @Parameter(exclude=true)
+            external.put("dubbo.override.exclude", "external");
+            // @Parameter(key="key1", useKeyAsProperty=false)
+            external.put("dubbo.override.key", "external");
+            // @Parameter(key="key2", useKeyAsProperty=true)
+            external.put("dubbo.override.key2", "external");
+            ApplicationModel.getEnvironment().setExternalConfigMap(external);
+            ApplicationModel.getEnvironment().initialize();
+
+            System.setProperty("dubbo.override.address", "system://127.0.0.1:2181");
+            System.setProperty("dubbo.override.protocol", "system");
+            // this will not override, use 'key' instead, @Parameter(key="key1", useKeyAsProperty=false)
+            System.setProperty("dubbo.override.key1", "system");
+            System.setProperty("dubbo.override.key2", "system");
+
+            // Load configuration from  system properties -> externalConfiguration -> RegistryConfig -> dubbo.properties
+            overrideConfig.refresh();
+
+            Assertions.assertEquals("system://127.0.0.1:2181", overrideConfig.getAddress());
+            Assertions.assertEquals("system", overrideConfig.getProtocol());
+            Assertions.assertEquals("override-config://", overrideConfig.getEscape());
+            Assertions.assertEquals("external", overrideConfig.getKey());
+            Assertions.assertEquals("system", overrideConfig.getUseKeyAsProperty());
+        } finally {
+            System.clearProperty("dubbo.override.address");
+            System.clearProperty("dubbo.override.protocol");
+            System.clearProperty("dubbo.override.key1");
+            System.clearProperty("dubbo.override.key2");
+            ApplicationModel.getEnvironment().clearExternalConfigs();
+        }
+    }
+
+    @Test
+    public void testRefreshSystem() {
+        try {
+            OverrideConfig overrideConfig = new OverrideConfig();
+            overrideConfig.setAddress("override-config://127.0.0.1:2181");
+            overrideConfig.setProtocol("override-config");
+            overrideConfig.setEscape("override-config://");
+            overrideConfig.setExclude("override-config");
+
+            System.setProperty("dubbo.override.address", "system://127.0.0.1:2181");
+            System.setProperty("dubbo.override.protocol", "system");
+            System.setProperty("dubbo.override.key", "system");
+
+            overrideConfig.refresh();
+
+            Assertions.assertEquals("system://127.0.0.1:2181", overrideConfig.getAddress());
+            Assertions.assertEquals("system", overrideConfig.getProtocol());
+            Assertions.assertEquals("override-config://", overrideConfig.getEscape());
+            Assertions.assertEquals("system", overrideConfig.getKey());
+        } finally {
+            System.clearProperty("dubbo.override.address");
+            System.clearProperty("dubbo.override.protocol");
+            System.clearProperty("dubbo.override.key1");
+            ApplicationModel.getEnvironment().clearExternalConfigs();
+        }
+    }
+
+    @Test
+    public void testRefreshProperties() throws Exception {
+        try {
+            ApplicationModel.getEnvironment().setExternalConfigMap(new HashMap<>());
+            OverrideConfig overrideConfig = new OverrideConfig();
+            overrideConfig.setAddress("override-config://127.0.0.1:2181");
+            overrideConfig.setProtocol("override-config");
+            overrideConfig.setEscape("override-config://");
+
+            Properties properties = new Properties();
+            properties.load(this.getClass().getResourceAsStream("/dubbo.properties"));
+            ConfigUtils.setProperties(properties);
+
+            overrideConfig.refresh();
+
+            Assertions.assertEquals("override-config://127.0.0.1:2181", overrideConfig.getAddress());
+            Assertions.assertEquals("override-config", overrideConfig.getProtocol());
+            Assertions.assertEquals("override-config://", overrideConfig.getEscape());
+            //Assertions.assertEquals("properties", overrideConfig.getUseKeyAsProperty());
+        } finally {
+            ApplicationModel.getEnvironment().clearExternalConfigs();
+            ConfigUtils.setProperties(null);
+        }
+    }
+
+    @Test
+    public void testRefreshExternal() {
+        try {
+            OverrideConfig overrideConfig = new OverrideConfig();
+            overrideConfig.setAddress("override-config://127.0.0.1:2181");
+            overrideConfig.setProtocol("override-config");
+            overrideConfig.setEscape("override-config://");
+            overrideConfig.setExclude("override-config");
+
+            Map<String, String> external = new HashMap<>();
+            external.put("dubbo.override.address", "external://127.0.0.1:2181");
+            external.put("dubbo.override.protocol", "external");
+            external.put("dubbo.override.escape", "external://");
+            // @Parameter(exclude=true)
+            external.put("dubbo.override.exclude", "external");
+            // @Parameter(key="key1", useKeyAsProperty=false)
+            external.put("dubbo.override.key", "external");
+            // @Parameter(key="key2", useKeyAsProperty=true)
+            external.put("dubbo.override.key2", "external");
+            ApplicationModel.getEnvironment().setExternalConfigMap(external);
+            ApplicationModel.getEnvironment().initialize();
+
+            overrideConfig.refresh();
+
+            Assertions.assertEquals("external://127.0.0.1:2181", overrideConfig.getAddress());
+            Assertions.assertEquals("external", overrideConfig.getProtocol());
+            Assertions.assertEquals("external://", overrideConfig.getEscape());
+            Assertions.assertEquals("external", overrideConfig.getExclude());
+            Assertions.assertEquals("external", overrideConfig.getKey());
+            Assertions.assertEquals("external", overrideConfig.getUseKeyAsProperty());
+        } finally {
+            ApplicationModel.getEnvironment().clearExternalConfigs();
+        }
+    }
+
+    @Test
+    public void testRefreshById() {
+        try {
+            OverrideConfig overrideConfig = new OverrideConfig();
+            overrideConfig.setId("override-id");
+            overrideConfig.setAddress("override-config://127.0.0.1:2181");
+            overrideConfig.setProtocol("override-config");
+            overrideConfig.setEscape("override-config://");
+            overrideConfig.setExclude("override-config");
+
+            Map<String, String> external = new HashMap<>();
+            external.put("dubbo.override.override-id.address", "external-override-id://127.0.0.1:2181");
+            external.put("dubbo.override.address", "external://127.0.0.1:2181");
+            // @Parameter(exclude=true)
+            external.put("dubbo.override.exclude", "external");
+            // @Parameter(key="key1", useKeyAsProperty=false)
+            external.put("dubbo.override.key", "external");
+            // @Parameter(key="key2", useKeyAsProperty=true)
+            external.put("dubbo.override.key2", "external");
+            ApplicationModel.getEnvironment().setExternalConfigMap(external);
+            ApplicationModel.getEnvironment().initialize();
+
+            ConfigCenterConfig configCenter = new ConfigCenterConfig();
+            overrideConfig.setConfigCenter(configCenter);
+            // Load configuration from  system properties -> externalConfiguration -> RegistryConfig -> dubbo.properties
+            overrideConfig.refresh();
+
+            Assertions.assertEquals("external-override-id://127.0.0.1:2181", overrideConfig.getAddress());
+            Assertions.assertEquals("override-config", overrideConfig.getProtocol());
+            Assertions.assertEquals("override-config://", overrideConfig.getEscape());
+            Assertions.assertEquals("external", overrideConfig.getKey());
+            Assertions.assertEquals("external", overrideConfig.getUseKeyAsProperty());
+        } finally {
+            ApplicationModel.getEnvironment().clearExternalConfigs();
+        }
+    }
+
+    @Test
+    public void testRefreshParameters() {
+        try {
+            Map<String, String> parameters = new HashMap<>();
+            parameters.put("key1", "value1");
+            parameters.put("key2", "value2");
+            OverrideConfig overrideConfig = new OverrideConfig();
+            overrideConfig.setParameters(parameters);
+
+
+            Map<String, String> external = new HashMap<>();
+            external.put("dubbo.override.parameters", "[{key3:value3},{key4:value4},{key2:value5}]");
+            ApplicationModel.getEnvironment().setExternalConfigMap(external);
+            ApplicationModel.getEnvironment().initialize();
+
+            ConfigCenterConfig configCenter = new ConfigCenterConfig();
+            overrideConfig.setConfigCenter(configCenter);
+            // Load configuration from  system properties -> externalConfiguration -> RegistryConfig -> dubbo.properties
+            overrideConfig.refresh();
+
+            Assertions.assertEquals("value1", overrideConfig.getParameters().get("key1"));
+            Assertions.assertEquals("value5", overrideConfig.getParameters().get("key2"));
+            Assertions.assertEquals("value3", overrideConfig.getParameters().get("key3"));
+            Assertions.assertEquals("value4", overrideConfig.getParameters().get("key4"));
+
+            System.setProperty("dubbo.override.parameters", "[{key3:value6}]");
+            overrideConfig.refresh();
+
+            Assertions.assertEquals("value6", overrideConfig.getParameters().get("key3"));
+            Assertions.assertEquals("value4", overrideConfig.getParameters().get("key4"));
+        } finally {
+            System.clearProperty("dubbo.override.parameters");
+            ApplicationModel.getEnvironment().clearExternalConfigs();
+        }
+    }
+
+    @Test
+    public void testOnlyPrefixedKeyTakeEffect() {
+        try {
+            OverrideConfig overrideConfig = new OverrideConfig();
+            overrideConfig.setNotConflictKey("value-from-config");
+
+            Map<String, String> external = new HashMap<>();
+            external.put("notConflictKey", "value-from-external");
+
+            try {
+                Map<String, String> map = new HashMap<>();
+                map.put("notConflictKey", "value-from-env");
+                map.put("dubbo.override.notConflictKey2", "value-from-env");
+                setOsEnv(map);
+            } catch (Exception e) {
+                // ignore
+                e.printStackTrace();
+            }
+
+            ApplicationModel.getEnvironment().setExternalConfigMap(external);
+
+            overrideConfig.refresh();
+
+            Assertions.assertEquals("value-from-config", overrideConfig.getNotConflictKey());
+            Assertions.assertEquals("value-from-env", overrideConfig.getNotConflictKey2());
+        } finally {
+            ApplicationModel.getEnvironment().clearExternalConfigs();
+
+        }
+    }
+
+    @Test
+    public void tetMetaData() {
+        OverrideConfig overrideConfig = new OverrideConfig();
+        overrideConfig.setId("override-id");
+        overrideConfig.setAddress("override-config://127.0.0.1:2181");
+        overrideConfig.setProtocol("override-config");
+        overrideConfig.setEscape("override-config://");
+        overrideConfig.setExclude("override-config");
+
+        Map<String, String> metaData = overrideConfig.getMetaData();
+        Assertions.assertEquals("override-config://127.0.0.1:2181", metaData.get("address"));
+        Assertions.assertEquals("override-config", metaData.get("protocol"));
+        Assertions.assertEquals("override-config://", metaData.get("escape"));
+        Assertions.assertEquals("override-config", metaData.get("exclude"));
+        Assertions.assertNull(metaData.get("key"));
+        Assertions.assertNull(metaData.get("key2"));
+    }
+
+    @Test
+    public void testEquals() {
+        ApplicationConfig application1 = new ApplicationConfig();
+        ApplicationConfig application2 = new ApplicationConfig();
+        application1.setName("app1");
+        application2.setName("app2");
+        Assertions.assertNotEquals(application1, application2);
+        application1.setName("sameName");
+        application2.setName("sameName");
+        Assertions.assertEquals(application1, application2);
+
+        ProtocolConfig protocol1 = new ProtocolConfig();
+        protocol1.setHost("127.0.0.1");// excluded
+        protocol1.setName("dubbo");
+        ProtocolConfig protocol2 = new ProtocolConfig();
+        protocol2.setHost("127.0.0.2");// excluded
+        protocol2.setName("dubbo");
+        Assertions.assertEquals(protocol1, protocol2);
+    }
+
+    @Retention(RetentionPolicy.RUNTIME)
+    @Target({ElementType.ANNOTATION_TYPE})
+    public @interface ConfigField {
+        String value() default "";
+    }
+
+    @Retention(RetentionPolicy.RUNTIME)
+    @Target({ElementType.FIELD, ElementType.METHOD, ElementType.ANNOTATION_TYPE})
+    public @interface Config {
+        Class<?> interfaceClass() default void.class;
+
+        String interfaceName() default "";
+
+        String[] filter() default {};
+
+        String[] listener() default {};
+
+        String[] parameters() default {};
+
+        ConfigField[] configFields() default {};
+
+        ConfigField configField() default @ConfigField;
+    }
+
+    private static class OverrideConfig extends AbstractInterfaceConfig {
+        public String address;
+        public String protocol;
+        public String exclude;
+        public String key;
+        public String useKeyAsProperty;
+        public String escape;
+        public String notConflictKey;
+        public String notConflictKey2;
+
+        public String getAddress() {
+            return address;
+        }
+
+        public void setAddress(String address) {
+            this.address = address;
+        }
+
+        public String getProtocol() {
+            return protocol;
+        }
+
+        public void setProtocol(String protocol) {
+            this.protocol = protocol;
+        }
+
+        @Parameter(excluded = true)
+        public String getExclude() {
+            return exclude;
+        }
+
+        public void setExclude(String exclude) {
+            this.exclude = exclude;
+        }
+
+        @Parameter(key = "key1", useKeyAsProperty = false)
+        public String getKey() {
+            return key;
+        }
+
+        public void setKey(String key) {
+            this.key = key;
+        }
+
+        @Parameter(key = "key2", useKeyAsProperty = true)
+        public String getUseKeyAsProperty() {
+            return useKeyAsProperty;
+        }
+
+        public void setUseKeyAsProperty(String useKeyAsProperty) {
+            this.useKeyAsProperty = useKeyAsProperty;
+        }
+
+        @Parameter(escaped = true)
+        public String getEscape() {
+            return escape;
+        }
+
+        public void setEscape(String escape) {
+            this.escape = escape;
+        }
+
+        public String getNotConflictKey() {
+            return notConflictKey;
+        }
+
+        public void setNotConflictKey(String notConflictKey) {
+            this.notConflictKey = notConflictKey;
+        }
+
+        public String getNotConflictKey2() {
+            return notConflictKey2;
+        }
+
+        public void setNotConflictKey2(String notConflictKey2) {
+            this.notConflictKey2 = notConflictKey2;
+        }
+    }
+
+    private static class PropertiesConfig extends AbstractConfig {
+        private char c;
+        private boolean bool;
+        private byte b;
+        private int i;
+        private long l;
+        private float f;
+        private double d;
+        private short s;
+        private String str;
+
+        PropertiesConfig() {
+        }
+
+        PropertiesConfig(String id) {
+            this.id = id;
+        }
+
+        public char getC() {
+            return c;
+        }
+
+        public void setC(char c) {
+            this.c = c;
+        }
+
+        public boolean isBool() {
+            return bool;
+        }
+
+        public void setBool(boolean bool) {
+            this.bool = bool;
+        }
+
+        public byte getB() {
+            return b;
+        }
+
+        public void setB(byte b) {
+            this.b = b;
+        }
+
+        public int getI() {
+            return i;
+        }
+
+        public void setI(int i) {
+            this.i = i;
+        }
+
+        public long getL() {
+            return l;
+        }
+
+        public void setL(long l) {
+            this.l = l;
+        }
+
+        public float getF() {
+            return f;
+        }
+
+        public void setF(float f) {
+            this.f = f;
+        }
+
+        public double getD() {
+            return d;
+        }
+
+        public void setD(double d) {
+            this.d = d;
+        }
+
+        public String getStr() {
+            return str;
+        }
+
+        public void setStr(String str) {
+            this.str = str;
+        }
+
+        public short getS() {
+            return s;
+        }
+
+        public void setS(short s) {
+            this.s = s;
+        }
+    }
+
+    private static class ParameterConfig {
+        private int number;
+        private String name;
+        private int age;
+        private String secret;
+
+        ParameterConfig() {
+        }
+
+        ParameterConfig(int number, String name, int age, String secret) {
+            this.number = number;
+            this.name = name;
+            this.age = age;
+            this.secret = secret;
+        }
+
+        @Parameter(key = "num", append = true)
+        public int getNumber() {
+            return number;
+        }
+
+        public void setNumber(int number) {
+            this.number = number;
+        }
+
+        @Parameter(key = "naming", append = true, escaped = true, required = true)
+        public String getName() {
+            return name;
+        }
+
+        public void setName(String name) {
+            this.name = name;
+        }
+
+        public int getAge() {
+            return age;
+        }
+
+        public void setAge(int age) {
+            this.age = age;
+        }
+
+        @Parameter(excluded = true)
+        public String getSecret() {
+            return secret;
+        }
+
+        public void setSecret(String secret) {
+            this.secret = secret;
+        }
+
+        public Map getParameters() {
+            Map<String, String> map = new HashMap<String, String>();
+            map.put("key.1", "one");
+            map.put("key-2", "two");
+            return map;
+        }
+    }
+
+    private static class AttributeConfig {
+        private char letter;
+        private boolean activate;
+        private byte flag;
+
+        public AttributeConfig(char letter, boolean activate, byte flag) {
+            this.letter = letter;
+            this.activate = activate;
+            this.flag = flag;
+        }
+
+        @Parameter(attribute = true, key = "let")
+        public char getLetter() {
+            return letter;
+        }
+
+        public void setLetter(char letter) {
+            this.letter = letter;
+        }
+
+        @Parameter(attribute = true)
+        public boolean isActivate() {
+            return activate;
+        }
+
+        public void setActivate(boolean activate) {
+            this.activate = activate;
+        }
+
+        public byte getFlag() {
+            return flag;
+        }
+
+        public void setFlag(byte flag) {
+            this.flag = flag;
+        }
+    }
+
+    private static class AnnotationConfig extends AbstractConfig {
+        private Class interfaceClass;
+        private String filter;
+        private String listener;
+        private Map<String, String> parameters;
+        private String[] configFields;
+
+        public Class getInterface() {
+            return interfaceClass;
+        }
+
+        public void setInterface(Class interfaceName) {
+            this.interfaceClass = interfaceName;
+        }
+
+        public String getFilter() {
+            return filter;
+        }
+
+        public void setFilter(String filter) {
+            this.filter = filter;
+        }
+
+        public String getListener() {
+            return listener;
+        }
+
+        public void setListener(String listener) {
+            this.listener = listener;
+        }
+
+        public Map<String, String> getParameters() {
+            return parameters;
+        }
+
+        public void setParameters(Map<String, String> parameters) {
+            this.parameters = parameters;
+        }
+
+        public String[] getConfigFields() {
+            return configFields;
+        }
+
+        public void setConfigFields(String[] configFields) {
+            this.configFields = configFields;
+        }
+    }
+
+    protected static void setOsEnv(Map<String, String> newenv) throws Exception {
+        try {
+            Class<?> processEnvironmentClass = Class.forName("java.lang.ProcessEnvironment");
+            Field theEnvironmentField = processEnvironmentClass.getDeclaredField("theEnvironment");
+            theEnvironmentField.setAccessible(true);
+            Map<String, String> env = (Map<String, String>) theEnvironmentField.get(null);
+            env.putAll(newenv);
+            Field theCaseInsensitiveEnvironmentField = processEnvironmentClass.getDeclaredField("theCaseInsensitiveEnvironment");
+            theCaseInsensitiveEnvironmentField.setAccessible(true);
+            Map<String, String> cienv = (Map<String, String>) theCaseInsensitiveEnvironmentField.get(null);
+            cienv.putAll(newenv);
+        } catch (NoSuchFieldException e) {
+            Class[] classes = Collections.class.getDeclaredClasses();
+            Map<String, String> env = System.getenv();
+            for (Class cl : classes) {
+                if ("java.util.Collections$UnmodifiableMap".equals(cl.getName())) {
+                    Field field = cl.getDeclaredField("m");
+                    field.setAccessible(true);
+                    Object obj = field.get(env);
+                    Map<String, String> map = (Map<String, String>) obj;
+                    map.clear();
+                    map.putAll(newenv);
+                }
+            }
+        }
+    }
+}
diff --git a/dubbo-test/src/test/java/org/apache/dubbo/config/AbstractInterfaceConfigTest.java b/dubbo-test/src/test/java/org/apache/dubbo/config/AbstractInterfaceConfigTest.java
new file mode 100644
index 0000000..2bcd960
--- /dev/null
+++ b/dubbo-test/src/test/java/org/apache/dubbo/config/AbstractInterfaceConfigTest.java
@@ -0,0 +1,354 @@
+/*
+ * 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;
+
+import org.apache.dubbo.common.constants.CommonConstants;
+import org.apache.dubbo.config.api.Greeting;
+import org.apache.dubbo.config.mock.GreetingLocal1;
+import org.apache.dubbo.config.mock.GreetingLocal2;
+import org.apache.dubbo.config.mock.GreetingLocal3;
+import org.apache.dubbo.config.mock.GreetingMock1;
+import org.apache.dubbo.config.mock.GreetingMock2;
+import org.apache.dubbo.config.utils.ConfigValidationUtils;
+
+import org.junit.jupiter.api.AfterAll;
+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.io.TempDir;
+
+import java.io.File;
+import java.nio.file.Path;
+import java.util.Collections;
+
+public class AbstractInterfaceConfigTest {
+    private static File dubboProperties;
+
+    @BeforeAll
+    public static void setUp(@TempDir Path folder) {
+        dubboProperties = folder.resolve(CommonConstants.DUBBO_PROPERTIES_KEY).toFile();
+        System.setProperty(CommonConstants.DUBBO_PROPERTIES_KEY, dubboProperties.getAbsolutePath());
+    }
+
+    @AfterAll
+    public static void tearDown() {
+        System.clearProperty(CommonConstants.DUBBO_PROPERTIES_KEY);
+    }
+
+    @AfterEach
+    public void tearMethodAfterEachUT() {
+//        ApplicationModel.getConfigManager().clear();
+    }
+
+    @Test
+    public void testCheckRegistry1() {
+        System.setProperty("dubbo.registry.address", "addr1");
+        try {
+            InterfaceConfig interfaceConfig = new InterfaceConfig();
+            interfaceConfig.setApplication(new ApplicationConfig("testCheckRegistry1"));
+            interfaceConfig.checkRegistry();
+            Assertions.assertEquals(1, interfaceConfig.getRegistries().size());
+            Assertions.assertEquals("addr1", interfaceConfig.getRegistries().get(0).getAddress());
+        } finally {
+            System.clearProperty("dubbo.registry.address");
+        }
+    }
+
+    @Test
+    public void testCheckRegistry2() {
+        Assertions.assertThrows(IllegalStateException.class, () -> {
+            InterfaceConfig interfaceConfig = new InterfaceConfig();
+            interfaceConfig.checkRegistry();
+        });
+    }
+
+    @Test
+    public void checkInterfaceAndMethods1() {
+        Assertions.assertThrows(IllegalStateException.class, () -> {
+            InterfaceConfig interfaceConfig = new InterfaceConfig();
+            interfaceConfig.checkInterfaceAndMethods(null, null);
+        });
+    }
+
+    @Test
+    public void checkInterfaceAndMethods2() {
+        Assertions.assertThrows(IllegalStateException.class, () -> {
+            InterfaceConfig interfaceConfig = new InterfaceConfig();
+            interfaceConfig.checkInterfaceAndMethods(AbstractInterfaceConfigTest.class, null);
+        });
+    }
+
+    @Test
+    public void checkInterfaceAndMethod3() {
+        Assertions.assertThrows(IllegalStateException.class, () -> {
+            MethodConfig methodConfig = new MethodConfig();
+            InterfaceConfig interfaceConfig = new InterfaceConfig();
+            interfaceConfig.checkInterfaceAndMethods(Greeting.class, Collections.singletonList(methodConfig));
+        });
+    }
+
+    @Test
+    public void checkInterfaceAndMethod4() {
+        Assertions.assertThrows(IllegalStateException.class, () -> {
+            MethodConfig methodConfig = new MethodConfig();
+            methodConfig.setName("nihao");
+            InterfaceConfig interfaceConfig = new InterfaceConfig();
+            interfaceConfig.checkInterfaceAndMethods(Greeting.class, Collections.singletonList(methodConfig));
+        });
+    }
+
+    @Test
+    public void checkInterfaceAndMethod5() {
+        MethodConfig methodConfig = new MethodConfig();
+        methodConfig.setName("hello");
+        InterfaceConfig interfaceConfig = new InterfaceConfig();
+        interfaceConfig.checkInterfaceAndMethods(Greeting.class, Collections.singletonList(methodConfig));
+    }
+
+    @Test
+    public void checkStubAndMock1() {
+        Assertions.assertThrows(IllegalStateException.class, () -> {
+            InterfaceConfig interfaceConfig = new InterfaceConfig();
+            interfaceConfig.setLocal(GreetingLocal1.class.getName());
+            interfaceConfig.checkStubAndLocal(Greeting.class);
+            ConfigValidationUtils.checkMock(Greeting.class, interfaceConfig);
+        });
+    }
+
+    @Test
+    public void checkStubAndMock2() {
+        Assertions.assertThrows(IllegalStateException.class, () -> {
+            InterfaceConfig interfaceConfig = new InterfaceConfig();
+            interfaceConfig.setLocal(GreetingLocal2.class.getName());
+            interfaceConfig.checkStubAndLocal(Greeting.class);
+            ConfigValidationUtils.checkMock(Greeting.class, interfaceConfig);
+        });
+    }
+
+    @Test
+    public void checkStubAndMock3() {
+        InterfaceConfig interfaceConfig = new InterfaceConfig();
+        interfaceConfig.setLocal(GreetingLocal3.class.getName());
+        interfaceConfig.checkStubAndLocal(Greeting.class);
+        ConfigValidationUtils.checkMock(Greeting.class, interfaceConfig);
+    }
+
+    @Test
+    public void checkStubAndMock4() {
+        Assertions.assertThrows(IllegalStateException.class, () -> {
+            InterfaceConfig interfaceConfig = new InterfaceConfig();
+            interfaceConfig.setStub(GreetingLocal1.class.getName());
+            interfaceConfig.checkStubAndLocal(Greeting.class);
+            ConfigValidationUtils.checkMock(Greeting.class, interfaceConfig);
+        });
+    }
+
+    @Test
+    public void checkStubAndMock5() {
+        Assertions.assertThrows(IllegalStateException.class, () -> {
+            InterfaceConfig interfaceConfig = new InterfaceConfig();
+            interfaceConfig.setStub(GreetingLocal2.class.getName());
+            interfaceConfig.checkStubAndLocal(Greeting.class);
+            ConfigValidationUtils.checkMock(Greeting.class, interfaceConfig);
+        });
+    }
+
+    @Test
+    public void checkStubAndMock6() {
+        InterfaceConfig interfaceConfig = new InterfaceConfig();
+        interfaceConfig.setStub(GreetingLocal3.class.getName());
+        interfaceConfig.checkStubAndLocal(Greeting.class);
+        ConfigValidationUtils.checkMock(Greeting.class, interfaceConfig);
+    }
+
+    @Test
+    public void checkStubAndMock7() {
+        Assertions.assertThrows(IllegalStateException.class, () -> {
+            InterfaceConfig interfaceConfig = new InterfaceConfig();
+            interfaceConfig.setMock("return {a, b}");
+            interfaceConfig.checkStubAndLocal(Greeting.class);
+            ConfigValidationUtils.checkMock(Greeting.class, interfaceConfig);
+        });
+    }
+
+    @Test
+    public void checkStubAndMock8() {
+        Assertions.assertThrows(IllegalStateException.class, () -> {
+            InterfaceConfig interfaceConfig = new InterfaceConfig();
+            interfaceConfig.setMock(GreetingMock1.class.getName());
+            interfaceConfig.checkStubAndLocal(Greeting.class);
+            ConfigValidationUtils.checkMock(Greeting.class, interfaceConfig);
+        });
+    }
+
+    @Test
+    public void checkStubAndMock9() {
+        Assertions.assertThrows(IllegalStateException.class, () -> {
+            InterfaceConfig interfaceConfig = new InterfaceConfig();
+            interfaceConfig.setMock(GreetingMock2.class.getName());
+            interfaceConfig.checkStubAndLocal(Greeting.class);
+            ConfigValidationUtils.checkMock(Greeting.class, interfaceConfig);
+        });
+    }
+
+    @Test
+    public void testLocal() {
+        InterfaceConfig interfaceConfig = new InterfaceConfig();
+        interfaceConfig.setLocal((Boolean) null);
+        Assertions.assertNull(interfaceConfig.getLocal());
+        interfaceConfig.setLocal(true);
+        Assertions.assertEquals("true", interfaceConfig.getLocal());
+        interfaceConfig.setLocal("GreetingMock");
+        Assertions.assertEquals("GreetingMock", interfaceConfig.getLocal());
+    }
+
+    @Test
+    public void testStub() {
+        InterfaceConfig interfaceConfig = new InterfaceConfig();
+        interfaceConfig.setStub((Boolean) null);
+        Assertions.assertNull(interfaceConfig.getStub());
+        interfaceConfig.setStub(true);
+        Assertions.assertEquals("true", interfaceConfig.getStub());
+        interfaceConfig.setStub("GreetingMock");
+        Assertions.assertEquals("GreetingMock", interfaceConfig.getStub());
+    }
+
+    @Test
+    public void testCluster() {
+        InterfaceConfig interfaceConfig = new InterfaceConfig();
+        interfaceConfig.setCluster("mockcluster");
+        Assertions.assertEquals("mockcluster", interfaceConfig.getCluster());
+    }
+
+    @Test
+    public void testProxy() {
+        InterfaceConfig interfaceConfig = new InterfaceConfig();
+        interfaceConfig.setProxy("mockproxyfactory");
+        Assertions.assertEquals("mockproxyfactory", interfaceConfig.getProxy());
+    }
+
+    @Test
+    public void testConnections() {
+        InterfaceConfig interfaceConfig = new InterfaceConfig();
+        interfaceConfig.setConnections(1);
+        Assertions.assertEquals(1, interfaceConfig.getConnections().intValue());
+    }
+
+    @Test
+    public void testFilter() {
+        InterfaceConfig interfaceConfig = new InterfaceConfig();
+        interfaceConfig.setFilter("mockfilter");
+        Assertions.assertEquals("mockfilter", interfaceConfig.getFilter());
+    }
+
+    @Test
+    public void testListener() {
+        InterfaceConfig interfaceConfig = new InterfaceConfig();
+        interfaceConfig.setListener("mockinvokerlistener");
+        Assertions.assertEquals("mockinvokerlistener", interfaceConfig.getListener());
+    }
+
+    @Test
+    public void testLayer() {
+        InterfaceConfig interfaceConfig = new InterfaceConfig();
+        interfaceConfig.setLayer("layer");
+        Assertions.assertEquals("layer", interfaceConfig.getLayer());
+    }
+
+    @Test
+    public void testApplication() {
+        InterfaceConfig interfaceConfig = new InterfaceConfig();
+        ApplicationConfig applicationConfig = new ApplicationConfig();
+        interfaceConfig.setApplication(applicationConfig);
+        Assertions.assertSame(applicationConfig, interfaceConfig.getApplication());
+    }
+
+    @Test
+    public void testModule() {
+        InterfaceConfig interfaceConfig = new InterfaceConfig();
+        ModuleConfig moduleConfig = new ModuleConfig();
+        interfaceConfig.setModule(moduleConfig);
+        Assertions.assertSame(moduleConfig, interfaceConfig.getModule());
+    }
+
+    @Test
+    public void testRegistry() {
+        InterfaceConfig interfaceConfig = new InterfaceConfig();
+        RegistryConfig registryConfig = new RegistryConfig();
+        interfaceConfig.setRegistry(registryConfig);
+        Assertions.assertSame(registryConfig, interfaceConfig.getRegistry());
+    }
+
+    @Test
+    public void testRegistries() {
+        InterfaceConfig interfaceConfig = new InterfaceConfig();
+        RegistryConfig registryConfig = new RegistryConfig();
+        interfaceConfig.setRegistries(Collections.singletonList(registryConfig));
+        Assertions.assertEquals(1, interfaceConfig.getRegistries().size());
+        Assertions.assertSame(registryConfig, interfaceConfig.getRegistries().get(0));
+    }
+
+    @Test
+    public void testMonitor() {
+        InterfaceConfig interfaceConfig = new InterfaceConfig();
+        interfaceConfig.setMonitor("monitor-addr");
+        Assertions.assertEquals("monitor-addr", interfaceConfig.getMonitor().getAddress());
+        MonitorConfig monitorConfig = new MonitorConfig();
+        interfaceConfig.setMonitor(monitorConfig);
+        Assertions.assertSame(monitorConfig, interfaceConfig.getMonitor());
+    }
+
+    @Test
+    public void testOwner() {
+        InterfaceConfig interfaceConfig = new InterfaceConfig();
+        interfaceConfig.setOwner("owner");
+        Assertions.assertEquals("owner", interfaceConfig.getOwner());
+    }
+
+    @Test
+    public void testCallbacks() {
+        InterfaceConfig interfaceConfig = new InterfaceConfig();
+        interfaceConfig.setCallbacks(2);
+        Assertions.assertEquals(2, interfaceConfig.getCallbacks().intValue());
+    }
+
+    @Test
+    public void testOnconnect() {
+        InterfaceConfig interfaceConfig = new InterfaceConfig();
+        interfaceConfig.setOnconnect("onConnect");
+        Assertions.assertEquals("onConnect", interfaceConfig.getOnconnect());
+    }
+
+    @Test
+    public void testOndisconnect() {
+        InterfaceConfig interfaceConfig = new InterfaceConfig();
+        interfaceConfig.setOndisconnect("onDisconnect");
+        Assertions.assertEquals("onDisconnect", interfaceConfig.getOndisconnect());
+    }
+
+    @Test
+    public void testScope() {
+        InterfaceConfig interfaceConfig = new InterfaceConfig();
+        interfaceConfig.setScope("scope");
+        Assertions.assertEquals("scope", interfaceConfig.getScope());
+    }
+
+    public static class InterfaceConfig extends AbstractInterfaceConfig {
+
+    }
+}
diff --git a/dubbo-test/src/test/java/org/apache/dubbo/config/AbstractMethodConfigTest.java b/dubbo-test/src/test/java/org/apache/dubbo/config/AbstractMethodConfigTest.java
new file mode 100644
index 0000000..5b82bc8
--- /dev/null
+++ b/dubbo-test/src/test/java/org/apache/dubbo/config/AbstractMethodConfigTest.java
@@ -0,0 +1,126 @@
+/*
+ * 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;
+
+import org.junit.jupiter.api.Test;
+
+import java.util.HashMap;
+import java.util.Map;
+
+import static org.hamcrest.MatcherAssert.assertThat;
+import static org.hamcrest.Matchers.equalTo;
+import static org.hamcrest.Matchers.is;
+import static org.hamcrest.Matchers.isEmptyOrNullString;
+import static org.hamcrest.Matchers.sameInstance;
+
+public class AbstractMethodConfigTest {
+    @Test
+    public void testTimeout() throws Exception {
+        MethodConfig methodConfig = new MethodConfig();
+        methodConfig.setTimeout(10);
+        assertThat(methodConfig.getTimeout(), equalTo(10));
+    }
+
+    @Test
+    public void testForks() throws Exception {
+        MethodConfig methodConfig = new MethodConfig();
+        methodConfig.setForks(10);
+        assertThat(methodConfig.getForks(), equalTo(10));
+    }
+
+    @Test
+    public void testRetries() throws Exception {
+        MethodConfig methodConfig = new MethodConfig();
+        methodConfig.setRetries(3);
+        assertThat(methodConfig.getRetries(), equalTo(3));
+    }
+
+    @Test
+    public void testLoadbalance() throws Exception {
+        MethodConfig methodConfig = new MethodConfig();
+        methodConfig.setLoadbalance("mockloadbalance");
+        assertThat(methodConfig.getLoadbalance(), equalTo("mockloadbalance"));
+    }
+
+    @Test
+    public void testAsync() throws Exception {
+        MethodConfig methodConfig = new MethodConfig();
+        methodConfig.setAsync(true);
+        assertThat(methodConfig.isAsync(), is(true));
+    }
+
+    @Test
+    public void testActives() throws Exception {
+        MethodConfig methodConfig = new MethodConfig();
+        methodConfig.setActives(10);
+        assertThat(methodConfig.getActives(), equalTo(10));
+    }
+
+    @Test
+    public void testSent() throws Exception {
+        MethodConfig methodConfig = new MethodConfig();
+        methodConfig.setSent(true);
+        assertThat(methodConfig.getSent(), is(true));
+    }
+
+    @Test
+    public void testMock() throws Exception {
+        MethodConfig methodConfig = new MethodConfig();
+        methodConfig.setMock((Boolean) null);
+        assertThat(methodConfig.getMock(), isEmptyOrNullString());
+        methodConfig.setMock(true);
+        assertThat(methodConfig.getMock(), equalTo("true"));
+        methodConfig.setMock("return null");
+        assertThat(methodConfig.getMock(), equalTo("return null"));
+        methodConfig.setMock("mock");
+        assertThat(methodConfig.getMock(), equalTo("mock"));
+    }
+
+    @Test
+    public void testMerger() throws Exception {
+        MethodConfig methodConfig = new MethodConfig();
+        methodConfig.setMerger("merger");
+        assertThat(methodConfig.getMerger(), equalTo("merger"));
+    }
+
+    @Test
+    public void testCache() throws Exception {
+        MethodConfig methodConfig = new MethodConfig();
+        methodConfig.setCache("cache");
+        assertThat(methodConfig.getCache(), equalTo("cache"));
+    }
+
+    @Test
+    public void testValidation() throws Exception {
+        MethodConfig methodConfig = new MethodConfig();
+        methodConfig.setValidation("validation");
+        assertThat(methodConfig.getValidation(), equalTo("validation"));
+    }
+
+    @Test
+    public void testParameters() throws Exception {
+        MethodConfig methodConfig = new MethodConfig();
+        Map<String, String> parameters = new HashMap<String, String>();
+        parameters.put("key", "value");
+        methodConfig.setParameters(parameters);
+        assertThat(methodConfig.getParameters(), sameInstance(parameters));
+    }
+
+    private static class MethodConfig extends AbstractMethodConfig {
+
+    }
+}
diff --git a/dubbo-test/src/test/java/org/apache/dubbo/config/AbstractReferenceConfigTest.java b/dubbo-test/src/test/java/org/apache/dubbo/config/AbstractReferenceConfigTest.java
new file mode 100644
index 0000000..2966322
--- /dev/null
+++ b/dubbo-test/src/test/java/org/apache/dubbo/config/AbstractReferenceConfigTest.java
@@ -0,0 +1,212 @@
+/*
+ * 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;
+
+import org.apache.dubbo.common.URL;
+import org.apache.dubbo.common.extension.ExtensionLoader;
+import org.apache.dubbo.remoting.Constants;
+import org.apache.dubbo.rpc.cluster.RouterFactory;
+import org.apache.dubbo.rpc.cluster.router.condition.ConditionRouterFactory;
+import org.apache.dubbo.rpc.cluster.router.condition.config.AppRouterFactory;
+import org.apache.dubbo.rpc.cluster.router.tag.TagRouterFactory;
+import org.junit.jupiter.api.Assertions;
+import org.junit.jupiter.api.Test;
+
+import java.util.HashMap;
+import java.util.List;
+import java.util.Map;
+
+import static org.apache.dubbo.common.constants.CommonConstants.GENERIC_SERIALIZATION_NATIVE_JAVA;
+import static org.apache.dubbo.common.constants.CommonConstants.INVOKER_LISTENER_KEY;
+import static org.apache.dubbo.common.constants.CommonConstants.REFERENCE_FILTER_KEY;
+import static org.apache.dubbo.common.constants.CommonConstants.STUB_EVENT_KEY;
+import static org.apache.dubbo.rpc.cluster.Constants.CLUSTER_STICKY_KEY;
+import static org.apache.dubbo.rpc.cluster.Constants.ROUTER_KEY;
+import static org.hamcrest.MatcherAssert.assertThat;
+import static org.hamcrest.Matchers.equalTo;
+import static org.hamcrest.Matchers.hasKey;
+import static org.hamcrest.Matchers.hasValue;
+import static org.hamcrest.Matchers.is;
+import static org.mockito.Mockito.mock;
+import static org.mockito.Mockito.when;
+
+public class AbstractReferenceConfigTest {
+
+    @Test
+    public void testCheck() throws Exception {
+        ReferenceConfig referenceConfig = new ReferenceConfig();
+        referenceConfig.setCheck(true);
+        assertThat(referenceConfig.isCheck(), is(true));
+    }
+
+    @Test
+    public void testInit() throws Exception {
+        ReferenceConfig referenceConfig = new ReferenceConfig();
+        referenceConfig.setInit(true);
+        assertThat(referenceConfig.isInit(), is(true));
+    }
+
+    @Test
+    public void testGeneric() throws Exception {
+        ReferenceConfig referenceConfig = new ReferenceConfig();
+        referenceConfig.setGeneric(true);
+        assertThat(referenceConfig.isGeneric(), is(true));
+        Map<String, String> parameters = new HashMap<String, String>();
+        AbstractInterfaceConfig.appendParameters(parameters, referenceConfig);
+        // FIXME: not sure why AbstractReferenceConfig has both isGeneric and getGeneric
+        assertThat(parameters, hasKey("generic"));
+    }
+
+    @Test
+    public void testInjvm() throws Exception {
+        ReferenceConfig referenceConfig = new ReferenceConfig();
+        referenceConfig.setInit(true);
+        assertThat(referenceConfig.isInit(), is(true));
+    }
+
+    @Test
+    public void testFilter() throws Exception {
+        ReferenceConfig referenceConfig = new ReferenceConfig();
+        referenceConfig.setFilter("mockfilter");
+        assertThat(referenceConfig.getFilter(), equalTo("mockfilter"));
+        Map<String, String> parameters = new HashMap<String, String>();
+        parameters.put(REFERENCE_FILTER_KEY, "prefilter");
+        AbstractInterfaceConfig.appendParameters(parameters, referenceConfig);
+        assertThat(parameters, hasValue("prefilter,mockfilter"));
+    }
+
+    @Test
+    public void testRouter() throws Exception {
+        ReferenceConfig referenceConfig = new ReferenceConfig();
+        referenceConfig.setRouter("condition");
+        assertThat(referenceConfig.getRouter(), equalTo("condition"));
+        Map<String, String> parameters = new HashMap<String, String>();
+        parameters.put(ROUTER_KEY, "tag");
+        AbstractInterfaceConfig.appendParameters(parameters, referenceConfig);
+        assertThat(parameters, hasValue("tag,condition"));
+        URL url = mock(URL.class);
+        when(url.getParameter(ROUTER_KEY)).thenReturn("condition");
+        List<RouterFactory> routerFactories = ExtensionLoader.getExtensionLoader(RouterFactory.class).getActivateExtension(url, ROUTER_KEY);
+        assertThat(routerFactories.stream().anyMatch(routerFactory -> routerFactory.getClass().equals(ConditionRouterFactory.class)), is(true));
+        when(url.getParameter(ROUTER_KEY)).thenReturn("-tag,-app");
+        routerFactories = ExtensionLoader.getExtensionLoader(RouterFactory.class).getActivateExtension(url, ROUTER_KEY);
+        assertThat(routerFactories.stream()
+                .allMatch(routerFactory -> !routerFactory.getClass().equals(TagRouterFactory.class)
+                        && !routerFactory.getClass().equals(AppRouterFactory.class)), is(true));
+    }
+
+    @Test
+    public void testListener() throws Exception {
+        ReferenceConfig referenceConfig = new ReferenceConfig();
+        referenceConfig.setListener("mockinvokerlistener");
+        assertThat(referenceConfig.getListener(), equalTo("mockinvokerlistener"));
+        Map<String, String> parameters = new HashMap<String, String>();
+        parameters.put(INVOKER_LISTENER_KEY, "prelistener");
+        AbstractInterfaceConfig.appendParameters(parameters, referenceConfig);
+        assertThat(parameters, hasValue("prelistener,mockinvokerlistener"));
+    }
+
+    @Test
+    public void testLazy() throws Exception {
+        ReferenceConfig referenceConfig = new ReferenceConfig();
+        referenceConfig.setLazy(true);
+        assertThat(referenceConfig.getLazy(), is(true));
+    }
+
+    @Test
+    public void testOnconnect() throws Exception {
+        ReferenceConfig referenceConfig = new ReferenceConfig();
+        referenceConfig.setOnconnect("onConnect");
+        assertThat(referenceConfig.getOnconnect(), equalTo("onConnect"));
+        assertThat(referenceConfig.getStubevent(), is(true));
+    }
+
+    @Test
+    public void testOndisconnect() throws Exception {
+        ReferenceConfig referenceConfig = new ReferenceConfig();
+        referenceConfig.setOndisconnect("onDisconnect");
+        assertThat(referenceConfig.getOndisconnect(), equalTo("onDisconnect"));
+        assertThat(referenceConfig.getStubevent(), is(true));
+    }
+
+    @Test
+    public void testStubevent() throws Exception {
+        ReferenceConfig referenceConfig = new ReferenceConfig();
+        referenceConfig.setOnconnect("onConnect");
+        Map<String, String> parameters = new HashMap<String, String>();
+        AbstractInterfaceConfig.appendParameters(parameters, referenceConfig);
+        assertThat(parameters, hasKey(STUB_EVENT_KEY));
+    }
+
+    @Test
+    public void testReconnect() throws Exception {
+        ReferenceConfig referenceConfig = new ReferenceConfig();
+        referenceConfig.setReconnect("reconnect");
+        Map<String, String> parameters = new HashMap<String, String>();
+        AbstractInterfaceConfig.appendParameters(parameters, referenceConfig);
+        assertThat(referenceConfig.getReconnect(), equalTo("reconnect"));
+        assertThat(parameters, hasKey(Constants.RECONNECT_KEY));
+    }
+
+    @Test
+    public void testSticky() throws Exception {
+        ReferenceConfig referenceConfig = new ReferenceConfig();
+        referenceConfig.setSticky(true);
+        Map<String, String> parameters = new HashMap<String, String>();
+        AbstractInterfaceConfig.appendParameters(parameters, referenceConfig);
+        assertThat(referenceConfig.getSticky(), is(true));
+        assertThat(parameters, hasKey(CLUSTER_STICKY_KEY));
+    }
+
+    @Test
+    public void testVersion() throws Exception {
+        ReferenceConfig referenceConfig = new ReferenceConfig();
+        referenceConfig.setVersion("version");
+        assertThat(referenceConfig.getVersion(), equalTo("version"));
+    }
+
+    @Test
+    public void testGroup() throws Exception {
+        ReferenceConfig referenceConfig = new ReferenceConfig();
+        referenceConfig.setGroup("group");
+        assertThat(referenceConfig.getGroup(), equalTo("group"));
+    }
+
+    @Test
+    public void testGenericOverride() {
+        ReferenceConfig referenceConfig = new ReferenceConfig();
+        referenceConfig.setGeneric("false");
+        referenceConfig.refresh();
+        Assertions.assertFalse(referenceConfig.isGeneric());
+        Assertions.assertEquals("false", referenceConfig.getGeneric());
+
+        ReferenceConfig referenceConfig1 = new ReferenceConfig();
+        referenceConfig1.setGeneric(GENERIC_SERIALIZATION_NATIVE_JAVA);
+        referenceConfig1.refresh();
+        Assertions.assertEquals(GENERIC_SERIALIZATION_NATIVE_JAVA, referenceConfig1.getGeneric());
+        Assertions.assertTrue(referenceConfig1.isGeneric());
+
+        ReferenceConfig referenceConfig2 = new ReferenceConfig();
+        referenceConfig2.refresh();
+        Assertions.assertNull(referenceConfig2.getGeneric());
+    }
+
+    private static class ReferenceConfig extends AbstractReferenceConfig {
+
+    }
+}
diff --git a/dubbo-test/src/test/java/org/apache/dubbo/config/AbstractServiceConfigTest.java b/dubbo-test/src/test/java/org/apache/dubbo/config/AbstractServiceConfigTest.java
new file mode 100644
index 0000000..bd0e7cd
--- /dev/null
+++ b/dubbo-test/src/test/java/org/apache/dubbo/config/AbstractServiceConfigTest.java
@@ -0,0 +1,184 @@
+/*
+ * 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;
+
+
+import org.junit.jupiter.api.Test;
+
+import java.util.ArrayList;
+import java.util.Collections;
+import java.util.HashMap;
+import java.util.Map;
+
+import static org.apache.dubbo.common.constants.CommonConstants.EXPORTER_LISTENER_KEY;
+import static org.apache.dubbo.common.constants.CommonConstants.SERVICE_FILTER_KEY;
+import static org.hamcrest.MatcherAssert.assertThat;
+import static org.hamcrest.Matchers.equalTo;
+import static org.hamcrest.Matchers.hasEntry;
+import static org.hamcrest.Matchers.hasSize;
+import static org.hamcrest.Matchers.is;
+import static org.hamcrest.Matchers.notNullValue;
+import static org.hamcrest.Matchers.nullValue;
+
+public class AbstractServiceConfigTest {
+    @Test
+    public void testVersion() throws Exception {
+        ServiceConfig serviceConfig = new ServiceConfig();
+        serviceConfig.setVersion("version");
+        assertThat(serviceConfig.getVersion(), equalTo("version"));
+    }
+
+    @Test
+    public void testGroup() throws Exception {
+        ServiceConfig serviceConfig = new ServiceConfig();
+        serviceConfig.setGroup("group");
+        assertThat(serviceConfig.getGroup(), equalTo("group"));
+    }
+
+    @Test
+    public void testDelay() throws Exception {
+        ServiceConfig serviceConfig = new ServiceConfig();
+        serviceConfig.setDelay(1000);
+        assertThat(serviceConfig.getDelay(), equalTo(1000));
+    }
+
+    @Test
+    public void testExport() throws Exception {
+        ServiceConfig serviceConfig = new ServiceConfig();
+        serviceConfig.setExport(true);
+        assertThat(serviceConfig.getExport(), is(true));
+    }
+
+    @Test
+    public void testWeight() throws Exception {
+        ServiceConfig serviceConfig = new ServiceConfig();
+        serviceConfig.setWeight(500);
+        assertThat(serviceConfig.getWeight(), equalTo(500));
+    }
+
+    @Test
+    public void testDocument() throws Exception {
+        ServiceConfig serviceConfig = new ServiceConfig();
+        serviceConfig.setDocument("http://dubbo.apache.org");
+        assertThat(serviceConfig.getDocument(), equalTo("http://dubbo.apache.org"));
+        Map<String, String> parameters = new HashMap<String, String>();
+        AbstractServiceConfig.appendParameters(parameters, serviceConfig);
+        assertThat(parameters, hasEntry("document", "http%3A%2F%2Fdubbo.apache.org"));
+    }
+
+    @Test
+    public void testToken() throws Exception {
+        ServiceConfig serviceConfig = new ServiceConfig();
+        serviceConfig.setToken("token");
+        assertThat(serviceConfig.getToken(), equalTo("token"));
+        serviceConfig.setToken((Boolean) null);
+        assertThat(serviceConfig.getToken(), nullValue());
+        serviceConfig.setToken(true);
+        assertThat(serviceConfig.getToken(), is("true"));
+    }
+
+    @Test
+    public void testDeprecated() throws Exception {
+        ServiceConfig serviceConfig = new ServiceConfig();
+        serviceConfig.setDeprecated(true);
+        assertThat(serviceConfig.isDeprecated(), is(true));
+    }
+
+    @Test
+    public void testDynamic() throws Exception {
+        ServiceConfig serviceConfig = new ServiceConfig();
+        serviceConfig.setDynamic(true);
+        assertThat(serviceConfig.isDynamic(), is(true));
+    }
+
+    @Test
+    public void testProtocol() throws Exception {
+        ServiceConfig serviceConfig = new ServiceConfig();
+        assertThat(serviceConfig.getProtocol(), nullValue());
+        serviceConfig.setProtocol(new ProtocolConfig());
+        assertThat(serviceConfig.getProtocol(), notNullValue());
+        serviceConfig.setProtocols(new ArrayList<>(Collections.singletonList(new ProtocolConfig())));
+        assertThat(serviceConfig.getProtocols(), hasSize(1));
+    }
+
+    @Test
+    public void testAccesslog() throws Exception {
+        ServiceConfig serviceConfig = new ServiceConfig();
+        serviceConfig.setAccesslog("access.log");
+        assertThat(serviceConfig.getAccesslog(), equalTo("access.log"));
+        serviceConfig.setAccesslog((Boolean) null);
+        assertThat(serviceConfig.getAccesslog(), nullValue());
+        serviceConfig.setAccesslog(true);
+        assertThat(serviceConfig.getAccesslog(), equalTo("true"));
+    }
+
+    @Test
+    public void testExecutes() throws Exception {
+        ServiceConfig serviceConfig = new ServiceConfig();
+        serviceConfig.setExecutes(10);
+        assertThat(serviceConfig.getExecutes(), equalTo(10));
+    }
+
+    @Test
+    public void testFilter() throws Exception {
+        ServiceConfig serviceConfig = new ServiceConfig();
+        serviceConfig.setFilter("mockfilter");
+        assertThat(serviceConfig.getFilter(), equalTo("mockfilter"));
+        Map<String, String> parameters = new HashMap<String, String>();
+        parameters.put(SERVICE_FILTER_KEY, "prefilter");
+        AbstractServiceConfig.appendParameters(parameters, serviceConfig);
+        assertThat(parameters, hasEntry(SERVICE_FILTER_KEY, "prefilter,mockfilter"));
+    }
+
+    @Test
+    public void testListener() throws Exception {
+        ServiceConfig serviceConfig = new ServiceConfig();
+        serviceConfig.setListener("mockexporterlistener");
+        assertThat(serviceConfig.getListener(), equalTo("mockexporterlistener"));
+        Map<String, String> parameters = new HashMap<String, String>();
+        parameters.put(EXPORTER_LISTENER_KEY, "prelistener");
+        AbstractServiceConfig.appendParameters(parameters, serviceConfig);
+        assertThat(parameters, hasEntry(EXPORTER_LISTENER_KEY, "prelistener,mockexporterlistener"));
+    }
+
+    @Test
+    public void testRegister() throws Exception {
+        ServiceConfig serviceConfig = new ServiceConfig();
+        serviceConfig.setRegister(true);
+        assertThat(serviceConfig.isRegister(), is(true));
+    }
+
+    @Test
+    public void testWarmup() throws Exception {
+        ServiceConfig serviceConfig = new ServiceConfig();
+        serviceConfig.setWarmup(100);
+        assertThat(serviceConfig.getWarmup(), equalTo(100));
+    }
+
+    @Test
+    public void testSerialization() throws Exception {
+        ServiceConfig serviceConfig = new ServiceConfig();
+        serviceConfig.setSerialization("serialization");
+        assertThat(serviceConfig.getSerialization(), equalTo("serialization"));
+    }
+
+
+    private static class ServiceConfig extends AbstractServiceConfig {
+
+    }
+}
diff --git a/dubbo-test/src/test/java/org/apache/dubbo/config/ApplicationConfigTest.java b/dubbo-test/src/test/java/org/apache/dubbo/config/ApplicationConfigTest.java
new file mode 100644
index 0000000..f7ff994
--- /dev/null
+++ b/dubbo-test/src/test/java/org/apache/dubbo/config/ApplicationConfigTest.java
@@ -0,0 +1,217 @@
+/*
+ * 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;
+
+import org.junit.jupiter.api.Assertions;
+import org.junit.jupiter.api.Test;
+
+import java.util.Collections;
+import java.util.HashMap;
+import java.util.Map;
+
+import static org.apache.dubbo.common.constants.CommonConstants.APPLICATION_KEY;
+import static org.apache.dubbo.common.constants.CommonConstants.DUMP_DIRECTORY;
+import static org.apache.dubbo.common.constants.QosConstants.ACCEPT_FOREIGN_IP;
+import static org.apache.dubbo.common.constants.QosConstants.QOS_ENABLE;
+import static org.hamcrest.MatcherAssert.assertThat;
+import static org.hamcrest.Matchers.contains;
+import static org.hamcrest.Matchers.equalTo;
+import static org.hamcrest.Matchers.hasEntry;
+import static org.hamcrest.Matchers.is;
+import static org.hamcrest.Matchers.sameInstance;
+import static org.hamcrest.collection.IsCollectionWithSize.hasSize;
+
+public class ApplicationConfigTest {
+    @Test
+    public void testName() throws Exception {
+        ApplicationConfig application = new ApplicationConfig();
+        application.setName("app");
+        assertThat(application.getName(), equalTo("app"));
+        application = new ApplicationConfig("app2");
+        assertThat(application.getName(), equalTo("app2"));
+        Map<String, String> parameters = new HashMap<String, String>();
+        ApplicationConfig.appendParameters(parameters, application);
+        assertThat(parameters, hasEntry(APPLICATION_KEY, "app2"));
+    }
+
+    @Test
+    public void testVersion() throws Exception {
+        ApplicationConfig application = new ApplicationConfig("app");
+        application.setVersion("1.0.0");
+        assertThat(application.getVersion(), equalTo("1.0.0"));
+        Map<String, String> parameters = new HashMap<String, String>();
+        ApplicationConfig.appendParameters(parameters, application);
+        assertThat(parameters, hasEntry("application.version", "1.0.0"));
+    }
+
+    @Test
+    public void testOwner() throws Exception {
+        ApplicationConfig application = new ApplicationConfig("app");
+        application.setOwner("owner");
+        assertThat(application.getOwner(), equalTo("owner"));
+    }
+
+    @Test
+    public void testOrganization() throws Exception {
+        ApplicationConfig application = new ApplicationConfig("app");
+        application.setOrganization("org");
+        assertThat(application.getOrganization(), equalTo("org"));
+    }
+
+    @Test
+    public void testArchitecture() throws Exception {
+        ApplicationConfig application = new ApplicationConfig("app");
+        application.setArchitecture("arch");
+        assertThat(application.getArchitecture(), equalTo("arch"));
+    }
+
+    @Test
+    public void testEnvironment1() throws Exception {
+        ApplicationConfig application = new ApplicationConfig("app");
+        application.setEnvironment("develop");
+        assertThat(application.getEnvironment(), equalTo("develop"));
+        application.setEnvironment("test");
+        assertThat(application.getEnvironment(), equalTo("test"));
+        application.setEnvironment("product");
+        assertThat(application.getEnvironment(), equalTo("product"));
+    }
+
+    @Test
+    public void testEnvironment2() throws Exception {
+        Assertions.assertThrows(IllegalStateException.class, () -> {
+            ApplicationConfig application = new ApplicationConfig("app");
+            application.setEnvironment("illegal-env");
+        });
+    }
+
+    @Test
+    public void testRegistry() throws Exception {
+        ApplicationConfig application = new ApplicationConfig("app");
+        RegistryConfig registry = new RegistryConfig();
+        application.setRegistry(registry);
+        assertThat(application.getRegistry(), sameInstance(registry));
+        application.setRegistries(Collections.singletonList(registry));
+        assertThat(application.getRegistries(), contains(registry));
+        assertThat(application.getRegistries(), hasSize(1));
+    }
+
+    @Test
+    public void testMonitor() throws Exception {
+        ApplicationConfig application = new ApplicationConfig("app");
+        application.setMonitor(new MonitorConfig("monitor-addr"));
+        assertThat(application.getMonitor().getAddress(), equalTo("monitor-addr"));
+        application.setMonitor("monitor-addr");
+        assertThat(application.getMonitor().getAddress(), equalTo("monitor-addr"));
+    }
+
+    @Test
+    public void testLogger() throws Exception {
+        ApplicationConfig application = new ApplicationConfig("app");
+        application.setLogger("log4j");
+        assertThat(application.getLogger(), equalTo("log4j"));
+    }
+
+    @Test
+    public void testDefault() throws Exception {
+        ApplicationConfig application = new ApplicationConfig("app");
+        application.setDefault(true);
+        assertThat(application.isDefault(), is(true));
+    }
+
+    @Test
+    public void testDumpDirectory() throws Exception {
+        ApplicationConfig application = new ApplicationConfig("app");
+        application.setDumpDirectory("/dump");
+        assertThat(application.getDumpDirectory(), equalTo("/dump"));
+        Map<String, String> parameters = new HashMap<String, String>();
+        ApplicationConfig.appendParameters(parameters, application);
+        assertThat(parameters, hasEntry(DUMP_DIRECTORY, "/dump"));
+    }
+
+    @Test
+    public void testQosEnable() throws Exception {
+        ApplicationConfig application = new ApplicationConfig("app");
+        application.setQosEnable(true);
+        assertThat(application.getQosEnable(), is(true));
+        Map<String, String> parameters = new HashMap<String, String>();
+        ApplicationConfig.appendParameters(parameters, application);
+        assertThat(parameters, hasEntry(QOS_ENABLE, "true"));
+    }
+
+    @Test
+    public void testQosPort() throws Exception {
+        ApplicationConfig application = new ApplicationConfig("app");
+        application.setQosPort(8080);
+        assertThat(application.getQosPort(), equalTo(8080));
+    }
+
+    @Test
+    public void testQosAcceptForeignIp() throws Exception {
+        ApplicationConfig application = new ApplicationConfig("app");
+        application.setQosAcceptForeignIp(true);
+        assertThat(application.getQosAcceptForeignIp(), is(true));
+        Map<String, String> parameters = new HashMap<String, String>();
+        ApplicationConfig.appendParameters(parameters, application);
+        assertThat(parameters, hasEntry(ACCEPT_FOREIGN_IP, "true"));
+    }
+
+    @Test
+    public void testParameters() throws Exception {
+        ApplicationConfig application = new ApplicationConfig("app");
+        application.setQosAcceptForeignIp(true);
+        Map<String, String> parameters = new HashMap<String, String>();
+        parameters.put("k1", "v1");
+        ApplicationConfig.appendParameters(parameters, application);
+        assertThat(parameters, hasEntry("k1", "v1"));
+        assertThat(parameters, hasEntry(ACCEPT_FOREIGN_IP, "true"));
+    }
+
+    @Test
+    public void testAppendEnvironmentProperties() {
+        try {
+            ApplicationConfig application = new ApplicationConfig("app");
+            System.setProperty("dubbo.labels", "tag1=value1;tag2=value2 ; tag3 = value3");
+            application.refresh();
+            Map<String, String> parameters = application.getParameters();
+            Assertions.assertEquals("value1", parameters.get("tag1"));
+            Assertions.assertEquals("value2", parameters.get("tag2"));
+            Assertions.assertEquals("value3", parameters.get("tag3"));
+
+            ApplicationConfig application1 = new ApplicationConfig("app");
+            System.setProperty("dubbo.env.keys", "tag1, tag2,tag3");
+            // mock environment variables
+            System.setProperty("tag1", "value1");
+            System.setProperty("tag2", "value2");
+            System.setProperty("tag3", "value3");
+            application1.refresh();
+            Map<String, String> parameters1 = application1.getParameters();
+            Assertions.assertEquals("value1", parameters1.get("tag1"));
+            Assertions.assertEquals("value2", parameters1.get("tag2"));
+            Assertions.assertEquals("value3", parameters1.get("tag3"));
+
+            Map<String, String> urlParameters = new HashMap<>();
+            ApplicationConfig.appendParameters(urlParameters, application1);
+            Assertions.assertEquals("value1", urlParameters.get("tag1"));
+            Assertions.assertEquals("value2", urlParameters.get("tag2"));
+            Assertions.assertEquals("value3", urlParameters.get("tag3"));
+        } finally {
+            System.clearProperty("dubbo.labels");
+            System.clearProperty("dubbo.keys");
+        }
+    }
+}
diff --git a/dubbo-test/src/test/java/org/apache/dubbo/config/ArgumentConfigTest.java b/dubbo-test/src/test/java/org/apache/dubbo/config/ArgumentConfigTest.java
new file mode 100644
index 0000000..0fff22d
--- /dev/null
+++ b/dubbo-test/src/test/java/org/apache/dubbo/config/ArgumentConfigTest.java
@@ -0,0 +1,63 @@
+/*
+ * 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;
+
+import org.junit.jupiter.api.Test;
+
+import java.util.HashMap;
+import java.util.Map;
+
+import static org.hamcrest.MatcherAssert.assertThat;
+import static org.hamcrest.Matchers.equalTo;
+import static org.hamcrest.Matchers.hasEntry;
+import static org.hamcrest.Matchers.is;
+
+public class ArgumentConfigTest {
+    @Test
+    public void testIndex() throws Exception {
+        ArgumentConfig argument = new ArgumentConfig();
+        argument.setIndex(1);
+        assertThat(argument.getIndex(), is(1));
+    }
+
+    @Test
+    public void testType() throws Exception {
+        ArgumentConfig argument = new ArgumentConfig();
+        argument.setType("int");
+        assertThat(argument.getType(), equalTo("int"));
+    }
+
+    @Test
+    public void testCallback() throws Exception {
+        ArgumentConfig argument = new ArgumentConfig();
+        argument.setCallback(true);
+        assertThat(argument.isCallback(), is(true));
+    }
+
+    @Test
+    public void testArguments() throws Exception {
+        ArgumentConfig argument = new ArgumentConfig();
+        argument.setIndex(1);
+        argument.setType("int");
+        argument.setCallback(true);
+        Map<String, String> parameters = new HashMap<String, String>();
+        AbstractServiceConfig.appendParameters(parameters, argument);
+        assertThat(parameters, hasEntry("callback", "true"));
+        assertThat(parameters.size(), is(1));
+    }
+}
diff --git a/dubbo-test/src/test/java/org/apache/dubbo/config/ConfigCenterConfigTest.java b/dubbo-test/src/test/java/org/apache/dubbo/config/ConfigCenterConfigTest.java
new file mode 100644
index 0000000..fcba6fa
--- /dev/null
+++ b/dubbo-test/src/test/java/org/apache/dubbo/config/ConfigCenterConfigTest.java
@@ -0,0 +1,44 @@
+/*
+ * 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;
+
+
+import org.junit.jupiter.api.Assertions;
+import org.junit.jupiter.api.Test;
+
+public class ConfigCenterConfigTest {
+    @Test
+    public void testPrefix() {
+        ConfigCenterConfig config = new ConfigCenterConfig();
+        Assertions.assertEquals("dubbo.config-center", config.getPrefix());
+    }
+
+    @Test
+    public void testToUrl() {
+        ConfigCenterConfig config = new ConfigCenterConfig();
+        config.setNamespace("namespace");
+        config.setGroup("group");
+        config.setAddress("zookeeper://127.0.0.1:2181");
+
+        Assertions.assertEquals("zookeeper://127.0.0.1:2181/ConfigCenterConfig?check=true&" +
+                        "config-file=dubbo.properties&group=group&highest-priority=true&" +
+                        "namespace=namespace&timeout=3000",
+                config.toUrl().toFullString()
+        );
+    }
+}
diff --git a/dubbo-test/src/test/java/org/apache/dubbo/config/ConsumerConfigTest.java b/dubbo-test/src/test/java/org/apache/dubbo/config/ConsumerConfigTest.java
new file mode 100644
index 0000000..49be546
--- /dev/null
+++ b/dubbo-test/src/test/java/org/apache/dubbo/config/ConsumerConfigTest.java
@@ -0,0 +1,81 @@
+/*
+ * 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;
+
+import org.junit.jupiter.api.Test;
+
+import static org.hamcrest.MatcherAssert.assertThat;
+import static org.hamcrest.Matchers.equalTo;
+import static org.hamcrest.Matchers.is;
+
+public class ConsumerConfigTest {
+    @Test
+    public void testTimeout() throws Exception {
+        try {
+            System.clearProperty("sun.rmi.transport.tcp.responseTimeout");
+            ConsumerConfig consumer = new ConsumerConfig();
+            consumer.setTimeout(10);
+            assertThat(consumer.getTimeout(), is(10));
+            assertThat(System.getProperty("sun.rmi.transport.tcp.responseTimeout"), equalTo("10"));
+        } finally {
+            System.clearProperty("sun.rmi.transport.tcp.responseTimeout");
+        }
+    }
+
+    @Test
+    public void testDefault() throws Exception {
+        ConsumerConfig consumer = new ConsumerConfig();
+        consumer.setDefault(true);
+        assertThat(consumer.isDefault(), is(true));
+    }
+
+    @Test
+    public void testClient() throws Exception {
+        ConsumerConfig consumer = new ConsumerConfig();
+        consumer.setClient("client");
+        assertThat(consumer.getClient(), equalTo("client"));
+    }
+
+    @Test
+    public void testThreadpool() throws Exception {
+        ConsumerConfig consumer = new ConsumerConfig();
+        consumer.setThreadpool("fixed");
+        assertThat(consumer.getThreadpool(), equalTo("fixed"));
+    }
+
+    @Test
+    public void testCorethreads() throws Exception {
+        ConsumerConfig consumer = new ConsumerConfig();
+        consumer.setCorethreads(10);
+        assertThat(consumer.getCorethreads(), equalTo(10));
+    }
+
+    @Test
+    public void testThreads() throws Exception {
+        ConsumerConfig consumer = new ConsumerConfig();
+        consumer.setThreads(20);
+        assertThat(consumer.getThreads(), equalTo(20));
+    }
+
+    @Test
+    public void testQueues() throws Exception {
+        ConsumerConfig consumer = new ConsumerConfig();
+        consumer.setQueues(5);
+        assertThat(consumer.getQueues(), equalTo(5));
+    }
+}
diff --git a/dubbo-test/src/test/java/org/apache/dubbo/config/MethodConfigTest.java b/dubbo-test/src/test/java/org/apache/dubbo/config/MethodConfigTest.java
new file mode 100644
index 0000000..b190d5c
--- /dev/null
+++ b/dubbo-test/src/test/java/org/apache/dubbo/config/MethodConfigTest.java
@@ -0,0 +1,240 @@
+/*
+ * 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;
+
+import org.apache.dubbo.config.annotation.Argument;
+import org.apache.dubbo.config.annotation.Method;
+import org.apache.dubbo.config.annotation.Reference;
+
+import org.hamcrest.Matchers;
+import org.junit.jupiter.api.Test;
+
+import java.util.Collections;
+import java.util.HashMap;
+import java.util.List;
+import java.util.Map;
+
+import static org.apache.dubbo.config.Constants.ON_INVOKE_INSTANCE_KEY;
+import static org.apache.dubbo.config.Constants.ON_INVOKE_METHOD_KEY;
+import static org.apache.dubbo.config.Constants.ON_RETURN_INSTANCE_KEY;
+import static org.apache.dubbo.config.Constants.ON_RETURN_METHOD_KEY;
+import static org.apache.dubbo.config.Constants.ON_THROW_INSTANCE_KEY;
+import static org.apache.dubbo.config.Constants.ON_THROW_METHOD_KEY;
+import static org.hamcrest.MatcherAssert.assertThat;
+import static org.hamcrest.Matchers.contains;
+import static org.hamcrest.Matchers.equalTo;
+import static org.hamcrest.Matchers.hasEntry;
+import static org.hamcrest.Matchers.hasKey;
+import static org.hamcrest.Matchers.is;
+import static org.hamcrest.Matchers.not;
+
+public class MethodConfigTest {
+    private static final String METHOD_NAME = "sayHello";
+    private static final int TIMEOUT = 1300;
+    private static final int RETRIES = 4;
+    private static final String LOADBALANCE = "random";
+    private static final boolean ASYNC = true;
+    private static final int ACTIVES = 3;
+    private static final int EXECUTES = 5;
+    private static final boolean DEPERECATED = true;
+    private static final boolean STICKY = true;
+    private static final String ONINVOKE = "i";
+    private static final String ONTHROW = "t";
+    private static final String ONRETURN = "r";
+    private static final String CACHE = "c";
+    private static final String VALIDATION = "v";
+    private static final int ARGUMENTS_INDEX = 24;
+    private static final boolean ARGUMENTS_CALLBACK = true;
+    private static final String ARGUMENTS_TYPE = "sss";
+
+    @Reference(methods = {@Method(name = METHOD_NAME, timeout = TIMEOUT, retries = RETRIES, loadbalance = LOADBALANCE, async = ASYNC,
+            actives = ACTIVES, executes = EXECUTES, deprecated = DEPERECATED, sticky = STICKY, oninvoke = ONINVOKE, onthrow = ONTHROW, onreturn = ONRETURN, cache = CACHE, validation = VALIDATION,
+            arguments = {@Argument(index = ARGUMENTS_INDEX, callback = ARGUMENTS_CALLBACK, type = ARGUMENTS_TYPE)})})
+    private String testField;
+
+    @Test
+    public void testStaticConstructor() throws NoSuchFieldException {
+        Method[] methods = this.getClass().getDeclaredField("testField").getAnnotation(Reference.class).methods();
+        List<MethodConfig> methodConfigs = MethodConfig.constructMethodConfig(methods);
+        MethodConfig methodConfig = methodConfigs.get(0);
+
+        assertThat(METHOD_NAME, equalTo(methodConfig.getName()));
+        assertThat(TIMEOUT, equalTo(methodConfig.getTimeout().intValue()));
+        assertThat(RETRIES, equalTo(methodConfig.getRetries().intValue()));
+        assertThat(LOADBALANCE, equalTo(methodConfig.getLoadbalance()));
+        assertThat(ASYNC, equalTo(methodConfig.isAsync()));
+        assertThat(ACTIVES, equalTo(methodConfig.getActives().intValue()));
+        assertThat(EXECUTES, equalTo(methodConfig.getExecutes().intValue()));
+        assertThat(DEPERECATED, equalTo(methodConfig.getDeprecated()));
+        assertThat(STICKY, equalTo(methodConfig.getSticky()));
+        assertThat(ONINVOKE, equalTo(methodConfig.getOninvoke()));
+        assertThat(ONTHROW, equalTo(methodConfig.getOnthrow()));
+        assertThat(ONRETURN, equalTo(methodConfig.getOnreturn()));
+        assertThat(CACHE, equalTo(methodConfig.getCache()));
+        assertThat(VALIDATION, equalTo(methodConfig.getValidation()));
+        assertThat(ARGUMENTS_INDEX, equalTo(methodConfig.getArguments().get(0).getIndex().intValue()));
+        assertThat(ARGUMENTS_CALLBACK, equalTo(methodConfig.getArguments().get(0).isCallback()));
+        assertThat(ARGUMENTS_TYPE, equalTo(methodConfig.getArguments().get(0).getType()));
+    }
+
+    @Test
+    public void testName() throws Exception {
+        MethodConfig method = new MethodConfig();
+        method.setName("hello");
+        assertThat(method.getName(), equalTo("hello"));
+        Map<String, String> parameters = new HashMap<String, String>();
+        MethodConfig.appendParameters(parameters, method);
+        assertThat(parameters, not(hasKey("name")));
+    }
+
+    @Test
+    public void testStat() throws Exception {
+        MethodConfig method = new MethodConfig();
+        method.setStat(10);
+        assertThat(method.getStat(), equalTo(10));
+    }
+
+    @Test
+    public void testRetry() throws Exception {
+        MethodConfig method = new MethodConfig();
+        method.setRetry(true);
+        assertThat(method.isRetry(), is(true));
+    }
+
+    @Test
+    public void testReliable() throws Exception {
+        MethodConfig method = new MethodConfig();
+        method.setReliable(true);
+        assertThat(method.isReliable(), is(true));
+    }
+
+    @Test
+    public void testExecutes() throws Exception {
+        MethodConfig method = new MethodConfig();
+        method.setExecutes(10);
+        assertThat(method.getExecutes(), equalTo(10));
+    }
+
+    @Test
+    public void testDeprecated() throws Exception {
+        MethodConfig method = new MethodConfig();
+        method.setDeprecated(true);
+        assertThat(method.getDeprecated(), is(true));
+    }
+
+    @Test
+    public void testArguments() throws Exception {
+        MethodConfig method = new MethodConfig();
+        ArgumentConfig argument = new ArgumentConfig();
+        method.setArguments(Collections.singletonList(argument));
+        assertThat(method.getArguments(), contains(argument));
+        assertThat(method.getArguments(), Matchers.<ArgumentConfig>hasSize(1));
+    }
+
+    @Test
+    public void testSticky() throws Exception {
+        MethodConfig method = new MethodConfig();
+        method.setSticky(true);
+        assertThat(method.getSticky(), is(true));
+    }
+
+    @Test
+    public void testOnreturn() throws Exception {
+        MethodConfig method = new MethodConfig();
+        method.setOnreturn("on-return-object");
+        assertThat(method.getOnreturn(), equalTo((Object) "on-return-object"));
+        Map<String, Object> attribute = new HashMap<String, Object>();
+        MethodConfig.appendAttributes(attribute, method);
+        assertThat(attribute, hasEntry((Object) ON_RETURN_INSTANCE_KEY, (Object) "on-return-object"));
+        Map<String, String> parameters = new HashMap<String, String>();
+        MethodConfig.appendParameters(parameters, method);
+        assertThat(parameters.size(), is(0));
+    }
+
+    @Test
+    public void testOnreturnMethod() throws Exception {
+        MethodConfig method = new MethodConfig();
+        method.setOnreturnMethod("on-return-method");
+        assertThat(method.getOnreturnMethod(), equalTo("on-return-method"));
+        Map<String, Object> attribute = new HashMap<String, Object>();
+        MethodConfig.appendAttributes(attribute, method);
+        assertThat(attribute, hasEntry((Object) ON_RETURN_METHOD_KEY, (Object) "on-return-method"));
+        Map<String, String> parameters = new HashMap<String, String>();
+        MethodConfig.appendParameters(parameters, method);
+        assertThat(parameters.size(), is(0));
+    }
+
+    @Test
+    public void testOnthrow() throws Exception {
+        MethodConfig method = new MethodConfig();
+        method.setOnthrow("on-throw-object");
+        assertThat(method.getOnthrow(), equalTo((Object) "on-throw-object"));
+        Map<String, Object> attribute = new HashMap<String, Object>();
+        MethodConfig.appendAttributes(attribute, method);
+        assertThat(attribute, hasEntry((Object) ON_THROW_INSTANCE_KEY, (Object) "on-throw-object"));
+        Map<String, String> parameters = new HashMap<String, String>();
+        MethodConfig.appendParameters(parameters, method);
+        assertThat(parameters.size(), is(0));
+    }
+
+    @Test
+    public void testOnthrowMethod() throws Exception {
+        MethodConfig method = new MethodConfig();
+        method.setOnthrowMethod("on-throw-method");
+        assertThat(method.getOnthrowMethod(), equalTo("on-throw-method"));
+        Map<String, Object> attribute = new HashMap<String, Object>();
+        MethodConfig.appendAttributes(attribute, method);
+        assertThat(attribute, hasEntry((Object) ON_THROW_METHOD_KEY, (Object) "on-throw-method"));
+        Map<String, String> parameters = new HashMap<String, String>();
+        MethodConfig.appendParameters(parameters, method);
+        assertThat(parameters.size(), is(0));
+    }
+
+    @Test
+    public void testOninvoke() throws Exception {
+        MethodConfig method = new MethodConfig();
+        method.setOninvoke("on-invoke-object");
+        assertThat(method.getOninvoke(), equalTo((Object) "on-invoke-object"));
+        Map<String, Object> attribute = new HashMap<String, Object>();
+        MethodConfig.appendAttributes(attribute, method);
+        assertThat(attribute, hasEntry((Object) ON_INVOKE_INSTANCE_KEY, (Object) "on-invoke-object"));
+        Map<String, String> parameters = new HashMap<String, String>();
+        MethodConfig.appendParameters(parameters, method);
+        assertThat(parameters.size(), is(0));
+    }
+
+    @Test
+    public void testOninvokeMethod() throws Exception {
+        MethodConfig method = new MethodConfig();
+        method.setOninvokeMethod("on-invoke-method");
+        assertThat(method.getOninvokeMethod(), equalTo("on-invoke-method"));
+        Map<String, Object> attribute = new HashMap<String, Object>();
+        MethodConfig.appendAttributes(attribute, method);
+        assertThat(attribute, hasEntry((Object) ON_INVOKE_METHOD_KEY, (Object) "on-invoke-method"));
+        Map<String, String> parameters = new HashMap<String, String>();
+        MethodConfig.appendParameters(parameters, method);
+        assertThat(parameters.size(), is(0));
+    }
+
+    @Test
+    public void testReturn() throws Exception {
+        MethodConfig method = new MethodConfig();
+        method.setReturn(true);
+        assertThat(method.isReturn(), is(true));
+    }
+}
diff --git a/dubbo-test/src/test/java/org/apache/dubbo/config/ModuleConfigTest.java b/dubbo-test/src/test/java/org/apache/dubbo/config/ModuleConfigTest.java
new file mode 100644
index 0000000..a5977cb
--- /dev/null
+++ b/dubbo-test/src/test/java/org/apache/dubbo/config/ModuleConfigTest.java
@@ -0,0 +1,104 @@
+/*
+ * 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;
+
+import org.hamcrest.Matchers;
+import org.junit.jupiter.api.Test;
+
+import java.util.Collections;
+import java.util.HashMap;
+import java.util.Map;
+
+import static org.hamcrest.MatcherAssert.assertThat;
+import static org.hamcrest.Matchers.contains;
+import static org.hamcrest.Matchers.equalTo;
+import static org.hamcrest.Matchers.hasEntry;
+import static org.hamcrest.Matchers.is;
+import static org.hamcrest.Matchers.sameInstance;
+
+public class ModuleConfigTest {
+
+    @Test
+    public void testName2() throws Exception {
+        ModuleConfig module = new ModuleConfig();
+        module.setName("module-name");
+        assertThat(module.getName(), equalTo("module-name"));
+        assertThat(module.getId(), equalTo("module-name"));
+        Map<String, String> parameters = new HashMap<String, String>();
+        ModuleConfig.appendParameters(parameters, module);
+        assertThat(parameters, hasEntry("module", "module-name"));
+    }
+
+    @Test
+    public void testVersion() throws Exception {
+        ModuleConfig module = new ModuleConfig();
+        module.setName("module-name");
+        module.setVersion("1.0.0");
+        assertThat(module.getVersion(), equalTo("1.0.0"));
+        Map<String, String> parameters = new HashMap<String, String>();
+        ModuleConfig.appendParameters(parameters, module);
+        assertThat(parameters, hasEntry("module.version", "1.0.0"));
+    }
+
+    @Test
+    public void testOwner() throws Exception {
+        ModuleConfig module = new ModuleConfig();
+        module.setOwner("owner");
+        assertThat(module.getOwner(), equalTo("owner"));
+    }
+
+    @Test
+    public void testOrganization() throws Exception {
+        ModuleConfig module = new ModuleConfig();
+        module.setOrganization("org");
+        assertThat(module.getOrganization(), equalTo("org"));
+    }
+
+    @Test
+    public void testRegistry() throws Exception {
+        ModuleConfig module = new ModuleConfig();
+        RegistryConfig registry = new RegistryConfig();
+        module.setRegistry(registry);
+        assertThat(module.getRegistry(), sameInstance(registry));
+    }
+
+    @Test
+    public void testRegistries() throws Exception {
+        ModuleConfig module = new ModuleConfig();
+        RegistryConfig registry = new RegistryConfig();
+        module.setRegistries(Collections.singletonList(registry));
+        assertThat(module.getRegistries(), Matchers.<RegistryConfig>hasSize(1));
+        assertThat(module.getRegistries(), contains(registry));
+    }
+
+    @Test
+    public void testMonitor() throws Exception {
+        ModuleConfig module = new ModuleConfig();
+        module.setMonitor("monitor-addr1");
+        assertThat(module.getMonitor().getAddress(), equalTo("monitor-addr1"));
+        module.setMonitor(new MonitorConfig("monitor-addr2"));
+        assertThat(module.getMonitor().getAddress(), equalTo("monitor-addr2"));
+    }
+
+    @Test
+    public void testDefault() throws Exception {
+        ModuleConfig module = new ModuleConfig();
+        module.setDefault(true);
+        assertThat(module.isDefault(), is(true));
+    }
+}
diff --git a/dubbo-test/src/test/java/org/apache/dubbo/config/MonitorConfigTest.java b/dubbo-test/src/test/java/org/apache/dubbo/config/MonitorConfigTest.java
new file mode 100644
index 0000000..60dd40a
--- /dev/null
+++ b/dubbo-test/src/test/java/org/apache/dubbo/config/MonitorConfigTest.java
@@ -0,0 +1,107 @@
+/*
+ * 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;
+
+import org.junit.jupiter.api.Test;
+
+import java.util.Collections;
+import java.util.HashMap;
+import java.util.Map;
+
+import static org.hamcrest.MatcherAssert.assertThat;
+import static org.hamcrest.Matchers.equalTo;
+import static org.hamcrest.Matchers.hasEntry;
+import static org.hamcrest.Matchers.is;
+
+public class MonitorConfigTest {
+    @Test
+    public void testAddress() throws Exception {
+        MonitorConfig monitor = new MonitorConfig();
+        monitor.setAddress("monitor-addr");
+        assertThat(monitor.getAddress(), equalTo("monitor-addr"));
+        Map<String, String> parameters = new HashMap<String, String>();
+        MonitorConfig.appendParameters(parameters, monitor);
+        assertThat(parameters.isEmpty(), is(true));
+    }
+
+    @Test
+    public void testProtocol() throws Exception {
+        MonitorConfig monitor = new MonitorConfig();
+        monitor.setProtocol("protocol");
+        assertThat(monitor.getProtocol(), equalTo("protocol"));
+        Map<String, String> parameters = new HashMap<String, String>();
+        MonitorConfig.appendParameters(parameters, monitor);
+        assertThat(parameters.isEmpty(), is(true));
+    }
+
+    @Test
+    public void testUsername() throws Exception {
+        MonitorConfig monitor = new MonitorConfig();
+        monitor.setUsername("user");
+        assertThat(monitor.getUsername(), equalTo("user"));
+        Map<String, String> parameters = new HashMap<String, String>();
+        MonitorConfig.appendParameters(parameters, monitor);
+        assertThat(parameters.isEmpty(), is(true));
+    }
+
+    @Test
+    public void testPassword() throws Exception {
+        MonitorConfig monitor = new MonitorConfig();
+        monitor.setPassword("secret");
+        assertThat(monitor.getPassword(), equalTo("secret"));
+        Map<String, String> parameters = new HashMap<String, String>();
+        MonitorConfig.appendParameters(parameters, monitor);
+        assertThat(parameters.isEmpty(), is(true));
+    }
+
+    @Test
+    public void testGroup() throws Exception {
+        MonitorConfig monitor = new MonitorConfig();
+        monitor.setGroup("group");
+        assertThat(monitor.getGroup(), equalTo("group"));
+    }
+
+    @Test
+    public void testVersion() throws Exception {
+        MonitorConfig monitor = new MonitorConfig();
+        monitor.setVersion("1.0.0");
+        assertThat(monitor.getVersion(), equalTo("1.0.0"));
+    }
+
+    @Test
+    public void testParameters() throws Exception {
+        MonitorConfig monitor = new MonitorConfig();
+        Map<String, String> parameters = Collections.singletonMap("k1", "v1");
+        monitor.setParameters(parameters);
+        assertThat(monitor.getParameters(), hasEntry("k1", "v1"));
+    }
+
+    @Test
+    public void testDefault() throws Exception {
+        MonitorConfig monitor = new MonitorConfig();
+        monitor.setDefault(true);
+        assertThat(monitor.isDefault(), is(true));
+    }
+
+    @Test
+    public void testInterval() throws Exception {
+        MonitorConfig monitor = new MonitorConfig();
+        monitor.setInterval("100");
+        assertThat(monitor.getInterval(), equalTo("100"));
+    }
+}
diff --git a/dubbo-test/src/test/java/org/apache/dubbo/config/ProtocolConfigTest.java b/dubbo-test/src/test/java/org/apache/dubbo/config/ProtocolConfigTest.java
new file mode 100644
index 0000000..3a66608
--- /dev/null
+++ b/dubbo-test/src/test/java/org/apache/dubbo/config/ProtocolConfigTest.java
@@ -0,0 +1,204 @@
+/*
+ * 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;
+
+import org.junit.jupiter.api.Test;
+
+import java.util.Collections;
+import java.util.HashMap;
+import java.util.Map;
+
+import static org.hamcrest.MatcherAssert.assertThat;
+import static org.hamcrest.Matchers.equalTo;
+import static org.hamcrest.Matchers.hasEntry;
+import static org.hamcrest.Matchers.is;
+
+public class ProtocolConfigTest {
+
+    @Test
+    public void testName() throws Exception {
+        ProtocolConfig protocol = new ProtocolConfig();
+        protocol.setName("name");
+        Map<String, String> parameters = new HashMap<String, String>();
+        ProtocolConfig.appendParameters(parameters, protocol);
+        assertThat(protocol.getName(), equalTo("name"));
+        assertThat(protocol.getId(), equalTo("name"));
+        assertThat(parameters.isEmpty(), is(true));
+    }
+
+    @Test
+    public void testHost() throws Exception {
+        ProtocolConfig protocol = new ProtocolConfig();
+        protocol.setHost("host");
+        Map<String, String> parameters = new HashMap<String, String>();
+        ProtocolConfig.appendParameters(parameters, protocol);
+        assertThat(protocol.getHost(), equalTo("host"));
+        assertThat(parameters.isEmpty(), is(true));
+    }
+
+    @Test
+    public void testPort() throws Exception {
+        ProtocolConfig protocol = new ProtocolConfig();
+        protocol.setPort(8080);
+        Map<String, String> parameters = new HashMap<String, String>();
+        ProtocolConfig.appendParameters(parameters, protocol);
+        assertThat(protocol.getPort(), equalTo(8080));
+        assertThat(parameters.isEmpty(), is(true));
+    }
+
+    @Test
+    public void testPath() throws Exception {
+        ProtocolConfig protocol = new ProtocolConfig();
+        protocol.setContextpath("context-path");
+        Map<String, String> parameters = new HashMap<String, String>();
+        ProtocolConfig.appendParameters(parameters, protocol);
+        assertThat(protocol.getPath(), equalTo("context-path"));
+        assertThat(protocol.getContextpath(), equalTo("context-path"));
+        assertThat(parameters.isEmpty(), is(true));
+        protocol.setPath("path");
+        assertThat(protocol.getPath(), equalTo("path"));
+        assertThat(protocol.getContextpath(), equalTo("path"));
+    }
+
+    @Test
+    public void testCorethreads() throws Exception {
+        ProtocolConfig protocol = new ProtocolConfig();
+        protocol.setCorethreads(10);
+        assertThat(protocol.getCorethreads(), is(10));
+    }
+
+    @Test
+    public void testThreads() throws Exception {
+        ProtocolConfig protocol = new ProtocolConfig();
+        protocol.setThreads(10);
+        assertThat(protocol.getThreads(), is(10));
+    }
+
+    @Test
+    public void testIothreads() throws Exception {
+        ProtocolConfig protocol = new ProtocolConfig();
+        protocol.setIothreads(10);
+        assertThat(protocol.getIothreads(), is(10));
+    }
+
+    @Test
+    public void testQueues() throws Exception {
+        ProtocolConfig protocol = new ProtocolConfig();
+        protocol.setQueues(10);
+        assertThat(protocol.getQueues(), is(10));
+    }
+
+    @Test
+    public void testAccepts() throws Exception {
+        ProtocolConfig protocol = new ProtocolConfig();
+        protocol.setAccepts(10);
+        assertThat(protocol.getAccepts(), is(10));
+    }
+
+    @Test
+    public void testCodec() throws Exception {
+        ProtocolConfig protocol = new ProtocolConfig();
+        protocol.setName("dubbo");
+        protocol.setCodec("mockcodec");
+        assertThat(protocol.getCodec(), equalTo("mockcodec"));
+    }
+
+    @Test
+    public void testAccesslog() throws Exception {
+        ProtocolConfig protocol = new ProtocolConfig();
+        protocol.setAccesslog("access.log");
+        assertThat(protocol.getAccesslog(), equalTo("access.log"));
+    }
+
+    @Test
+    public void testTelnet() throws Exception {
+        ProtocolConfig protocol = new ProtocolConfig();
+        protocol.setTelnet("mocktelnethandler");
+        assertThat(protocol.getTelnet(), equalTo("mocktelnethandler"));
+    }
+
+    @Test
+    public void testRegister() throws Exception {
+        ProtocolConfig protocol = new ProtocolConfig();
+        protocol.setRegister(true);
+        assertThat(protocol.isRegister(), is(true));
+    }
+
+    @Test
+    public void testTransporter() throws Exception {
+        ProtocolConfig protocol = new ProtocolConfig();
+        protocol.setTransporter("mocktransporter");
+        assertThat(protocol.getTransporter(), equalTo("mocktransporter"));
+    }
+
+    @Test
+    public void testExchanger() throws Exception {
+        ProtocolConfig protocol = new ProtocolConfig();
+        protocol.setExchanger("mockexchanger");
+        assertThat(protocol.getExchanger(), equalTo("mockexchanger"));
+    }
+
+    @Test
+    public void testDispatcher() throws Exception {
+        ProtocolConfig protocol = new ProtocolConfig();
+        protocol.setDispatcher("mockdispatcher");
+        assertThat(protocol.getDispatcher(), equalTo("mockdispatcher"));
+    }
+
+    @Test
+    public void testNetworker() throws Exception {
+        ProtocolConfig protocol = new ProtocolConfig();
+        protocol.setNetworker("networker");
+        assertThat(protocol.getNetworker(), equalTo("networker"));
+    }
+
+    @Test
+    public void testParameters() throws Exception {
+        ProtocolConfig protocol = new ProtocolConfig();
+        protocol.setParameters(Collections.singletonMap("k1", "v1"));
+        assertThat(protocol.getParameters(), hasEntry("k1", "v1"));
+    }
+
+    @Test
+    public void testDefault() throws Exception {
+        ProtocolConfig protocol = new ProtocolConfig();
+        protocol.setDefault(true);
+        assertThat(protocol.isDefault(), is(true));
+    }
+
+    @Test
+    public void testKeepAlive() throws Exception {
+        ProtocolConfig protocol = new ProtocolConfig();
+        protocol.setKeepAlive(true);
+        assertThat(protocol.getKeepAlive(), is(true));
+    }
+
+    @Test
+    public void testOptimizer() throws Exception {
+        ProtocolConfig protocol = new ProtocolConfig();
+        protocol.setOptimizer("optimizer");
+        assertThat(protocol.getOptimizer(), equalTo("optimizer"));
+    }
+
+    @Test
+    public void testExtension() throws Exception {
+        ProtocolConfig protocol = new ProtocolConfig();
+        protocol.setExtension("extension");
+        assertThat(protocol.getExtension(), equalTo("extension"));
+    }
+}
diff --git a/dubbo-test/src/test/java/org/apache/dubbo/config/ProviderConfigTest.java b/dubbo-test/src/test/java/org/apache/dubbo/config/ProviderConfigTest.java
new file mode 100644
index 0000000..f76990f
--- /dev/null
+++ b/dubbo-test/src/test/java/org/apache/dubbo/config/ProviderConfigTest.java
@@ -0,0 +1,219 @@
+/*
+ * 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;
+
+import org.junit.jupiter.api.Test;
+
+import java.util.HashMap;
+import java.util.Map;
+
+import static org.hamcrest.MatcherAssert.assertThat;
+import static org.hamcrest.Matchers.equalTo;
+import static org.hamcrest.Matchers.hasEntry;
+import static org.hamcrest.Matchers.hasKey;
+import static org.hamcrest.Matchers.is;
+import static org.hamcrest.Matchers.not;
+
+public class ProviderConfigTest {
+    @Test
+    public void testProtocol() throws Exception {
+        ProviderConfig provider = new ProviderConfig();
+        provider.setProtocol("protocol");
+        assertThat(provider.getProtocol().getName(), equalTo("protocol"));
+    }
+
+    @Test
+    public void testDefault() throws Exception {
+        ProviderConfig provider = new ProviderConfig();
+        provider.setDefault(true);
+        Map<String, String> parameters = new HashMap<String, String>();
+        ProviderConfig.appendParameters(parameters, provider);
+        assertThat(provider.isDefault(), is(true));
+        assertThat(parameters, not(hasKey("default")));
+    }
+
+    @Test
+    public void testHost() throws Exception {
+        ProviderConfig provider = new ProviderConfig();
+        provider.setHost("demo-host");
+        Map<String, String> parameters = new HashMap<String, String>();
+        ProviderConfig.appendParameters(parameters, provider);
+        assertThat(provider.getHost(), equalTo("demo-host"));
+        assertThat(parameters, not(hasKey("host")));
+    }
+
+    @Test
+    public void testPort() throws Exception {
+        ProviderConfig provider = new ProviderConfig();
+        provider.setPort(8080);
+        Map<String, String> parameters = new HashMap<String, String>();
+        ProviderConfig.appendParameters(parameters, provider);
+        assertThat(provider.getPort(), is(8080));
+        assertThat(parameters, not(hasKey("port")));
+    }
+
+    @Test
+    public void testPath() throws Exception {
+        ProviderConfig provider = new ProviderConfig();
+        provider.setPath("/path");
+        Map<String, String> parameters = new HashMap<String, String>();
+        ProviderConfig.appendParameters(parameters, provider);
+        assertThat(provider.getPath(), equalTo("/path"));
+        assertThat(provider.getContextpath(), equalTo("/path"));
+        assertThat(parameters, not(hasKey("path")));
+    }
+
+    @Test
+    public void testContextPath() throws Exception {
+        ProviderConfig provider = new ProviderConfig();
+        provider.setContextpath("/context-path");
+        Map<String, String> parameters = new HashMap<String, String>();
+        ProviderConfig.appendParameters(parameters, provider);
+        assertThat(provider.getContextpath(), equalTo("/context-path"));
+        assertThat(parameters, not(hasKey("/context-path")));
+    }
+
+    @Test
+    public void testThreadpool() throws Exception {
+        ProviderConfig provider = new ProviderConfig();
+        provider.setThreadpool("mockthreadpool");
+        assertThat(provider.getThreadpool(), equalTo("mockthreadpool"));
+    }
+
+    @Test
+    public void testThreads() throws Exception {
+        ProviderConfig provider = new ProviderConfig();
+        provider.setThreads(10);
+        assertThat(provider.getThreads(), is(10));
+    }
+
+    @Test
+    public void testIothreads() throws Exception {
+        ProviderConfig provider = new ProviderConfig();
+        provider.setIothreads(10);
+        assertThat(provider.getIothreads(), is(10));
+    }
+
+    @Test
+    public void testQueues() throws Exception {
+        ProviderConfig provider = new ProviderConfig();
+        provider.setQueues(10);
+        assertThat(provider.getQueues(), is(10));
+    }
+
+    @Test
+    public void testAccepts() throws Exception {
+        ProviderConfig provider = new ProviderConfig();
+        provider.setAccepts(10);
+        assertThat(provider.getAccepts(), is(10));
+    }
+
+    @Test
+    public void testCharset() throws Exception {
+        ProviderConfig provider = new ProviderConfig();
+        provider.setCharset("utf-8");
+        assertThat(provider.getCharset(), equalTo("utf-8"));
+    }
+
+    @Test
+    public void testPayload() throws Exception {
+        ProviderConfig provider = new ProviderConfig();
+        provider.setPayload(10);
+        assertThat(provider.getPayload(), is(10));
+    }
+
+    @Test
+    public void testBuffer() throws Exception {
+        ProviderConfig provider = new ProviderConfig();
+        provider.setBuffer(10);
+        assertThat(provider.getBuffer(), is(10));
+    }
+
+    @Test
+    public void testServer() throws Exception {
+        ProviderConfig provider = new ProviderConfig();
+        provider.setServer("demo-server");
+        assertThat(provider.getServer(), equalTo("demo-server"));
+    }
+
+    @Test
+    public void testClient() throws Exception {
+        ProviderConfig provider = new ProviderConfig();
+        provider.setClient("client");
+        assertThat(provider.getClient(), equalTo("client"));
+    }
+
+    @Test
+    public void testTelnet() throws Exception {
+        ProviderConfig provider = new ProviderConfig();
+        provider.setTelnet("mocktelnethandler");
+        assertThat(provider.getTelnet(), equalTo("mocktelnethandler"));
+    }
+
+    @Test
+    public void testPrompt() throws Exception {
+        ProviderConfig provider = new ProviderConfig();
+        provider.setPrompt("#");
+        Map<String, String> parameters = new HashMap<String, String>();
+        ProviderConfig.appendParameters(parameters, provider);
+        assertThat(provider.getPrompt(), equalTo("#"));
+        assertThat(parameters, hasEntry("prompt", "%23"));
+    }
+
+    @Test
+    public void testStatus() throws Exception {
+        ProviderConfig provider = new ProviderConfig();
+        provider.setStatus("mockstatuschecker");
+        assertThat(provider.getStatus(), equalTo("mockstatuschecker"));
+    }
+
+    @Test
+    public void testTransporter() throws Exception {
+        ProviderConfig provider = new ProviderConfig();
+        provider.setTransporter("mocktransporter");
+        assertThat(provider.getTransporter(), equalTo("mocktransporter"));
+    }
+
+    @Test
+    public void testExchanger() throws Exception {
+        ProviderConfig provider = new ProviderConfig();
+        provider.setExchanger("mockexchanger");
+        assertThat(provider.getExchanger(), equalTo("mockexchanger"));
+    }
+
+    @Test
+    public void testDispatcher() throws Exception {
+        ProviderConfig provider = new ProviderConfig();
+        provider.setDispatcher("mockdispatcher");
+        assertThat(provider.getDispatcher(), equalTo("mockdispatcher"));
+    }
+
+    @Test
+    public void testNetworker() throws Exception {
+        ProviderConfig provider = new ProviderConfig();
+        provider.setNetworker("networker");
+        assertThat(provider.getNetworker(), equalTo("networker"));
+    }
+
+    @Test
+    public void testWait() throws Exception {
+        ProviderConfig provider = new ProviderConfig();
+        provider.setWait(10);
+        assertThat(provider.getWait(), equalTo(10));
+    }
+}
diff --git a/dubbo-test/src/test/java/org/apache/dubbo/config/ReferenceConfigTest.java b/dubbo-test/src/test/java/org/apache/dubbo/config/ReferenceConfigTest.java
new file mode 100644
index 0000000..775596c
--- /dev/null
+++ b/dubbo-test/src/test/java/org/apache/dubbo/config/ReferenceConfigTest.java
@@ -0,0 +1,159 @@
+/*
+ * 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;
+
+import org.apache.dubbo.config.annotation.Argument;
+import org.apache.dubbo.config.annotation.Method;
+import org.apache.dubbo.config.annotation.Reference;
+import org.apache.dubbo.config.api.DemoService;
+import org.apache.dubbo.config.provider.impl.DemoServiceImpl;
+import org.apache.dubbo.rpc.model.ApplicationModel;
+
+import org.junit.jupiter.api.AfterEach;
+import org.junit.jupiter.api.Assertions;
+import org.junit.jupiter.api.BeforeEach;
+import org.junit.jupiter.api.Test;
+
+import static org.apache.dubbo.rpc.Constants.LOCAL_PROTOCOL;
+
+public class ReferenceConfigTest {
+
+    @BeforeEach
+    public void setUp() {
+        ApplicationModel.reset();
+    }
+
+    @AfterEach
+    public void tearDown() {
+        ApplicationModel.reset();
+    }
+
+    @Test
+    public void testInjvm() throws Exception {
+        ApplicationConfig application = new ApplicationConfig();
+        application.setName("test-protocol-random-port");
+
+        RegistryConfig registry = new RegistryConfig();
+        registry.setAddress("multicast://224.5.6.7:1234");
+
+        ProtocolConfig protocol = new ProtocolConfig();
+        protocol.setName("mockprotocol");
+
+        ServiceConfig<DemoService> demoService;
+        demoService = new ServiceConfig<DemoService>();
+        demoService.setInterface(DemoService.class);
+        demoService.setRef(new DemoServiceImpl());
+        demoService.setApplication(application);
+        demoService.setRegistry(registry);
+        demoService.setProtocol(protocol);
+
+        ReferenceConfig<DemoService> rc = new ReferenceConfig<DemoService>();
+        rc.setApplication(application);
+        rc.setRegistry(registry);
+        rc.setInterface(DemoService.class.getName());
+        rc.setInjvm(false);
+
+        try {
+            System.setProperty("java.net.preferIPv4Stack", "true");
+            demoService.export();
+            rc.get();
+            Assertions.assertTrue(!LOCAL_PROTOCOL.equalsIgnoreCase(
+                    rc.getInvoker().getUrl().getProtocol()));
+        } finally {
+            System.clearProperty("java.net.preferIPv4Stack");
+            demoService.unexport();
+        }
+    }
+
+    /**
+     * unit test for dubbo-1765
+     */
+    @Test
+    public void testReferenceRetry() {
+        ApplicationConfig application = new ApplicationConfig();
+        application.setName("test-reference-retry");
+        RegistryConfig registry = new RegistryConfig();
+        registry.setAddress("multicast://224.5.6.7:1234");
+        ProtocolConfig protocol = new ProtocolConfig();
+        protocol.setName("mockprotocol");
+
+        ReferenceConfig<DemoService> rc = new ReferenceConfig<DemoService>();
+        rc.setApplication(application);
+        rc.setRegistry(registry);
+        rc.setInterface(DemoService.class.getName());
+
+        boolean success = false;
+        DemoService demoService = null;
+        try {
+            demoService = rc.get();
+            success = true;
+        } catch (Exception e) {
+            e.printStackTrace();
+        }
+        Assertions.assertFalse(success);
+        Assertions.assertNull(demoService);
+
+        ServiceConfig<DemoService> sc = new ServiceConfig<DemoService>();
+        sc.setInterface(DemoService.class);
+        sc.setRef(new DemoServiceImpl());
+        sc.setApplication(application);
+        sc.setRegistry(registry);
+        sc.setProtocol(protocol);
+
+        try {
+            System.setProperty("java.net.preferIPv4Stack", "true");
+            sc.export();
+            demoService = rc.get();
+            success = true;
+        } catch (Exception e) {
+            e.printStackTrace();
+        } finally {
+            System.clearProperty("java.net.preferIPv4Stack");
+        }
+        Assertions.assertTrue(success);
+        Assertions.assertNotNull(demoService);
+
+    }
+
+    @Test
+    public void testConstructWithReferenceAnnotation() throws NoSuchFieldException {
+        Reference reference = getClass().getDeclaredField("innerTest").getAnnotation(Reference.class);
+        ReferenceConfig referenceConfig = new ReferenceConfig(reference);
+        Assertions.assertEquals(1, referenceConfig.getMethods().size());
+        Assertions.assertEquals(((MethodConfig) referenceConfig.getMethods().get(0)).getName(), "sayHello");
+        Assertions.assertEquals(1300, (int) ((MethodConfig) referenceConfig.getMethods().get(0)).getTimeout());
+        Assertions.assertEquals(4, (int) ((MethodConfig) referenceConfig.getMethods().get(0)).getRetries());
+        Assertions.assertEquals(((MethodConfig) referenceConfig.getMethods().get(0)).getLoadbalance(), "random");
+        Assertions.assertEquals(3, (int) ((MethodConfig) referenceConfig.getMethods().get(0)).getActives());
+        Assertions.assertEquals(5, (int) ((MethodConfig) referenceConfig.getMethods().get(0)).getExecutes());
+        Assertions.assertTrue(((MethodConfig) referenceConfig.getMethods().get(0)).isAsync());
+        Assertions.assertEquals(((MethodConfig) referenceConfig.getMethods().get(0)).getOninvoke(), "i");
+        Assertions.assertEquals(((MethodConfig) referenceConfig.getMethods().get(0)).getOnreturn(), "r");
+        Assertions.assertEquals(((MethodConfig) referenceConfig.getMethods().get(0)).getOnthrow(), "t");
+        Assertions.assertEquals(((MethodConfig) referenceConfig.getMethods().get(0)).getCache(), "c");
+    }
+
+
+    @Reference(methods = {@Method(name = "sayHello", timeout = 1300, retries = 4, loadbalance = "random", async = true,
+            actives = 3, executes = 5, deprecated = true, sticky = true, oninvoke = "i", onthrow = "t", onreturn = "r", cache = "c", validation = "v",
+            arguments = {@Argument(index = 24, callback = true, type = "sss")})})
+    private InnerTest innerTest;
+
+    private class InnerTest {
+
+    }
+}
diff --git a/dubbo-test/src/test/java/org/apache/dubbo/config/RegistryConfigTest.java b/dubbo-test/src/test/java/org/apache/dubbo/config/RegistryConfigTest.java
new file mode 100644
index 0000000..fb74b1e
--- /dev/null
+++ b/dubbo-test/src/test/java/org/apache/dubbo/config/RegistryConfigTest.java
@@ -0,0 +1,190 @@
+/*
+ * 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;
+
+import org.junit.jupiter.api.Assertions;
+import org.junit.jupiter.api.Test;
+
+import java.util.Collections;
+import java.util.HashMap;
+import java.util.Map;
+
+import static org.apache.dubbo.common.constants.CommonConstants.SHUTDOWN_WAIT_KEY;
+import static org.apache.dubbo.config.Constants.SHUTDOWN_TIMEOUT_KEY;
+import static org.hamcrest.CoreMatchers.is;
+import static org.hamcrest.MatcherAssert.assertThat;
+import static org.hamcrest.Matchers.equalTo;
+import static org.hamcrest.Matchers.hasEntry;
+import static org.hamcrest.Matchers.hasKey;
+import static org.hamcrest.Matchers.not;
+
+public class RegistryConfigTest {
+    @Test
+    public void testProtocol() throws Exception {
+        RegistryConfig registry = new RegistryConfig();
+        registry.setProtocol("protocol");
+        assertThat(registry.getProtocol(), equalTo(registry.getProtocol()));
+    }
+
+    @Test
+    public void testAddress() throws Exception {
+        RegistryConfig registry = new RegistryConfig();
+        registry.setAddress("localhost");
+        assertThat(registry.getAddress(), equalTo("localhost"));
+        Map<String, String> parameters = new HashMap<String, String>();
+        RegistryConfig.appendParameters(parameters, registry);
+        assertThat(parameters, not(hasKey("address")));
+    }
+
+    @Test
+    public void testUsername() throws Exception {
+        RegistryConfig registry = new RegistryConfig();
+        registry.setUsername("username");
+        assertThat(registry.getUsername(), equalTo("username"));
+    }
+
+    @Test
+    public void testPassword() throws Exception {
+        RegistryConfig registry = new RegistryConfig();
+        registry.setPassword("password");
+        assertThat(registry.getPassword(), equalTo("password"));
+    }
+
+    @Test
+    public void testWait() throws Exception {
+        try {
+            RegistryConfig registry = new RegistryConfig();
+            registry.setWait(10);
+            assertThat(registry.getWait(), is(10));
+            assertThat(System.getProperty(SHUTDOWN_WAIT_KEY), equalTo("10"));
+        } finally {
+            System.clearProperty(SHUTDOWN_TIMEOUT_KEY);
+        }
+    }
+
+    @Test
+    public void testCheck() throws Exception {
+        RegistryConfig registry = new RegistryConfig();
+        registry.setCheck(true);
+        assertThat(registry.isCheck(), is(true));
+    }
+
+    @Test
+    public void testFile() throws Exception {
+        RegistryConfig registry = new RegistryConfig();
+        registry.setFile("file");
+        assertThat(registry.getFile(), equalTo("file"));
+    }
+
+    @Test
+    public void testTransporter() throws Exception {
+        RegistryConfig registry = new RegistryConfig();
+        registry.setTransporter("transporter");
+        assertThat(registry.getTransporter(), equalTo("transporter"));
+    }
+
+    @Test
+    public void testClient() throws Exception {
+        RegistryConfig registry = new RegistryConfig();
+        registry.setClient("client");
+        assertThat(registry.getClient(), equalTo("client"));
+    }
+
+    @Test
+    public void testTimeout() throws Exception {
+        RegistryConfig registry = new RegistryConfig();
+        registry.setTimeout(10);
+        assertThat(registry.getTimeout(), is(10));
+    }
+
+    @Test
+    public void testSession() throws Exception {
+        RegistryConfig registry = new RegistryConfig();
+        registry.setSession(10);
+        assertThat(registry.getSession(), is(10));
+    }
+
+    @Test
+    public void testDynamic() throws Exception {
+        RegistryConfig registry = new RegistryConfig();
+        registry.setDynamic(true);
+        assertThat(registry.isDynamic(), is(true));
+    }
+
+    @Test
+    public void testRegister() throws Exception {
+        RegistryConfig registry = new RegistryConfig();
+        registry.setRegister(true);
+        assertThat(registry.isRegister(), is(true));
+    }
+
+    @Test
+    public void testSubscribe() throws Exception {
+        RegistryConfig registry = new RegistryConfig();
+        registry.setSubscribe(true);
+        assertThat(registry.isSubscribe(), is(true));
+    }
+
+    @Test
+    public void testCluster() throws Exception {
+        RegistryConfig registry = new RegistryConfig();
+        registry.setCluster("cluster");
+        assertThat(registry.getCluster(), equalTo("cluster"));
+    }
+
+    @Test
+    public void testGroup() throws Exception {
+        RegistryConfig registry = new RegistryConfig();
+        registry.setGroup("group");
+        assertThat(registry.getGroup(), equalTo("group"));
+    }
+
+    @Test
+    public void testVersion() throws Exception {
+        RegistryConfig registry = new RegistryConfig();
+        registry.setVersion("1.0.0");
+        assertThat(registry.getVersion(), equalTo("1.0.0"));
+    }
+
+    @Test
+    public void testParameters() throws Exception {
+        RegistryConfig registry = new RegistryConfig();
+        registry.setParameters(Collections.singletonMap("k1", "v1"));
+        assertThat(registry.getParameters(), hasEntry("k1", "v1"));
+        Map<String, String> parameters = new HashMap<String, String>();
+        RegistryConfig.appendParameters(parameters, registry);
+        assertThat(parameters, hasEntry("k1", "v1"));
+    }
+
+    @Test
+    public void testDefault() throws Exception {
+        RegistryConfig registry = new RegistryConfig();
+        registry.setDefault(true);
+        assertThat(registry.isDefault(), is(true));
+    }
+
+    @Test
+    public void testEquals() throws Exception {
+        RegistryConfig registry1 = new RegistryConfig();
+        RegistryConfig registry2 = new RegistryConfig();
+        registry1.setAddress("zookeeper://127.0.0.1:2182");
+        registry2.setAddress("zookeeper://127.0.0.1:2183");
+        Assertions.assertNotEquals(registry1, registry2);
+    }
+
+}
diff --git a/dubbo-test/src/test/java/org/apache/dubbo/config/ServiceConfigTest.java b/dubbo-test/src/test/java/org/apache/dubbo/config/ServiceConfigTest.java
new file mode 100644
index 0000000..4d157ff
--- /dev/null
+++ b/dubbo-test/src/test/java/org/apache/dubbo/config/ServiceConfigTest.java
@@ -0,0 +1,264 @@
+/*
+ * 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;
+
+import org.apache.dubbo.common.URL;
+import org.apache.dubbo.config.api.DemoService;
+import org.apache.dubbo.config.api.Greeting;
+import org.apache.dubbo.config.mock.MockProtocol2;
+import org.apache.dubbo.config.mock.MockRegistryFactory2;
+import org.apache.dubbo.config.mock.TestProxyFactory;
+import org.apache.dubbo.config.provider.impl.DemoServiceImpl;
+import org.apache.dubbo.registry.Registry;
+import org.apache.dubbo.rpc.Exporter;
+import org.apache.dubbo.rpc.Invoker;
+import org.apache.dubbo.rpc.Protocol;
+import org.apache.dubbo.rpc.service.GenericService;
+
+import org.junit.jupiter.api.AfterEach;
+import org.junit.jupiter.api.Assertions;
+import org.junit.jupiter.api.BeforeEach;
+import org.junit.jupiter.api.Disabled;
+import org.junit.jupiter.api.Test;
+import org.mockito.Mockito;
+
+import java.util.Collections;
+import java.util.concurrent.TimeUnit;
+
+import static org.apache.dubbo.common.constants.CommonConstants.ANYHOST_KEY;
+import static org.apache.dubbo.common.constants.CommonConstants.APPLICATION_KEY;
+import static org.apache.dubbo.common.constants.CommonConstants.GENERIC_SERIALIZATION_BEAN;
+import static org.apache.dubbo.common.constants.CommonConstants.GENERIC_SERIALIZATION_DEFAULT;
+import static org.apache.dubbo.common.constants.CommonConstants.GENERIC_SERIALIZATION_NATIVE_JAVA;
+import static org.apache.dubbo.common.constants.CommonConstants.INTERFACE_KEY;
+import static org.apache.dubbo.common.constants.CommonConstants.METHODS_KEY;
+import static org.apache.dubbo.common.constants.CommonConstants.PROVIDER;
+import static org.apache.dubbo.common.constants.CommonConstants.SHUTDOWN_WAIT_KEY;
+import static org.apache.dubbo.common.constants.CommonConstants.SIDE_KEY;
+import static org.apache.dubbo.config.Constants.SHUTDOWN_TIMEOUT_KEY;
+import static org.apache.dubbo.remoting.Constants.BIND_IP_KEY;
+import static org.apache.dubbo.remoting.Constants.BIND_PORT_KEY;
+import static org.apache.dubbo.rpc.Constants.GENERIC_KEY;
+import static org.apache.dubbo.rpc.cluster.Constants.EXPORT_KEY;
+import static org.hamcrest.CoreMatchers.containsString;
+import static org.hamcrest.CoreMatchers.equalTo;
+import static org.hamcrest.CoreMatchers.is;
+import static org.hamcrest.MatcherAssert.assertThat;
+import static org.hamcrest.Matchers.hasEntry;
+import static org.hamcrest.Matchers.hasKey;
+import static org.hamcrest.Matchers.hasSize;
+import static org.junit.jupiter.api.Assertions.assertEquals;
+import static org.junit.jupiter.api.Assertions.assertTrue;
+import static org.mockito.Mockito.withSettings;
+
+public class ServiceConfigTest {
+    private Protocol protocolDelegate = Mockito.mock(Protocol.class);
+    private Registry registryDelegate = Mockito.mock(Registry.class);
+    private Exporter exporter = Mockito.mock(Exporter.class);
+    private ServiceConfig<DemoServiceImpl> service = new ServiceConfig<DemoServiceImpl>();
+    private ServiceConfig<DemoServiceImpl> service2 = new ServiceConfig<DemoServiceImpl>();
+    private ServiceConfig<DemoServiceImpl> delayService = new ServiceConfig<DemoServiceImpl>();
+
+    @BeforeEach
+    public void setUp() throws Exception {
+        MockProtocol2.delegate = protocolDelegate;
+        MockRegistryFactory2.registry = registryDelegate;
+        Mockito.when(protocolDelegate.export(Mockito.any(Invoker.class))).thenReturn(exporter);
+
+        ApplicationConfig app = new ApplicationConfig("app");
+
+        ProtocolConfig protocolConfig = new ProtocolConfig();
+        protocolConfig.setName("mockprotocol2");
+
+        ProviderConfig provider = new ProviderConfig();
+        provider.setExport(true);
+        provider.setProtocol(protocolConfig);
+
+        RegistryConfig registry = new RegistryConfig();
+        registry.setProtocol("mockprotocol2");
+        registry.setAddress("N/A");
+
+        ArgumentConfig argument = new ArgumentConfig();
+        argument.setIndex(0);
+        argument.setCallback(false);
+
+        MethodConfig method = new MethodConfig();
+        method.setName("echo");
+        method.setArguments(Collections.singletonList(argument));
+
+        service.setProvider(provider);
+        service.setApplication(app);
+        service.setRegistry(registry);
+        service.setInterface(DemoService.class);
+        service.setRef(new DemoServiceImpl());
+        service.setMethods(Collections.singletonList(method));
+
+        service2.setProvider(provider);
+        service2.setApplication(app);
+        service2.setRegistry(registry);
+        service2.setInterface(DemoService.class);
+        service2.setRef(new DemoServiceImpl());
+        service2.setMethods(Collections.singletonList(method));
+        service2.setProxy("testproxyfactory");
+
+        delayService.setProvider(provider);
+        delayService.setApplication(app);
+        delayService.setRegistry(registry);
+        delayService.setInterface(DemoService.class);
+        delayService.setRef(new DemoServiceImpl());
+        delayService.setMethods(Collections.singletonList(method));
+        delayService.setDelay(100);
+
+//        ApplicationModel.getConfigManager().clear();
+    }
+
+    @AfterEach
+    public void tearDown() {
+//        ApplicationModel.getConfigManager().clear();
+    }
+
+    @Test
+    public void testExport() throws Exception {
+        service.export();
+
+        assertThat(service.getExportedUrls(), hasSize(1));
+        URL url = service.toUrl();
+        assertThat(url.getProtocol(), equalTo("mockprotocol2"));
+        assertThat(url.getPath(), equalTo(DemoService.class.getName()));
+        assertThat(url.getParameters(), hasEntry(ANYHOST_KEY, "true"));
+        assertThat(url.getParameters(), hasEntry(APPLICATION_KEY, "app"));
+        assertThat(url.getParameters(), hasKey(BIND_IP_KEY));
+        assertThat(url.getParameters(), hasKey(BIND_PORT_KEY));
+        assertThat(url.getParameters(), hasEntry(EXPORT_KEY, "true"));
+        assertThat(url.getParameters(), hasEntry("echo.0.callback", "false"));
+        assertThat(url.getParameters(), hasEntry(GENERIC_KEY, "false"));
+        assertThat(url.getParameters(), hasEntry(INTERFACE_KEY, DemoService.class.getName()));
+        assertThat(url.getParameters(), hasKey(METHODS_KEY));
+        assertThat(url.getParameters().get(METHODS_KEY), containsString("echo"));
+        assertThat(url.getParameters(), hasEntry(SIDE_KEY, PROVIDER));
+        Mockito.verify(protocolDelegate).export(Mockito.any(Invoker.class));
+    }
+
+    @Test
+    public void testProxy() throws Exception {
+        service2.export();
+
+        assertThat(service2.getExportedUrls(), hasSize(1));
+        assertEquals(2, TestProxyFactory.count); // local injvm and registry protocol, so expected is 2
+    }
+
+
+    @Test
+    public void testDelayExport() throws Exception {
+        delayService.export();
+        assertTrue(delayService.getExportedUrls().isEmpty());
+        //add 300ms to ensure that the delayService has been exported
+        TimeUnit.MILLISECONDS.sleep(delayService.getDelay() + 300);
+        assertThat(delayService.getExportedUrls(), hasSize(1));
+    }
+
+    @Test
+    @Disabled("cannot pass in travis")
+    public void testUnexport() throws Exception {
+        System.setProperty(SHUTDOWN_WAIT_KEY, "0");
+        try {
+            service.export();
+            service.unexport();
+            Thread.sleep(1000);
+            Mockito.verify(exporter, Mockito.atLeastOnce()).unexport();
+        } finally {
+            System.clearProperty(SHUTDOWN_TIMEOUT_KEY);
+        }
+    }
+
+    @Test
+    public void testInterfaceClass() throws Exception {
+        ServiceConfig<Greeting> service = new ServiceConfig<Greeting>();
+        service.setInterface(Greeting.class.getName());
+        service.setRef(Mockito.mock(Greeting.class));
+        assertThat(service.getInterfaceClass() == Greeting.class, is(true));
+        service = new ServiceConfig<Greeting>();
+        service.setRef(Mockito.mock(Greeting.class, withSettings().extraInterfaces(GenericService.class)));
+        assertThat(service.getInterfaceClass() == GenericService.class, is(true));
+    }
+
+    @Test
+    public void testInterface1() throws Exception {
+        Assertions.assertThrows(IllegalStateException.class, () -> {
+            ServiceConfig<DemoService> service = new ServiceConfig<DemoService>();
+            service.setInterface(DemoServiceImpl.class);
+        });
+    }
+
+    @Test
+    public void testInterface2() throws Exception {
+        ServiceConfig<DemoService> service = new ServiceConfig<DemoService>();
+        service.setInterface(DemoService.class);
+        assertThat(service.getInterface(), equalTo(DemoService.class.getName()));
+    }
+
+    @Test
+    public void testProvider() throws Exception {
+        ServiceConfig service = new ServiceConfig();
+        ProviderConfig provider = new ProviderConfig();
+        service.setProvider(provider);
+        assertThat(service.getProvider(), is(provider));
+    }
+
+    @Test
+    public void testGeneric1() throws Exception {
+        ServiceConfig service = new ServiceConfig();
+        service.setGeneric(GENERIC_SERIALIZATION_DEFAULT);
+        assertThat(service.getGeneric(), equalTo(GENERIC_SERIALIZATION_DEFAULT));
+        service.setGeneric(GENERIC_SERIALIZATION_NATIVE_JAVA);
+        assertThat(service.getGeneric(), equalTo(GENERIC_SERIALIZATION_NATIVE_JAVA));
+        service.setGeneric(GENERIC_SERIALIZATION_BEAN);
+        assertThat(service.getGeneric(), equalTo(GENERIC_SERIALIZATION_BEAN));
+    }
+
+    @Test
+    public void testGeneric2() throws Exception {
+        Assertions.assertThrows(IllegalArgumentException.class, () -> {
+            ServiceConfig service = new ServiceConfig();
+            service.setGeneric("illegal");
+        });
+    }
+
+//    @Test
+//    public void testMock() throws Exception {
+//        Assertions.assertThrows(IllegalArgumentException.class, () -> {
+//            ServiceConfig service = new ServiceConfig();
+//            service.setMock("true");
+//        });
+//    }
+//
+//    @Test
+//    public void testMock2() throws Exception {
+//        Assertions.assertThrows(IllegalArgumentException.class, () -> {
+//            ServiceConfig service = new ServiceConfig();
+//            service.setMock(true);
+//        });
+//    }
+
+    @Test
+    public void testApplicationInUrl() {
+        service.export();
+        Assertions.assertNotNull(service.toUrl().getParameter(APPLICATION_KEY));
+        Assertions.assertEquals("app", service.toUrl().getParameter(APPLICATION_KEY));
+    }
+}
diff --git a/dubbo-test/src/test/java/org/apache/dubbo/config/api/Box.java b/dubbo-test/src/test/java/org/apache/dubbo/config/api/Box.java
new file mode 100644
index 0000000..e63f924
--- /dev/null
+++ b/dubbo-test/src/test/java/org/apache/dubbo/config/api/Box.java
@@ -0,0 +1,23 @@
+/*
+ * 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.api;
+
+public interface Box {
+
+    String getName();
+
+}
\ No newline at end of file
diff --git a/dubbo-test/src/test/java/org/apache/dubbo/config/api/DemoException.java b/dubbo-test/src/test/java/org/apache/dubbo/config/api/DemoException.java
new file mode 100644
index 0000000..2f32c3f
--- /dev/null
+++ b/dubbo-test/src/test/java/org/apache/dubbo/config/api/DemoException.java
@@ -0,0 +1,42 @@
+/*
+ * 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.api;
+
+/**
+ * DemoException
+ */
+public class DemoException extends Exception {
+
+    private static final long serialVersionUID = -8213943026163641747L;
+
+    public DemoException() {
+        super();
+    }
+
+    public DemoException(String message, Throwable cause) {
+        super(message, cause);
+    }
+
+    public DemoException(String message) {
+        super(message);
+    }
+
+    public DemoException(Throwable cause) {
+        super(cause);
+    }
+
+}
diff --git a/dubbo-test/src/test/java/org/apache/dubbo/config/api/DemoService.java b/dubbo-test/src/test/java/org/apache/dubbo/config/api/DemoService.java
new file mode 100644
index 0000000..c5bc722
--- /dev/null
+++ b/dubbo-test/src/test/java/org/apache/dubbo/config/api/DemoService.java
@@ -0,0 +1,37 @@
+/*
+ * 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.api;
+
+import java.util.List;
+
+
+/**
+ * DemoService
+ */
+public interface DemoService {
+
+    String sayName(String name);
+
+    Box getBox();
+
+    void throwDemoException() throws DemoException;
+
+    List<User> getUsers(List<User> users);
+
+    int echo(int i);
+
+}
\ No newline at end of file
diff --git a/dubbo-test/src/test/java/org/apache/dubbo/config/api/Greeting.java b/dubbo-test/src/test/java/org/apache/dubbo/config/api/Greeting.java
new file mode 100644
index 0000000..c2afa98
--- /dev/null
+++ b/dubbo-test/src/test/java/org/apache/dubbo/config/api/Greeting.java
@@ -0,0 +1,24 @@
+/*
+ * 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.api;
+
+import org.apache.dubbo.common.extension.SPI;
+
+@SPI
+public interface Greeting {
+    String hello();
+}
diff --git a/dubbo-test/src/test/java/org/apache/dubbo/config/api/User.java b/dubbo-test/src/test/java/org/apache/dubbo/config/api/User.java
new file mode 100644
index 0000000..5e55cbb
--- /dev/null
+++ b/dubbo-test/src/test/java/org/apache/dubbo/config/api/User.java
@@ -0,0 +1,65 @@
+/*
+ * 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.api;
+
+import java.io.Serializable;
+
+/**
+ * User
+ */
+public class User implements Serializable {
+
+    private static final long serialVersionUID = 1L;
+
+    private String name;
+
+    public User() {
+    }
+
+    public User(String name) {
+        this.name = name;
+    }
+
+    public String getName() {
+        return name;
+    }
+
+    public void setName(String name) {
+        this.name = name;
+    }
+
+    @Override
+    public int hashCode() {
+        return name == null ? -1 : name.hashCode();
+    }
+
+    @Override
+    public boolean equals(Object obj) {
+        if (!(obj instanceof User)) {
+            return false;
+        }
+        User other = (User) obj;
+        if (this == other) {
+            return true;
+        }
+        if (name != null && other.name != null) {
+            return name.equals(other.name);
+        }
+        return false;
+    }
+
+}
diff --git a/dubbo-test/src/test/java/org/apache/dubbo/config/bootstrap/ConsulDubboServiceConsumerBootstrap.java b/dubbo-test/src/test/java/org/apache/dubbo/config/bootstrap/ConsulDubboServiceConsumerBootstrap.java
new file mode 100644
index 0000000..824de82
--- /dev/null
+++ b/dubbo-test/src/test/java/org/apache/dubbo/config/bootstrap/ConsulDubboServiceConsumerBootstrap.java
@@ -0,0 +1,52 @@
+/*
+ * 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.bootstrap;
+
+import org.apache.dubbo.config.bootstrap.rest.UserService;
+
+import static org.apache.dubbo.common.constants.CommonConstants.DEFAULT_METADATA_STORAGE_TYPE;
+
+/**
+ * Dubbo Provider Bootstrap
+ *
+ * @since 2.7.5
+ */
+public class ConsulDubboServiceConsumerBootstrap {
+
+    public static void main(String[] args) throws Exception {
+
+        DubboBootstrap bootstrap = DubboBootstrap.getInstance()
+                .application("consul-dubbo-consumer", app -> app.metadata(DEFAULT_METADATA_STORAGE_TYPE))
+                .registry("zookeeper", builder -> builder.address("consul://127.0.0.1:8500?registry-type=service&subscribed-services=consul-dubbo-provider")
+                        .useAsConfigCenter(true)
+                        .useAsMetadataCenter(true))
+                .reference("echo", builder -> builder.interfaceClass(EchoService.class).protocol("dubbo"))
+                .reference("user", builder -> builder.interfaceClass(UserService.class).protocol("rest"))
+                .start();
+
+        EchoService echoService = bootstrap.getCache().get(EchoService.class);
+        UserService userService = bootstrap.getCache().get(UserService.class);
+
+        for (int i = 0; i < 5; i++) {
+            Thread.sleep(2000L);
+            System.out.println(echoService.echo("Hello,World"));
+            System.out.println(userService.getUser(i * 1L));
+        }
+
+        bootstrap.stop();
+    }
+}
diff --git a/dubbo-test/src/test/java/org/apache/dubbo/config/bootstrap/ConsulDubboServiceProviderBootstrap.java b/dubbo-test/src/test/java/org/apache/dubbo/config/bootstrap/ConsulDubboServiceProviderBootstrap.java
new file mode 100644
index 0000000..ef38944
--- /dev/null
+++ b/dubbo-test/src/test/java/org/apache/dubbo/config/bootstrap/ConsulDubboServiceProviderBootstrap.java
@@ -0,0 +1,42 @@
+/*
+ * 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.bootstrap;
+
+import org.apache.dubbo.config.bootstrap.rest.UserService;
+import org.apache.dubbo.config.bootstrap.rest.UserServiceImpl;
+
+import static org.apache.dubbo.common.constants.CommonConstants.DEFAULT_METADATA_STORAGE_TYPE;
+
+/**
+ * TODO
+ */
+public class ConsulDubboServiceProviderBootstrap {
+
+    public static void main(String[] args) {
+        DubboBootstrap.getInstance()
+                .application("consul-dubbo-provider", app -> app.metadata(DEFAULT_METADATA_STORAGE_TYPE))
+                .registry(builder -> builder.address("consul://127.0.0.1:8500?registry-type=service")
+                        .useAsConfigCenter(true)
+                        .useAsMetadataCenter(true))
+                .protocol("dubbo", builder -> builder.port(-1).name("dubbo"))
+                .protocol("rest", builder -> builder.port(8081).name("rest"))
+                .service("echo", builder -> builder.interfaceClass(EchoService.class).ref(new EchoServiceImpl()).protocolIds("dubbo"))
+                .service("user", builder -> builder.interfaceClass(UserService.class).ref(new UserServiceImpl()).protocolIds("rest"))
+                .start()
+                .await();
+    }
+}
diff --git a/dubbo-test/src/test/java/org/apache/dubbo/config/bootstrap/DubboBootstrapTest.java b/dubbo-test/src/test/java/org/apache/dubbo/config/bootstrap/DubboBootstrapTest.java
new file mode 100644
index 0000000..6136dd4
--- /dev/null
+++ b/dubbo-test/src/test/java/org/apache/dubbo/config/bootstrap/DubboBootstrapTest.java
@@ -0,0 +1,154 @@
+/*
+ * 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.bootstrap;
+
+import org.apache.dubbo.common.URL;
+import org.apache.dubbo.common.constants.CommonConstants;
+import org.apache.dubbo.common.utils.ConfigUtils;
+import org.apache.dubbo.config.AbstractInterfaceConfigTest;
+import org.apache.dubbo.config.ApplicationConfig;
+import org.apache.dubbo.config.MonitorConfig;
+import org.apache.dubbo.config.utils.ConfigValidationUtils;
+import org.apache.dubbo.monitor.MonitorService;
+import org.apache.dubbo.registry.RegistryService;
+
+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.io.TempDir;
+
+import java.io.BufferedOutputStream;
+import java.io.File;
+import java.io.FileOutputStream;
+import java.io.IOException;
+import java.io.OutputStream;
+import java.nio.file.Path;
+import java.util.List;
+import java.util.Properties;
+
+import static org.apache.dubbo.common.constants.CommonConstants.SHUTDOWN_WAIT_KEY;
+import static org.apache.dubbo.common.constants.CommonConstants.SHUTDOWN_WAIT_SECONDS_KEY;
+
+/**
+ * {@link DubboBootstrap} Test
+ *
+ * @since 2.7.5
+ */
+public class DubboBootstrapTest {
+
+    private static File dubboProperties;
+
+    @BeforeAll
+    public static void setUp(@TempDir Path folder) {
+        dubboProperties = folder.resolve(CommonConstants.DUBBO_PROPERTIES_KEY).toFile();
+        System.setProperty(CommonConstants.DUBBO_PROPERTIES_KEY, dubboProperties.getAbsolutePath());
+    }
+
+    @AfterEach
+    public void tearDown() throws IOException {
+
+    }
+
+    @Test
+    public void checkApplication() {
+        System.setProperty("dubbo.application.name", "demo");
+        ApplicationConfig applicationConfig = new ApplicationConfig();
+        applicationConfig.refresh();
+        Assertions.assertEquals("demo", applicationConfig.getName());
+        System.clearProperty("dubbo.application.name");
+    }
+
+    @Test
+    public void compatibleApplicationShutdown() {
+        try {
+            ConfigUtils.setProperties(null);
+            System.clearProperty(SHUTDOWN_WAIT_KEY);
+            System.clearProperty(SHUTDOWN_WAIT_SECONDS_KEY);
+
+            writeDubboProperties(SHUTDOWN_WAIT_KEY, "100");
+            ConfigValidationUtils.validateApplicationConfig(new ApplicationConfig("demo"));
+            Assertions.assertEquals("100", System.getProperty(SHUTDOWN_WAIT_KEY));
+
+            System.clearProperty(SHUTDOWN_WAIT_KEY);
+            ConfigUtils.setProperties(null);
+            writeDubboProperties(SHUTDOWN_WAIT_SECONDS_KEY, "1000");
+            ConfigValidationUtils.validateApplicationConfig(new ApplicationConfig("demo"));
+            Assertions.assertEquals("1000", System.getProperty(SHUTDOWN_WAIT_SECONDS_KEY));
+        } finally {
+            ConfigUtils.setProperties(null);
+            System.clearProperty("dubbo.application.name");
+            System.clearProperty(SHUTDOWN_WAIT_KEY);
+            System.clearProperty(SHUTDOWN_WAIT_SECONDS_KEY);
+        }
+    }
+
+    @Test
+    public void testLoadRegistries() {
+        System.setProperty("dubbo.registry.address", "addr1");
+        AbstractInterfaceConfigTest.InterfaceConfig interfaceConfig = new AbstractInterfaceConfigTest.InterfaceConfig();
+        // FIXME: now we need to check first, then load
+        interfaceConfig.setApplication(new ApplicationConfig("testLoadRegistries"));
+        interfaceConfig.checkRegistry();
+        List<URL> urls = ConfigValidationUtils.loadRegistries(interfaceConfig, true);
+        Assertions.assertEquals(1, urls.size());
+        URL url = urls.get(0);
+        Assertions.assertEquals("registry", url.getProtocol());
+        Assertions.assertEquals("addr1:9090", url.getAddress());
+        Assertions.assertEquals(RegistryService.class.getName(), url.getPath());
+        Assertions.assertTrue(url.getParameters().containsKey("timestamp"));
+        Assertions.assertTrue(url.getParameters().containsKey("pid"));
+        Assertions.assertTrue(url.getParameters().containsKey("registry"));
+        Assertions.assertTrue(url.getParameters().containsKey("dubbo"));
+    }
+
+
+    @Test
+    public void testLoadMonitor() {
+        System.setProperty("dubbo.monitor.address", "monitor-addr:12080");
+        System.setProperty("dubbo.monitor.protocol", "monitor");
+        AbstractInterfaceConfigTest.InterfaceConfig interfaceConfig = new AbstractInterfaceConfigTest.InterfaceConfig();
+        interfaceConfig.setApplication(new ApplicationConfig("testLoadMonitor"));
+        interfaceConfig.setMonitor(new MonitorConfig());
+        URL url = ConfigValidationUtils.loadMonitor(interfaceConfig, new URL("dubbo", "addr1", 9090));
+        Assertions.assertEquals("monitor-addr:12080", url.getAddress());
+        Assertions.assertEquals(MonitorService.class.getName(), url.getParameter("interface"));
+        Assertions.assertNotNull(url.getParameter("dubbo"));
+        Assertions.assertNotNull(url.getParameter("pid"));
+        Assertions.assertNotNull(url.getParameter("timestamp"));
+    }
+
+    private void writeDubboProperties(String key, String value) {
+        OutputStream os = null;
+        try {
+            os = new BufferedOutputStream(new FileOutputStream(dubboProperties));
+            Properties properties = new Properties();
+            properties.put(key, value);
+            properties.store(os, "");
+            os.close();
+        } catch (IOException e) {
+            if (os != null) {
+                try {
+                    os.close();
+                } catch (IOException ioe) {
+                    // ignore
+                }
+            }
+        }
+    }
+
+}
diff --git a/dubbo-test/src/test/java/org/apache/dubbo/config/bootstrap/DubboServiceConsumerBootstrap.java b/dubbo-test/src/test/java/org/apache/dubbo/config/bootstrap/DubboServiceConsumerBootstrap.java
new file mode 100644
index 0000000..f493c16
--- /dev/null
+++ b/dubbo-test/src/test/java/org/apache/dubbo/config/bootstrap/DubboServiceConsumerBootstrap.java
@@ -0,0 +1,58 @@
+/*
+ * 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.bootstrap;
+
+import org.apache.dubbo.config.MetadataReportConfig;
+import org.apache.dubbo.config.bootstrap.rest.UserService;
+
+/**
+ * Dubbo Provider Bootstrap
+ *
+ * @since 2.7.5
+ */
+public class DubboServiceConsumerBootstrap {
+
+    public static void main(String[] args) throws Exception {
+
+        DubboBootstrap bootstrap = DubboBootstrap.getInstance()
+                .application("dubbo-consumer-demo")
+                .protocol(builder -> builder.port(20887).name("dubbo"))
+                // Eureka
+//                .registry(builder -> builder.address("eureka://127.0.0.1:8761?registry-type=service&subscribed-services=dubbo-provider-demo"))
+
+                // Zookeeper
+                .registry("zookeeper", builder -> builder.address("zookeeper://127.0.0.1:2181?registry-type=service&subscribed-services=dubbo-provider-demo"))
+                .metadataReport(new MetadataReportConfig("zookeeper://127.0.0.1:2181"))
+
+                // Nacos
+                // .registry("nacos", builder -> builder.address("nacos://127.0.0.1:8848?registry.type=service&subscribed.services=dubbo-provider-demo"))
+
+                // Consul
+                // .registry("consul", builder -> builder.address("consul://127.0.0.1:8500?registry.type=service&subscribed.services=dubbo-provider-demo").group("namespace1"))
+                .reference("echo", builder -> builder.interfaceClass(EchoService.class).protocol("dubbo"))
+                .reference("user", builder -> builder.interfaceClass(UserService.class).protocol("rest"))
+                .start();
+
+        EchoService echoService = bootstrap.getCache().get(EchoService.class);
+
+        for (int i = 0; i < 500; i++) {
+            Thread.sleep(2000L);
+            System.out.println(echoService.echo("Hello,World"));
+        }
+
+    }
+}
diff --git a/dubbo-test/src/test/java/org/apache/dubbo/config/bootstrap/DubboServiceProviderBootstrap.java b/dubbo-test/src/test/java/org/apache/dubbo/config/bootstrap/DubboServiceProviderBootstrap.java
new file mode 100644
index 0000000..35285dd
--- /dev/null
+++ b/dubbo-test/src/test/java/org/apache/dubbo/config/bootstrap/DubboServiceProviderBootstrap.java
@@ -0,0 +1,95 @@
+/*
+ * 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.bootstrap;
+
+import org.apache.dubbo.config.ApplicationConfig;
+import org.apache.dubbo.config.MetadataReportConfig;
+import org.apache.dubbo.config.ProtocolConfig;
+import org.apache.dubbo.config.RegistryConfig;
+import org.apache.dubbo.config.ServiceConfig;
+import org.apache.dubbo.config.bootstrap.rest.UserService;
+import org.apache.dubbo.config.bootstrap.rest.UserServiceImpl;
+
+import java.util.Arrays;
+
+/**
+ * Dubbo Provider Bootstrap
+ *
+ * @since 2.7.5
+ */
+public class DubboServiceProviderBootstrap {
+
+    public static void main(String[] args) {
+        multipleRegistries();
+    }
+
+    private static void multipleRegistries() {
+        ProtocolConfig restProtocol = new ProtocolConfig();
+        restProtocol.setName("rest");
+        restProtocol.setId("rest");
+        restProtocol.setPort(-1);
+
+        RegistryConfig interfaceRegistry = new RegistryConfig();
+        interfaceRegistry.setId("interfaceRegistry");
+        interfaceRegistry.setAddress("zookeeper://127.0.0.1:2181");
+
+        RegistryConfig serviceRegistry = new RegistryConfig();
+        serviceRegistry.setId("serviceRegistry");
+        serviceRegistry.setAddress("zookeeper://127.0.0.1:2181?registry-type=service");
+
+        ServiceConfig<EchoService> echoService = new ServiceConfig<>();
+        echoService.setInterface(EchoService.class.getName());
+        echoService.setRef(new EchoServiceImpl());
+//        echoService.setRegistries(Arrays.asList(interfaceRegistry, serviceRegistry));
+
+        ServiceConfig<UserService> userService = new ServiceConfig<>();
+        userService.setInterface(UserService.class.getName());
+        userService.setRef(new UserServiceImpl());
+        userService.setProtocol(restProtocol);
+//        userService.setRegistries(Arrays.asList(interfaceRegistry, serviceRegistry));
+
+        ApplicationConfig applicationConfig = new ApplicationConfig("dubbo-provider-demo");
+        applicationConfig.setMetadataType("remote");
+        DubboBootstrap.getInstance()
+                .application(applicationConfig)
+                // Zookeeper in service registry type
+//                .registry("zookeeper", builder -> builder.address("zookeeper://127.0.0.1:2181?registry.type=service"))
+                // Nacos
+//                .registry("zookeeper", builder -> builder.address("nacos://127.0.0.1:8848?registry.type=service"))
+                .registries(Arrays.asList(interfaceRegistry, serviceRegistry))
+//                .registry(RegistryBuilder.newBuilder().address("consul://127.0.0.1:8500?registry.type=service").build())
+                .protocol(builder -> builder.port(-1).name("dubbo"))
+                .metadataReport(new MetadataReportConfig("zookeeper://127.0.0.1:2181"))
+                .service(echoService)
+                .service(userService)
+                .start()
+                .await();
+    }
+
+    private static void testSCCallDubbo() {
+
+    }
+
+    private static void testDubboCallSC() {
+
+    }
+
+    private static void testDubboTansormation() {
+
+    }
+
+}
diff --git a/dubbo-test/src/test/java/org/apache/dubbo/config/bootstrap/DubboServiceProviderMinimumBootstrap.java b/dubbo-test/src/test/java/org/apache/dubbo/config/bootstrap/DubboServiceProviderMinimumBootstrap.java
new file mode 100644
index 0000000..b4e3cfa
--- /dev/null
+++ b/dubbo-test/src/test/java/org/apache/dubbo/config/bootstrap/DubboServiceProviderMinimumBootstrap.java
@@ -0,0 +1,38 @@
+/*
+ * Licensed to the Apache Software Foundation (ASF) under one or more
+ * contributor license agreements.  See the NOTICE file distributed with
+ * this work for additional information regarding copyright ownership.
+ * The ASF licenses this file to You under the Apache License, Version 2.0
+ * (the "License"); you may not use this file except in compliance with
+ * the License.  You may obtain a copy of the License at
+ *
+ *     http://www.apache.org/licenses/LICENSE-2.0
+ *
+ * Unless required by applicable law or agreed to in writing, software
+ * distributed under the License is distributed on an "AS IS" BASIS,
+ * WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied.
+ * See the License for the specific language governing permissions and
+ * limitations under the License.
+ */
+package org.apache.dubbo.config.bootstrap;
+
+import org.apache.dubbo.config.bootstrap.rest.UserService;
+import org.apache.dubbo.config.bootstrap.rest.UserServiceImpl;
+
+/**
+ * TODO
+ */
+public class DubboServiceProviderMinimumBootstrap {
+
+    public static void main(String[] args) {
+        DubboBootstrap.getInstance()
+                .application("dubbo-provider-demo")
+                .registry(builder -> builder.address("zookeeper://127.0.0.1:2181?registry-type=service"))
+//                .registry(builder -> builder.address("eureka://127.0.0.1:8761?registry-type=service"))
+                .protocol(builder -> builder.port(-1).name("dubbo"))
+                .service("echo", builder -> builder.interfaceClass(EchoService.class).ref(new EchoServiceImpl()))
+                .service("user", builder -> builder.interfaceClass(UserService.class).ref(new UserServiceImpl()))
+                .start()
+                .await();
+    }
+}
diff --git a/dubbo-test/src/test/java/org/apache/dubbo/config/bootstrap/EchoService.java b/dubbo-test/src/test/java/org/apache/dubbo/config/bootstrap/EchoService.java
new file mode 100644
index 0000000..7969c07
--- /dev/null
+++ b/dubbo-test/src/test/java/org/apache/dubbo/config/bootstrap/EchoService.java
@@ -0,0 +1,31 @@
+/*
+ * 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.bootstrap;
+
+/**
+ * Echo Service
+ *
+ * @since 2.7.5
+ */
+public interface EchoService {
+
+    String GROUP = "DEFAULT";
+
+    String VERSION = "1.0.0";
+
+    String echo(String message);
+}
diff --git a/dubbo-test/src/test/java/org/apache/dubbo/config/bootstrap/EchoServiceImpl.java b/dubbo-test/src/test/java/org/apache/dubbo/config/bootstrap/EchoServiceImpl.java
new file mode 100644
index 0000000..7c9225d
--- /dev/null
+++ b/dubbo-test/src/test/java/org/apache/dubbo/config/bootstrap/EchoServiceImpl.java
@@ -0,0 +1,36 @@
+/*
+ * 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.bootstrap;
+
+import org.apache.dubbo.rpc.RpcContext;
+
+import static java.lang.String.format;
+
+/**
+ * The implementation of {@link EchoService}
+ *
+ * @see EchoService
+ * @since 2.7.5
+ */
+public class EchoServiceImpl implements EchoService {
+
+    @Override
+    public String echo(String message) {
+        RpcContext rpcContext = RpcContext.getContext();
+        return format("[%s:%s] ECHO - %s", rpcContext.getLocalHost(), rpcContext.getLocalPort(), message);
+    }
+}
diff --git a/dubbo-test/src/test/java/org/apache/dubbo/config/bootstrap/EtcdDubboServiceConsumerBootstrap.java b/dubbo-test/src/test/java/org/apache/dubbo/config/bootstrap/EtcdDubboServiceConsumerBootstrap.java
new file mode 100644
index 0000000..8d61524
--- /dev/null
+++ b/dubbo-test/src/test/java/org/apache/dubbo/config/bootstrap/EtcdDubboServiceConsumerBootstrap.java
@@ -0,0 +1,51 @@
+/*
+ * 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.bootstrap;
+
+import org.apache.dubbo.config.MetadataReportConfig;
+import org.apache.dubbo.config.bootstrap.rest.UserService;
+
+/**
+ * Dubbo Provider Bootstrap
+ *
+ * @since 2.7.5
+ */
+public class EtcdDubboServiceConsumerBootstrap {
+
+    public static void main(String[] args) throws Exception {
+
+        DubboBootstrap bootstrap = DubboBootstrap.getInstance()
+                .application("dubbo-consumer-demo")
+                // Zookeeper
+                .protocol(builder -> builder.port(20887).name("dubbo"))
+                .registry("etcd3", builder -> builder.address("etcd3://127.0.0.1:2379?registry-type=service&subscribed-services=dubbo-provider-demo"))
+                .metadataReport(new MetadataReportConfig("etcd://127.0.0.1:2379"))
+                // Nacos
+//                .registry("consul", builder -> builder.address("consul://127.0.0.1:8500?registry.type=service&subscribed.services=dubbo-provider-demo").group("namespace1"))
+                .reference("echo", builder -> builder.interfaceClass(EchoService.class).protocol("dubbo"))
+                .reference("user", builder -> builder.interfaceClass(UserService.class).protocol("rest"))
+                .start();
+
+        EchoService echoService = bootstrap.getCache().get(EchoService.class);
+
+        for (int i = 0; i < 500; i++) {
+            Thread.sleep(2000L);
+            System.out.println(echoService.echo("Hello,World"));
+        }
+
+    }
+}
diff --git a/dubbo-test/src/test/java/org/apache/dubbo/config/bootstrap/EtcdDubboServiceProviderBootstrap.java b/dubbo-test/src/test/java/org/apache/dubbo/config/bootstrap/EtcdDubboServiceProviderBootstrap.java
new file mode 100644
index 0000000..cbe7b01
--- /dev/null
+++ b/dubbo-test/src/test/java/org/apache/dubbo/config/bootstrap/EtcdDubboServiceProviderBootstrap.java
@@ -0,0 +1,94 @@
+/*
+ * 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.bootstrap;
+
+import org.apache.dubbo.config.ApplicationConfig;
+import org.apache.dubbo.config.ProtocolConfig;
+import org.apache.dubbo.config.RegistryConfig;
+import org.apache.dubbo.config.ServiceConfig;
+import org.apache.dubbo.config.bootstrap.rest.UserService;
+import org.apache.dubbo.config.bootstrap.rest.UserServiceImpl;
+
+import java.util.Arrays;
+
+/**
+ * Dubbo Provider Bootstrap
+ *
+ * @since 2.7.5
+ */
+public class EtcdDubboServiceProviderBootstrap {
+
+    public static void main(String[] args) {
+        multipleRegistries();
+    }
+
+    private static void multipleRegistries() {
+        ProtocolConfig restProtocol = new ProtocolConfig();
+        restProtocol.setName("rest");
+        restProtocol.setId("rest");
+        restProtocol.setPort(-1);
+
+        RegistryConfig interfaceRegistry = new RegistryConfig();
+        interfaceRegistry.setId("interfaceRegistry");
+        interfaceRegistry.setAddress("etcd3://127.0.0.1:2379");
+
+        RegistryConfig serviceRegistry = new RegistryConfig();
+        serviceRegistry.setId("serviceRegistry");
+        serviceRegistry.setAddress("etcd3://127.0.0.1:2379?registry-type=service");
+
+        ServiceConfig<EchoService> echoService = new ServiceConfig<>();
+        echoService.setInterface(EchoService.class.getName());
+        echoService.setRef(new EchoServiceImpl());
+//        echoService.setRegistries(Arrays.asList(interfaceRegistry, serviceRegistry));
+
+        ServiceConfig<UserService> userService = new ServiceConfig<>();
+        userService.setInterface(UserService.class.getName());
+        userService.setRef(new UserServiceImpl());
+        userService.setProtocol(restProtocol);
+//        userService.setRegistries(Arrays.asList(interfaceRegistry, serviceRegistry));
+
+        ApplicationConfig applicationConfig = new ApplicationConfig("dubbo-provider-demo");
+//        applicationConfig.setMetadataType("remote");
+        DubboBootstrap.getInstance()
+                .application(applicationConfig)
+                // Zookeeper in service registry type
+//                .registry("zookeeper", builder -> builder.address("zookeeper://127.0.0.1:2181?registry.type=service"))
+                // Nacos
+//                .registry("zookeeper", builder -> builder.address("nacos://127.0.0.1:8848?registry.type=service"))
+                .registries(Arrays.asList(interfaceRegistry, serviceRegistry))
+//                .registry(RegistryBuilder.newBuilder().address("consul://127.0.0.1:8500?registry.type=service").build())
+                .protocol(builder -> builder.port(-1).name("dubbo"))
+//                .metadataReport(new MetadataReportConfig("etcd://127.0.0.1:2379"))
+                .service(echoService)
+                .service(userService)
+                .start()
+                .await();
+    }
+
+    private static void testSCCallDubbo() {
+
+    }
+
+    private static void testDubboCallSC() {
+
+    }
+
+    private static void testDubboTansormation() {
+
+    }
+
+}
diff --git a/dubbo-test/src/test/java/org/apache/dubbo/config/bootstrap/NacosDubboServiceConsumerBootstrap.java b/dubbo-test/src/test/java/org/apache/dubbo/config/bootstrap/NacosDubboServiceConsumerBootstrap.java
new file mode 100644
index 0000000..37262e2
--- /dev/null
+++ b/dubbo-test/src/test/java/org/apache/dubbo/config/bootstrap/NacosDubboServiceConsumerBootstrap.java
@@ -0,0 +1,56 @@
+/*
+ * 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.bootstrap;
+
+import org.apache.dubbo.config.ApplicationConfig;
+import org.apache.dubbo.config.bootstrap.rest.UserService;
+
+import static org.apache.dubbo.common.constants.CommonConstants.REMOTE_METADATA_STORAGE_TYPE;
+
+/**
+ * Dubbo Provider Bootstrap
+ *
+ * @since 2.7.5
+ */
+public class NacosDubboServiceConsumerBootstrap {
+
+    public static void main(String[] args) throws Exception {
+
+        ApplicationConfig applicationConfig = new ApplicationConfig("dubbo-nacos-consumer-demo");
+        applicationConfig.setMetadataType(REMOTE_METADATA_STORAGE_TYPE);
+        DubboBootstrap bootstrap = DubboBootstrap.getInstance()
+                .application(applicationConfig)
+                // Nacos in service registry type
+                .registry("nacos", builder -> builder.address("nacos://127.0.0.1:8848?registry-type=service")
+                        .useAsConfigCenter(true)
+                        .useAsMetadataCenter(true))
+                // Nacos in traditional registry type
+//                .registry("nacos-traditional", builder -> builder.address("nacos://127.0.0.1:8848"))
+                .reference("echo", builder -> builder.interfaceClass(EchoService.class).protocol("dubbo"))
+                .reference("user", builder -> builder.interfaceClass(UserService.class).protocol("rest"))
+                .start();
+
+        EchoService echoService = bootstrap.getCache().get(EchoService.class);
+        UserService userService = bootstrap.getCache().get(UserService.class);
+
+        for (int i = 0; i < 5; i++) {
+            Thread.sleep(2000L);
+            System.out.println(echoService.echo("Hello,World"));
+            System.out.println(userService.getUser(i * 1L));
+        }
+    }
+}
diff --git a/dubbo-test/src/test/java/org/apache/dubbo/config/bootstrap/NacosDubboServiceProviderBootstrap.java b/dubbo-test/src/test/java/org/apache/dubbo/config/bootstrap/NacosDubboServiceProviderBootstrap.java
new file mode 100644
index 0000000..72c597a
--- /dev/null
+++ b/dubbo-test/src/test/java/org/apache/dubbo/config/bootstrap/NacosDubboServiceProviderBootstrap.java
@@ -0,0 +1,51 @@
+/*
+ * 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.bootstrap;
+
+import org.apache.dubbo.config.ApplicationConfig;
+import org.apache.dubbo.config.bootstrap.rest.UserService;
+import org.apache.dubbo.config.bootstrap.rest.UserServiceImpl;
+
+import static org.apache.dubbo.common.constants.CommonConstants.REMOTE_METADATA_STORAGE_TYPE;
+import static org.apache.dubbo.common.constants.RegistryConstants.REGISTRY_TYPE_KEY;
+import static org.apache.dubbo.common.constants.RegistryConstants.SERVICE_REGISTRY_TYPE;
+
+/**
+ * Dubbo Provider Bootstrap
+ *
+ * @since 2.7.5
+ */
+public class NacosDubboServiceProviderBootstrap {
+
+    public static void main(String[] args) {
+        ApplicationConfig applicationConfig = new ApplicationConfig("dubbo-nacos-provider-demo");
+        applicationConfig.setMetadataType(REMOTE_METADATA_STORAGE_TYPE);
+        DubboBootstrap.getInstance()
+                .application(applicationConfig)
+                // Nacos in service registry type
+                .registry("nacos", builder -> builder.address("nacos://127.0.0.1:8848?username=nacos&password=nacos")
+                        .parameter(REGISTRY_TYPE_KEY, SERVICE_REGISTRY_TYPE))
+                // Nacos in traditional registry type
+//                .registry("nacos-traditional", builder -> builder.address("nacos://127.0.0.1:8848"))
+                .protocol("dubbo", builder -> builder.port(20885).name("dubbo"))
+                .protocol("rest", builder -> builder.port(9090).name("rest"))
+                .service(builder -> builder.id("echo").interfaceClass(EchoService.class).ref(new EchoServiceImpl()).protocolIds("dubbo"))
+                .service(builder -> builder.id("user").interfaceClass(UserService.class).ref(new UserServiceImpl()).protocolIds("rest"))
+                .start()
+                .await();
+    }
+}
diff --git a/dubbo-test/src/test/java/org/apache/dubbo/config/bootstrap/ZookeeperDubboServiceConsumerBootstrap.java b/dubbo-test/src/test/java/org/apache/dubbo/config/bootstrap/ZookeeperDubboServiceConsumerBootstrap.java
new file mode 100644
index 0000000..27f3eb9
--- /dev/null
+++ b/dubbo-test/src/test/java/org/apache/dubbo/config/bootstrap/ZookeeperDubboServiceConsumerBootstrap.java
@@ -0,0 +1,55 @@
+/*
+ * 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.bootstrap;
+
+import org.apache.dubbo.config.bootstrap.rest.UserService;
+
+import static org.apache.dubbo.common.constants.CommonConstants.COMPOSITE_METADATA_STORAGE_TYPE;
+import static org.apache.dubbo.common.constants.RegistryConstants.REGISTRY_TYPE_KEY;
+import static org.apache.dubbo.common.constants.RegistryConstants.SERVICE_REGISTRY_TYPE;
+
+/**
+ * Dubbo Provider Bootstrap
+ *
+ * @since 2.7.5
+ */
+public class ZookeeperDubboServiceConsumerBootstrap {
+
+    public static void main(String[] args) throws Exception {
+
+        DubboBootstrap bootstrap = DubboBootstrap.getInstance()
+                .application("zookeeper-dubbo-consumer", app -> app.metadata(COMPOSITE_METADATA_STORAGE_TYPE))
+                .registry("zookeeper", builder -> builder.address("zookeeper://127.0.0.1:2181")
+                        .parameter(REGISTRY_TYPE_KEY, SERVICE_REGISTRY_TYPE)
+                        .useAsConfigCenter(true)
+                        .useAsMetadataCenter(true))
+                .reference("echo", builder -> builder.interfaceClass(EchoService.class).protocol("dubbo").services("zookeeper-dubbo-provider"))
+                .reference("user", builder -> builder.interfaceClass(UserService.class).protocol("rest"))
+                .start();
+
+        EchoService echoService = bootstrap.getCache().get(EchoService.class);
+        UserService userService = bootstrap.getCache().get(UserService.class);
+
+        for (int i = 0; i < 5; i++) {
+            Thread.sleep(2000L);
+            System.out.println(echoService.echo("Hello,World"));
+            System.out.println(userService.getUser(i * 1L));
+        }
+
+        bootstrap.stop();
+    }
+}
diff --git a/dubbo-test/src/test/java/org/apache/dubbo/config/bootstrap/ZookeeperDubboServiceProviderBootstrap.java b/dubbo-test/src/test/java/org/apache/dubbo/config/bootstrap/ZookeeperDubboServiceProviderBootstrap.java
new file mode 100644
index 0000000..889aae2
--- /dev/null
+++ b/dubbo-test/src/test/java/org/apache/dubbo/config/bootstrap/ZookeeperDubboServiceProviderBootstrap.java
@@ -0,0 +1,43 @@
+/*
+ * 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.bootstrap;
+
+import org.apache.dubbo.config.bootstrap.rest.UserService;
+import org.apache.dubbo.config.bootstrap.rest.UserServiceImpl;
+
+import static org.apache.dubbo.common.constants.CommonConstants.COMPOSITE_METADATA_STORAGE_TYPE;
+import static org.apache.dubbo.common.constants.RegistryConstants.REGISTRY_TYPE_KEY;
+import static org.apache.dubbo.common.constants.RegistryConstants.SERVICE_REGISTRY_TYPE;
+
+/**
+ * TODO
+ */
+public class ZookeeperDubboServiceProviderBootstrap {
+
+    public static void main(String[] args) {
+        DubboBootstrap.getInstance()
+                .application("zookeeper-dubbo-provider", app -> app.metadata(COMPOSITE_METADATA_STORAGE_TYPE))
+                .registry(builder -> builder.address("127.0.0.1:2181").protocol("zookeeper")
+                        .parameter(REGISTRY_TYPE_KEY, SERVICE_REGISTRY_TYPE))
+                .protocol("dubbo", builder -> builder.port(-1).name("dubbo"))
+                .protocol("rest", builder -> builder.port(8081).name("rest"))
+                .service("echo", builder -> builder.interfaceClass(EchoService.class).ref(new EchoServiceImpl()).protocolIds("dubbo"))
+                .service("user", builder -> builder.interfaceClass(UserService.class).ref(new UserServiceImpl()).protocolIds("rest"))
+                .start()
+                .await();
+    }
+}
diff --git a/dubbo-test/src/test/java/org/apache/dubbo/config/bootstrap/builders/AbstractBuilderTest.java b/dubbo-test/src/test/java/org/apache/dubbo/config/bootstrap/builders/AbstractBuilderTest.java
new file mode 100644
index 0000000..d32b5cd
--- /dev/null
+++ b/dubbo-test/src/test/java/org/apache/dubbo/config/bootstrap/builders/AbstractBuilderTest.java
@@ -0,0 +1,126 @@
+/*
+ * 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.bootstrap.builders;
+
+import org.apache.dubbo.config.AbstractConfig;
+
+import org.junit.jupiter.api.Assertions;
+import org.junit.jupiter.api.Test;
+
+import java.util.HashMap;
+import java.util.Map;
+
+class AbstractBuilderTest {
+
+    @Test
+    void id() {
+        Builder builder = new Builder();
+        builder.id("id");
+        Assertions.assertEquals("id", builder.build().getId());
+    }
+
+    @Test
+    void prefix() {
+        Builder builder = new Builder();
+        builder.prefix("prefix");
+        Assertions.assertEquals("prefix", builder.build().getPrefix());
+    }
+
+    @Test
+    void appendParameter() {
+        Map<String, String> source = null;
+
+        Map<String, String> parameters = new HashMap<>();
+        parameters.put("default.num", "one");
+        parameters.put("num", "ONE");
+        source = AbstractBuilder.appendParameters(source, parameters);
+
+        Assertions.assertTrue(source.containsKey("default.num"));
+        Assertions.assertEquals("ONE", source.get("num"));
+    }
+
+    @Test
+    void appendParameter2() {
+        Map<String, String> source = new HashMap<>();
+        source.put("default.num", "one1");
+        source.put("num", "ONE1");
+
+        Map<String, String> parameters = new HashMap<>();
+        parameters.put("default.num", "one");
+        parameters.put("num", "ONE");
+        source = AbstractBuilder.appendParameters(source, parameters);
+
+        Assertions.assertTrue(source.containsKey("default.num"));
+        Assertions.assertEquals("ONE", source.get("num"));
+    }
+
+    @Test
+    void appendParameters() {
+        Map<String, String> source = null;
+
+        source = AbstractBuilder.appendParameter(source, "default.num", "one");
+        source = AbstractBuilder.appendParameter(source, "num", "ONE");
+
+        Assertions.assertTrue(source.containsKey("default.num"));
+        Assertions.assertEquals("ONE", source.get("num"));
+    }
+
+    @Test
+    void appendParameters2() {
+        Map<String, String> source = new HashMap<>();
+        source.put("default.num", "one1");
+        source.put("num", "ONE1");
+
+        source = AbstractBuilder.appendParameter(source, "default.num", "one");
+        source = AbstractBuilder.appendParameter(source, "num", "ONE");
+
+        Assertions.assertTrue(source.containsKey("default.num"));
+        Assertions.assertEquals("ONE", source.get("num"));
+    }
+
+    @Test
+    void build() {
+        Builder builder = new Builder();
+        builder.id("id");
+        builder.prefix("prefix");
+
+        Config config = builder.build();
+        Config config2 = builder.build();
+
+        Assertions.assertEquals("id", config.getId());
+        Assertions.assertEquals("prefix", config.getPrefix());
+
+        Assertions.assertNotSame(config, config2);
+    }
+
+    private static class Builder extends AbstractBuilder<Config, Builder> {
+        public Config build() {
+            Config parameterConfig = new Config();
+            super.build(parameterConfig);
+
+            return parameterConfig;
+        }
+
+        @Override
+        protected Builder getThis() {
+            return this;
+        }
+    }
+
+    private static class Config extends AbstractConfig {
+    }
+}
\ No newline at end of file
diff --git a/dubbo-test/src/test/java/org/apache/dubbo/config/bootstrap/builders/AbstractInterfaceBuilderTest.java b/dubbo-test/src/test/java/org/apache/dubbo/config/bootstrap/builders/AbstractInterfaceBuilderTest.java
new file mode 100644
index 0000000..c3bb9cf
--- /dev/null
+++ b/dubbo-test/src/test/java/org/apache/dubbo/config/bootstrap/builders/AbstractInterfaceBuilderTest.java
@@ -0,0 +1,311 @@
+/*
+ * 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.bootstrap.builders;
+
+import org.apache.dubbo.config.AbstractInterfaceConfig;
+import org.apache.dubbo.config.ApplicationConfig;
+import org.apache.dubbo.config.ConfigCenterConfig;
+import org.apache.dubbo.config.MetadataReportConfig;
+import org.apache.dubbo.config.ModuleConfig;
+import org.apache.dubbo.config.MonitorConfig;
+import org.apache.dubbo.config.RegistryConfig;
+
+import org.junit.jupiter.api.Assertions;
+import org.junit.jupiter.api.Test;
+
+import java.util.Collections;
+
+class AbstractInterfaceBuilderTest {
+
+    @Test
+    void local() {
+        InterfaceBuilder builder = new InterfaceBuilder();
+        builder.local("GreetingMock");
+        Assertions.assertEquals("GreetingMock", builder.build().getLocal());
+    }
+
+    @Test
+    void local1() {
+        InterfaceBuilder builder = new InterfaceBuilder();
+        builder.local((Boolean) null);
+        Assertions.assertNull(builder.build().getLocal());
+        builder.local(false);
+        Assertions.assertEquals("false", builder.build().getLocal());
+        builder.local(true);
+        Assertions.assertEquals("true", builder.build().getLocal());
+    }
+
+    @Test
+    void stub() {
+        InterfaceBuilder builder = new InterfaceBuilder();
+        builder.stub("GreetingMock");
+        Assertions.assertEquals("GreetingMock", builder.build().getStub());
+    }
+
+    @Test
+    void stub1() {
+        InterfaceBuilder builder = new InterfaceBuilder();
+        builder.stub((Boolean) null);
+        Assertions.assertNull(builder.build().getLocal());
+        builder.stub(false);
+        Assertions.assertEquals("false", builder.build().getStub());
+        builder.stub(true);
+        Assertions.assertEquals("true", builder.build().getStub());
+    }
+
+    @Test
+    void monitor() {
+        InterfaceBuilder builder = new InterfaceBuilder();
+        builder.monitor("123");
+
+        MonitorConfig monitorConfig = new MonitorConfig("123");
+        Assertions.assertEquals(monitorConfig, builder.build().getMonitor());
+    }
+
+    @Test
+    void monitor1() {
+        MonitorConfig monitorConfig = new MonitorConfig("123");
+        InterfaceBuilder builder = new InterfaceBuilder();
+        builder.monitor(monitorConfig);
+
+        Assertions.assertEquals(monitorConfig, builder.build().getMonitor());
+    }
+
+    @Test
+    void proxy() {
+        InterfaceBuilder builder = new InterfaceBuilder();
+        builder.proxy("mockproxyfactory");
+
+        Assertions.assertEquals("mockproxyfactory", builder.build().getProxy());
+    }
+
+    @Test
+    void cluster() {
+        InterfaceBuilder builder = new InterfaceBuilder();
+        builder.cluster("mockcluster");
+
+        Assertions.assertEquals("mockcluster", builder.build().getCluster());
+    }
+
+    @Test
+    void filter() {
+        InterfaceBuilder builder = new InterfaceBuilder();
+        builder.filter("mockfilter");
+
+        Assertions.assertEquals("mockfilter", builder.build().getFilter());
+    }
+
+    @Test
+    void listener() {
+        InterfaceBuilder builder = new InterfaceBuilder();
+        builder.listener("mockinvokerlistener");
+
+        Assertions.assertEquals("mockinvokerlistener", builder.build().getListener());
+    }
+
+    @Test
+    void owner() {
+        InterfaceBuilder builder = new InterfaceBuilder();
+        builder.owner("owner");
+
+        Assertions.assertEquals("owner", builder.build().getOwner());
+    }
+
+    @Test
+    void connections() {
+        InterfaceBuilder builder = new InterfaceBuilder();
+        builder.connections(1);
+
+        Assertions.assertEquals(1, builder.build().getConnections().intValue());
+    }
+
+    @Test
+    void layer() {
+        InterfaceBuilder builder = new InterfaceBuilder();
+        builder.layer("layer");
+
+        Assertions.assertEquals("layer", builder.build().getLayer());
+    }
+
+    @Test
+    void application() {
+        ApplicationConfig applicationConfig = new ApplicationConfig();
+
+        InterfaceBuilder builder = new InterfaceBuilder();
+        builder.application(applicationConfig);
+
+        Assertions.assertEquals(applicationConfig, builder.build().getApplication());
+    }
+
+    @Test
+    void module() {
+        ModuleConfig moduleConfig = new ModuleConfig();
+        InterfaceBuilder builder = new InterfaceBuilder();
+        builder.module(moduleConfig);
+
+        Assertions.assertEquals(moduleConfig, builder.build().getModule());
+    }
+
+    @Test
+    void addRegistries() {
+        RegistryConfig registryConfig = new RegistryConfig();
+
+        InterfaceBuilder builder = new InterfaceBuilder();
+        builder.addRegistries(Collections.singletonList(registryConfig));
+
+        Assertions.assertEquals(1, builder.build().getRegistries().size());
+        Assertions.assertSame(registryConfig, builder.build().getRegistries().get(0));
+        Assertions.assertSame(registryConfig, builder.build().getRegistry());
+    }
+
+    @Test
+    void addRegistry() {
+        RegistryConfig registryConfig = new RegistryConfig();
+
+        InterfaceBuilder builder = new InterfaceBuilder();
+        builder.addRegistry(registryConfig);
+
+        Assertions.assertEquals(1, builder.build().getRegistries().size());
+        Assertions.assertSame(registryConfig, builder.build().getRegistries().get(0));
+        Assertions.assertSame(registryConfig, builder.build().getRegistry());
+    }
+
+    @Test
+    void registryIds() {
+        InterfaceBuilder builder = new InterfaceBuilder();
+        builder.registryIds("registryIds");
+
+        Assertions.assertEquals("registryIds", builder.build().getRegistryIds());
+    }
+
+    @Test
+    void onconnect() {
+        InterfaceBuilder builder = new InterfaceBuilder();
+        builder.onconnect("onconnect");
+
+        Assertions.assertEquals("onconnect", builder.build().getOnconnect());
+    }
+
+    @Test
+    void ondisconnect() {
+        InterfaceBuilder builder = new InterfaceBuilder();
+        builder.ondisconnect("ondisconnect");
+
+        Assertions.assertEquals("ondisconnect", builder.build().getOndisconnect());
+    }
+
+    @Test
+    void metadataReportConfig() {
+        MetadataReportConfig metadataReportConfig = new MetadataReportConfig();
+
+        InterfaceBuilder builder = new InterfaceBuilder();
+        builder.metadataReportConfig(metadataReportConfig);
+
+        Assertions.assertEquals(metadataReportConfig, builder.build().getMetadataReportConfig());
+    }
+
+    @Test
+    void configCenter() {
+        ConfigCenterConfig configCenterConfig = new ConfigCenterConfig();
+
+        InterfaceBuilder builder = new InterfaceBuilder();
+        builder.configCenter(configCenterConfig);
+
+        Assertions.assertEquals(configCenterConfig, builder.build().getConfigCenter());
+    }
+
+    @Test
+    void callbacks() {
+        InterfaceBuilder builder = new InterfaceBuilder();
+        builder.callbacks(2);
+        Assertions.assertEquals(2, builder.build().getCallbacks().intValue());
+    }
+
+    @Test
+    void scope() {
+        InterfaceBuilder builder = new InterfaceBuilder();
+        builder.scope("scope");
+
+        Assertions.assertEquals("scope", builder.build().getScope());
+    }
+
+    @Test
+    void build() {
+        MonitorConfig monitorConfig = new MonitorConfig("123");
+        ApplicationConfig applicationConfig = new ApplicationConfig();
+        ModuleConfig moduleConfig = new ModuleConfig();
+        RegistryConfig registryConfig = new RegistryConfig();
+        MetadataReportConfig metadataReportConfig = new MetadataReportConfig();
+        ConfigCenterConfig configCenterConfig = new ConfigCenterConfig();
+
+        InterfaceBuilder builder = new InterfaceBuilder();
+        builder.id("id").prefix("prefix").local(true).stub(false).monitor("123").proxy("mockproxyfactory").cluster("mockcluster")
+                .filter("mockfilter").listener("mockinvokerlistener").owner("owner").connections(1)
+                .layer("layer").application(applicationConfig).module(moduleConfig)
+                .addRegistry(registryConfig).registryIds("registryIds")
+                .onconnect("onconnet").ondisconnect("ondisconnect")
+                .metadataReportConfig(metadataReportConfig)
+                .configCenter(configCenterConfig)
+                .callbacks(2).scope("scope");
+
+        InterfaceConfig config = builder.build();
+        InterfaceConfig config2 = builder.build();
+
+        Assertions.assertEquals("id", config.getId());
+        Assertions.assertEquals("prefix", config.getPrefix());
+        Assertions.assertEquals("true", config.getLocal());
+        Assertions.assertEquals("false", config.getStub());
+        Assertions.assertEquals(monitorConfig, config.getMonitor());
+        Assertions.assertEquals("mockproxyfactory", config.getProxy());
+        Assertions.assertEquals("mockcluster", config.getCluster());
+        Assertions.assertEquals("mockfilter", config.getFilter());
+        Assertions.assertEquals("mockinvokerlistener", config.getListener());
+        Assertions.assertEquals("owner", config.getOwner());
+        Assertions.assertEquals(1, config.getConnections().intValue());
+        Assertions.assertEquals("layer", config.getLayer());
+        Assertions.assertEquals(applicationConfig, config.getApplication());
+        Assertions.assertEquals(moduleConfig, config.getModule());
+        Assertions.assertEquals(registryConfig, config.getRegistry());
+        Assertions.assertEquals("registryIds", config.getRegistryIds());
+        Assertions.assertEquals("onconnet", config.getOnconnect());
+        Assertions.assertEquals("ondisconnect", config.getOndisconnect());
+        Assertions.assertEquals(metadataReportConfig, config.getMetadataReportConfig());
+        Assertions.assertEquals(configCenterConfig, config.getConfigCenter());
+        Assertions.assertEquals(2, config.getCallbacks().intValue());
+        Assertions.assertEquals("scope", config.getScope());
+
+        Assertions.assertNotSame(config, config2);
+    }
+
+    private static class InterfaceBuilder extends AbstractInterfaceBuilder<InterfaceConfig, InterfaceBuilder> {
+
+        public InterfaceConfig build() {
+            InterfaceConfig config = new InterfaceConfig();
+            super.build(config);
+
+            return config;
+        }
+
+        @Override
+        protected InterfaceBuilder getThis() {
+            return this;
+        }
+    }
+
+    private static class InterfaceConfig extends AbstractInterfaceConfig {
+    }
+}
\ No newline at end of file
diff --git a/dubbo-test/src/test/java/org/apache/dubbo/config/bootstrap/builders/AbstractMethodBuilderTest.java b/dubbo-test/src/test/java/org/apache/dubbo/config/bootstrap/builders/AbstractMethodBuilderTest.java
new file mode 100644
index 0000000..13a179f
--- /dev/null
+++ b/dubbo-test/src/test/java/org/apache/dubbo/config/bootstrap/builders/AbstractMethodBuilderTest.java
@@ -0,0 +1,196 @@
+/*
+ * 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.bootstrap.builders;
+
+import org.apache.dubbo.config.AbstractMethodConfig;
+
+import org.junit.jupiter.api.Assertions;
+import org.junit.jupiter.api.Test;
+
+import java.util.HashMap;
+import java.util.Map;
+
+class AbstractMethodBuilderTest {
+
+    @Test
+    void timeout() {
+        MethodBuilder builder = new MethodBuilder();
+        builder.timeout(10);
+
+        Assertions.assertEquals(10, builder.build().getTimeout());
+    }
+
+    @Test
+    void retries() {
+        MethodBuilder builder = new MethodBuilder();
+        builder.retries(3);
+
+        Assertions.assertEquals(3, builder.build().getRetries());
+    }
+
+    @Test
+    void actives() {
+        MethodBuilder builder = new MethodBuilder();
+        builder.actives(3);
+
+        Assertions.assertEquals(3, builder.build().getActives());
+    }
+
+    @Test
+    void loadbalance() {
+        MethodBuilder builder = new MethodBuilder();
+        builder.loadbalance("mockloadbalance");
+
+        Assertions.assertEquals("mockloadbalance", builder.build().getLoadbalance());
+    }
+
+    @Test
+    void async() {
+        MethodBuilder builder = new MethodBuilder();
+        builder.async(true);
+
+        Assertions.assertTrue(builder.build().isAsync());
+    }
+
+    @Test
+    void sent() {
+        MethodBuilder builder = new MethodBuilder();
+        builder.sent(true);
+
+        Assertions.assertTrue(builder.build().getSent());
+    }
+
+    @Test
+    void mock() {
+        MethodBuilder builder = new MethodBuilder();
+        builder.mock("mock");
+        Assertions.assertEquals("mock", builder.build().getMock());
+        builder.mock("return null");
+        Assertions.assertEquals("return null", builder.build().getMock());
+    }
+
+    @Test
+    void mock1() {
+        MethodBuilder builder = new MethodBuilder();
+        builder.mock(true);
+        Assertions.assertEquals("true", builder.build().getMock());
+        builder.mock(false);
+        Assertions.assertEquals("false", builder.build().getMock());
+    }
+
+    @Test
+    void merger() {
+        MethodBuilder builder = new MethodBuilder();
+        builder.merger("merger");
+        Assertions.assertEquals("merger", builder.build().getMerger());
+    }
+
+    @Test
+    void cache() {
+        MethodBuilder builder = new MethodBuilder();
+        builder.cache("cache");
+        Assertions.assertEquals("cache", builder.build().getCache());
+    }
+
+    @Test
+    void validation() {
+        MethodBuilder builder = new MethodBuilder();
+        builder.validation("validation");
+        Assertions.assertEquals("validation", builder.build().getValidation());
+    }
+
+    @Test
+    void appendParameter() {
+        MethodBuilder builder = new MethodBuilder();
+        builder.appendParameter("default.num", "one").appendParameter("num", "ONE");
+
+        Map<String, String> parameters = builder.build().getParameters();
+
+        Assertions.assertTrue(parameters.containsKey("default.num"));
+        Assertions.assertEquals("ONE", parameters.get("num"));
+    }
+
+    @Test
+    void appendParameters() {
+        Map<String, String> source = new HashMap<>();
+        source.put("default.num", "one");
+        source.put("num", "ONE");
+
+        MethodBuilder builder = new MethodBuilder();
+        builder.appendParameters(source);
+
+        Map<String, String> parameters = builder.build().getParameters();
+
+        Assertions.assertTrue(parameters.containsKey("default.num"));
+        Assertions.assertEquals("ONE", parameters.get("num"));
+    }
+
+    @Test
+    void forks() {
+        MethodBuilder builder = new MethodBuilder();
+        builder.forks(5);
+
+        Assertions.assertEquals(5, builder.build().getForks());
+    }
+
+    @Test
+    void build() {
+        MethodBuilder builder = new MethodBuilder();
+        builder.id("id").prefix("prefix").timeout(1).retries(2).actives(3).loadbalance("mockloadbalance").async(true)
+                .sent(false).mock("mock").merger("merger").cache("cache").validation("validation")
+                .appendParameter("default.num", "one");
+
+        MethodConfig config = builder.build();
+        MethodConfig config2 = builder.build();
+
+        Assertions.assertEquals("id", config.getId());
+        Assertions.assertEquals("prefix", config.getPrefix());
+        Assertions.assertEquals(1, config.getTimeout());
+        Assertions.assertEquals(2, config.getRetries());
+        Assertions.assertEquals(3, config.getActives());
+        Assertions.assertEquals("mockloadbalance", config.getLoadbalance());
+        Assertions.assertTrue(config.isAsync());
+        Assertions.assertFalse(config.getSent());
+        Assertions.assertEquals("mock", config.getMock());
+        Assertions.assertEquals("merger", config.getMerger());
+        Assertions.assertEquals("cache", config.getCache());
+        Assertions.assertEquals("validation", config.getValidation());
+        Assertions.assertTrue(config.getParameters().containsKey("default.num"));
+        Assertions.assertEquals("one", config.getParameters().get("default.num"));
+
+        Assertions.assertNotSame(config, config2);
+
+    }
+
+    private static class MethodBuilder extends AbstractMethodBuilder<MethodConfig, MethodBuilder> {
+
+        public MethodConfig build() {
+            MethodConfig parameterConfig = new MethodConfig();
+            super.build(parameterConfig);
+
+            return parameterConfig;
+        }
+
+        @Override
+        protected MethodBuilder getThis() {
+            return this;
+        }
+    }
+
+    private static class MethodConfig extends AbstractMethodConfig {
+    }
+}
\ No newline at end of file
diff --git a/dubbo-test/src/test/java/org/apache/dubbo/config/bootstrap/builders/AbstractReferenceBuilderTest.java b/dubbo-test/src/test/java/org/apache/dubbo/config/bootstrap/builders/AbstractReferenceBuilderTest.java
new file mode 100644
index 0000000..c505ca9
--- /dev/null
+++ b/dubbo-test/src/test/java/org/apache/dubbo/config/bootstrap/builders/AbstractReferenceBuilderTest.java
@@ -0,0 +1,151 @@
+/*
+ * 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.bootstrap.builders;
+
+import org.apache.dubbo.config.AbstractReferenceConfig;
+
+import org.junit.jupiter.api.Assertions;
+import org.junit.jupiter.api.Test;
+
+import static org.apache.dubbo.common.constants.CommonConstants.GENERIC_SERIALIZATION_BEAN;
+
+class AbstractReferenceBuilderTest {
+
+    @Test
+    void check() {
+        ReferenceBuilder builder = new ReferenceBuilder();
+        builder.check(true);
+        Assertions.assertTrue(builder.build().isCheck());
+        builder.check(false);
+        Assertions.assertFalse(builder.build().isCheck());
+    }
+
+    @Test
+    void init() {
+        ReferenceBuilder builder = new ReferenceBuilder();
+        builder.init(true);
+        Assertions.assertTrue(builder.build().isInit());
+        builder.init(false);
+        Assertions.assertFalse(builder.build().isInit());
+    }
+
+    @Test
+    void generic() {
+        ReferenceBuilder builder = new ReferenceBuilder();
+        builder.generic(true);
+        Assertions.assertTrue(builder.build().isGeneric());
+        builder.generic(false);
+        Assertions.assertFalse(builder.build().isGeneric());
+    }
+
+    @Test
+    void generic1() {
+        ReferenceBuilder builder = new ReferenceBuilder();
+        builder.generic(GENERIC_SERIALIZATION_BEAN);
+        Assertions.assertEquals(GENERIC_SERIALIZATION_BEAN, builder.build().getGeneric());
+    }
+
+    @Test
+    void injvm() {
+        ReferenceBuilder builder = new ReferenceBuilder();
+        builder.injvm(true);
+        Assertions.assertTrue(builder.build().isInjvm());
+        builder.injvm(false);
+        Assertions.assertFalse(builder.build().isInjvm());
+    }
+
+    @Test
+    void lazy() {
+        ReferenceBuilder builder = new ReferenceBuilder();
+        builder.lazy(true);
+        Assertions.assertTrue(builder.build().getLazy());
+        builder.lazy(false);
+        Assertions.assertFalse(builder.build().getLazy());
+    }
+
+    @Test
+    void reconnect() {
+        ReferenceBuilder builder = new ReferenceBuilder();
+        builder.reconnect("reconnect");
+        Assertions.assertEquals("reconnect", builder.build().getReconnect());
+    }
+
+    @Test
+    void sticky() {
+        ReferenceBuilder builder = new ReferenceBuilder();
+        builder.sticky(true);
+        Assertions.assertTrue(builder.build().getSticky());
+        builder.sticky(false);
+        Assertions.assertFalse(builder.build().getSticky());
+    }
+
+    @Test
+    void version() {
+        ReferenceBuilder builder = new ReferenceBuilder();
+        builder.version("version");
+        Assertions.assertEquals("version", builder.build().getVersion());
+    }
+
+    @Test
+    void group() {
+        ReferenceBuilder builder = new ReferenceBuilder();
+        builder.group("group");
+        Assertions.assertEquals("group", builder.build().getGroup());
+    }
+
+    @Test
+    void build() {
+        ReferenceBuilder builder = new ReferenceBuilder();
+        builder.check(true).init(false).generic(true).injvm(false).lazy(true).reconnect("reconnect").sticky(false)
+                .version("version").group("group").id("id").prefix("prefix");
+
+        ReferenceConfig config = builder.build();
+        ReferenceConfig config2 = builder.build();
+
+        Assertions.assertEquals("id", config.getId());
+        Assertions.assertEquals("prefix", config.getPrefix());
+        Assertions.assertTrue(config.isCheck());
+        Assertions.assertFalse(config.isInit());
+        Assertions.assertTrue(config.isGeneric());
+        Assertions.assertFalse(config.isInjvm());
+        Assertions.assertTrue(config.getLazy());
+        Assertions.assertFalse(config.getSticky());
+        Assertions.assertEquals("reconnect", config.getReconnect());
+        Assertions.assertEquals("version", config.getVersion());
+        Assertions.assertEquals("group", config.getGroup());
+
+        Assertions.assertNotSame(config, config2);
+    }
+
+    private static class ReferenceBuilder extends AbstractReferenceBuilder<ReferenceConfig, ReferenceBuilder> {
+
+        public ReferenceConfig build() {
+            ReferenceConfig parameterConfig = new ReferenceConfig();
+            super.build(parameterConfig);
+
+            return parameterConfig;
+        }
+
+        @Override
+        protected ReferenceBuilder getThis() {
+            return this;
+        }
+    }
+
+    private static class ReferenceConfig extends AbstractReferenceConfig {
+    }
+}
\ No newline at end of file
diff --git a/dubbo-test/src/test/java/org/apache/dubbo/config/bootstrap/builders/AbstractServiceBuilderTest.java b/dubbo-test/src/test/java/org/apache/dubbo/config/bootstrap/builders/AbstractServiceBuilderTest.java
new file mode 100644
index 0000000..d030160
--- /dev/null
+++ b/dubbo-test/src/test/java/org/apache/dubbo/config/bootstrap/builders/AbstractServiceBuilderTest.java
@@ -0,0 +1,245 @@
+/*
+ * 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.bootstrap.builders;
+
+import org.apache.dubbo.config.AbstractServiceConfig;
+import org.apache.dubbo.config.ProtocolConfig;
+
+import org.junit.jupiter.api.Assertions;
+import org.junit.jupiter.api.Test;
+
+import java.util.Collections;
+
+class AbstractServiceBuilderTest {
+
+    @Test
+    void version() {
+        ServiceBuilder builder = new ServiceBuilder();
+        builder.version("version");
+        Assertions.assertEquals("version", builder.build().getVersion());
+    }
+
+    @Test
+    void group() {
+        ServiceBuilder builder = new ServiceBuilder();
+        builder.group("group");
+        Assertions.assertEquals("group", builder.build().getGroup());
+    }
+
+    @Test
+    void deprecated() {
+        ServiceBuilder builder = new ServiceBuilder();
+        builder.deprecated(true);
+        Assertions.assertTrue(builder.build().isDeprecated());
+        builder.deprecated(false);
+        Assertions.assertFalse(builder.build().isDeprecated());
+    }
+
+    @Test
+    void delay() {
+        ServiceBuilder builder = new ServiceBuilder();
+        builder.delay(1000);
+        Assertions.assertEquals(1000, builder.build().getDelay());
+    }
+
+    @Test
+    void export() {
+        ServiceBuilder builder = new ServiceBuilder();
+        builder.export(true);
+        Assertions.assertTrue(builder.build().getExport());
+        builder.export(false);
+        Assertions.assertFalse(builder.build().getExport());
+    }
+
+    @Test
+    void weight() {
+        ServiceBuilder builder = new ServiceBuilder();
+        builder.weight(500);
+        Assertions.assertEquals(500, builder.build().getWeight());
+    }
+
+    @Test
+    void document() {
+        ServiceBuilder builder = new ServiceBuilder();
+        builder.document("http://dubbo.apache.org");
+        Assertions.assertEquals("http://dubbo.apache.org", builder.build().getDocument());
+    }
+
+    @Test
+    void dynamic() {
+        ServiceBuilder builder = new ServiceBuilder();
+        builder.dynamic(true);
+        Assertions.assertTrue(builder.build().isDynamic());
+        builder.dynamic(false);
+        Assertions.assertFalse(builder.build().isDynamic());
+    }
+
+    @Test
+    void token() {
+        ServiceBuilder builder = new ServiceBuilder();
+        builder.token("token");
+        Assertions.assertEquals("token", builder.build().getToken());
+    }
+
+    @Test
+    void token1() {
+        ServiceBuilder builder = new ServiceBuilder();
+        builder.token(true);
+        Assertions.assertEquals("true", builder.build().getToken());
+        builder.token(false);
+        Assertions.assertEquals("false", builder.build().getToken());
+        builder.token((Boolean) null);
+        Assertions.assertNull(builder.build().getToken());
+    }
+
+    @Test
+    void accesslog() {
+        ServiceBuilder builder = new ServiceBuilder();
+        builder.accesslog("accesslog");
+        Assertions.assertEquals("accesslog", builder.build().getAccesslog());
+    }
+
+    @Test
+    void accesslog1() {
+        ServiceBuilder builder = new ServiceBuilder();
+        builder.accesslog(true);
+        Assertions.assertEquals("true", builder.build().getAccesslog());
+        builder.accesslog(false);
+        Assertions.assertEquals("false", builder.build().getAccesslog());
+        builder.accesslog((Boolean) null);
+        Assertions.assertNull(builder.build().getAccesslog());
+    }
+
+    @Test
+    void addProtocols() {
+        ProtocolConfig protocol = new ProtocolConfig();
+        ServiceBuilder builder = new ServiceBuilder();
+        Assertions.assertNull(builder.build().getProtocols());
+        builder.addProtocols(Collections.singletonList(protocol));
+        Assertions.assertNotNull(builder.build().getProtocols());
+        Assertions.assertEquals(1, builder.build().getProtocols().size());
+    }
+
+    @Test
+    void addProtocol() {
+        ProtocolConfig protocol = new ProtocolConfig();
+        ServiceBuilder builder = new ServiceBuilder();
+        Assertions.assertNull(builder.build().getProtocols());
+        builder.addProtocol(protocol);
+        Assertions.assertNotNull(builder.build().getProtocols());
+        Assertions.assertEquals(1, builder.build().getProtocols().size());
+        Assertions.assertEquals(protocol, builder.build().getProtocol());
+    }
+
+    @Test
+    void protocolIds() {
+        ServiceBuilder builder = new ServiceBuilder();
+        builder.protocolIds("protocolIds");
+        Assertions.assertEquals("protocolIds", builder.build().getProtocolIds());
+    }
+
+    @Test
+    void tag() {
+        ServiceBuilder builder = new ServiceBuilder();
+        builder.tag("tag");
+        Assertions.assertEquals("tag", builder.build().getTag());
+    }
+
+    @Test
+    void executes() {
+        ServiceBuilder builder = new ServiceBuilder();
+        builder.executes(10);
+        Assertions.assertEquals(10, builder.build().getExecutes());
+    }
+
+    @Test
+    void register() {
+        ServiceBuilder builder = new ServiceBuilder();
+        builder.register(true);
+        Assertions.assertTrue(builder.build().isRegister());
+        builder.register(false);
+        Assertions.assertFalse(builder.build().isRegister());
+    }
+
+    @Test
+    void warmup() {
+        ServiceBuilder builder = new ServiceBuilder();
+        builder.warmup(100);
+        Assertions.assertEquals(100, builder.build().getWarmup());
+    }
+
+    @Test
+    void serialization() {
+        ServiceBuilder builder = new ServiceBuilder();
+        builder.serialization("serialization");
+        Assertions.assertEquals("serialization", builder.build().getSerialization());
+    }
+
+    @Test
+    void build() {
+        ProtocolConfig protocol = new ProtocolConfig();
+
+        ServiceBuilder builder = new ServiceBuilder();
+        builder.version("version").group("group").deprecated(true).delay(1000).export(false).weight(1)
+                .document("document").dynamic(true).token("token").accesslog("accesslog")
+                .addProtocol(protocol).protocolIds("protocolIds").tag("tag").executes(100).register(false)
+                .warmup(200).serialization("serialization").id("id").prefix("prefix");
+
+        ServiceConfig config = builder.build();
+        ServiceConfig config2 = builder.build();
+
+        Assertions.assertEquals("id", config.getId());
+        Assertions.assertEquals("prefix", config.getPrefix());
+        Assertions.assertEquals("version", config.getVersion());
+        Assertions.assertEquals("group", config.getGroup());
+        Assertions.assertEquals("document", config.getDocument());
+        Assertions.assertEquals("token", config.getToken());
+        Assertions.assertEquals("accesslog", config.getAccesslog());
+        Assertions.assertEquals("protocolIds", config.getProtocolIds());
+        Assertions.assertEquals("tag", config.getTag());
+        Assertions.assertEquals("serialization", config.getSerialization());
+        Assertions.assertTrue(config.isDeprecated());
+        Assertions.assertFalse(config.getExport());
+        Assertions.assertTrue(config.isDynamic());
+        Assertions.assertFalse(config.isRegister());
+        Assertions.assertEquals(1000, config.getDelay());
+        Assertions.assertEquals(1, config.getWeight());
+        Assertions.assertEquals(100, config.getExecutes());
+        Assertions.assertEquals(200, config.getWarmup());
+
+        Assertions.assertNotSame(config, config2);
+    }
+
+    private static class ServiceBuilder extends AbstractServiceBuilder<ServiceConfig, ServiceBuilder> {
+
+        public ServiceConfig build() {
+            ServiceConfig parameterConfig = new ServiceConfig();
+            super.build(parameterConfig);
+
+            return parameterConfig;
+        }
+
+        @Override
+        protected ServiceBuilder getThis() {
+            return this;
+        }
+    }
+
+    private static class ServiceConfig extends AbstractServiceConfig {
+
+    }
+}
\ No newline at end of file
diff --git a/dubbo-test/src/test/java/org/apache/dubbo/config/bootstrap/builders/ApplicationBuilderTest.java b/dubbo-test/src/test/java/org/apache/dubbo/config/bootstrap/builders/ApplicationBuilderTest.java
new file mode 100644
index 0000000..6c37eae
--- /dev/null
+++ b/dubbo-test/src/test/java/org/apache/dubbo/config/bootstrap/builders/ApplicationBuilderTest.java
@@ -0,0 +1,255 @@
+/*
+ * 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.bootstrap.builders;
+
+import org.apache.dubbo.config.ApplicationConfig;
+import org.apache.dubbo.config.MonitorConfig;
+import org.apache.dubbo.config.RegistryConfig;
+
+import org.junit.jupiter.api.Assertions;
+import org.junit.jupiter.api.Test;
+
+import java.util.Collections;
+import java.util.HashMap;
+import java.util.Map;
+
+class ApplicationBuilderTest {
+
+    @Test
+    void name() {
+        ApplicationBuilder builder = new ApplicationBuilder();
+        builder.name("app");
+        Assertions.assertEquals("app", builder.build().getName());
+    }
+
+    @Test
+    void version() {
+        ApplicationBuilder builder = new ApplicationBuilder();
+        builder.version("version");
+        Assertions.assertEquals("version", builder.build().getVersion());
+    }
+
+    @Test
+    void owner() {
+        ApplicationBuilder builder = new ApplicationBuilder();
+        builder.owner("owner");
+        Assertions.assertEquals("owner", builder.build().getOwner());
+    }
+
+    @Test
+    void organization() {
+        ApplicationBuilder builder = new ApplicationBuilder();
+        builder.organization("organization");
+        Assertions.assertEquals("organization", builder.build().getOrganization());
+    }
+
+    @Test
+    void architecture() {
+        ApplicationBuilder builder = new ApplicationBuilder();
+        builder.architecture("architecture");
+        Assertions.assertEquals("architecture", builder.build().getArchitecture());
+    }
+
+    @Test
+    void environment() {
+        ApplicationBuilder builder = new ApplicationBuilder();
+        Assertions.assertEquals("product", builder.build().getEnvironment());
+        builder.environment("develop");
+        Assertions.assertEquals("develop", builder.build().getEnvironment());
+        builder.environment("test");
+        Assertions.assertEquals("test", builder.build().getEnvironment());
+        builder.environment("product");
+        Assertions.assertEquals("product", builder.build().getEnvironment());
+    }
+
+    @Test
+    void compiler() {
+        ApplicationBuilder builder = new ApplicationBuilder();
+        builder.compiler("compiler");
+        Assertions.assertEquals("compiler", builder.build().getCompiler());
+    }
+
+    @Test
+    void logger() {
+        ApplicationBuilder builder = new ApplicationBuilder();
+        builder.logger("log4j");
+        Assertions.assertEquals("log4j", builder.build().getLogger());
+    }
+
+    @Test
+    void addRegistry() {
+        RegistryConfig registry = new RegistryConfig();
+        ApplicationBuilder builder = new ApplicationBuilder();
+        builder.addRegistry(registry);
+        Assertions.assertNotNull(builder.build().getRegistry());
+        Assertions.assertEquals(1, builder.build().getRegistries().size());
+        Assertions.assertSame(registry, builder.build().getRegistry());
+    }
+
+    @Test
+    void addRegistries() {
+        RegistryConfig registry = new RegistryConfig();
+        ApplicationBuilder builder = new ApplicationBuilder();
+        builder.addRegistries(Collections.singletonList(registry));
+        Assertions.assertNotNull(builder.build().getRegistry());
+        Assertions.assertEquals(1, builder.build().getRegistries().size());
+        Assertions.assertSame(registry, builder.build().getRegistry());
+    }
+
+    @Test
+    void registryIds() {
+        ApplicationBuilder builder = new ApplicationBuilder();
+        builder.registryIds("registryIds");
+        Assertions.assertEquals("registryIds", builder.build().getRegistryIds());
+    }
+
+    @Test
+    void monitor() {
+        MonitorConfig monitor = new MonitorConfig("monitor-addr");
+        ApplicationBuilder builder = new ApplicationBuilder();
+        builder.monitor(monitor);
+        Assertions.assertSame(monitor, builder.build().getMonitor());
+        Assertions.assertEquals("monitor-addr", builder.build().getMonitor().getAddress());
+    }
+
+    @Test
+    void monitor1() {
+        ApplicationBuilder builder = new ApplicationBuilder();
+        builder.monitor("monitor-addr");
+        Assertions.assertEquals("monitor-addr", builder.build().getMonitor().getAddress());
+    }
+
+    @Test
+    void isDefault() {
+        ApplicationBuilder builder = new ApplicationBuilder();
+        builder.isDefault(true);
+        Assertions.assertTrue(builder.build().isDefault());
+        builder.isDefault(false);
+        Assertions.assertFalse(builder.build().isDefault());
+        builder.isDefault(null);
+        Assertions.assertNull(builder.build().isDefault());
+    }
+
+    @Test
+    void dumpDirectory() {
+        ApplicationBuilder builder = new ApplicationBuilder();
+        builder.dumpDirectory("dumpDirectory");
+        Assertions.assertEquals("dumpDirectory", builder.build().getDumpDirectory());
+    }
+
+    @Test
+    void qosEnable() {
+        ApplicationBuilder builder = new ApplicationBuilder();
+        builder.qosEnable(true);
+        Assertions.assertTrue(builder.build().getQosEnable());
+        builder.qosEnable(false);
+        Assertions.assertFalse(builder.build().getQosEnable());
+        builder.qosEnable(null);
+        Assertions.assertNull(builder.build().getQosEnable());
+    }
+
+    @Test
+    void qosPort() {
+        ApplicationBuilder builder = new ApplicationBuilder();
+        builder.qosPort(8080);
+        Assertions.assertEquals(8080, builder.build().getQosPort());
+    }
+
+    @Test
+    void qosAcceptForeignIp() {
+        ApplicationBuilder builder = new ApplicationBuilder();
+        builder.qosAcceptForeignIp(true);
+        Assertions.assertTrue(builder.build().getQosAcceptForeignIp());
+        builder.qosAcceptForeignIp(false);
+        Assertions.assertFalse(builder.build().getQosAcceptForeignIp());
+        builder.qosAcceptForeignIp(null);
+        Assertions.assertNull(builder.build().getQosAcceptForeignIp());
+    }
+
+    @Test
+    void shutwait() {
+        ApplicationBuilder builder = new ApplicationBuilder();
+        builder.shutwait("shutwait");
+        Assertions.assertEquals("shutwait", builder.build().getShutwait());
+    }
+
+    @Test
+    void appendParameter() {
+        ApplicationBuilder builder = new ApplicationBuilder();
+        builder.appendParameter("default.num", "one").appendParameter("num", "ONE");
+
+        Map<String, String> parameters = builder.build().getParameters();
+
+        Assertions.assertTrue(parameters.containsKey("default.num"));
+        Assertions.assertEquals("ONE", parameters.get("num"));
+    }
+
+    @Test
+    void appendParameters() {
+        Map<String, String> source = new HashMap<>();
+        source.put("default.num", "one");
+        source.put("num", "ONE");
+
+        ApplicationBuilder builder = new ApplicationBuilder();
+        builder.appendParameters(source);
+
+        Map<String, String> parameters = builder.build().getParameters();
+
+        Assertions.assertTrue(parameters.containsKey("default.num"));
+        Assertions.assertEquals("ONE", parameters.get("num"));
+    }
+
+    @Test
+    void build() {
+        MonitorConfig monitor = new MonitorConfig("monitor-addr");
+        RegistryConfig registry = new RegistryConfig();
+
+        ApplicationBuilder builder = new ApplicationBuilder();
+        builder.id("id").prefix("prefix").name("name").version("version").owner("owner").organization("organization").architecture("architecture")
+                .environment("develop").compiler("compiler").logger("log4j").monitor(monitor).isDefault(false)
+                .dumpDirectory("dumpDirectory").qosEnable(true).qosPort(8080).qosAcceptForeignIp(false)
+                .shutwait("shutwait").registryIds("registryIds").addRegistry(registry)
+                .appendParameter("default.num", "one");
+
+        ApplicationConfig config = builder.build();
+        ApplicationConfig config2 = builder.build();
+
+        Assertions.assertEquals("id", config.getId());
+        Assertions.assertEquals("prefix", config.getPrefix());
+        Assertions.assertEquals("name", config.getName());
+        Assertions.assertEquals("version", config.getVersion());
+        Assertions.assertEquals("owner", config.getOwner());
+        Assertions.assertEquals("organization", config.getOrganization());
+        Assertions.assertEquals("architecture", config.getArchitecture());
+        Assertions.assertEquals("develop", config.getEnvironment());
+        Assertions.assertEquals("compiler", config.getCompiler());
+        Assertions.assertEquals("log4j", config.getLogger());
+        Assertions.assertSame(monitor, config.getMonitor());
+        Assertions.assertFalse(config.isDefault());
+        Assertions.assertEquals("dumpDirectory", config.getDumpDirectory());
+        Assertions.assertTrue(config.getQosEnable());
+        Assertions.assertEquals(8080, config.getQosPort());
+        Assertions.assertFalse(config.getQosAcceptForeignIp());
+        Assertions.assertEquals("shutwait", config.getShutwait());
+        Assertions.assertEquals("registryIds", config.getRegistryIds());
+        Assertions.assertSame(registry, config.getRegistry());
+        Assertions.assertTrue(config.getParameters().containsKey("default.num"));
+        Assertions.assertEquals("one", config.getParameters().get("default.num"));
+
+        Assertions.assertNotSame(config, config2);
+    }
+}
\ No newline at end of file
diff --git a/dubbo-test/src/test/java/org/apache/dubbo/config/bootstrap/builders/ArgumentBuilderTest.java b/dubbo-test/src/test/java/org/apache/dubbo/config/bootstrap/builders/ArgumentBuilderTest.java
new file mode 100644
index 0000000..1b6638d
--- /dev/null
+++ b/dubbo-test/src/test/java/org/apache/dubbo/config/bootstrap/builders/ArgumentBuilderTest.java
@@ -0,0 +1,63 @@
+/*
+ * 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.bootstrap.builders;
+
+import org.apache.dubbo.config.ArgumentConfig;
+
+import org.junit.jupiter.api.Assertions;
+import org.junit.jupiter.api.Test;
+
+class ArgumentBuilderTest {
+
+    @Test
+    void index() {
+        ArgumentBuilder builder = new ArgumentBuilder();
+        builder.index(1);
+        Assertions.assertEquals(1, builder.build().getIndex());
+    }
+
+    @Test
+    void type() {
+        ArgumentBuilder builder = new ArgumentBuilder();
+        builder.type("int");
+        Assertions.assertEquals("int", builder.build().getType());
+    }
+
+    @Test
+    void callback() {
+        ArgumentBuilder builder = new ArgumentBuilder();
+        builder.callback(true);
+        Assertions.assertTrue(builder.build().isCallback());
+        builder.callback(false);
+        Assertions.assertFalse(builder.build().isCallback());
+    }
+
+    @Test
+    void build() {
+        ArgumentBuilder builder = new ArgumentBuilder();
+        builder.index(1).type("int").callback(true);
+
+        ArgumentConfig argument1 = builder.build();
+        ArgumentConfig argument2 = builder.build();
+
+        Assertions.assertTrue(argument1.isCallback());
+        Assertions.assertEquals("int", argument1.getType());
+        Assertions.assertEquals(1, argument1.getIndex());
+
+        Assertions.assertNotSame(argument1, argument2);
+    }
+}
\ No newline at end of file
diff --git a/dubbo-test/src/test/java/org/apache/dubbo/config/bootstrap/builders/ConfigCenterBuilderTest.java b/dubbo-test/src/test/java/org/apache/dubbo/config/bootstrap/builders/ConfigCenterBuilderTest.java
new file mode 100644
index 0000000..b9f321b
--- /dev/null
+++ b/dubbo-test/src/test/java/org/apache/dubbo/config/bootstrap/builders/ConfigCenterBuilderTest.java
@@ -0,0 +1,169 @@
+/*
+ * 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.bootstrap.builders;
+
+import org.apache.dubbo.config.ConfigCenterConfig;
+
+import org.junit.jupiter.api.Assertions;
+import org.junit.jupiter.api.Test;
+
+import java.util.HashMap;
+import java.util.Map;
+
+class ConfigCenterBuilderTest {
+
+    @Test
+    void protocol() {
+        ConfigCenterBuilder builder = new ConfigCenterBuilder();
+        builder.protocol("protocol");
+        Assertions.assertEquals("protocol", builder.build().getProtocol());
+    }
+
+    @Test
+    void address() {
+        ConfigCenterBuilder builder = new ConfigCenterBuilder();
+        builder.address("address");
+        Assertions.assertEquals("address", builder.build().getAddress());
+    }
+
+    @Test
+    void cluster() {
+        ConfigCenterBuilder builder = new ConfigCenterBuilder();
+        builder.cluster("cluster");
+        Assertions.assertEquals("cluster", builder.build().getCluster());
+    }
+
+    @Test
+    void namespace() {
+        ConfigCenterBuilder builder = new ConfigCenterBuilder();
+        builder.namespace("namespace");
+        Assertions.assertEquals("namespace", builder.build().getNamespace());
+    }
+
+    @Test
+    void group() {
+        ConfigCenterBuilder builder = new ConfigCenterBuilder();
+        builder.group("group");
+        Assertions.assertEquals("group", builder.build().getGroup());
+    }
+
+    @Test
+    void username() {
+        ConfigCenterBuilder builder = new ConfigCenterBuilder();
+        builder.username("username");
+        Assertions.assertEquals("username", builder.build().getUsername());
+    }
+
+    @Test
+    void password() {
+        ConfigCenterBuilder builder = new ConfigCenterBuilder();
+        builder.password("password");
+        Assertions.assertEquals("password", builder.build().getPassword());
+    }
+
+    @Test
+    void timeout() {
+        ConfigCenterBuilder builder = new ConfigCenterBuilder();
+        builder.timeout(1000L);
+        Assertions.assertEquals(1000L, builder.build().getTimeout());
+    }
+
+    @Test
+    void highestPriority() {
+        ConfigCenterBuilder builder = new ConfigCenterBuilder();
+        builder.highestPriority(true);
+        Assertions.assertTrue(builder.build().isHighestPriority());
+    }
+
+    @Test
+    void check() {
+        ConfigCenterBuilder builder = new ConfigCenterBuilder();
+        builder.check(true);
+        Assertions.assertTrue(builder.build().isCheck());
+    }
+
+    @Test
+    void configFile() {
+        ConfigCenterBuilder builder = new ConfigCenterBuilder();
+        builder.configFile("configFile");
+        Assertions.assertEquals("configFile", builder.build().getConfigFile());
+    }
+
+    @Test
+    void appConfigFile() {
+        ConfigCenterBuilder builder = new ConfigCenterBuilder();
+        builder.appConfigFile("appConfigFile");
+        Assertions.assertEquals("appConfigFile", builder.build().getAppConfigFile());
+    }
+
+    @Test
+    void appendParameter() {
+        ConfigCenterBuilder builder = new ConfigCenterBuilder();
+        builder.appendParameter("default.num", "one").appendParameter("num", "ONE");
+
+        Map<String, String> parameters = builder.build().getParameters();
+
+        Assertions.assertTrue(parameters.containsKey("default.num"));
+        Assertions.assertEquals("ONE", parameters.get("num"));
+    }
+
+    @Test
+    void appendParameters() {
+        Map<String, String> source = new HashMap<>();
+        source.put("default.num", "one");
+        source.put("num", "ONE");
+
+        ConfigCenterBuilder builder = new ConfigCenterBuilder();
+        builder.appendParameters(source);
+
+        Map<String, String> parameters = builder.build().getParameters();
+
+        Assertions.assertTrue(parameters.containsKey("default.num"));
+        Assertions.assertEquals("ONE", parameters.get("num"));
+    }
+
+    @Test
+    void build() {
+        ConfigCenterBuilder builder = new ConfigCenterBuilder();
+        builder.check(true).protocol("protocol").address("address").appConfigFile("appConfigFile")
+                .cluster("cluster").configFile("configFile").group("group").highestPriority(false)
+                .namespace("namespace").password("password").timeout(1000L).username("usernama")
+                .appendParameter("default.num", "one").id("id").prefix("prefix");
+
+        ConfigCenterConfig config = builder.build();
+        ConfigCenterConfig config2 = builder.build();
+
+        Assertions.assertTrue(config.isCheck());
+        Assertions.assertFalse(config.isHighestPriority());
+        Assertions.assertEquals(1000L, config.getTimeout());
+        Assertions.assertEquals("protocol", config.getProtocol());
+        Assertions.assertEquals("address", config.getAddress());
+        Assertions.assertEquals("appConfigFile", config.getAppConfigFile());
+        Assertions.assertEquals("cluster", config.getCluster());
+        Assertions.assertEquals("configFile", config.getConfigFile());
+        Assertions.assertEquals("group", config.getGroup());
+        Assertions.assertEquals("namespace", config.getNamespace());
+        Assertions.assertEquals("password", config.getPassword());
+        Assertions.assertEquals("usernama", config.getUsername());
+        Assertions.assertTrue(config.getParameters().containsKey("default.num"));
+        Assertions.assertEquals("one", config.getParameters().get("default.num"));
+        Assertions.assertEquals("id", config.getId());
+        Assertions.assertEquals("prefix", config.getPrefix());
+
+        Assertions.assertNotSame(config, config2);
+    }
+}
\ No newline at end of file
diff --git a/dubbo-test/src/test/java/org/apache/dubbo/config/bootstrap/builders/ConsumerBuilderTest.java b/dubbo-test/src/test/java/org/apache/dubbo/config/bootstrap/builders/ConsumerBuilderTest.java
new file mode 100644
index 0000000..bb7e131
--- /dev/null
+++ b/dubbo-test/src/test/java/org/apache/dubbo/config/bootstrap/builders/ConsumerBuilderTest.java
@@ -0,0 +1,95 @@
+/*
+ * 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.bootstrap.builders;
+
+import org.apache.dubbo.config.ConsumerConfig;
+
+import org.junit.jupiter.api.Assertions;
+import org.junit.jupiter.api.Test;
+
+class ConsumerBuilderTest {
+
+    @Test
+    void isDefault() {
+        ConsumerBuilder builder = new ConsumerBuilder();
+        builder.isDefault(false);
+        Assertions.assertFalse(builder.build().isDefault());
+    }
+
+    @Test
+    void client() {
+        ConsumerBuilder builder = new ConsumerBuilder();
+        builder.client("client");
+        Assertions.assertEquals("client", builder.build().getClient());
+    }
+
+    @Test
+    void threadPool() {
+        ConsumerBuilder builder = new ConsumerBuilder();
+        builder.threadPool("threadPool");
+        Assertions.assertEquals("threadPool", builder.build().getThreadpool());
+    }
+
+    @Test
+    void coreThreads() {
+        ConsumerBuilder builder = new ConsumerBuilder();
+        builder.coreThreads(10);
+        Assertions.assertEquals(10, builder.build().getCorethreads());
+    }
+
+    @Test
+    void threads() {
+        ConsumerBuilder builder = new ConsumerBuilder();
+        builder.threads(100);
+        Assertions.assertEquals(100, builder.build().getThreads());
+    }
+
+    @Test
+    void queues() {
+        ConsumerBuilder builder = new ConsumerBuilder();
+        builder.queues(200);
+        Assertions.assertEquals(200, builder.build().getQueues());
+    }
+
+    @Test
+    void shareConnections() {
+        ConsumerBuilder builder = new ConsumerBuilder();
+        builder.shareConnections(300);
+        Assertions.assertEquals(300, builder.build().getShareconnections());
+    }
+
+    @Test
+    void build() {
+        ConsumerBuilder builder = new ConsumerBuilder();
+        builder.isDefault(true).client("client").threadPool("threadPool").coreThreads(10).threads(100).queues(200)
+                .shareConnections(300).id("id").prefix("prefix");
+
+        ConsumerConfig config = builder.build();
+        ConsumerConfig config2 = builder.build();
+
+        Assertions.assertTrue(config.isDefault());
+        Assertions.assertEquals("client", config.getClient());
+        Assertions.assertEquals("threadPool", config.getThreadpool());
+        Assertions.assertEquals("id", config.getId());
+        Assertions.assertEquals("prefix", config.getPrefix());
+        Assertions.assertEquals(10, config.getCorethreads());
+        Assertions.assertEquals(100, config.getThreads());
+        Assertions.assertEquals(200, config.getQueues());
+        Assertions.assertEquals(300, config.getShareconnections());
+        Assertions.assertNotSame(config, config2);
+    }
+}
\ No newline at end of file
diff --git a/dubbo-test/src/test/java/org/apache/dubbo/config/bootstrap/builders/MetadataReportBuilderTest.java b/dubbo-test/src/test/java/org/apache/dubbo/config/bootstrap/builders/MetadataReportBuilderTest.java
new file mode 100644
index 0000000..5d60dd8
--- /dev/null
+++ b/dubbo-test/src/test/java/org/apache/dubbo/config/bootstrap/builders/MetadataReportBuilderTest.java
@@ -0,0 +1,151 @@
+/*
+ * 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.bootstrap.builders;
+
+import org.apache.dubbo.config.MetadataReportConfig;
+
+import org.junit.jupiter.api.Assertions;
+import org.junit.jupiter.api.Test;
+
+import java.util.HashMap;
+import java.util.Map;
+
+class MetadataReportBuilderTest {
+
+    @Test
+    void address() {
+        MetadataReportBuilder builder = new MetadataReportBuilder();
+        builder.address("address");
+        Assertions.assertEquals("address", builder.build().getAddress());
+    }
+
+    @Test
+    void username() {
+        MetadataReportBuilder builder = new MetadataReportBuilder();
+        builder.username("username");
+        Assertions.assertEquals("username", builder.build().getUsername());
+    }
+
+    @Test
+    void password() {
+        MetadataReportBuilder builder = new MetadataReportBuilder();
+        builder.password("password");
+        Assertions.assertEquals("password", builder.build().getPassword());
+    }
+
+    @Test
+    void timeout() {
+        MetadataReportBuilder builder = new MetadataReportBuilder();
+        builder.timeout(1000);
+        Assertions.assertEquals(1000, builder.build().getTimeout());
+    }
+
+    @Test
+    void group() {
+        MetadataReportBuilder builder = new MetadataReportBuilder();
+        builder.group("group");
+        Assertions.assertEquals("group", builder.build().getGroup());
+    }
+
+    @Test
+    void appendParameter() {
+        MetadataReportBuilder builder = new MetadataReportBuilder();
+        builder.appendParameter("default.num", "one").appendParameter("num", "ONE");
+
+        Map<String, String> parameters = builder.build().getParameters();
+
+        Assertions.assertTrue(parameters.containsKey("default.num"));
+        Assertions.assertEquals("ONE", parameters.get("num"));
+    }
+
+    @Test
+    void appendParameters() {
+        Map<String, String> source = new HashMap<>();
+        source.put("default.num", "one");
+        source.put("num", "ONE");
+
+        MetadataReportBuilder builder = new MetadataReportBuilder();
+        builder.appendParameters(source);
+
+        Map<String, String> parameters = builder.build().getParameters();
+
+        Assertions.assertTrue(parameters.containsKey("default.num"));
+        Assertions.assertEquals("ONE", parameters.get("num"));
+    }
+
+    @Test
+    void retryTimes() {
+        MetadataReportBuilder builder = new MetadataReportBuilder();
+        builder.retryTimes(1);
+        Assertions.assertEquals(1, builder.build().getRetryTimes());
+    }
+
+    @Test
+    void retryPeriod() {
+        MetadataReportBuilder builder = new MetadataReportBuilder();
+        builder.retryPeriod(2);
+        Assertions.assertEquals(2, builder.build().getRetryPeriod());
+    }
+
+    @Test
+    void cycleReport() {
+        MetadataReportBuilder builder = new MetadataReportBuilder();
+        builder.cycleReport(true);
+        Assertions.assertTrue(builder.build().getCycleReport());
+        builder.cycleReport(false);
+        Assertions.assertFalse(builder.build().getCycleReport());
+        builder.cycleReport(null);
+        Assertions.assertNull(builder.build().getCycleReport());
+    }
+
+    @Test
+    void syncReport() {
+        MetadataReportBuilder builder = new MetadataReportBuilder();
+        builder.syncReport(true);
+        Assertions.assertTrue(builder.build().getSyncReport());
+        builder.syncReport(false);
+        Assertions.assertFalse(builder.build().getSyncReport());
+        builder.syncReport(null);
+        Assertions.assertNull(builder.build().getSyncReport());
+    }
+
+    @Test
+    void build() {
+        MetadataReportBuilder builder = new MetadataReportBuilder();
+        builder.address("address").username("username").password("password").timeout(1000).group("group")
+                .retryTimes(1).retryPeriod(2).cycleReport(true).syncReport(false)
+                .appendParameter("default.num", "one").id("id").prefix("prefix");
+
+        MetadataReportConfig config = builder.build();
+        MetadataReportConfig config2 = builder.build();
+
+        Assertions.assertTrue(config.getCycleReport());
+        Assertions.assertFalse(config.getSyncReport());
+        Assertions.assertEquals(1000, config.getTimeout());
+        Assertions.assertEquals(1, config.getRetryTimes());
+        Assertions.assertEquals(2, config.getRetryPeriod());
+        Assertions.assertEquals("address", config.getAddress());
+        Assertions.assertEquals("username", config.getUsername());
+        Assertions.assertEquals("password", config.getPassword());
+        Assertions.assertEquals("group", config.getGroup());
+        Assertions.assertTrue(config.getParameters().containsKey("default.num"));
+        Assertions.assertEquals("one", config.getParameters().get("default.num"));
+        Assertions.assertEquals("id", config.getId());
+        Assertions.assertEquals("prefix", config.getPrefix());
+        Assertions.assertNotSame(config, config2);
+    }
+}
\ No newline at end of file
diff --git a/dubbo-test/src/test/java/org/apache/dubbo/config/bootstrap/builders/MethodBuilderTest.java b/dubbo-test/src/test/java/org/apache/dubbo/config/bootstrap/builders/MethodBuilderTest.java
new file mode 100644
index 0000000..9196c48
--- /dev/null
+++ b/dubbo-test/src/test/java/org/apache/dubbo/config/bootstrap/builders/MethodBuilderTest.java
@@ -0,0 +1,189 @@
+/*
+ * 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.bootstrap.builders;
+
+import org.apache.dubbo.config.ArgumentConfig;
+import org.apache.dubbo.config.MethodConfig;
+
+import org.junit.jupiter.api.Assertions;
+import org.junit.jupiter.api.Test;
+
+import java.util.Collections;
+
+class MethodBuilderTest {
+
+    @Test
+    void name() {
+        MethodBuilder builder = new MethodBuilder();
+        builder.name("name");
+        Assertions.assertEquals("name", builder.build().getName());
+    }
+
+    @Test
+    void stat() {
+        MethodBuilder builder = new MethodBuilder();
+        builder.stat(1);
+        Assertions.assertEquals(1, builder.build().getStat());
+    }
+
+    @Test
+    void retry() {
+        MethodBuilder builder = new MethodBuilder();
+        builder.retry(true);
+        Assertions.assertTrue(builder.build().isRetry());
+    }
+
+    @Test
+    void reliable() {
+        MethodBuilder builder = new MethodBuilder();
+        builder.reliable(true);
+        Assertions.assertTrue(builder.build().isReliable());
+    }
+
+    @Test
+    void executes() {
+        MethodBuilder builder = new MethodBuilder();
+        builder.executes(1);
+        Assertions.assertEquals(1, builder.build().getExecutes());
+    }
+
+    @Test
+    void deprecated() {
+        MethodBuilder builder = new MethodBuilder();
+        builder.deprecated(true);
+        Assertions.assertTrue(builder.build().getDeprecated());
+    }
+
+    @Test
+    void sticky() {
+        MethodBuilder builder = new MethodBuilder();
+        builder.sticky(true);
+        Assertions.assertTrue(builder.build().getSticky());
+    }
+
+    @Test
+    void isReturn() {
+        MethodBuilder builder = new MethodBuilder();
+        builder.isReturn(true);
+        Assertions.assertTrue(builder.build().isReturn());
+    }
+
+    @Test
+    void oninvoke() {
+        MethodBuilder builder = new MethodBuilder();
+        builder.oninvoke("on-invoke-object");
+        Assertions.assertEquals("on-invoke-object", builder.build().getOninvoke());
+    }
+
+    @Test
+    void oninvokeMethod() {
+        MethodBuilder builder = new MethodBuilder();
+        builder.oninvokeMethod("on-invoke-method");
+        Assertions.assertEquals("on-invoke-method", builder.build().getOninvokeMethod());
+    }
+
+    @Test
+    void onreturn() {
+        MethodBuilder builder = new MethodBuilder();
+        builder.onreturn("on-return-object");
+        Assertions.assertEquals("on-return-object", builder.build().getOnreturn());
+    }
+
+    @Test
+    void onreturnMethod() {
+        MethodBuilder builder = new MethodBuilder();
+        builder.onreturnMethod("on-return-method");
+        Assertions.assertEquals("on-return-method", builder.build().getOnreturnMethod());
+    }
+
+    @Test
+    void onthrow() {
+        MethodBuilder builder = new MethodBuilder();
+        builder.onthrow("on-throw-object");
+        Assertions.assertEquals("on-throw-object", builder.build().getOnthrow());
+    }
+
+    @Test
+    void onthrowMethod() {
+        MethodBuilder builder = new MethodBuilder();
+        builder.onthrowMethod("on-throw-method");
+        Assertions.assertEquals("on-throw-method", builder.build().getOnthrowMethod());
+    }
+
+    @Test
+    void addArguments() {
+        ArgumentConfig argument = new ArgumentConfig();
+        MethodBuilder builder = new MethodBuilder();
+        builder.addArguments(Collections.singletonList(argument));
+        Assertions.assertTrue(builder.build().getArguments().contains(argument));
+        Assertions.assertEquals(1, builder.build().getArguments().size());
+    }
+
+    @Test
+    void addArgument() {
+        ArgumentConfig argument = new ArgumentConfig();
+        MethodBuilder builder = new MethodBuilder();
+        builder.addArgument(argument);
+        Assertions.assertTrue(builder.build().getArguments().contains(argument));
+        Assertions.assertEquals(1, builder.build().getArguments().size());
+    }
+
+    @Test
+    void service() {
+        MethodBuilder builder = new MethodBuilder();
+        builder.service("service");
+        Assertions.assertEquals("service", builder.build().getService());
+    }
+
+    @Test
+    void serviceId() {
+        MethodBuilder builder = new MethodBuilder();
+        builder.serviceId("serviceId");
+        Assertions.assertEquals("serviceId", builder.build().getServiceId());
+    }
+
+    @Test
+    void build() {
+        ArgumentConfig argument = new ArgumentConfig();
+        MethodBuilder builder = new MethodBuilder();
+        builder.name("name").stat(1).retry(true).reliable(false).executes(2).deprecated(true).sticky(false)
+                .isReturn(true).oninvoke("on-invoke-object").oninvokeMethod("on-invoke-method").service("service")
+                .onreturn("on-return-object").onreturnMethod("on-return-method").serviceId("serviceId")
+                .onthrow("on-throw-object").onthrowMethod("on-throw-method").addArgument(argument);
+
+        MethodConfig config = builder.build();
+        MethodConfig config2 = builder.build();
+
+        Assertions.assertTrue(config.isRetry());
+        Assertions.assertFalse(config.isReliable());
+        Assertions.assertTrue(config.getDeprecated());
+        Assertions.assertFalse(config.getSticky());
+        Assertions.assertTrue(config.isReturn());
+        Assertions.assertEquals(1, config.getStat());
+        Assertions.assertEquals(2, config.getExecutes());
+        Assertions.assertEquals("on-invoke-object", config.getOninvoke());
+        Assertions.assertEquals("on-invoke-method", config.getOninvokeMethod());
+        Assertions.assertEquals("on-return-object", config.getOnreturn());
+        Assertions.assertEquals("on-return-method", config.getOnreturnMethod());
+        Assertions.assertEquals("on-throw-object", config.getOnthrow());
+        Assertions.assertEquals("on-throw-method", config.getOnthrowMethod());
+        Assertions.assertEquals("name", config.getName());
+        Assertions.assertEquals("service", config.getService());
+        Assertions.assertEquals("serviceId", config.getServiceId());
+        Assertions.assertNotSame(config, config2);
+    }
+}
\ No newline at end of file
diff --git a/dubbo-test/src/test/java/org/apache/dubbo/config/bootstrap/builders/ModuleBuilderTest.java b/dubbo-test/src/test/java/org/apache/dubbo/config/bootstrap/builders/ModuleBuilderTest.java
new file mode 100644
index 0000000..bbf7d2e
--- /dev/null
+++ b/dubbo-test/src/test/java/org/apache/dubbo/config/bootstrap/builders/ModuleBuilderTest.java
@@ -0,0 +1,112 @@
+/*
+ * 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.bootstrap.builders;
+
+import org.apache.dubbo.config.ModuleConfig;
+import org.apache.dubbo.config.MonitorConfig;
+import org.apache.dubbo.config.RegistryConfig;
+
+import org.junit.jupiter.api.Assertions;
+import org.junit.jupiter.api.Test;
+
+import java.util.Collections;
+
+class ModuleBuilderTest {
+
+    @Test
+    void name() {
+        ModuleBuilder builder = new ModuleBuilder();
+        builder.name("name");
+        Assertions.assertEquals("name", builder.build().getName());
+    }
+
+    @Test
+    void version() {
+        ModuleBuilder builder = new ModuleBuilder();
+        builder.version("version");
+        Assertions.assertEquals("version", builder.build().getVersion());
+    }
+
+    @Test
+    void owner() {
+        ModuleBuilder builder = new ModuleBuilder();
+        builder.owner("owner");
+        Assertions.assertEquals("owner", builder.build().getOwner());
+    }
+
+    @Test
+    void organization() {
+        ModuleBuilder builder = new ModuleBuilder();
+        builder.organization("organization");
+        Assertions.assertEquals("organization", builder.build().getOrganization());
+    }
+
+    @Test
+    void addRegistries() {
+        RegistryConfig registry = new RegistryConfig();
+        ModuleBuilder builder = new ModuleBuilder();
+        builder.addRegistries(Collections.singletonList(registry));
+        Assertions.assertTrue(builder.build().getRegistries().contains(registry));
+        Assertions.assertEquals(1, builder.build().getRegistries().size());
+    }
+
+    @Test
+    void addRegistry() {
+        RegistryConfig registry = new RegistryConfig();
+        ModuleBuilder builder = new ModuleBuilder();
+        builder.addRegistry(registry);
+        Assertions.assertTrue(builder.build().getRegistries().contains(registry));
+        Assertions.assertEquals(1, builder.build().getRegistries().size());
+    }
+
+    @Test
+    void monitor() {
+        MonitorConfig monitor = new MonitorConfig();
+        ModuleBuilder builder = new ModuleBuilder();
+        builder.monitor(monitor);
+        Assertions.assertSame(monitor, builder.build().getMonitor());
+    }
+
+    @Test
+    void isDefault() {
+        ModuleBuilder builder = new ModuleBuilder();
+        builder.isDefault(true);
+        Assertions.assertTrue(builder.build().isDefault());
+    }
+
+    @Test
+    void build() {
+        RegistryConfig registry = new RegistryConfig();
+        MonitorConfig monitor = new MonitorConfig();
+
+        ModuleBuilder builder = new ModuleBuilder();
+        builder.name("name").version("version").owner("owner").organization("organization").addRegistry(registry)
+                .monitor(monitor).isDefault(false);
+
+        ModuleConfig config = builder.build();
+        ModuleConfig config2 = builder.build();
+
+        Assertions.assertEquals("name", config.getName());
+        Assertions.assertEquals("version", config.getVersion());
+        Assertions.assertEquals("owner", config.getOwner());
+        Assertions.assertEquals("organization", config.getOrganization());
+        Assertions.assertTrue(builder.build().getRegistries().contains(registry));
+        Assertions.assertSame(monitor, builder.build().getMonitor());
+        Assertions.assertFalse(config.isDefault());
+        Assertions.assertNotSame(config, config2);
+    }
+}
\ No newline at end of file
diff --git a/dubbo-test/src/test/java/org/apache/dubbo/config/bootstrap/builders/MonitorBuilderTest.java b/dubbo-test/src/test/java/org/apache/dubbo/config/bootstrap/builders/MonitorBuilderTest.java
new file mode 100644
index 0000000..ca4005f
--- /dev/null
+++ b/dubbo-test/src/test/java/org/apache/dubbo/config/bootstrap/builders/MonitorBuilderTest.java
@@ -0,0 +1,135 @@
+/*
+ * 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.bootstrap.builders;
+
+import org.apache.dubbo.config.MonitorConfig;
+
+import org.junit.jupiter.api.Assertions;
+import org.junit.jupiter.api.Test;
+
+import java.util.HashMap;
+import java.util.Map;
+
+class MonitorBuilderTest {
+
+    @Test
+    void protocol() {
+        MonitorBuilder builder = new MonitorBuilder();
+        builder.protocol("protocol");
+        Assertions.assertEquals("protocol", builder.build().getProtocol());
+    }
+
+    @Test
+    void address() {
+        MonitorBuilder builder = new MonitorBuilder();
+        builder.address("address");
+        Assertions.assertEquals("address", builder.build().getAddress());
+    }
+
+    @Test
+    void username() {
+        MonitorBuilder builder = new MonitorBuilder();
+        builder.username("username");
+        Assertions.assertEquals("username", builder.build().getUsername());
+    }
+
+    @Test
+    void password() {
+        MonitorBuilder builder = new MonitorBuilder();
+        builder.password("password");
+        Assertions.assertEquals("password", builder.build().getPassword());
+    }
+
+    @Test
+    void group() {
+        MonitorBuilder builder = new MonitorBuilder();
+        builder.group("group");
+        Assertions.assertEquals("group", builder.build().getGroup());
+    }
+
+    @Test
+    void version() {
+        MonitorBuilder builder = new MonitorBuilder();
+        builder.version("version");
+        Assertions.assertEquals("version", builder.build().getVersion());
+    }
+
+    @Test
+    void interval() {
+        MonitorBuilder builder = new MonitorBuilder();
+        builder.interval("interval");
+        Assertions.assertEquals("interval", builder.build().getInterval());
+    }
+
+    @Test
+    void isDefault() {
+        MonitorBuilder builder = new MonitorBuilder();
+        builder.isDefault(true);
+        Assertions.assertTrue(builder.build().isDefault());
+    }
+
+    @Test
+    void appendParameter() {
+        MonitorBuilder builder = new MonitorBuilder();
+        builder.appendParameter("default.num", "one").appendParameter("num", "ONE");
+
+        Map<String, String> parameters = builder.build().getParameters();
+
+        Assertions.assertTrue(parameters.containsKey("default.num"));
+        Assertions.assertEquals("ONE", parameters.get("num"));
+    }
+
+    @Test
+    void appendParameters() {
+        Map<String, String> source = new HashMap<>();
+        source.put("default.num", "one");
+        source.put("num", "ONE");
+
+        MonitorBuilder builder = new MonitorBuilder();
+        builder.appendParameters(source);
+
+        Map<String, String> parameters = builder.build().getParameters();
+
+        Assertions.assertTrue(parameters.containsKey("default.num"));
+        Assertions.assertEquals("ONE", parameters.get("num"));
+    }
+
+    @Test
+    void build() {
+        MonitorBuilder builder = new MonitorBuilder();
+        builder.protocol("protocol").address("address").group("group").interval("interval").isDefault(true)
+                .password("password").username("username").version("version")
+                .appendParameter("default.num", "one").id("id").prefix("prefix");
+
+        MonitorConfig config = builder.build();
+        MonitorConfig config2 = builder.build();
+
+        Assertions.assertEquals("protocol", config.getProtocol());
+        Assertions.assertEquals("address", config.getAddress());
+        Assertions.assertEquals("group", config.getGroup());
+        Assertions.assertEquals("interval", config.getInterval());
+        Assertions.assertEquals("password", config.getPassword());
+        Assertions.assertEquals("username", config.getUsername());
+        Assertions.assertEquals("version", config.getVersion());
+        Assertions.assertTrue(config.isDefault());
+        Assertions.assertTrue(config.getParameters().containsKey("default.num"));
+        Assertions.assertEquals("one", config.getParameters().get("default.num"));
+        Assertions.assertEquals("id", config.getId());
+        Assertions.assertEquals("prefix", config.getPrefix());
+        Assertions.assertNotSame(config, config2);
+    }
+}
\ No newline at end of file
diff --git a/dubbo-test/src/test/java/org/apache/dubbo/config/bootstrap/builders/ProtocolBuilderTest.java b/dubbo-test/src/test/java/org/apache/dubbo/config/bootstrap/builders/ProtocolBuilderTest.java
new file mode 100644
index 0000000..8a0711e
--- /dev/null
+++ b/dubbo-test/src/test/java/org/apache/dubbo/config/bootstrap/builders/ProtocolBuilderTest.java
@@ -0,0 +1,338 @@
+/*
+ * 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.bootstrap.builders;
+
+import org.apache.dubbo.config.ProtocolConfig;
+
+import org.junit.jupiter.api.Assertions;
+import org.junit.jupiter.api.Test;
+
+import java.util.HashMap;
+import java.util.Map;
+
+class ProtocolBuilderTest {
+
+    @Test
+    void name() {
+        ProtocolBuilder builder = new ProtocolBuilder();
+        builder.name("name");
+        Assertions.assertEquals("name", builder.build().getName());
+    }
+
+    @Test
+    void host() {
+        ProtocolBuilder builder = new ProtocolBuilder();
+        builder.host("host");
+        Assertions.assertEquals("host", builder.build().getHost());
+    }
+
+    @Test
+    void port() {
+        ProtocolBuilder builder = new ProtocolBuilder();
+        builder.port(8080);
+        Assertions.assertEquals(8080, builder.build().getPort());
+    }
+
+    @Test
+    void contextpath() {
+        ProtocolBuilder builder = new ProtocolBuilder();
+        builder.contextpath("contextpath");
+        Assertions.assertEquals("contextpath", builder.build().getContextpath());
+    }
+
+    @Test
+    void path() {
+        ProtocolBuilder builder = new ProtocolBuilder();
+        builder.path("path");
+        Assertions.assertEquals("path", builder.build().getPath());
+    }
+
+    @Test
+    void threadpool() {
+        ProtocolBuilder builder = new ProtocolBuilder();
+        builder.threadpool("mockthreadpool");
+        Assertions.assertEquals("mockthreadpool", builder.build().getThreadpool());
+    }
+
+    @Test
+    void corethreads() {
+        ProtocolBuilder builder = new ProtocolBuilder();
+        builder.corethreads(10);
+        Assertions.assertEquals(10, builder.build().getCorethreads());
+    }
+
+    @Test
+    void threads() {
+        ProtocolBuilder builder = new ProtocolBuilder();
+        builder.threads(20);
+        Assertions.assertEquals(20, builder.build().getThreads());
+    }
+
+    @Test
+    void iothreads() {
+        ProtocolBuilder builder = new ProtocolBuilder();
+        builder.iothreads(25);
+        Assertions.assertEquals(25, builder.build().getIothreads());
+    }
+
+    @Test
+    void queues() {
+        ProtocolBuilder builder = new ProtocolBuilder();
+        builder.queues(30);
+        Assertions.assertEquals(30, builder.build().getQueues());
+    }
+
+    @Test
+    void accepts() {
+        ProtocolBuilder builder = new ProtocolBuilder();
+        builder.accepts(35);
+        Assertions.assertEquals(35, builder.build().getAccepts());
+    }
+
+    @Test
+    void codec() {
+        ProtocolBuilder builder = new ProtocolBuilder();
+        builder.codec("mockcodec");
+        Assertions.assertEquals("mockcodec", builder.build().getCodec());
+    }
+
+    @Test
+    void serialization() {
+        ProtocolBuilder builder = new ProtocolBuilder();
+        builder.serialization("serialization");
+        Assertions.assertEquals("serialization", builder.build().getSerialization());
+    }
+
+    @Test
+    void charset() {
+        ProtocolBuilder builder = new ProtocolBuilder();
+        builder.charset("utf-8");
+        Assertions.assertEquals("utf-8", builder.build().getCharset());
+    }
+
+    @Test
+    void payload() {
+        ProtocolBuilder builder = new ProtocolBuilder();
+        builder.payload(40);
+        Assertions.assertEquals(40, builder.build().getPayload());
+    }
+
+    @Test
+    void buffer() {
+        ProtocolBuilder builder = new ProtocolBuilder();
+        builder.buffer(1024);
+        Assertions.assertEquals(1024, builder.build().getBuffer());
+    }
+
+    @Test
+    void heartbeat() {
+        ProtocolBuilder builder = new ProtocolBuilder();
+        builder.heartbeat(1000);
+        Assertions.assertEquals(1000, builder.build().getHeartbeat());
+    }
+
+    @Test
+    void accesslog() {
+        ProtocolBuilder builder = new ProtocolBuilder();
+        builder.accesslog("accesslog");
+        Assertions.assertEquals("accesslog", builder.build().getAccesslog());
+    }
+
+    @Test
+    void transporter() {
+        ProtocolBuilder builder = new ProtocolBuilder();
+        builder.transporter("mocktransporter");
+        Assertions.assertEquals("mocktransporter", builder.build().getTransporter());
+    }
+
+    @Test
+    void exchanger() {
+        ProtocolBuilder builder = new ProtocolBuilder();
+        builder.exchanger("mockexchanger");
+        Assertions.assertEquals("mockexchanger", builder.build().getExchanger());
+    }
+
+    @Test
+    void dispatcher() {
+        ProtocolBuilder builder = new ProtocolBuilder();
+        builder.dispatcher("mockdispatcher");
+        Assertions.assertEquals("mockdispatcher", builder.build().getDispatcher());
+    }
+
+    @Test
+    void dispather() {
+        ProtocolBuilder builder = new ProtocolBuilder();
+        builder.dispather("mockdispatcher");
+        Assertions.assertEquals("mockdispatcher", builder.build().getDispather());
+    }
+
+    @Test
+    void networker() {
+        ProtocolBuilder builder = new ProtocolBuilder();
+        builder.networker("networker");
+        Assertions.assertEquals("networker", builder.build().getNetworker());
+    }
+
+    @Test
+    void server() {
+        ProtocolBuilder builder = new ProtocolBuilder();
+        builder.server("server");
+        Assertions.assertEquals("server", builder.build().getServer());
+    }
+
+    @Test
+    void client() {
+        ProtocolBuilder builder = new ProtocolBuilder();
+        builder.client("client");
+        Assertions.assertEquals("client", builder.build().getClient());
+    }
+
+    @Test
+    void telnet() {
+        ProtocolBuilder builder = new ProtocolBuilder();
+        builder.telnet("mocktelnethandler");
+        Assertions.assertEquals("mocktelnethandler", builder.build().getTelnet());
+    }
+
+    @Test
+    void prompt() {
+        ProtocolBuilder builder = new ProtocolBuilder();
+        builder.prompt("prompt");
+        Assertions.assertEquals("prompt", builder.build().getPrompt());
+    }
+
+    @Test
+    void status() {
+        ProtocolBuilder builder = new ProtocolBuilder();
+        builder.status("mockstatuschecker");
+        Assertions.assertEquals("mockstatuschecker", builder.build().getStatus());
+    }
+
+    @Test
+    void register() {
+        ProtocolBuilder builder = new ProtocolBuilder();
+        builder.register(true);
+        Assertions.assertTrue(builder.build().isRegister());
+    }
+
+    @Test
+    void keepAlive() {
+        ProtocolBuilder builder = new ProtocolBuilder();
+        builder.keepAlive(true);
+        Assertions.assertTrue(builder.build().getKeepAlive());
+    }
+
+    @Test
+    void optimizer() {
+        ProtocolBuilder builder = new ProtocolBuilder();
+        builder.optimizer("optimizer");
+        Assertions.assertEquals("optimizer", builder.build().getOptimizer());
+    }
+
+    @Test
+    void extension() {
+        ProtocolBuilder builder = new ProtocolBuilder();
+        builder.extension("extension");
+        Assertions.assertEquals("extension", builder.build().getExtension());
+    }
+
+    @Test
+    void appendParameter() {
+        ProtocolBuilder builder = new ProtocolBuilder();
+        builder.appendParameter("default.num", "one").appendParameter("num", "ONE");
+
+        Map<String, String> parameters = builder.build().getParameters();
+
+        Assertions.assertTrue(parameters.containsKey("default.num"));
+        Assertions.assertEquals("ONE", parameters.get("num"));
+    }
+
+    @Test
+    void appendParameters() {
+        Map<String, String> source = new HashMap<>();
+        source.put("default.num", "one");
+        source.put("num", "ONE");
+
+        ProtocolBuilder builder = new ProtocolBuilder();
+        builder.appendParameters(source);
+
+        Map<String, String> parameters = builder.build().getParameters();
+
+        Assertions.assertTrue(parameters.containsKey("default.num"));
+        Assertions.assertEquals("ONE", parameters.get("num"));
+    }
+
+    @Test
+    void isDefault() {
+        ProtocolBuilder builder = new ProtocolBuilder();
+        builder.isDefault(true);
+        Assertions.assertTrue(builder.build().isDefault());
+    }
+
+    @Test
+    void build() {
+        ProtocolBuilder builder = new ProtocolBuilder();
+        builder.name("name").host("host").port(8080).contextpath("contextpath").threadpool("mockthreadpool")
+                .corethreads(1).threads(2).iothreads(3).queues(4).accepts(5).codec("mockcodec")
+                .serialization("serialization").charset("utf-8").payload(6).buffer(1024).heartbeat(1000)
+                .accesslog("accesslog").transporter("mocktransporter").exchanger("mockexchanger")
+                .dispatcher("mockdispatcher").networker("networker").server("server").client("client")
+                .telnet("mocktelnethandler").prompt("prompt").status("mockstatuschecker").register(true).keepAlive(false)
+                .optimizer("optimizer").extension("extension").isDefault(true)
+                .appendParameter("default.num", "one").id("id").prefix("prefix");
+
+        ProtocolConfig config = builder.build();
+        ProtocolConfig config2 = builder.build();
+
+        Assertions.assertEquals(8080, config.getPort());
+        Assertions.assertEquals(1, config.getCorethreads());
+        Assertions.assertEquals(2, config.getThreads());
+        Assertions.assertEquals(3, config.getIothreads());
+        Assertions.assertEquals(4, config.getQueues());
+        Assertions.assertEquals(5, config.getAccepts());
+        Assertions.assertEquals(6, config.getPayload());
+        Assertions.assertEquals(1024, config.getBuffer());
+        Assertions.assertEquals(1000, config.getHeartbeat());
+        Assertions.assertEquals("name", config.getName());
+        Assertions.assertEquals("host", config.getHost());
+        Assertions.assertEquals("contextpath", config.getContextpath());
+        Assertions.assertEquals("mockthreadpool", config.getThreadpool());
+        Assertions.assertEquals("mockcodec", config.getCodec());
+        Assertions.assertEquals("serialization", config.getSerialization());
+        Assertions.assertEquals("utf-8", config.getCharset());
+        Assertions.assertEquals("accesslog", config.getAccesslog());
+        Assertions.assertEquals("mocktransporter", config.getTransporter());
+        Assertions.assertEquals("mockexchanger", config.getExchanger());
+        Assertions.assertEquals("mockdispatcher", config.getDispatcher());
+        Assertions.assertEquals("networker", config.getNetworker());
+        Assertions.assertEquals("server", config.getServer());
+        Assertions.assertEquals("client", config.getClient());
+        Assertions.assertEquals("mocktelnethandler", config.getTelnet());
+        Assertions.assertEquals("prompt", config.getPrompt());
+        Assertions.assertEquals("mockstatuschecker", config.getStatus());
+        Assertions.assertEquals("optimizer", config.getOptimizer());
+        Assertions.assertEquals("extension", config.getExtension());
+        Assertions.assertTrue(config.isRegister());
+        Assertions.assertFalse(config.getKeepAlive());
+        Assertions.assertTrue(config.isDefault());
+        Assertions.assertTrue(config.getParameters().containsKey("default.num"));
+        Assertions.assertEquals("one", config.getParameters().get("default.num"));
+        Assertions.assertEquals("id", config.getId());
+        Assertions.assertEquals("prefix", config.getPrefix());
+        Assertions.assertNotSame(config, config2);
+    }
+}
\ No newline at end of file
diff --git a/dubbo-test/src/test/java/org/apache/dubbo/config/bootstrap/builders/ProviderBuilderTest.java b/dubbo-test/src/test/java/org/apache/dubbo/config/bootstrap/builders/ProviderBuilderTest.java
new file mode 100644
index 0000000..5f10b6c
--- /dev/null
+++ b/dubbo-test/src/test/java/org/apache/dubbo/config/bootstrap/builders/ProviderBuilderTest.java
@@ -0,0 +1,227 @@
+/*
+ * 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.bootstrap.builders;
+
+import org.apache.dubbo.config.ProviderConfig;
+
+import org.junit.jupiter.api.Assertions;
+import org.junit.jupiter.api.Test;
+
+class ProviderBuilderTest {
+
+    @Test
+    void setHost() {
+        ProviderBuilder builder = new ProviderBuilder();
+        builder.host("host");
+        Assertions.assertEquals("host", builder.build().getHost());
+    }
+
+    @Test
+    void port() {
+        ProviderBuilder builder = new ProviderBuilder();
+        builder.port(8080);
+        Assertions.assertEquals(8080, builder.build().getPort());
+    }
+
+    @Test
+    void contextPath() {
+        ProviderBuilder builder = new ProviderBuilder();
+        builder.contextPath("contextpath");
+        Assertions.assertEquals("contextpath", builder.build().getContextpath());
+    }
+
+    @Test
+    void threadPool() {
+        ProviderBuilder builder = new ProviderBuilder();
+        builder.threadPool("mockthreadpool");
+        Assertions.assertEquals("mockthreadpool", builder.build().getThreadpool());
+    }
+
+    @Test
+    void threads() {
+        ProviderBuilder builder = new ProviderBuilder();
+        builder.threads(20);
+        Assertions.assertEquals(20, builder.build().getThreads());
+    }
+
+    @Test
+    void ioThreads() {
+        ProviderBuilder builder = new ProviderBuilder();
+        builder.ioThreads(25);
+        Assertions.assertEquals(25, builder.build().getIothreads());
+    }
+
+    @Test
+    void queues() {
+        ProviderBuilder builder = new ProviderBuilder();
+        builder.queues(30);
+        Assertions.assertEquals(30, builder.build().getQueues());
+    }
+
+    @Test
+    void accepts() {
+        ProviderBuilder builder = new ProviderBuilder();
+        builder.accepts(35);
+        Assertions.assertEquals(35, builder.build().getAccepts());
+    }
+
+    @Test
+    void codec() {
+        ProviderBuilder builder = new ProviderBuilder();
+        builder.codec("mockcodec");
+        Assertions.assertEquals("mockcodec", builder.build().getCodec());
+    }
+
+    @Test
+    void charset() {
+        ProviderBuilder builder = new ProviderBuilder();
+        builder.charset("utf-8");
+        Assertions.assertEquals("utf-8", builder.build().getCharset());
+    }
+
+    @Test
+    void payload() {
+        ProviderBuilder builder = new ProviderBuilder();
+        builder.payload(40);
+        Assertions.assertEquals(40, builder.build().getPayload());
+    }
+
+    @Test
+    void buffer() {
+        ProviderBuilder builder = new ProviderBuilder();
+        builder.buffer(1024);
+        Assertions.assertEquals(1024, builder.build().getBuffer());
+    }
+
+    @Test
+    void transporter() {
+        ProviderBuilder builder = new ProviderBuilder();
+        builder.transporter("mocktransporter");
+        Assertions.assertEquals("mocktransporter", builder.build().getTransporter());
+    }
+
+    @Test
+    void exchanger() {
+        ProviderBuilder builder = new ProviderBuilder();
+        builder.exchanger("mockexchanger");
+        Assertions.assertEquals("mockexchanger", builder.build().getExchanger());
+    }
+
+    @Test
+    void dispatcher() {
+        ProviderBuilder builder = new ProviderBuilder();
+        builder.dispatcher("mockdispatcher");
+        Assertions.assertEquals("mockdispatcher", builder.build().getDispatcher());
+    }
+
+    @Test
+    void networker() {
+        ProviderBuilder builder = new ProviderBuilder();
+        builder.networker("networker");
+        Assertions.assertEquals("networker", builder.build().getNetworker());
+    }
+
+    @Test
+    void server() {
+        ProviderBuilder builder = new ProviderBuilder();
+        builder.server("server");
+        Assertions.assertEquals("server", builder.build().getServer());
+    }
+
+    @Test
+    void client() {
+        ProviderBuilder builder = new ProviderBuilder();
+        builder.client("client");
+        Assertions.assertEquals("client", builder.build().getClient());
+    }
+
+    @Test
+    void telnet() {
+        ProviderBuilder builder = new ProviderBuilder();
+        builder.telnet("mocktelnethandler");
+        Assertions.assertEquals("mocktelnethandler", builder.build().getTelnet());
+    }
+
+    @Test
+    void prompt() {
+        ProviderBuilder builder = new ProviderBuilder();
+        builder.prompt("prompt");
+        Assertions.assertEquals("prompt", builder.build().getPrompt());
+    }
+
+    @Test
+    void status() {
+        ProviderBuilder builder = new ProviderBuilder();
+        builder.status("mockstatuschecker");
+        Assertions.assertEquals("mockstatuschecker", builder.build().getStatus());
+    }
+
+    @Test
+    void Wait() {
+        ProviderBuilder builder = new ProviderBuilder();
+        builder.wait(Integer.valueOf(1000));
+        Assertions.assertEquals(1000, builder.build().getWait());
+    }
+
+    @Test
+    void isDefault() {
+        ProviderBuilder builder = new ProviderBuilder();
+        builder.isDefault(true);
+        Assertions.assertTrue(builder.build().isDefault());
+    }
+
+    @Test
+    void build() {
+        ProviderBuilder builder = new ProviderBuilder();
+        builder.host("host").port(8080).contextPath("contextpath").threadPool("mockthreadpool")
+                .threads(2).ioThreads(3).queues(4).accepts(5).codec("mockcodec")
+                .charset("utf-8").payload(6).buffer(1024).transporter("mocktransporter").exchanger("mockexchanger")
+                .dispatcher("mockdispatcher").networker("networker").server("server").client("client")
+                .telnet("mocktelnethandler").prompt("prompt").status("mockstatuschecker").wait(Integer.valueOf(1000))
+                .isDefault(true).id("id").prefix("prefix");
+
+        ProviderConfig config = builder.build();
+        ProviderConfig config2 = builder.build();
+
+        Assertions.assertEquals(8080, config.getPort());
+        Assertions.assertEquals(2, config.getThreads());
+        Assertions.assertEquals(3, config.getIothreads());
+        Assertions.assertEquals(4, config.getQueues());
+        Assertions.assertEquals(5, config.getAccepts());
+        Assertions.assertEquals(6, config.getPayload());
+        Assertions.assertEquals(1024, config.getBuffer());
+        Assertions.assertEquals(1000, config.getWait());
+        Assertions.assertEquals("host", config.getHost());
+        Assertions.assertEquals("contextpath", config.getContextpath());
+        Assertions.assertEquals("mockthreadpool", config.getThreadpool());
+        Assertions.assertEquals("mockcodec", config.getCodec());
+        Assertions.assertEquals("utf-8", config.getCharset());
+        Assertions.assertEquals("mocktransporter", config.getTransporter());
+        Assertions.assertEquals("mockexchanger", config.getExchanger());
+        Assertions.assertEquals("mockdispatcher", config.getDispatcher());
+        Assertions.assertEquals("networker", config.getNetworker());
+        Assertions.assertEquals("server", config.getServer());
+        Assertions.assertEquals("client", config.getClient());
+        Assertions.assertEquals("mocktelnethandler", config.getTelnet());
+        Assertions.assertEquals("prompt", config.getPrompt());
+        Assertions.assertEquals("mockstatuschecker", config.getStatus());
+        Assertions.assertTrue(config.isDefault());
+        Assertions.assertEquals("id", config.getId());
+        Assertions.assertEquals("prefix", config.getPrefix());
+        Assertions.assertNotSame(config, config2);
+    }
+}
\ No newline at end of file
diff --git a/dubbo-test/src/test/java/org/apache/dubbo/config/bootstrap/builders/ReferenceBuilderTest.java b/dubbo-test/src/test/java/org/apache/dubbo/config/bootstrap/builders/ReferenceBuilderTest.java
new file mode 100644
index 0000000..4d11ef4
--- /dev/null
+++ b/dubbo-test/src/test/java/org/apache/dubbo/config/bootstrap/builders/ReferenceBuilderTest.java
@@ -0,0 +1,125 @@
+/*
+ * 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.bootstrap.builders;
+
+import org.apache.dubbo.config.ConsumerConfig;
+import org.apache.dubbo.config.MethodConfig;
+import org.apache.dubbo.config.ReferenceConfig;
+import org.apache.dubbo.config.api.DemoService;
+
+import org.junit.jupiter.api.Assertions;
+import org.junit.jupiter.api.Test;
+
+import java.util.Collections;
+
+import static org.apache.dubbo.common.utils.CollectionUtils.ofSet;
+
+class ReferenceBuilderTest {
+
+    @Test
+    void interfaceName() {
+        ReferenceBuilder builder = new ReferenceBuilder();
+        builder.interfaceName(DemoService.class.getName());
+        Assertions.assertEquals("org.apache.dubbo.config.api.DemoService", builder.build().getInterface());
+    }
+
+    @Test
+    void interfaceClass() {
+        ReferenceBuilder builder = new ReferenceBuilder();
+        builder.interfaceClass(DemoService.class);
+        Assertions.assertEquals(DemoService.class, builder.build().getInterfaceClass());
+    }
+
+    @Test
+    void client() {
+        ReferenceBuilder builder = new ReferenceBuilder();
+        builder.client("client");
+        Assertions.assertEquals("client", builder.build().getClient());
+    }
+
+    @Test
+    void url() {
+        ReferenceBuilder builder = new ReferenceBuilder();
+        builder.url("url");
+        Assertions.assertEquals("url", builder.build().getUrl());
+    }
+
+    @Test
+    void addMethods() {
+        MethodConfig method = new MethodConfig();
+        ReferenceBuilder builder = new ReferenceBuilder();
+        builder.addMethods(Collections.singletonList(method));
+        Assertions.assertTrue(builder.build().getMethods().contains(method));
+        Assertions.assertEquals(1, builder.build().getMethods().size());
+    }
+
+    @Test
+    void addMethod() {
+        MethodConfig method = new MethodConfig();
+        ReferenceBuilder builder = new ReferenceBuilder();
+        builder.addMethod(method);
+        Assertions.assertTrue(builder.build().getMethods().contains(method));
+        Assertions.assertEquals(1, builder.build().getMethods().size());
+    }
+
+    @Test
+    void consumer() {
+        ConsumerConfig consumer = new ConsumerConfig();
+        ReferenceBuilder builder = new ReferenceBuilder();
+        builder.consumer(consumer);
+        Assertions.assertSame(consumer, builder.build().getConsumer());
+    }
+
+    @Test
+    void protocol() {
+        ReferenceBuilder builder = new ReferenceBuilder();
+        builder.protocol("protocol");
+        Assertions.assertEquals("protocol", builder.build().getProtocol());
+    }
+
+    @Test
+    void build() {
+        ConsumerConfig consumer = new ConsumerConfig();
+        MethodConfig method = new MethodConfig();
+
+        ReferenceBuilder<DemoService> builder = new ReferenceBuilder<>();
+        builder.id("id")
+                .interfaceClass(DemoService.class)
+                .protocol("protocol")
+                .client("client")
+                .url("url")
+                .consumer(consumer)
+                .addMethod(method)
+                // introduced since 2.7.8
+                .services("test-service", "test-service2");
+
+        ReferenceConfig config = builder.build();
+        ReferenceConfig config2 = builder.build();
+
+        Assertions.assertEquals("org.apache.dubbo.config.api.DemoService", config.getInterface());
+        Assertions.assertEquals(DemoService.class, config.getInterfaceClass());
+        Assertions.assertEquals("protocol", config.getProtocol());
+        Assertions.assertEquals("client", config.getClient());
+        Assertions.assertEquals("url", config.getUrl());
+        Assertions.assertEquals(consumer, config.getConsumer());
+        Assertions.assertEquals("test-service,test-service2", config.getServices());
+        Assertions.assertEquals(ofSet("test-service", "test-service2"), config.getSubscribedServices());
+        Assertions.assertTrue(config.getMethods().contains(method));
+        Assertions.assertEquals(1, config.getMethods().size());
+        Assertions.assertNotSame(config, config2);
+    }
+}
\ No newline at end of file
diff --git a/dubbo-test/src/test/java/org/apache/dubbo/config/bootstrap/builders/RegistryBuilderTest.java b/dubbo-test/src/test/java/org/apache/dubbo/config/bootstrap/builders/RegistryBuilderTest.java
new file mode 100644
index 0000000..b125547
--- /dev/null
+++ b/dubbo-test/src/test/java/org/apache/dubbo/config/bootstrap/builders/RegistryBuilderTest.java
@@ -0,0 +1,256 @@
+/*
+ * 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.bootstrap.builders;
+
+import org.apache.dubbo.config.RegistryConfig;
+
+import org.junit.jupiter.api.Assertions;
+import org.junit.jupiter.api.Test;
+
+import java.util.HashMap;
+import java.util.Map;
+
+class RegistryBuilderTest {
+
+    @Test
+    void address() {
+        RegistryBuilder builder = new RegistryBuilder();
+        builder.address("address");
+        Assertions.assertEquals("address", builder.build().getAddress());
+    }
+
+    @Test
+    void username() {
+        RegistryBuilder builder = new RegistryBuilder();
+        builder.username("username");
+        Assertions.assertEquals("username", builder.build().getUsername());
+    }
+
+    @Test
+    void password() {
+        RegistryBuilder builder = new RegistryBuilder();
+        builder.password("password");
+        Assertions.assertEquals("password", builder.build().getPassword());
+    }
+
+    @Test
+    void port() {
+        RegistryBuilder builder = new RegistryBuilder();
+        builder.port(8080);
+        Assertions.assertEquals(8080, builder.build().getPort());
+    }
+
+    @Test
+    void protocol() {
+        RegistryBuilder builder = new RegistryBuilder();
+        builder.protocol("protocol");
+        Assertions.assertEquals("protocol", builder.build().getProtocol());
+    }
+
+    @Test
+    void transporter() {
+        RegistryBuilder builder = new RegistryBuilder();
+        builder.transporter("transporter");
+        Assertions.assertEquals("transporter", builder.build().getTransporter());
+    }
+
+    @Test
+    void transport() {
+        RegistryBuilder builder = new RegistryBuilder();
+        builder.transport("transport");
+        Assertions.assertEquals("transport", builder.build().getTransport());
+    }
+
+    @Test
+    void server() {
+        RegistryBuilder builder = new RegistryBuilder();
+        builder.server("server");
+        Assertions.assertEquals("server", builder.build().getServer());
+    }
+
+    @Test
+    void client() {
+        RegistryBuilder builder = new RegistryBuilder();
+        builder.client("client");
+        Assertions.assertEquals("client", builder.build().getClient());
+    }
+
+    @Test
+    void cluster() {
+        RegistryBuilder builder = new RegistryBuilder();
+        builder.cluster("cluster");
+        Assertions.assertEquals("cluster", builder.build().getCluster());
+    }
+
+    @Test
+    void group() {
+        RegistryBuilder builder = new RegistryBuilder();
+        builder.group("group");
+        Assertions.assertEquals("group", builder.build().getGroup());
+    }
+
+    @Test
+    void version() {
+        RegistryBuilder builder = new RegistryBuilder();
+        builder.version("version");
+        Assertions.assertEquals("version", builder.build().getVersion());
+    }
+
+    @Test
+    void timeout() {
+        RegistryBuilder builder = new RegistryBuilder();
+        builder.timeout(1000);
+        Assertions.assertEquals(1000, builder.build().getTimeout());
+    }
+
+    @Test
+    void session() {
+        RegistryBuilder builder = new RegistryBuilder();
+        builder.session(2000);
+        Assertions.assertEquals(2000, builder.build().getSession());
+    }
+
+    @Test
+    void file() {
+        RegistryBuilder builder = new RegistryBuilder();
+        builder.file("file");
+        Assertions.assertEquals("file", builder.build().getFile());
+    }
+
+    @Test
+    void testWait() {
+        RegistryBuilder builder = new RegistryBuilder();
+        builder.wait(Integer.valueOf(1000));
+        Assertions.assertEquals(1000, builder.build().getWait());
+    }
+
+    @Test
+    void isCheck() {
+        RegistryBuilder builder = new RegistryBuilder();
+        builder.isCheck(true);
+        Assertions.assertTrue(builder.build().isCheck());
+    }
+
+    @Test
+    void isDynamic() {
+        RegistryBuilder builder = new RegistryBuilder();
+        builder.isDynamic(true);
+        Assertions.assertTrue(builder.build().isDynamic());
+    }
+
+    @Test
+    void register() {
+        RegistryBuilder builder = new RegistryBuilder();
+        builder.register(true);
+        Assertions.assertTrue(builder.build().isRegister());
+    }
+
+    @Test
+    void subscribe() {
+        RegistryBuilder builder = new RegistryBuilder();
+        builder.subscribe(true);
+        Assertions.assertTrue(builder.build().isSubscribe());
+    }
+
+    @Test
+    void appendParameter() {
+        RegistryBuilder builder = new RegistryBuilder();
+        builder.appendParameter("default.num", "one").appendParameter("num", "ONE");
+
+        Map<String, String> parameters = builder.build().getParameters();
+
+        Assertions.assertTrue(parameters.containsKey("default.num"));
+        Assertions.assertEquals("ONE", parameters.get("num"));
+    }
+
+    @Test
+    void appendParameters() {
+        Map<String, String> source = new HashMap<>();
+        source.put("default.num", "one");
+        source.put("num", "ONE");
+
+        RegistryBuilder builder = new RegistryBuilder();
+        builder.appendParameters(source);
+
+        Map<String, String> parameters = builder.build().getParameters();
+
+        Assertions.assertTrue(parameters.containsKey("default.num"));
+        Assertions.assertEquals("ONE", parameters.get("num"));
+    }
+
+    @Test
+    void isDefault() {
+        RegistryBuilder builder = new RegistryBuilder();
+        builder.isDefault(true);
+        Assertions.assertTrue(builder.build().isDefault());
+    }
+
+    @Test
+    void simplified() {
+        RegistryBuilder builder = new RegistryBuilder();
+        builder.simplified(true);
+        Assertions.assertTrue(builder.build().getSimplified());
+    }
+
+    @Test
+    void extraKeys() {
+        RegistryBuilder builder = new RegistryBuilder();
+        builder.extraKeys("extraKeys");
+        Assertions.assertEquals("extraKeys", builder.build().getExtraKeys());
+    }
+
+    @Test
+    void build() {
+        RegistryBuilder builder = new RegistryBuilder();
+        builder.address("address").username("username").password("password").port(8080).protocol("protocol")
+                .transporter("transporter").server("server").client("client").cluster("cluster").group("group")
+                .version("version").timeout(1000).session(2000).file("file").wait(Integer.valueOf(10)).isCheck(true)
+                .isDynamic(false).register(true).subscribe(false).isDefault(true).simplified(false).extraKeys("A")
+                .parameter("default.num", "one").id("id").prefix("prefix");
+
+        RegistryConfig config = builder.build();
+        RegistryConfig config2 = builder.build();
+
+        Assertions.assertEquals(8080, config.getPort());
+        Assertions.assertEquals(1000, config.getTimeout());
+        Assertions.assertEquals(2000, config.getSession());
+        Assertions.assertEquals(10, config.getWait());
+        Assertions.assertTrue(config.isCheck());
+        Assertions.assertFalse(config.isDynamic());
+        Assertions.assertTrue(config.isRegister());
+        Assertions.assertFalse(config.isSubscribe());
+        Assertions.assertTrue(config.isDefault());
+        Assertions.assertFalse(config.getSimplified());
+        Assertions.assertEquals("address", config.getAddress());
+        Assertions.assertEquals("username", config.getUsername());
+        Assertions.assertEquals("password", config.getPassword());
+        Assertions.assertEquals("protocol", config.getProtocol());
+        Assertions.assertEquals("transporter", config.getTransporter());
+        Assertions.assertEquals("server", config.getServer());
+        Assertions.assertEquals("client", config.getClient());
+        Assertions.assertEquals("cluster", config.getCluster());
+        Assertions.assertEquals("group", config.getGroup());
+        Assertions.assertEquals("version", config.getVersion());
+        Assertions.assertEquals("file", config.getFile());
+        Assertions.assertEquals("A", config.getExtraKeys());
+        Assertions.assertTrue(config.getParameters().containsKey("default.num"));
+        Assertions.assertEquals("one", config.getParameters().get("default.num"));
+        Assertions.assertEquals("id", config.getId());
+        Assertions.assertEquals("prefix", config.getPrefix());
+        Assertions.assertNotSame(config, config2);
+    }
+}
\ No newline at end of file
diff --git a/dubbo-test/src/test/java/org/apache/dubbo/config/bootstrap/builders/ServiceBuilderTest.java b/dubbo-test/src/test/java/org/apache/dubbo/config/bootstrap/builders/ServiceBuilderTest.java
new file mode 100644
index 0000000..ae07c24
--- /dev/null
+++ b/dubbo-test/src/test/java/org/apache/dubbo/config/bootstrap/builders/ServiceBuilderTest.java
@@ -0,0 +1,131 @@
+/*
+ * 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.bootstrap.builders;
+
+import org.apache.dubbo.config.MethodConfig;
+import org.apache.dubbo.config.ProviderConfig;
+import org.apache.dubbo.config.ServiceConfig;
+
+import org.junit.jupiter.api.Assertions;
+import org.junit.jupiter.api.Test;
+
+import java.util.Collections;
+
+import static org.apache.dubbo.common.constants.CommonConstants.GENERIC_SERIALIZATION_BEAN;
+import static org.apache.dubbo.common.constants.CommonConstants.GENERIC_SERIALIZATION_DEFAULT;
+import static org.apache.dubbo.common.constants.CommonConstants.GENERIC_SERIALIZATION_NATIVE_JAVA;
+import static org.hamcrest.CoreMatchers.equalTo;
+import static org.hamcrest.MatcherAssert.assertThat;
+
+class ServiceBuilderTest {
+
+    @Test
+    void path() {
+        ServiceBuilder builder = new ServiceBuilder();
+        builder.path("path");
+        Assertions.assertEquals("path", builder.build().getPath());
+    }
+
+    @Test
+    void addMethod() {
+        MethodConfig method = new MethodConfig();
+        ServiceBuilder builder = new ServiceBuilder();
+        builder.addMethod(method);
+        Assertions.assertTrue(builder.build().getMethods().contains(method));
+        Assertions.assertEquals(1, builder.build().getMethods().size());
+    }
+
+    @Test
+    void addMethods() {
+        MethodConfig method = new MethodConfig();
+        ServiceBuilder builder = new ServiceBuilder();
+        builder.addMethods(Collections.singletonList(method));
+        Assertions.assertTrue(builder.build().getMethods().contains(method));
+        Assertions.assertEquals(1, builder.build().getMethods().size());
+    }
+
+    @Test
+    void provider() {
+        ProviderConfig provider = new ProviderConfig();
+        ServiceBuilder builder = new ServiceBuilder();
+        builder.provider(provider);
+        Assertions.assertSame(provider, builder.build().getProvider());
+    }
+
+    @Test
+    void providerIds() {
+        ServiceBuilder builder = new ServiceBuilder();
+        builder.providerIds("providerIds");
+        Assertions.assertEquals("providerIds", builder.build().getProviderIds());
+    }
+
+    @Test
+    public void generic() throws Exception {
+        ServiceBuilder builder = new ServiceBuilder();
+        builder.generic(GENERIC_SERIALIZATION_DEFAULT);
+        assertThat(builder.build().getGeneric(), equalTo(GENERIC_SERIALIZATION_DEFAULT));
+        builder.generic(GENERIC_SERIALIZATION_NATIVE_JAVA);
+        assertThat(builder.build().getGeneric(), equalTo(GENERIC_SERIALIZATION_NATIVE_JAVA));
+        builder.generic(GENERIC_SERIALIZATION_BEAN);
+        assertThat(builder.build().getGeneric(), equalTo(GENERIC_SERIALIZATION_BEAN));
+    }
+
+    @Test
+    public void generic1() throws Exception {
+        Assertions.assertThrows(IllegalArgumentException.class, () -> {
+            ServiceBuilder builder = new ServiceBuilder();
+            builder.generic("illegal").build();
+        });
+    }
+//
+//    @Test
+//    public void Mock() throws Exception {
+//        Assertions.assertThrows(IllegalArgumentException.class, () -> {
+//            ServiceBuilder builder = new ServiceBuilder();
+//            builder.mock("true");
+//        });
+//    }
+//
+//    @Test
+//    public void Mock1() throws Exception {
+//        Assertions.assertThrows(IllegalArgumentException.class, () -> {
+//            ServiceBuilder builder = new ServiceBuilder();
+//            builder.mock(true);
+//        });
+//    }
+
+    @Test
+    void build() {
+        MethodConfig method = new MethodConfig();
+        ProviderConfig provider = new ProviderConfig();
+
+        ServiceBuilder builder = new ServiceBuilder();
+        builder.path("path").addMethod(method).provider(provider).providerIds("providerIds")
+                .generic(GENERIC_SERIALIZATION_DEFAULT);
+
+        ServiceConfig config = builder.build();
+        ServiceConfig config2 = builder.build();
+
+        assertThat(config.getGeneric(), equalTo(GENERIC_SERIALIZATION_DEFAULT));
+        Assertions.assertEquals("path", config.getPath());
+        Assertions.assertEquals("providerIds", config.getProviderIds());
+        Assertions.assertSame(provider, config.getProvider());
+        Assertions.assertTrue(config.getMethods().contains(method));
+        Assertions.assertEquals(1, config.getMethods().size());
+        Assertions.assertNotSame(config, config2);
+    }
+}
\ No newline at end of file
diff --git a/dubbo-test/src/test/java/org/apache/dubbo/config/bootstrap/compatible/DubboInterfaceConsumerBootstrap.java b/dubbo-test/src/test/java/org/apache/dubbo/config/bootstrap/compatible/DubboInterfaceConsumerBootstrap.java
new file mode 100644
index 0000000..738a881
--- /dev/null
+++ b/dubbo-test/src/test/java/org/apache/dubbo/config/bootstrap/compatible/DubboInterfaceConsumerBootstrap.java
@@ -0,0 +1,57 @@
+/*
+ * 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.bootstrap.compatible;
+
+import org.apache.dubbo.config.RegistryConfig;
+import org.apache.dubbo.config.bootstrap.DubboBootstrap;
+import org.apache.dubbo.config.bootstrap.EchoService;
+import org.apache.dubbo.config.bootstrap.rest.UserService;
+
+/**
+ * Dubbo Provider Bootstrap
+ *
+ * @since 2.7.5
+ */
+public class DubboInterfaceConsumerBootstrap {
+
+    public static void main(String[] args) throws Exception {
+        RegistryConfig interfaceRegistry = new RegistryConfig();
+        interfaceRegistry.setId("interfaceRegistry");
+        interfaceRegistry.setAddress("zookeeper://127.0.0.1:2181");
+
+        DubboBootstrap bootstrap = DubboBootstrap.getInstance()
+                .application("dubbo-consumer-demo")
+                // Zookeeper
+                .registry(interfaceRegistry)
+                // Nacos
+//                .registry("consul", builder -> builder.address("consul://127.0.0.1:8500?registry.type=service&subscribed.services=dubbo-provider-demo"))
+                .reference("echo", builder -> builder.interfaceClass(EchoService.class).protocol("dubbo"))
+                .reference("user", builder -> builder.interfaceClass(UserService.class).protocol("rest"))
+                .start()
+                .await();
+
+        EchoService echoService = bootstrap.getCache().get(EchoService.class);
+        UserService userService = bootstrap.getCache().get(UserService.class);
+
+        for (int i = 0; i < 500; i++) {
+            Thread.sleep(2000L);
+            System.out.println(echoService.echo("Hello,World"));
+            System.out.println(userService.getUser(1L));
+        }
+
+    }
+}
diff --git a/dubbo-test/src/test/java/org/apache/dubbo/config/bootstrap/rest/User.java b/dubbo-test/src/test/java/org/apache/dubbo/config/bootstrap/rest/User.java
new file mode 100644
index 0000000..cfd52e2
--- /dev/null
+++ b/dubbo-test/src/test/java/org/apache/dubbo/config/bootstrap/rest/User.java
@@ -0,0 +1,77 @@
+/*
+ *
+ *   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.bootstrap.rest;
+
+import org.codehaus.jackson.annotate.JsonProperty;
+
+import javax.validation.constraints.Min;
+import javax.validation.constraints.NotNull;
+import javax.validation.constraints.Size;
+import javax.xml.bind.annotation.XmlAccessType;
+import javax.xml.bind.annotation.XmlAccessorType;
+import javax.xml.bind.annotation.XmlElement;
+import javax.xml.bind.annotation.XmlRootElement;
+import java.io.Serializable;
+
+@XmlRootElement
+@XmlAccessorType(XmlAccessType.FIELD)
+public class User implements Serializable {
+
+    @NotNull
+    @Min(1L)
+    private Long id;
+
+    @JsonProperty("username")
+    @XmlElement(name = "username")
+    @NotNull
+    @Size(min = 6, max = 50)
+    private String name;
+
+    public User() {
+    }
+
+    public User(Long id, String name) {
+        this.id = id;
+        this.name = name;
+    }
+
+    public Long getId() {
+        return id;
+    }
+
+    public void setId(Long id) {
+        this.id = id;
+    }
+
+    public String getName() {
+        return name;
+    }
+
+    public void setName(String name) {
+        this.name = name;
+    }
+
+    @Override
+    public String toString() {
+        return "User (" +
+                "id=" + id +
+                ", name='" + name + '\'' +
+                ')';
+    }
+}
diff --git a/dubbo-test/src/test/java/org/apache/dubbo/config/bootstrap/rest/UserService.java b/dubbo-test/src/test/java/org/apache/dubbo/config/bootstrap/rest/UserService.java
new file mode 100644
index 0000000..fa5b7ae
--- /dev/null
+++ b/dubbo-test/src/test/java/org/apache/dubbo/config/bootstrap/rest/UserService.java
@@ -0,0 +1,45 @@
+/*
+ *
+ *   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.bootstrap.rest;
+
+
+import org.apache.dubbo.rpc.protocol.rest.support.ContentType;
+
+import io.swagger.annotations.Api;
+import io.swagger.annotations.ApiOperation;
+import io.swagger.annotations.ApiParam;
+
+import javax.ws.rs.Consumes;
+import javax.ws.rs.GET;
+import javax.ws.rs.Path;
+import javax.ws.rs.PathParam;
+import javax.ws.rs.Produces;
+import javax.ws.rs.core.MediaType;
+
+@Path("users")
+@Consumes({MediaType.APPLICATION_JSON, MediaType.TEXT_XML})
+@Produces({ContentType.APPLICATION_JSON_UTF_8, ContentType.TEXT_XML_UTF_8})
+@Api(value = "UserService")
+public interface UserService {
+
+    @GET
+    @Path("{id : \\d+}")
+    @ApiOperation(value = "getUser")
+    User getUser(@ApiParam(value = "id") @PathParam("id") Long id);
+}
diff --git a/dubbo-test/src/test/java/org/apache/dubbo/config/bootstrap/rest/UserServiceImpl.java b/dubbo-test/src/test/java/org/apache/dubbo/config/bootstrap/rest/UserServiceImpl.java
new file mode 100644
index 0000000..8cb0bd0
--- /dev/null
+++ b/dubbo-test/src/test/java/org/apache/dubbo/config/bootstrap/rest/UserServiceImpl.java
@@ -0,0 +1,32 @@
+/*
+ *
+ *   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.bootstrap.rest;
+
+import java.util.concurrent.atomic.AtomicLong;
+
+public class UserServiceImpl implements UserService {
+
+    private final AtomicLong idGen = new AtomicLong();
+
+    @Override
+    public User getUser(Long id) {
+        return new User(id, "username" + id);
+    }
+
+}
diff --git a/dubbo-test/src/test/java/org/apache/dubbo/config/cache/CacheService.java b/dubbo-test/src/test/java/org/apache/dubbo/config/cache/CacheService.java
new file mode 100644
index 0000000..7696b24
--- /dev/null
+++ b/dubbo-test/src/test/java/org/apache/dubbo/config/cache/CacheService.java
@@ -0,0 +1,26 @@
+/*
+ * 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.cache;
+
+/**
+ * ValidationService
+ */
+public interface CacheService {
+
+    String findCache(String id);
+
+}
diff --git a/dubbo-test/src/test/java/org/apache/dubbo/config/cache/CacheServiceImpl.java b/dubbo-test/src/test/java/org/apache/dubbo/config/cache/CacheServiceImpl.java
new file mode 100644
index 0000000..14e9ee7
--- /dev/null
+++ b/dubbo-test/src/test/java/org/apache/dubbo/config/cache/CacheServiceImpl.java
@@ -0,0 +1,32 @@
+/*
+ * 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.cache;
+
+import java.util.concurrent.atomic.AtomicInteger;
+
+/**
+ * ValidationServiceImpl
+ */
+public class CacheServiceImpl implements CacheService {
+
+    private final AtomicInteger i = new AtomicInteger();
+
+    public String findCache(String id) {
+        return "request: " + id + ", response: " + i.getAndIncrement();
+    }
+
+}
diff --git a/dubbo-test/src/test/java/org/apache/dubbo/config/cache/CacheTest.java b/dubbo-test/src/test/java/org/apache/dubbo/config/cache/CacheTest.java
new file mode 100644
index 0000000..ed7cb5e
--- /dev/null
+++ b/dubbo-test/src/test/java/org/apache/dubbo/config/cache/CacheTest.java
@@ -0,0 +1,140 @@
+/*
+ * 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.cache;
+
+import org.apache.dubbo.cache.Cache;
+import org.apache.dubbo.cache.CacheFactory;
+import org.apache.dubbo.cache.support.threadlocal.ThreadLocalCache;
+import org.apache.dubbo.common.URL;
+import org.apache.dubbo.common.extension.ExtensionLoader;
+import org.apache.dubbo.config.ApplicationConfig;
+import org.apache.dubbo.config.MethodConfig;
+import org.apache.dubbo.config.ProtocolConfig;
+import org.apache.dubbo.config.ReferenceConfig;
+import org.apache.dubbo.config.RegistryConfig;
+import org.apache.dubbo.config.ServiceConfig;
+import org.apache.dubbo.rpc.Invocation;
+import org.apache.dubbo.rpc.RpcInvocation;
+
+import org.junit.jupiter.api.AfterEach;
+import org.junit.jupiter.api.BeforeEach;
+import org.junit.jupiter.api.Test;
+
+import java.util.Arrays;
+import java.util.HashMap;
+import java.util.Map;
+
+import static org.junit.jupiter.api.Assertions.assertFalse;
+import static org.junit.jupiter.api.Assertions.assertTrue;
+
+/**
+ * CacheTest
+ */
+public class CacheTest {
+
+    @BeforeEach
+    public void setUp() {
+//        ApplicationModel.getConfigManager().clear();
+    }
+
+    @AfterEach
+    public void tearDown() {
+//        ApplicationModel.getConfigManager().clear();
+    }
+
+    private void testCache(String type) throws Exception {
+        ApplicationConfig applicationConfig = new ApplicationConfig("cache-test");
+        RegistryConfig registryConfig = new RegistryConfig("N/A");
+        ProtocolConfig protocolConfig = new ProtocolConfig("injvm");
+        ServiceConfig<CacheService> service = new ServiceConfig<CacheService>();
+        service.setApplication(applicationConfig);
+        service.setRegistry(registryConfig);
+        service.setProtocol(protocolConfig);
+        service.setInterface(CacheService.class.getName());
+        service.setRef(new CacheServiceImpl());
+        service.export();
+        try {
+            ReferenceConfig<CacheService> reference = new ReferenceConfig<CacheService>();
+            reference.setApplication(applicationConfig);
+            reference.setInterface(CacheService.class);
+            reference.setUrl("injvm://127.0.0.1?scope=remote&cache=true");
+
+            MethodConfig method = new MethodConfig();
+            method.setName("findCache");
+            method.setCache(type);
+            reference.setMethods(Arrays.asList(method));
+
+            CacheService cacheService = reference.get();
+            try {
+                // verify cache, same result is returned for multiple invocations (in fact, the return value increases
+                // on every invocation on the server side)
+                String fix = null;
+                for (int i = 0; i < 3; i++) {
+                    String result = cacheService.findCache("0");
+                    assertTrue(fix == null || fix.equals(result));
+                    fix = result;
+                    Thread.sleep(100);
+                }
+
+                if ("lru".equals(type)) {
+                    // default cache.size is 1000 for LRU, should have cache expired if invoke more than 1001 times
+                    for (int n = 0; n < 1001; n++) {
+                        String pre = null;
+                        for (int i = 0; i < 10; i++) {
+                            String result = cacheService.findCache(String.valueOf(n));
+                            assertTrue(pre == null || pre.equals(result));
+                            pre = result;
+                        }
+                    }
+
+                    // verify if the first cache item is expired in LRU cache
+                    String result = cacheService.findCache("0");
+                    assertFalse(fix == null || fix.equals(result));
+                }
+            } finally {
+                reference.destroy();
+            }
+        } finally {
+            service.unexport();
+        }
+    }
+
+    @Test
+    public void testCacheLru() throws Exception {
+        testCache("lru");
+    }
+
+    @Test
+    public void testCacheThreadlocal() throws Exception {
+        testCache("threadlocal");
+    }
+
+    @Test
+    public void testCacheProvider() throws Exception {
+        CacheFactory cacheFactory = ExtensionLoader.getExtensionLoader(CacheFactory.class).getAdaptiveExtension();
+
+        Map<String, String> parameters = new HashMap<String, String>();
+        parameters.put("findCache.cache", "threadlocal");
+        URL url = new URL("dubbo", "127.0.0.1", 29582, "org.apache.dubbo.config.cache.CacheService", parameters);
+
+        Invocation invocation = new RpcInvocation("findCache", CacheService.class.getName(), "", new Class[]{String.class}, new String[]{"0"}, null, null, null);
+
+        Cache cache = cacheFactory.getCache(url, invocation);
+        assertTrue(cache instanceof ThreadLocalCache);
+    }
+
+}
diff --git a/dubbo-test/src/test/java/org/apache/dubbo/config/consumer/DemoActionByAnnotation.java b/dubbo-test/src/test/java/org/apache/dubbo/config/consumer/DemoActionByAnnotation.java
new file mode 100644
index 0000000..23d00e4
--- /dev/null
+++ b/dubbo-test/src/test/java/org/apache/dubbo/config/consumer/DemoActionByAnnotation.java
@@ -0,0 +1,35 @@
+/*
+ * 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.consumer;
+
+import org.apache.dubbo.config.api.DemoService;
+
+import org.springframework.beans.factory.annotation.Autowired;
+
+/**
+ * DemoAction
+ */
+public class DemoActionByAnnotation {
+
+    @Autowired
+    private DemoService demoService;
+
+    public DemoService getDemoService() {
+        return demoService;
+    }
+
+}
\ No newline at end of file
diff --git a/dubbo-test/src/test/java/org/apache/dubbo/config/consumer/DemoActionBySetter.java b/dubbo-test/src/test/java/org/apache/dubbo/config/consumer/DemoActionBySetter.java
new file mode 100644
index 0000000..0606e26
--- /dev/null
+++ b/dubbo-test/src/test/java/org/apache/dubbo/config/consumer/DemoActionBySetter.java
@@ -0,0 +1,36 @@
+/*
+ * 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.consumer;
+
+import org.apache.dubbo.config.api.DemoService;
+
+/**
+ * DemoAction
+ */
+public class DemoActionBySetter {
+
+    private DemoService demoService;
+
+    public DemoService getDemoService() {
+        return demoService;
+    }
+
+    public void setDemoService(DemoService demoService) {
+        this.demoService = demoService;
+    }
+
+}
\ No newline at end of file
diff --git a/dubbo-test/src/test/java/org/apache/dubbo/config/consumer/DemoInterceptor.java b/dubbo-test/src/test/java/org/apache/dubbo/config/consumer/DemoInterceptor.java
new file mode 100644
index 0000000..46d7e9a
--- /dev/null
+++ b/dubbo-test/src/test/java/org/apache/dubbo/config/consumer/DemoInterceptor.java
@@ -0,0 +1,31 @@
+/*
+ * 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.consumer;
+
+import org.aopalliance.intercept.MethodInterceptor;
+import org.aopalliance.intercept.MethodInvocation;
+
+/**
+ * DemoInterceptor
+ */
+public class DemoInterceptor implements MethodInterceptor {
+
+    public Object invoke(MethodInvocation invocation) throws Throwable {
+        return "aop:" + invocation.proceed();
+    }
+
+}
\ No newline at end of file
diff --git a/dubbo-test/src/test/java/org/apache/dubbo/config/event/listener/PublishingServiceDefinitionListenerTest.java b/dubbo-test/src/test/java/org/apache/dubbo/config/event/listener/PublishingServiceDefinitionListenerTest.java
new file mode 100644
index 0000000..e7e5376
--- /dev/null
+++ b/dubbo-test/src/test/java/org/apache/dubbo/config/event/listener/PublishingServiceDefinitionListenerTest.java
@@ -0,0 +1,94 @@
+/*
+ * 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.event.listener;
+
+import org.apache.dubbo.common.URL;
+import org.apache.dubbo.config.ApplicationConfig;
+import org.apache.dubbo.config.RegistryConfig;
+import org.apache.dubbo.config.ServiceConfig;
+import org.apache.dubbo.config.bootstrap.EchoService;
+import org.apache.dubbo.config.bootstrap.EchoServiceImpl;
+import org.apache.dubbo.config.context.ConfigManager;
+import org.apache.dubbo.config.event.ServiceConfigExportedEvent;
+import org.apache.dubbo.metadata.WritableMetadataService;
+import org.apache.dubbo.metadata.definition.model.FullServiceDefinition;
+import org.apache.dubbo.rpc.model.ApplicationModel;
+
+import com.google.gson.Gson;
+import org.junit.jupiter.api.AfterEach;
+import org.junit.jupiter.api.BeforeEach;
+import org.junit.jupiter.api.Test;
+
+import java.util.List;
+
+import static org.apache.dubbo.common.constants.CommonConstants.DEFAULT_METADATA_STORAGE_TYPE;
+import static org.apache.dubbo.common.constants.CommonConstants.PID_KEY;
+import static org.apache.dubbo.common.constants.CommonConstants.TIMESTAMP_KEY;
+import static org.apache.dubbo.metadata.definition.ServiceDefinitionBuilder.buildFullDefinition;
+import static org.apache.dubbo.remoting.Constants.BIND_IP_KEY;
+import static org.apache.dubbo.remoting.Constants.BIND_PORT_KEY;
+import static org.junit.jupiter.api.Assertions.assertEquals;
+
+/**
+ * {@link PublishingServiceDefinitionListener} Test-Cases
+ *
+ * @since 2.7.8
+ */
+public class PublishingServiceDefinitionListenerTest {
+
+    private WritableMetadataService writableMetadataService;
+
+    @BeforeEach
+    public void init() {
+        String metadataType = DEFAULT_METADATA_STORAGE_TYPE;
+        ConfigManager configManager = ApplicationModel.getConfigManager();
+        ApplicationConfig applicationConfig = new ApplicationConfig("dubbo-demo-provider");
+        applicationConfig.setMetadataType(metadataType);
+        configManager.setApplication(applicationConfig);
+        this.writableMetadataService = WritableMetadataService.getDefaultExtension();
+    }
+
+    @AfterEach
+    public void reset() {
+        ApplicationModel.reset();
+    }
+
+    /**
+     * Test {@link ServiceConfigExportedEvent} arising
+     */
+    @Test
+    public void testOnServiceConfigExportedEvent() {
+        ServiceConfig<EchoService> serviceConfig = new ServiceConfig<>();
+        serviceConfig.setInterface(EchoService.class);
+        serviceConfig.setRef(new EchoServiceImpl());
+        serviceConfig.setRegistry(new RegistryConfig("N/A"));
+        serviceConfig.export();
+
+        String serviceDefinition = writableMetadataService.getServiceDefinition(EchoService.class.getName());
+
+        List<URL> exportedUrls = serviceConfig.getExportedUrls();
+
+        FullServiceDefinition fullServiceDefinition = buildFullDefinition(
+                serviceConfig.getInterfaceClass(),
+                exportedUrls.get(0)
+                        .removeParameters(PID_KEY, TIMESTAMP_KEY, BIND_IP_KEY, BIND_PORT_KEY, TIMESTAMP_KEY)
+                        .getParameters()
+        );
+
+        assertEquals(serviceDefinition, new Gson().toJson(fullServiceDefinition));
+    }
+}
diff --git a/dubbo-test/src/test/java/org/apache/dubbo/config/invoker/DelegateProviderMetaDataInvokerTest.java b/dubbo-test/src/test/java/org/apache/dubbo/config/invoker/DelegateProviderMetaDataInvokerTest.java
new file mode 100644
index 0000000..a8cd438
--- /dev/null
+++ b/dubbo-test/src/test/java/org/apache/dubbo/config/invoker/DelegateProviderMetaDataInvokerTest.java
@@ -0,0 +1,60 @@
+/*
+ * 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.invoker;
+
+import org.apache.dubbo.config.ServiceConfig;
+import org.apache.dubbo.config.api.Greeting;
+import org.apache.dubbo.rpc.Invocation;
+import org.apache.dubbo.rpc.Invoker;
+
+import org.junit.jupiter.api.BeforeEach;
+import org.junit.jupiter.api.Test;
+import org.mockito.Mockito;
+
+import static org.hamcrest.MatcherAssert.assertThat;
+import static org.hamcrest.Matchers.sameInstance;
+
+public class DelegateProviderMetaDataInvokerTest {
+    private ServiceConfig service;
+    private Invoker<Greeting> invoker;
+
+    @BeforeEach
+    public void setUp() throws Exception {
+        service = Mockito.mock(ServiceConfig.class);
+        invoker = Mockito.mock(Invoker.class);
+    }
+
+    @Test
+    public void testDelegate() throws Exception {
+        DelegateProviderMetaDataInvoker<Greeting> delegate =
+                new DelegateProviderMetaDataInvoker<Greeting>(invoker, service);
+        delegate.getInterface();
+        Mockito.verify(invoker).getInterface();
+        delegate.getUrl();
+        Mockito.verify(invoker).getUrl();
+        delegate.isAvailable();
+        Mockito.verify(invoker).isAvailable();
+        Invocation invocation = Mockito.mock(Invocation.class);
+        delegate.invoke(invocation);
+        Mockito.verify(invoker).invoke(invocation);
+        delegate.destroy();
+        Mockito.verify(invoker).destroy();
+        assertThat(delegate.getMetadata(), sameInstance(service));
+    }
+
+}
diff --git a/dubbo-test/src/test/java/org/apache/dubbo/config/mock/GreetingLocal1.java b/dubbo-test/src/test/java/org/apache/dubbo/config/mock/GreetingLocal1.java
new file mode 100644
index 0000000..f3d5ee5
--- /dev/null
+++ b/dubbo-test/src/test/java/org/apache/dubbo/config/mock/GreetingLocal1.java
@@ -0,0 +1,21 @@
+/*
+ * 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.mock;
+
+public class GreetingLocal1 {
+
+}
diff --git a/dubbo-test/src/test/java/org/apache/dubbo/config/mock/GreetingLocal2.java b/dubbo-test/src/test/java/org/apache/dubbo/config/mock/GreetingLocal2.java
new file mode 100644
index 0000000..8cae406
--- /dev/null
+++ b/dubbo-test/src/test/java/org/apache/dubbo/config/mock/GreetingLocal2.java
@@ -0,0 +1,26 @@
+/*
+ * 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.mock;
+
+import org.apache.dubbo.config.api.Greeting;
+
+public class GreetingLocal2 implements Greeting {
+    @Override
+    public String hello() {
+        return "local";
+    }
+}
diff --git a/dubbo-test/src/test/java/org/apache/dubbo/config/mock/GreetingLocal3.java b/dubbo-test/src/test/java/org/apache/dubbo/config/mock/GreetingLocal3.java
new file mode 100644
index 0000000..9b14ac6
--- /dev/null
+++ b/dubbo-test/src/test/java/org/apache/dubbo/config/mock/GreetingLocal3.java
@@ -0,0 +1,32 @@
+/*
+ * 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.mock;
+
+import org.apache.dubbo.config.api.Greeting;
+
+public class GreetingLocal3 implements Greeting {
+    private Greeting greeting;
+
+    public GreetingLocal3(Greeting greeting) {
+        this.greeting = greeting;
+    }
+
+    @Override
+    public String hello() {
+        return null;
+    }
+}
diff --git a/dubbo-test/src/test/java/org/apache/dubbo/config/mock/GreetingMock1.java b/dubbo-test/src/test/java/org/apache/dubbo/config/mock/GreetingMock1.java
new file mode 100644
index 0000000..8bfe6e6
--- /dev/null
+++ b/dubbo-test/src/test/java/org/apache/dubbo/config/mock/GreetingMock1.java
@@ -0,0 +1,20 @@
+/*
+ * 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.mock;
+
+public class GreetingMock1 {
+}
diff --git a/dubbo-test/src/test/java/org/apache/dubbo/config/mock/GreetingMock2.java b/dubbo-test/src/test/java/org/apache/dubbo/config/mock/GreetingMock2.java
new file mode 100644
index 0000000..429bff4
--- /dev/null
+++ b/dubbo-test/src/test/java/org/apache/dubbo/config/mock/GreetingMock2.java
@@ -0,0 +1,29 @@
+/*
+ * 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.mock;
+
+import org.apache.dubbo.config.api.Greeting;
+
+public class GreetingMock2 implements Greeting {
+    private GreetingMock2() {
+    }
+
+    @Override
+    public String hello() {
+        return "mock";
+    }
+}
diff --git a/dubbo-test/src/test/java/org/apache/dubbo/config/mock/MockCluster.java b/dubbo-test/src/test/java/org/apache/dubbo/config/mock/MockCluster.java
new file mode 100644
index 0000000..39bf974
--- /dev/null
+++ b/dubbo-test/src/test/java/org/apache/dubbo/config/mock/MockCluster.java
@@ -0,0 +1,29 @@
+/*
+ * 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.mock;
+
+import org.apache.dubbo.rpc.Invoker;
+import org.apache.dubbo.rpc.RpcException;
+import org.apache.dubbo.rpc.cluster.Cluster;
+import org.apache.dubbo.rpc.cluster.Directory;
+
+public class MockCluster implements Cluster {
+    @Override
+    public <T> Invoker<T> join(Directory<T> directory) throws RpcException {
+        return null;
+    }
+}
diff --git a/dubbo-test/src/test/java/org/apache/dubbo/config/mock/MockCodec.java b/dubbo-test/src/test/java/org/apache/dubbo/config/mock/MockCodec.java
new file mode 100644
index 0000000..c1aac42
--- /dev/null
+++ b/dubbo-test/src/test/java/org/apache/dubbo/config/mock/MockCodec.java
@@ -0,0 +1,37 @@
+/*
+ * 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.mock;
+
+import org.apache.dubbo.remoting.Channel;
+import org.apache.dubbo.remoting.Codec;
+
+import java.io.IOException;
+import java.io.InputStream;
+import java.io.OutputStream;
+
+public class MockCodec implements Codec {
+    @Override
+    public void encode(Channel channel, OutputStream output, Object message) throws IOException {
+
+    }
+
+    @Override
+    public Object decode(Channel channel, InputStream input) throws IOException {
+        return null;
+    }
+}
diff --git a/dubbo-test/src/test/java/org/apache/dubbo/config/mock/MockDispatcher.java b/dubbo-test/src/test/java/org/apache/dubbo/config/mock/MockDispatcher.java
new file mode 100644
index 0000000..32fffca
--- /dev/null
+++ b/dubbo-test/src/test/java/org/apache/dubbo/config/mock/MockDispatcher.java
@@ -0,0 +1,29 @@
+/*
+ * 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.mock;
+
+import org.apache.dubbo.common.URL;
+import org.apache.dubbo.remoting.ChannelHandler;
+import org.apache.dubbo.remoting.Dispatcher;
+
+public class MockDispatcher implements Dispatcher {
+    @Override
+    public ChannelHandler dispatch(ChannelHandler handler, URL url) {
+        return null;
+    }
+}
diff --git a/dubbo-test/src/test/java/org/apache/dubbo/config/mock/MockExchanger.java b/dubbo-test/src/test/java/org/apache/dubbo/config/mock/MockExchanger.java
new file mode 100644
index 0000000..fccfd23
--- /dev/null
+++ b/dubbo-test/src/test/java/org/apache/dubbo/config/mock/MockExchanger.java
@@ -0,0 +1,37 @@
+/*
+ * 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.mock;
+
+import org.apache.dubbo.common.URL;
+import org.apache.dubbo.remoting.RemotingException;
+import org.apache.dubbo.remoting.exchange.ExchangeClient;
+import org.apache.dubbo.remoting.exchange.ExchangeHandler;
+import org.apache.dubbo.remoting.exchange.ExchangeServer;
+import org.apache.dubbo.remoting.exchange.Exchanger;
+
+public class MockExchanger implements Exchanger {
+    @Override
+    public ExchangeServer bind(URL url, ExchangeHandler handler) throws RemotingException {
+        return null;
+    }
+
+    @Override
+    public ExchangeClient connect(URL url, ExchangeHandler handler) throws RemotingException {
+        return null;
+    }
+}
diff --git a/dubbo-test/src/test/java/org/apache/dubbo/config/mock/MockExporterListener.java b/dubbo-test/src/test/java/org/apache/dubbo/config/mock/MockExporterListener.java
new file mode 100644
index 0000000..b93f44c
--- /dev/null
+++ b/dubbo-test/src/test/java/org/apache/dubbo/config/mock/MockExporterListener.java
@@ -0,0 +1,34 @@
+/*
+ * 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.mock;
+
+import org.apache.dubbo.rpc.Exporter;
+import org.apache.dubbo.rpc.ExporterListener;
+import org.apache.dubbo.rpc.RpcException;
+
+public class MockExporterListener implements ExporterListener {
+    @Override
+    public void exported(Exporter<?> exporter) throws RpcException {
+
+    }
+
+    @Override
+    public void unexported(Exporter<?> exporter) {
+
+    }
+}
diff --git a/dubbo-test/src/test/java/org/apache/dubbo/config/mock/MockFilter.java b/dubbo-test/src/test/java/org/apache/dubbo/config/mock/MockFilter.java
new file mode 100644
index 0000000..d51f123
--- /dev/null
+++ b/dubbo-test/src/test/java/org/apache/dubbo/config/mock/MockFilter.java
@@ -0,0 +1,30 @@
+/*
+ * 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.mock;
+
+import org.apache.dubbo.rpc.Filter;
+import org.apache.dubbo.rpc.Invocation;
+import org.apache.dubbo.rpc.Invoker;
+import org.apache.dubbo.rpc.Result;
+import org.apache.dubbo.rpc.RpcException;
+
+public class MockFilter implements Filter {
+    @Override
+    public Result invoke(Invoker<?> invoker, Invocation invocation) throws RpcException {
+        return null;
+    }
+}
diff --git a/dubbo-test/src/test/java/org/apache/dubbo/config/mock/MockInvokerListener.java b/dubbo-test/src/test/java/org/apache/dubbo/config/mock/MockInvokerListener.java
new file mode 100644
index 0000000..c929e54
--- /dev/null
+++ b/dubbo-test/src/test/java/org/apache/dubbo/config/mock/MockInvokerListener.java
@@ -0,0 +1,33 @@
+/*
+ * 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.mock;
+
+import org.apache.dubbo.rpc.Invoker;
+import org.apache.dubbo.rpc.InvokerListener;
+import org.apache.dubbo.rpc.RpcException;
+
+public class MockInvokerListener implements InvokerListener {
+    @Override
+    public void referred(Invoker<?> invoker) throws RpcException {
+
+    }
+
+    @Override
+    public void destroyed(Invoker<?> invoker) {
+
+    }
+}
diff --git a/dubbo-test/src/test/java/org/apache/dubbo/config/mock/MockLoadBalance.java b/dubbo-test/src/test/java/org/apache/dubbo/config/mock/MockLoadBalance.java
new file mode 100644
index 0000000..377f328
--- /dev/null
+++ b/dubbo-test/src/test/java/org/apache/dubbo/config/mock/MockLoadBalance.java
@@ -0,0 +1,32 @@
+/*
+ * 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.mock;
+
+import org.apache.dubbo.common.URL;
+import org.apache.dubbo.rpc.Invocation;
+import org.apache.dubbo.rpc.Invoker;
+import org.apache.dubbo.rpc.RpcException;
+import org.apache.dubbo.rpc.cluster.LoadBalance;
+
+import java.util.List;
+
+public class MockLoadBalance implements LoadBalance {
+    @Override
+    public <T> Invoker<T> select(List<Invoker<T>> invokers, URL url, Invocation invocation) throws RpcException {
+        return null;
+    }
+}
diff --git a/dubbo-test/src/test/java/org/apache/dubbo/config/mock/MockProtocol.java b/dubbo-test/src/test/java/org/apache/dubbo/config/mock/MockProtocol.java
new file mode 100644
index 0000000..2ab518c
--- /dev/null
+++ b/dubbo-test/src/test/java/org/apache/dubbo/config/mock/MockProtocol.java
@@ -0,0 +1,89 @@
+/*
+ * 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.mock;
+
+import org.apache.dubbo.common.URL;
+import org.apache.dubbo.rpc.Exporter;
+import org.apache.dubbo.rpc.Invocation;
+import org.apache.dubbo.rpc.Invoker;
+import org.apache.dubbo.rpc.Protocol;
+import org.apache.dubbo.rpc.Result;
+import org.apache.dubbo.rpc.RpcException;
+
+import org.mockito.Mockito;
+
+public class MockProtocol implements Protocol {
+
+    /* (non-Javadoc)
+     * @see org.apache.dubbo.rpc.Protocol#getDefaultPort()
+     */
+    @Override
+    public int getDefaultPort() {
+
+        return 0;
+    }
+
+    /* (non-Javadoc)
+     * @see org.apache.dubbo.rpc.Protocol#export(org.apache.dubbo.rpc.Invoker)
+     */
+    public <T> Exporter<T> export(Invoker<T> invoker) throws RpcException {
+        return Mockito.mock(Exporter.class);
+    }
+
+    /* (non-Javadoc)
+     * @see org.apache.dubbo.rpc.Protocol#refer(java.lang.Class, org.apache.dubbo.common.URL)
+     */
+    public <T> Invoker<T> refer(Class<T> type, URL url) throws RpcException {
+
+        final URL u = url;
+
+        return new Invoker<T>() {
+            @Override
+            public Class<T> getInterface() {
+                return null;
+            }
+
+            public URL getUrl() {
+                return u;
+            }
+
+            @Override
+            public boolean isAvailable() {
+                return true;
+            }
+
+            @Override
+            public Result invoke(Invocation invocation) throws RpcException {
+                return null;
+            }
+
+            @Override
+            public void destroy() {
+
+            }
+        };
+    }
+
+    /* (non-Javadoc)
+     * @see org.apache.dubbo.rpc.Protocol#destroy()
+     */
+    @Override
+    public void destroy() {
+
+    }
+
+}
diff --git a/dubbo-test/src/test/java/org/apache/dubbo/config/mock/MockProtocol2.java b/dubbo-test/src/test/java/org/apache/dubbo/config/mock/MockProtocol2.java
new file mode 100644
index 0000000..91653d4
--- /dev/null
+++ b/dubbo-test/src/test/java/org/apache/dubbo/config/mock/MockProtocol2.java
@@ -0,0 +1,48 @@
+/*
+ * 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.mock;
+
+import org.apache.dubbo.common.URL;
+import org.apache.dubbo.rpc.Exporter;
+import org.apache.dubbo.rpc.Invoker;
+import org.apache.dubbo.rpc.Protocol;
+import org.apache.dubbo.rpc.RpcException;
+
+public class MockProtocol2 implements Protocol {
+    public static Protocol delegate;
+
+    @Override
+    public int getDefaultPort() {
+        return delegate.getDefaultPort();
+    }
+
+    @Override
+    public <T> Exporter<T> export(Invoker<T> invoker) throws RpcException {
+        return delegate.export(invoker);
+    }
+
+    @Override
+    public <T> Invoker<T> refer(Class<T> type, URL url) throws RpcException {
+        return delegate.refer(type, url);
+    }
+
+    @Override
+    public void destroy() {
+        delegate.destroy();
+    }
+}
diff --git a/dubbo-test/src/test/java/org/apache/dubbo/config/mock/MockProxyFactory.java b/dubbo-test/src/test/java/org/apache/dubbo/config/mock/MockProxyFactory.java
new file mode 100644
index 0000000..49f05d8
--- /dev/null
+++ b/dubbo-test/src/test/java/org/apache/dubbo/config/mock/MockProxyFactory.java
@@ -0,0 +1,39 @@
+/*
+ * Licensed to the Apache Software Foundation (ASF) under one or more
+ * contributor license agreements.  See the NOTICE file distributed with
+ * this work for additional information regarding copyright ownership.
+ * The ASF licenses this file to You under the Apache License, Version 2.0
+ * (the "License"); you may not use this file except in compliance with
+ * the License.  You may obtain a copy of the License at
+ *
+ *      http://www.apache.org/licenses/LICENSE-2.0
+ *
+ * Unless required by applicable law or agreed to in writing, software
+ * distributed under the License is distributed on an "AS IS" BASIS,
+ * WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied.
+ * See the License for the specific language governing permissions and
+ * limitations under the License.
+ */
+package org.apache.dubbo.config.mock;
+
+import org.apache.dubbo.common.URL;
+import org.apache.dubbo.rpc.Invoker;
+import org.apache.dubbo.rpc.ProxyFactory;
+import org.apache.dubbo.rpc.RpcException;
... 2019 lines suppressed ...


[dubbo-spi-extensions] 29/39: 新增quick start demo, 修改bug

Posted by li...@apache.org.
This is an automated email from the ASF dual-hosted git repository.

liujun pushed a commit to branch 2.7.x
in repository https://gitbox.apache.org/repos/asf/dubbo-spi-extensions.git

commit 5f91e7957e4aeead7258121cd971fb4daf1d9dba
Author: qq213539 <21...@qq.com>
AuthorDate: Thu Dec 24 13:17:47 2020 +0800

    新增quick start demo, 修改bug
---
 .../core/DubboApiDocsAnnotationScanner.java        | 19 +++---
 .../dubbo/apidocs/core/beans/ApiCacheItem.java     | 16 ++++++
 .../apidocs/core/beans/ApiParamsCacheItem.java     | 16 ++++++
 .../dubbo/apidocs/core/beans/ModuleCacheItem.java  | 16 ++++++
 .../apache/dubbo/apidocs/utils/ClassTypeUtil.java  | 16 +++---
 .../apache/dubbo/apidocs/utils/SimpleTypeImpl.java | 16 ++++++
 .../apidocs/examples/api/IQuickStartDemo.java      | 36 ++++++++++++
 .../examples/params/QuickStartRequestBean.java     | 67 ++++++++++++++++++++++
 .../examples/params/QuickStartRespBean.java        | 52 +++++++++++++++++
 .../examples-provider-sca/pom.xml                  | 12 ++++
 .../examples-provider/pom.xml                      | 13 +++++
 .../examples/api/impl/QuickStartDemoImpl.java      | 42 ++++++++++++++
 12 files changed, 304 insertions(+), 17 deletions(-)

diff --git a/dubbo-api-docs/dubbo-api-docs-core/src/main/java/org/apache/dubbo/apidocs/core/DubboApiDocsAnnotationScanner.java b/dubbo-api-docs/dubbo-api-docs-core/src/main/java/org/apache/dubbo/apidocs/core/DubboApiDocsAnnotationScanner.java
index f43cb40..717bfa5 100644
--- a/dubbo-api-docs/dubbo-api-docs-core/src/main/java/org/apache/dubbo/apidocs/core/DubboApiDocsAnnotationScanner.java
+++ b/dubbo-api-docs/dubbo-api-docs-core/src/main/java/org/apache/dubbo/apidocs/core/DubboApiDocsAnnotationScanner.java
@@ -142,7 +142,7 @@ public class DubboApiDocsAnnotationScanner implements ApplicationListener<Applic
         //Description of API return data
         apiListItem.setApiRespDec(dubboApi.responseClassDescription());
 
-        // Interface parameters and response information
+        // API details in cache, contain interface parameters and response information
         ApiCacheItem apiParamsAndResp = new ApiCacheItem();
         DubboApiDocsCache.addApiParamsAndResp(
                 moduleAnn.apiInterface().getCanonicalName() + "." + method.getName(), apiParamsAndResp);
@@ -156,6 +156,7 @@ public class DubboApiDocsAnnotationScanner implements ApplicationListener<Applic
         apiParamsAndResp.setApiDocName(dubboApi.value());
         apiParamsAndResp.setApiVersion(dubboApi.version());
         apiParamsAndResp.setApiRespDec(dubboApi.responseClassDescription());
+        apiParamsAndResp.setDescription(dubboApi.description());
         apiParamsAndResp.setApiModelClass(moduleCacheItem.getModuleClassName());
         apiParamsAndResp.setParams(paramList);
         apiParamsAndResp.setResponse(ClassTypeUtil.calss2Json(method.getGenericReturnType(), method.getReturnType()));
@@ -265,28 +266,28 @@ public class DubboApiDocsAnnotationScanner implements ApplicationListener<Applic
         boolean hasAllowableValues = (param.getAllowableValues() != null && param.getAllowableValues().length > 0);
         // Processed or not
         boolean processed = false;
-        if (Integer.class.isAssignableFrom(classType)) {
+        if (Integer.class.isAssignableFrom(classType) || int.class.isAssignableFrom(classType)) {
             param.setHtmlType(HtmlTypeEnum.NUMBER_INTEGER);
             processed = true;
-        } else if (Byte.class.isAssignableFrom(classType)) {
+        } else if (Byte.class.isAssignableFrom(classType) || byte.class.isAssignableFrom(classType)) {
             param.setHtmlType(HtmlTypeEnum.TEXT_BYTE);
             processed = true;
-        } else if (Long.class.isAssignableFrom(classType)) {
+        } else if (Long.class.isAssignableFrom(classType) || long.class.isAssignableFrom(classType)) {
             param.setHtmlType(HtmlTypeEnum.NUMBER_INTEGER);
             processed = true;
-        } else if (Double.class.isAssignableFrom(classType)) {
+        } else if (Double.class.isAssignableFrom(classType) || double.class.isAssignableFrom(classType)) {
             param.setHtmlType(HtmlTypeEnum.NUMBER_DECIMAL);
             processed = true;
-        } else if (Float.class.isAssignableFrom(classType)) {
+        } else if (Float.class.isAssignableFrom(classType) || float.class.isAssignableFrom(classType)) {
             param.setHtmlType(HtmlTypeEnum.NUMBER_DECIMAL);
             processed = true;
         } else if (String.class.isAssignableFrom(classType)) {
             param.setHtmlType(HtmlTypeEnum.TEXT);
             processed = true;
-        } else if (Character.class.isAssignableFrom(classType)) {
+        } else if (Character.class.isAssignableFrom(classType) || char.class.isAssignableFrom(classType)) {
             param.setHtmlType(HtmlTypeEnum.TEXT_CHAR);
             processed = true;
-        } else if (Short.class.isAssignableFrom(classType)) {
+        } else if (Short.class.isAssignableFrom(classType) || short.class.isAssignableFrom(classType)) {
             param.setHtmlType(HtmlTypeEnum.NUMBER_INTEGER);
             processed = true;
         }
@@ -300,7 +301,7 @@ public class DubboApiDocsAnnotationScanner implements ApplicationListener<Applic
         }
 
         // haven't dealt with it. Go on
-        if (Boolean.class.isAssignableFrom(classType)) {
+        if (Boolean.class.isAssignableFrom(classType) || boolean.class.isAssignableFrom(classType)) {
             param.setHtmlType(HtmlTypeEnum.SELECT);
             // Boolean can only be true / false. No matter what the previous allowed value is, it is forced to replace
             param.setAllowableValues(new String[]{"true", "false"});
diff --git a/dubbo-api-docs/dubbo-api-docs-core/src/main/java/org/apache/dubbo/apidocs/core/beans/ApiCacheItem.java b/dubbo-api-docs/dubbo-api-docs-core/src/main/java/org/apache/dubbo/apidocs/core/beans/ApiCacheItem.java
index 21a7011..f88c039 100644
--- a/dubbo-api-docs/dubbo-api-docs-core/src/main/java/org/apache/dubbo/apidocs/core/beans/ApiCacheItem.java
+++ b/dubbo-api-docs/dubbo-api-docs-core/src/main/java/org/apache/dubbo/apidocs/core/beans/ApiCacheItem.java
@@ -1,3 +1,19 @@
+/*
+ * 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.apidocs.core.beans;
 
 import java.util.List;
diff --git a/dubbo-api-docs/dubbo-api-docs-core/src/main/java/org/apache/dubbo/apidocs/core/beans/ApiParamsCacheItem.java b/dubbo-api-docs/dubbo-api-docs-core/src/main/java/org/apache/dubbo/apidocs/core/beans/ApiParamsCacheItem.java
index 93347af..3571da2 100644
--- a/dubbo-api-docs/dubbo-api-docs-core/src/main/java/org/apache/dubbo/apidocs/core/beans/ApiParamsCacheItem.java
+++ b/dubbo-api-docs/dubbo-api-docs-core/src/main/java/org/apache/dubbo/apidocs/core/beans/ApiParamsCacheItem.java
@@ -1,3 +1,19 @@
+/*
+ * 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.apidocs.core.beans;
 
 import java.util.List;
diff --git a/dubbo-api-docs/dubbo-api-docs-core/src/main/java/org/apache/dubbo/apidocs/core/beans/ModuleCacheItem.java b/dubbo-api-docs/dubbo-api-docs-core/src/main/java/org/apache/dubbo/apidocs/core/beans/ModuleCacheItem.java
index 5f48980..e729969 100644
--- a/dubbo-api-docs/dubbo-api-docs-core/src/main/java/org/apache/dubbo/apidocs/core/beans/ModuleCacheItem.java
+++ b/dubbo-api-docs/dubbo-api-docs-core/src/main/java/org/apache/dubbo/apidocs/core/beans/ModuleCacheItem.java
@@ -1,3 +1,19 @@
+/*
+ * 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.apidocs.core.beans;
 
 import java.util.List;
diff --git a/dubbo-api-docs/dubbo-api-docs-core/src/main/java/org/apache/dubbo/apidocs/utils/ClassTypeUtil.java b/dubbo-api-docs/dubbo-api-docs-core/src/main/java/org/apache/dubbo/apidocs/utils/ClassTypeUtil.java
index a7e9179..b11d534 100644
--- a/dubbo-api-docs/dubbo-api-docs-core/src/main/java/org/apache/dubbo/apidocs/utils/ClassTypeUtil.java
+++ b/dubbo-api-docs/dubbo-api-docs-core/src/main/java/org/apache/dubbo/apidocs/utils/ClassTypeUtil.java
@@ -140,23 +140,23 @@ public class ClassTypeUtil {
     }
 
     private static Object initClassTypeWithDefaultValueNoProceeField(Type genericType, Class<?> classType, int processCount) {
-        if (Integer.class.isAssignableFrom(classType)) {
+        if (Integer.class.isAssignableFrom(classType) || int.class.isAssignableFrom(classType)) {
             return 0;
-        } else if (Byte.class.isAssignableFrom(classType)) {
+        } else if (Byte.class.isAssignableFrom(classType) || byte.class.isAssignableFrom(classType)) {
             return (byte) 0;
-        } else if (Long.class.isAssignableFrom(classType)) {
+        } else if (Long.class.isAssignableFrom(classType) || long.class.isAssignableFrom(classType)) {
             return 0L;
-        } else if (Double.class.isAssignableFrom(classType)) {
+        } else if (Double.class.isAssignableFrom(classType) || double.class.isAssignableFrom(classType)) {
             return 0.0D;
-        } else if (Float.class.isAssignableFrom(classType)) {
+        } else if (Float.class.isAssignableFrom(classType) || float.class.isAssignableFrom(classType)) {
             return 0.0F;
         } else if (String.class.isAssignableFrom(classType)) {
             return "";
-        } else if (Character.class.isAssignableFrom(classType)) {
+        } else if (Character.class.isAssignableFrom(classType) || char.class.isAssignableFrom(classType)) {
             return 'c';
-        } else if (Short.class.isAssignableFrom(classType)) {
+        } else if (Short.class.isAssignableFrom(classType) || short.class.isAssignableFrom(classType)) {
             return (short) 0;
-        } else if (Boolean.class.isAssignableFrom(classType)) {
+        } else if (Boolean.class.isAssignableFrom(classType) || boolean.class.isAssignableFrom(classType)) {
             return false;
         } else if (Date.class.isAssignableFrom(classType)) {
             return "【" + Date.class.getName() + "】yyyy-MM-dd HH:mm:ss";
diff --git a/dubbo-api-docs/dubbo-api-docs-core/src/main/java/org/apache/dubbo/apidocs/utils/SimpleTypeImpl.java b/dubbo-api-docs/dubbo-api-docs-core/src/main/java/org/apache/dubbo/apidocs/utils/SimpleTypeImpl.java
index d48fa74..826a96a 100644
--- a/dubbo-api-docs/dubbo-api-docs-core/src/main/java/org/apache/dubbo/apidocs/utils/SimpleTypeImpl.java
+++ b/dubbo-api-docs/dubbo-api-docs-core/src/main/java/org/apache/dubbo/apidocs/utils/SimpleTypeImpl.java
@@ -1,3 +1,19 @@
+/*
+ * 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.apidocs.utils;
 
 import java.lang.reflect.Type;
diff --git a/dubbo-api-docs/dubbo-api-docs-examples/examples-api/src/main/java/org/apache/dubbo/apidocs/examples/api/IQuickStartDemo.java b/dubbo-api-docs/dubbo-api-docs-examples/examples-api/src/main/java/org/apache/dubbo/apidocs/examples/api/IQuickStartDemo.java
new file mode 100644
index 0000000..ed99fe4
--- /dev/null
+++ b/dubbo-api-docs/dubbo-api-docs-examples/examples-api/src/main/java/org/apache/dubbo/apidocs/examples/api/IQuickStartDemo.java
@@ -0,0 +1,36 @@
+/*
+ * 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.apidocs.examples.api;
+
+import org.apache.dubbo.apidocs.examples.params.QuickStartRequestBean;
+import org.apache.dubbo.apidocs.examples.params.QuickStartRespBean;
+
+/**
+ * quick start demo.
+ */
+public interface IQuickStartDemo {
+
+    /**
+     * quick start demo.
+     *
+     * @param strParam
+     * @param beanParam
+     * @return org.apache.dubbo.apidocs.examples.params.QuickStartRespBean
+     */
+    QuickStartRespBean quickStart(String strParam, QuickStartRequestBean beanParam);
+
+}
diff --git a/dubbo-api-docs/dubbo-api-docs-examples/examples-api/src/main/java/org/apache/dubbo/apidocs/examples/params/QuickStartRequestBean.java b/dubbo-api-docs/dubbo-api-docs-examples/examples-api/src/main/java/org/apache/dubbo/apidocs/examples/params/QuickStartRequestBean.java
new file mode 100644
index 0000000..30e9ef3
--- /dev/null
+++ b/dubbo-api-docs/dubbo-api-docs-examples/examples-api/src/main/java/org/apache/dubbo/apidocs/examples/params/QuickStartRequestBean.java
@@ -0,0 +1,67 @@
+/*
+ * 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.apidocs.examples.params;
+
+import org.apache.dubbo.apidocs.annotations.RequestParam;
+
+/**
+ * quick start demo request parameter bean.
+ */
+public class QuickStartRequestBean {
+
+    @RequestParam(value = "You name", required = true, description = "please enter your full name", example = "Zhang San")
+    private String name;
+
+    @RequestParam(value = "You age", defaultValue = "18")
+    private int age;
+
+    @RequestParam("Are you a main?")
+    private boolean man;
+
+    public String getName() {
+        return name;
+    }
+
+    public void setName(String name) {
+        this.name = name;
+    }
+
+    public int getAge() {
+        return age;
+    }
+
+    public void setAge(int age) {
+        this.age = age;
+    }
+
+    public boolean getMan() {
+        return man;
+    }
+
+    public void setMan(boolean man) {
+        this.man = man;
+    }
+
+    @Override
+    public String toString() {
+        return "QuickStartRequestBean{" +
+                "name='" + name + '\'' +
+                ", age=" + age +
+                ", man=" + man +
+                '}';
+    }
+}
diff --git a/dubbo-api-docs/dubbo-api-docs-examples/examples-api/src/main/java/org/apache/dubbo/apidocs/examples/params/QuickStartRespBean.java b/dubbo-api-docs/dubbo-api-docs-examples/examples-api/src/main/java/org/apache/dubbo/apidocs/examples/params/QuickStartRespBean.java
new file mode 100644
index 0000000..ccb84c7
--- /dev/null
+++ b/dubbo-api-docs/dubbo-api-docs-examples/examples-api/src/main/java/org/apache/dubbo/apidocs/examples/params/QuickStartRespBean.java
@@ -0,0 +1,52 @@
+/*
+ * 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.apidocs.examples.params;
+
+import org.apache.dubbo.apidocs.annotations.ResponseProperty;
+
+/**
+ * quick star demo response bean.
+ */
+public class QuickStartRespBean {
+
+    @ResponseProperty(value = "Response code", example = "500")
+    private int code;
+
+    @ResponseProperty("Response message")
+    private String msg;
+
+    public QuickStartRespBean(int code, String msg) {
+        this.code = code;
+        this.msg = msg;
+    }
+
+    public int getCode() {
+        return code;
+    }
+
+    public void setCode(int code) {
+        this.code = code;
+    }
+
+    public String getMsg() {
+        return msg;
+    }
+
+    public void setMsg(String msg) {
+        this.msg = msg;
+    }
+}
diff --git a/dubbo-api-docs/dubbo-api-docs-examples/examples-provider-sca/pom.xml b/dubbo-api-docs/dubbo-api-docs-examples/examples-provider-sca/pom.xml
index 7765916..c1ff683 100644
--- a/dubbo-api-docs/dubbo-api-docs-examples/examples-provider-sca/pom.xml
+++ b/dubbo-api-docs/dubbo-api-docs-examples/examples-provider-sca/pom.xml
@@ -58,5 +58,17 @@
 
     </dependencies>
 
+    <build>
+        <plugins>
+            <plugin>
+                <groupId>org.springframework.boot</groupId>
+                <artifactId>spring-boot-maven-plugin</artifactId>
+                <configuration>
+                    <mainClass>org.apache.dubbo.apidocs.examples.ExampleScaApplication</mainClass>
+                    <classifier>exec</classifier>
+                </configuration>
+            </plugin>
+        </plugins>
+    </build>
 
 </project>
diff --git a/dubbo-api-docs/dubbo-api-docs-examples/examples-provider/pom.xml b/dubbo-api-docs/dubbo-api-docs-examples/examples-provider/pom.xml
index c3bd6c5..aa16cae 100644
--- a/dubbo-api-docs/dubbo-api-docs-examples/examples-provider/pom.xml
+++ b/dubbo-api-docs/dubbo-api-docs-examples/examples-provider/pom.xml
@@ -76,5 +76,18 @@
         </dependency>
     </dependencies>
 
+    <build>
+        <plugins>
+            <plugin>
+                <groupId>org.springframework.boot</groupId>
+                <artifactId>spring-boot-maven-plugin</artifactId>
+                <configuration>
+                    <mainClass>org.apache.dubbo.apidocs.examples.ExampleApplication</mainClass>
+                    <classifier>exec</classifier>
+                </configuration>
+            </plugin>
+        </plugins>
+    </build>
+
 
 </project>
diff --git a/dubbo-api-docs/dubbo-api-docs-examples/examples-provider/src/main/java/org/apache/dubbo/apidocs/examples/api/impl/QuickStartDemoImpl.java b/dubbo-api-docs/dubbo-api-docs-examples/examples-provider/src/main/java/org/apache/dubbo/apidocs/examples/api/impl/QuickStartDemoImpl.java
new file mode 100644
index 0000000..0d9bdc7
--- /dev/null
+++ b/dubbo-api-docs/dubbo-api-docs-examples/examples-provider/src/main/java/org/apache/dubbo/apidocs/examples/api/impl/QuickStartDemoImpl.java
@@ -0,0 +1,42 @@
+/*
+ * 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.apidocs.examples.api.impl;
+
+import org.apache.dubbo.apidocs.annotations.ApiDoc;
+import org.apache.dubbo.apidocs.annotations.ApiModule;
+import org.apache.dubbo.apidocs.annotations.RequestParam;
+import org.apache.dubbo.apidocs.examples.api.IQuickStartDemo;
+import org.apache.dubbo.apidocs.examples.params.QuickStartRequestBean;
+import org.apache.dubbo.apidocs.examples.params.QuickStartRespBean;
+import org.apache.dubbo.config.annotation.DubboService;
+
+/**
+ * quick start demo implement.
+ *
+ * @author klw(213539 @ qq.com)
+ * @date 2020/12/23 17:21
+ */
+@DubboService
+@ApiModule(value = "quick start demo", apiInterface = IQuickStartDemo.class, version = "v0.1")
+public class QuickStartDemoImpl implements IQuickStartDemo {
+
+    @ApiDoc(value = "quick start demo", version = "v0.1", description = "this api is a quick start demo", responseClassDescription="A quick star response bean")
+    @Override
+    public QuickStartRespBean quickStart(@RequestParam(value = "strParam", required = true) String strParam, QuickStartRequestBean beanParam) {
+        return new QuickStartRespBean(200, "hello " + beanParam.getName() + ", " + beanParam.toString());
+    }
+}


[dubbo-spi-extensions] 19/39: 增加使用 spring-cloud-starter-dubbo

Posted by li...@apache.org.
This is an automated email from the ASF dual-hosted git repository.

liujun pushed a commit to branch 2.7.x
in repository https://gitbox.apache.org/repos/asf/dubbo-spi-extensions.git

commit 955ac3d31885ea08c612f1f0a1f8cf1775a62585
Author: qq213539 <21...@qq.com>
AuthorDate: Fri Dec 4 17:58:14 2020 +0800

    增加使用 spring-cloud-starter-dubbo
---
 .../examples-provider-sca/pom.xml                  |  27 +++++
 .../apidocs/examples/ExampleScaApplication.java    |  43 +++++++
 .../apidocs/examples/api/impl/AsyncDemoImpl.java   | 104 +++++++++++++++++
 .../apidocs/examples/api/impl/SyncDemoImpl.java    | 125 +++++++++++++++++++++
 .../dubbo/apidocs/examples/cfg/DubboDocConfig.java |  34 ++++++
 dubbo-api-docs/dubbo-api-docs-examples/pom.xml     |  17 +++
 dubbo-api-docs/dubbo-api-docs-ui-server/pom.xml    |  17 +--
 dubbo-api-docs/pom.xml                             |   4 +
 8 files changed, 360 insertions(+), 11 deletions(-)

diff --git a/dubbo-api-docs/dubbo-api-docs-examples/examples-provider-sca/pom.xml b/dubbo-api-docs/dubbo-api-docs-examples/examples-provider-sca/pom.xml
index 6cd0781..7765916 100644
--- a/dubbo-api-docs/dubbo-api-docs-examples/examples-provider-sca/pom.xml
+++ b/dubbo-api-docs/dubbo-api-docs-examples/examples-provider-sca/pom.xml
@@ -29,6 +29,33 @@
 
     <dependencies>
 
+        <dependency>
+            <groupId>org.apache.dubbo</groupId>
+            <artifactId>dubbo-api-docs-core</artifactId>
+        </dependency>
+        <dependency>
+            <groupId>org.apache.dubbo.examples.apidocs</groupId>
+            <artifactId>examples-api</artifactId>
+        </dependency>
+        <dependency>
+            <groupId>org.springframework.boot</groupId>
+            <artifactId>spring-boot-autoconfigure</artifactId>
+        </dependency>
+        <dependency>
+            <groupId>com.alibaba.cloud</groupId>
+            <artifactId>spring-cloud-starter-alibaba-nacos-discovery</artifactId>
+        </dependency>
+
+        <dependency>
+            <groupId>com.alibaba.cloud</groupId>
+            <artifactId>spring-cloud-starter-dubbo</artifactId>
+        </dependency>
+
+        <dependency>
+            <groupId>org.springframework.boot</groupId>
+            <artifactId>spring-boot-starter-logging</artifactId>
+        </dependency>
+
     </dependencies>
 
 
diff --git a/dubbo-api-docs/dubbo-api-docs-examples/examples-provider-sca/src/main/java/org/apache/dubbo/apidocs/examples/ExampleScaApplication.java b/dubbo-api-docs/dubbo-api-docs-examples/examples-provider-sca/src/main/java/org/apache/dubbo/apidocs/examples/ExampleScaApplication.java
new file mode 100644
index 0000000..a6f600f
--- /dev/null
+++ b/dubbo-api-docs/dubbo-api-docs-examples/examples-provider-sca/src/main/java/org/apache/dubbo/apidocs/examples/ExampleScaApplication.java
@@ -0,0 +1,43 @@
+/*
+ * 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.apidocs.examples;
+
+import org.apache.dubbo.config.spring.context.annotation.EnableDubbo;
+
+import org.springframework.boot.WebApplicationType;
+import org.springframework.boot.autoconfigure.SpringBootApplication;
+import org.springframework.boot.builder.SpringApplicationBuilder;
+import org.springframework.cloud.client.discovery.EnableDiscoveryClient;
+
+/**
+ * example dubbo provider service using spring-cloud-starter-dubbo.
+ * @author klw(213539@qq.com)
+ * `2020/12/4` 17:48
+ */
+@SpringBootApplication
+@EnableDiscoveryClient
+@EnableDubbo(scanBasePackages = {"org.apache.dubbo.apidocs.examples.api"})
+public class ExampleScaApplication {
+
+    public static void main(String[] args) {
+        new SpringApplicationBuilder(ExampleScaApplication.class)
+                // Non web applications
+                .web(WebApplicationType.NONE)
+                .run(args);
+    }
+
+}
diff --git a/dubbo-api-docs/dubbo-api-docs-examples/examples-provider-sca/src/main/java/org/apache/dubbo/apidocs/examples/api/impl/AsyncDemoImpl.java b/dubbo-api-docs/dubbo-api-docs-examples/examples-provider-sca/src/main/java/org/apache/dubbo/apidocs/examples/api/impl/AsyncDemoImpl.java
new file mode 100644
index 0000000..b4f14fb
--- /dev/null
+++ b/dubbo-api-docs/dubbo-api-docs-examples/examples-provider-sca/src/main/java/org/apache/dubbo/apidocs/examples/api/impl/AsyncDemoImpl.java
@@ -0,0 +1,104 @@
+/*
+ * 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.apidocs.examples.api.impl;
+
+import org.apache.dubbo.apidocs.annotations.ApiDoc;
+import org.apache.dubbo.apidocs.annotations.ApiModule;
+import org.apache.dubbo.apidocs.examples.api.IAsyncDemo;
+import org.apache.dubbo.apidocs.examples.params.DemoParamBean1;
+import org.apache.dubbo.apidocs.examples.params.DemoParamBean2;
+import org.apache.dubbo.apidocs.examples.params.DemoParamBean3;
+import org.apache.dubbo.apidocs.examples.params.DemoParamBean4;
+import org.apache.dubbo.apidocs.examples.responses.DemoRespBean1;
+import org.apache.dubbo.config.annotation.DubboService;
+import java.util.List;
+import java.util.Map;
+import java.util.concurrent.CompletableFuture;
+import java.util.concurrent.ExecutorService;
+import java.util.concurrent.Executors;
+
+/**
+ * Asynchronous demo implementation.
+ * @author klw(213539@qq.com)
+ * 2020/12/4 17:53
+ */
+@DubboService(async = true)
+@ApiModule(value = "Asynchronous demo", apiInterface = IAsyncDemo.class)
+public class AsyncDemoImpl implements IAsyncDemo {
+
+    public static final ExecutorService EXECUTOR = Executors.newFixedThreadPool(Runtime.getRuntime().availableProcessors() * 40 * 3);
+
+    @ApiDoc("request and response parameters are beans")
+    @Override
+    public CompletableFuture<DemoRespBean1> demoApi1(DemoParamBean1 param1, DemoParamBean2 param2) {
+        DemoRespBean1 result = new DemoRespBean1();
+        result.setCode("123456789");
+        result.setMessage("called demoApi1 msg1");
+        result.setMessage2("called demoApi1 msg2");
+        return CompletableFuture.supplyAsync(() -> result, EXECUTOR);
+    }
+
+    @Override
+    @ApiDoc(value = "Map without generics", responseClassDescription="Map without generics")
+    public CompletableFuture<Map> demoApi6() {
+        return null;
+    }
+
+    @Override
+    @ApiDoc(value = "Map generic with Object", responseClassDescription="Map generic with Object")
+    public CompletableFuture<Map<Object, Object>> demoApi7() {
+        return null;
+    }
+
+    @Override
+    @ApiDoc(value = "List without generics", responseClassDescription="List without generics")
+    public CompletableFuture<List> demoApi10() {
+        return null;
+    }
+
+    @Override
+    @ApiDoc(value = "List generic with Object", responseClassDescription="List generic with Object")
+    public CompletableFuture<List<Object>> demoApi9() {
+        return null;
+    }
+
+    @Override
+    @ApiDoc(value = "Object", responseClassDescription="Object")
+    public CompletableFuture<Object> demoApi8() {
+        return null;
+    }
+
+    @Override
+    @ApiDoc(value = "Integer", responseClassDescription="Integer")
+    public CompletableFuture<Integer> demoApi11() {
+        return null;
+    }
+
+    @Override
+    @ApiDoc(value = "many generics", responseClassDescription="many generics")
+    public CompletableFuture<List<List<String>>> demoApi12(){
+        return null;
+    }
+
+    @Override
+    @ApiDoc(value = "Simple test", responseClassDescription = "Simple test")
+    public CompletableFuture<DemoParamBean3> demoApi13(DemoParamBean3 param1, DemoParamBean4 param2) {
+        DemoParamBean3 result = new DemoParamBean3();
+        result.setString("demoApi13 result");
+        return CompletableFuture.supplyAsync(() -> result, EXECUTOR);
+    }
+}
diff --git a/dubbo-api-docs/dubbo-api-docs-examples/examples-provider-sca/src/main/java/org/apache/dubbo/apidocs/examples/api/impl/SyncDemoImpl.java b/dubbo-api-docs/dubbo-api-docs-examples/examples-provider-sca/src/main/java/org/apache/dubbo/apidocs/examples/api/impl/SyncDemoImpl.java
new file mode 100644
index 0000000..60b6827
--- /dev/null
+++ b/dubbo-api-docs/dubbo-api-docs-examples/examples-provider-sca/src/main/java/org/apache/dubbo/apidocs/examples/api/impl/SyncDemoImpl.java
@@ -0,0 +1,125 @@
+/*
+ * 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.apidocs.examples.api.impl;
+
+import org.apache.dubbo.apidocs.annotations.ApiDoc;
+import org.apache.dubbo.apidocs.annotations.ApiModule;
+import org.apache.dubbo.apidocs.annotations.RequestParam;
+import org.apache.dubbo.apidocs.examples.api.ISyncDemo;
+import org.apache.dubbo.apidocs.examples.params.DemoParamBean1;
+import org.apache.dubbo.apidocs.examples.params.DemoParamBean2;
+import org.apache.dubbo.apidocs.examples.params.DemoParamBean3;
+import org.apache.dubbo.apidocs.examples.params.DemoParamBean4;
+import org.apache.dubbo.apidocs.examples.responses.BaseResponse;
+import org.apache.dubbo.apidocs.examples.responses.DemoRespBean1;
+import org.apache.dubbo.config.annotation.DubboService;
+
+import lombok.extern.slf4j.Slf4j;
+
+import java.util.List;
+import java.util.Map;
+
+/**
+ * Synchronous demo implementation.
+ * @author klw(213539@qq.com)
+ * 2020/12/4 17:53
+ */
+@Slf4j
+@DubboService
+@ApiModule(value = "Synchronous demo", apiInterface = ISyncDemo.class)
+public class SyncDemoImpl implements ISyncDemo {
+
+    @ApiDoc("request and response parameters are beans")
+    @Override
+    public DemoRespBean1 demoApi1(DemoParamBean1 param1, DemoParamBean2 param2) {
+        log.info("called demoApi1");
+        DemoRespBean1 result = new DemoRespBean1();
+        result.setCode("123456789");
+        result.setMessage("called demoApi1 msg1");
+        result.setMessage2("called demoApi1 msg2");
+        return result;
+    }
+
+    @ApiDoc(value = "request and response parameters are Strings", responseClassDescription="A string")
+    @Override
+    public String demoApi2(@RequestParam(value = "Parameter 1", required = true) String prarm1, String prarm2) {
+        log.info(" called demoApi2");
+        return "demoApi2";
+    }
+
+    @Override
+    public String demoApi3(String prarm1) {
+        return null;
+    }
+
+    @ApiDoc(value = "Nonparametric method with Dubbo doc annotation", responseClassDescription="A string")
+    @Override
+    public String demoApi4() {
+        return "asdfasdfsdafds";
+    }
+
+    @ApiDoc(value = " Use generics in response", responseClassDescription=" Use generics in response")
+    public BaseResponse<DemoRespBean1> demoApi5(){
+        BaseResponse<DemoRespBean1> response = new BaseResponse<>();
+        DemoRespBean1 responseData = new DemoRespBean1();
+        responseData.setCode("2222");
+        responseData.setMessage("msg1");
+        responseData.setMessage2("msg2");
+        response.setData(responseData);
+        response.setCode("1111");
+        response.setMessage("msg");
+        return response;
+    }
+
+    @Override
+    @ApiDoc(value = "Map without generics", responseClassDescription="Map without generics")
+    public Map demoApi6() {
+        return null;
+    }
+
+    @Override
+    @ApiDoc(value = "Map generic with Object", responseClassDescription="Map generic with Object")
+    public Map<Object, Object> demoApi7() {
+        return null;
+    }
+
+    @Override
+    @ApiDoc(value = "List without generics", responseClassDescription="List without generics")
+    public List demoApi10() {
+        return null;
+    }
+
+    @Override
+    @ApiDoc(value = "List generic with Object", responseClassDescription="List generic with Object")
+    public List<Object> demoApi9() {
+        return null;
+    }
+
+    @Override
+    @ApiDoc(value = "Object", responseClassDescription="Object")
+    public Object demoApi8() {
+        return null;
+    }
+
+    @Override
+    @ApiDoc(value = "Simple test", responseClassDescription = "Simple test")
+    public DemoParamBean3 demoApi13(DemoParamBean3 param1, DemoParamBean4 param2) {
+        DemoParamBean3 result = new DemoParamBean3();
+        result.setString("demoApi13 result");
+        return result;
+    }
+}
diff --git a/dubbo-api-docs/dubbo-api-docs-examples/examples-provider-sca/src/main/java/org/apache/dubbo/apidocs/examples/cfg/DubboDocConfig.java b/dubbo-api-docs/dubbo-api-docs-examples/examples-provider-sca/src/main/java/org/apache/dubbo/apidocs/examples/cfg/DubboDocConfig.java
new file mode 100644
index 0000000..d832f7d
--- /dev/null
+++ b/dubbo-api-docs/dubbo-api-docs-examples/examples-provider-sca/src/main/java/org/apache/dubbo/apidocs/examples/cfg/DubboDocConfig.java
@@ -0,0 +1,34 @@
+/*
+ * 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.apidocs.examples.cfg;
+
+import org.apache.dubbo.apidocs.EnableDubboApiDocs;
+
+import org.springframework.context.annotation.Configuration;
+import org.springframework.context.annotation.Profile;
+
+/**
+ * dubbo doc config.
+ * @author klw(213539@qq.com)
+ * 2020/12/4 17:52
+ */
+@Configuration
+// Enable dubbo api doc
+@EnableDubboApiDocs
+@Profile("dev")
+public class DubboDocConfig {
+}
diff --git a/dubbo-api-docs/dubbo-api-docs-examples/pom.xml b/dubbo-api-docs/dubbo-api-docs-examples/pom.xml
index 61862fe..1fe85e5 100644
--- a/dubbo-api-docs/dubbo-api-docs-examples/pom.xml
+++ b/dubbo-api-docs/dubbo-api-docs-examples/pom.xml
@@ -40,6 +40,23 @@
 
     <dependencyManagement>
         <dependencies>
+
+            <dependency>
+                <groupId>org.springframework.cloud</groupId>
+                <artifactId>spring-cloud-dependencies</artifactId>
+                <version>${spring-cloud.version}</version>
+                <type>pom</type>
+                <scope>import</scope>
+            </dependency>
+
+            <dependency>
+                <groupId>com.alibaba.cloud</groupId>
+                <artifactId>spring-cloud-alibaba-dependencies</artifactId>
+                <version>${spring-cloud-alibaba-dependencies.version}</version>
+                <type>pom</type>
+                <scope>import</scope>
+            </dependency>
+
             <!-- Internal libs -->
             <dependency>
                 <groupId>org.apache.dubbo.examples.apidocs</groupId>
diff --git a/dubbo-api-docs/dubbo-api-docs-ui-server/pom.xml b/dubbo-api-docs/dubbo-api-docs-ui-server/pom.xml
index 7698683..32a7230 100644
--- a/dubbo-api-docs/dubbo-api-docs-ui-server/pom.xml
+++ b/dubbo-api-docs/dubbo-api-docs-ui-server/pom.xml
@@ -241,17 +241,6 @@
                 <finalName>dubbo-api-docs-ui-server</finalName>
                 <plugins>
                     <plugin>
-                        <artifactId>maven-jar-plugin</artifactId>
-                        <configuration>
-                            <archive>
-                                <manifest>
-                                    <addDefaultImplementationEntries>true</addDefaultImplementationEntries>
-                                    <addDefaultSpecificationEntries>true</addDefaultSpecificationEntries>
-                                </manifest>
-                            </archive>
-                        </configuration>
-                    </plugin>
-                    <plugin>
                         <groupId>org.springframework.boot</groupId>
                         <artifactId>spring-boot-maven-plugin</artifactId>
                         <configuration>
@@ -270,6 +259,12 @@
                         <groupId>org.apache.maven.plugins</groupId>
                         <artifactId>maven-jar-plugin</artifactId>
                         <configuration>
+                            <archive>
+                                <manifest>
+                                    <addDefaultImplementationEntries>true</addDefaultImplementationEntries>
+                                    <addDefaultSpecificationEntries>true</addDefaultSpecificationEntries>
+                                </manifest>
+                            </archive>
                             <excludes>
                                 <exclude>**/application.yml</exclude>
                                 <exclude>**/log4j2.xml</exclude>
diff --git a/dubbo-api-docs/pom.xml b/dubbo-api-docs/pom.xml
index 706b315..96a5a09 100644
--- a/dubbo-api-docs/pom.xml
+++ b/dubbo-api-docs/pom.xml
@@ -21,6 +21,7 @@
         <groupId>org.apache</groupId>
         <artifactId>apache</artifactId>
         <version>19</version>
+        <relativePath/>
     </parent>
     <groupId>org.apache.dubbo</groupId>
     <artifactId>dubbo-api-docs</artifactId>
@@ -46,6 +47,9 @@
         <disruptor.version>3.4.2</disruptor.version>
         <springfox.version>3.0.0</springfox.version>
         <nacos.version>1.4.0</nacos.version>
+
+        <spring-cloud.version>Hoxton.SR8</spring-cloud.version>
+        <spring-cloud-alibaba-dependencies.version>2.2.3.RELEASE</spring-cloud-alibaba-dependencies.version>
     </properties>
 
     <dependencyManagement>


[dubbo-spi-extensions] 18/39: project.version 改为 revision

Posted by li...@apache.org.
This is an automated email from the ASF dual-hosted git repository.

liujun pushed a commit to branch 2.7.x
in repository https://gitbox.apache.org/repos/asf/dubbo-spi-extensions.git

commit 550dd3f7aa150732b5232b64816d3d7090f7697c
Author: qq213539 <21...@qq.com>
AuthorDate: Fri Nov 27 18:09:50 2020 +0800

    project.version 改为 revision
---
 dubbo-api-docs/pom.xml | 6 +++---
 1 file changed, 3 insertions(+), 3 deletions(-)

diff --git a/dubbo-api-docs/pom.xml b/dubbo-api-docs/pom.xml
index 5c70aa5..706b315 100644
--- a/dubbo-api-docs/pom.xml
+++ b/dubbo-api-docs/pom.xml
@@ -69,17 +69,17 @@
             <dependency>
                 <groupId>org.apache.dubbo</groupId>
                 <artifactId>dubbo-api-docs-annotations</artifactId>
-                <version>${project.version}</version>
+                <version>${revision}</version>
             </dependency>
             <dependency>
                 <groupId>org.apache.dubbo</groupId>
                 <artifactId>dubbo-api-docs-core</artifactId>
-                <version>${project.version}</version>
+                <version>${revision}</version>
             </dependency>
             <dependency>
                 <groupId>org.apache.dubbo</groupId>
                 <artifactId>dubbo-api-docs-ui-server</artifactId>
-                <version>${project.version}</version>
+                <version>${revision}</version>
             </dependency>
 
             <dependency>


[dubbo-spi-extensions] 16/39: 调整UI,增加接口参数展示,缓存结构由Map改为JavaBean,修正某些名称单次拼写错误

Posted by li...@apache.org.
This is an automated email from the ASF dual-hosted git repository.

liujun pushed a commit to branch 2.7.x
in repository https://gitbox.apache.org/repos/asf/dubbo-spi-extensions.git

commit 12500ac17b39f304b33e73be5adf87d508ec0b42
Author: qq213539 <21...@qq.com>
AuthorDate: Fri Nov 20 17:28:51 2020 +0800

    调整UI,增加接口参数展示,缓存结构由Map改为JavaBean,修正某些名称单次拼写错误
---
 .../core/DubboApiDocsAnnotationScanner.java        | 131 +++++++++++----------
 .../dubbo/apidocs/core/DubboApiDocsCache.java      |  31 ++---
 .../dubbo/apidocs/core/beans/ApiCacheItem.java     |  39 ++++++
 .../apidocs/core/beans/ApiParamsCacheItem.java     |  40 +++++++
 .../dubbo/apidocs/core/beans/ModuleCacheItem.java  |  26 ++++
 .../apache/dubbo/apidocs/core/beans/ParamBean.java |   2 +-
 .../core/providers/DubboDocProviderImpl.java       |   4 +-
 .../apidocs/core/providers/IDubboDocProvider.java  |   5 +-
 .../dubbo/apidocs/examples/api/ISyncDemo.java      |  10 +-
 .../apidocs/examples/api/impl/SyncDemoImpl.java    |   4 +-
 .../apidocs/controller/DubboApiDocsController.java |  70 +++++------
 ... => CallDubboServiceRequestInterfaceParam.java} |   6 +-
 .../dubbo/apidocs/utils/DubboGenericUtil.java      |  22 ++--
 .../src/main/resources/static/js/index.js          |   2 +-
 .../src/layouts/BasicLayout/index.tsx              |   6 +-
 .../dubbo-api-docs-ui/src/locales/en-US.json       |  11 +-
 .../dubbo-api-docs-ui/src/locales/zh-CN.json       |  11 +-
 .../dubbo-api-docs-ui/src/pages/ApiForm/index.tsx  | 103 ++++++++--------
 18 files changed, 318 insertions(+), 205 deletions(-)

diff --git a/dubbo-api-docs/dubbo-api-docs-core/src/main/java/org/apache/dubbo/apidocs/core/DubboApiDocsAnnotationScanner.java b/dubbo-api-docs/dubbo-api-docs-core/src/main/java/org/apache/dubbo/apidocs/core/DubboApiDocsAnnotationScanner.java
index a089805..94c2e88 100644
--- a/dubbo-api-docs/dubbo-api-docs-core/src/main/java/org/apache/dubbo/apidocs/core/DubboApiDocsAnnotationScanner.java
+++ b/dubbo-api-docs/dubbo-api-docs-core/src/main/java/org/apache/dubbo/apidocs/core/DubboApiDocsAnnotationScanner.java
@@ -16,6 +16,9 @@
  */
 package org.apache.dubbo.apidocs.core;
 
+import org.apache.dubbo.apidocs.core.beans.ApiCacheItem;
+import org.apache.dubbo.apidocs.core.beans.ApiParamsCacheItem;
+import org.apache.dubbo.apidocs.core.beans.ModuleCacheItem;
 import org.apache.dubbo.apidocs.core.beans.HtmlTypeEnum;
 import org.apache.dubbo.apidocs.core.beans.ParamBean;
 import org.apache.dubbo.apidocs.core.providers.DubboDocProviderImpl;
@@ -44,7 +47,6 @@ import java.lang.reflect.InvocationTargetException;
 import java.lang.reflect.Method;
 import java.lang.reflect.Parameter;
 import java.util.ArrayList;
-import java.util.HashMap;
 import java.util.List;
 import java.util.Map;
 
@@ -101,19 +103,19 @@ public class DubboApiDocsAnnotationScanner implements ApplicationListener<Applic
                 DubboService dubboService = apiModuleClass.getAnnotation(DubboService.class);
                 async = dubboService.async();
             }
-            Map<String, Object> moduleCacheItem = new HashMap<>(4);
+            ModuleCacheItem moduleCacheItem = new ModuleCacheItem();
             DubboApiDocsCache.addApiModule(moduleAnn.apiInterface().getCanonicalName(), moduleCacheItem);
             //module name
-            moduleCacheItem.put("moduleChName", moduleAnn.value());
+            moduleCacheItem.setModuleDocName(moduleAnn.value());
             //interface name containing package path
-            moduleCacheItem.put("moduleClassName", moduleAnn.apiInterface().getCanonicalName());
+            moduleCacheItem.setModuleClassName(moduleAnn.apiInterface().getCanonicalName());
             //module version
-            moduleCacheItem.put("moduleVersion", moduleAnn.version());
+            moduleCacheItem.setModuleVersion(moduleAnn.version());
 
             Method[] apiModuleMethods = apiModuleClass.getMethods();
             // API basic information list in module cache
-            List<Map<String, Object>> moduleApiList = new ArrayList<>(apiModuleMethods.length);
-            moduleCacheItem.put("moduleApiList", moduleApiList);
+            List<ApiCacheItem> moduleApiList = new ArrayList<>(apiModuleMethods.length);
+            moduleCacheItem.setModuleApiList(moduleApiList);
             for (Method method : apiModuleMethods) {
                 if (method.isAnnotationPresent(ApiDoc.class)) {
                     processApiDocAnnotation(method, moduleApiList, moduleAnn, async, moduleCacheItem);
@@ -123,48 +125,53 @@ public class DubboApiDocsAnnotationScanner implements ApplicationListener<Applic
         log.info("================= Dubbo API Docs-- doc annotations scanning and processing completed ================");
     }
 
-    private void processApiDocAnnotation(Method method, List<Map<String, Object>> moduleApiList, ApiModule moduleAnn,
-                                         boolean async, Map<String, Object> moduleCacheItem) {
+    private void processApiDocAnnotation(Method method, List<ApiCacheItem> moduleApiList, ApiModule moduleAnn,
+                                         boolean async, ModuleCacheItem moduleCacheItem) {
         ApiDoc dubboApi = method.getAnnotation(ApiDoc.class);
 
         // API basic information in API list in module
-        Map<String, Object> apiListItem = new HashMap<>(4);
+        ApiCacheItem apiListItem = new ApiCacheItem();
         moduleApiList.add(apiListItem);
         //API method name
-        apiListItem.put("apiName", method.getName());
+        apiListItem.setApiName(method.getName());
         //API name
-        apiListItem.put("apiChName", dubboApi.value());
+        apiListItem.setApiDocName(dubboApi.value());
         // API description
-        apiListItem.put("description", dubboApi.description());
+        apiListItem.setDescription(dubboApi.description());
         //API version
-        apiListItem.put("apiVersion", dubboApi.version());
+        apiListItem.setApiVersion(dubboApi.version());
         //Description of API return data
-        apiListItem.put("apiRespDec", dubboApi.responseClassDescription());
+        apiListItem.setApiRespDec(dubboApi.responseClassDescription());
 
         // Interface parameters and response information
-        Map<String, Object> apiParamsAndResp = new HashMap<>(2);
+        ApiCacheItem apiParamsAndResp = new ApiCacheItem();
         DubboApiDocsCache.addApiParamsAndResp(
                 moduleAnn.apiInterface().getCanonicalName() + "." + method.getName(), apiParamsAndResp);
 
         Class<?>[] argsClass = method.getParameterTypes();
         Annotation[][] argsAnns = method.getParameterAnnotations();
         Parameter[] parameters = method.getParameters();
-        List<Map<String, Object>> paramList = new ArrayList<>(argsClass.length);
-        apiParamsAndResp.put("async", async);
-        apiParamsAndResp.put("apiName", method.getName());
-        apiParamsAndResp.put("apiChName", dubboApi.value());
-        apiParamsAndResp.put("apiVersion", dubboApi.version());
-        apiParamsAndResp.put("apiRespDec", dubboApi.responseClassDescription());
-        apiParamsAndResp.put("apiModelClass", moduleCacheItem.get("moduleClassName"));
-        apiParamsAndResp.put("params", paramList);
-        apiParamsAndResp.put("response", ClassTypeUtil.calss2Json(method.getGenericReturnType(), method.getReturnType()));
+        List<ApiParamsCacheItem> paramList = new ArrayList<>(argsClass.length);
+        apiParamsAndResp.setAsync(async);
+        apiParamsAndResp.setApiName(method.getName());
+        apiParamsAndResp.setApiDocName(dubboApi.value());
+        apiParamsAndResp.setApiVersion(dubboApi.version());
+        apiParamsAndResp.setApiRespDec(dubboApi.responseClassDescription());
+        apiParamsAndResp.setApiModelClass(moduleCacheItem.getModuleClassName());
+        apiParamsAndResp.setParams(paramList);
+        apiParamsAndResp.setResponse(ClassTypeUtil.calss2Json(method.getGenericReturnType(), method.getReturnType()));
+        StringBuilder methodParamInfoSb = new StringBuilder();
         for (int i = 0; i < argsClass.length; i++) {
             Class<?> argClass = argsClass[i];
+            methodParamInfoSb.append("[").append(i).append("]").append(argClass.getCanonicalName());
+            if (i + 1 < argsClass.length) {
+                methodParamInfoSb.append(" | ");
+            }
             Annotation[] argAnns = argsAnns[i];
-            Map<String, Object> prarmListItem = new HashMap<>(2);
-            paramList.add(prarmListItem);
-            prarmListItem.put("prarmType", argClass.getCanonicalName());
-            prarmListItem.put("prarmIndex", i);
+            ApiParamsCacheItem paramListItem = new ApiParamsCacheItem();
+            paramList.add(paramListItem);
+            paramListItem.setParamType(argClass.getCanonicalName());
+            paramListItem.setParamIndex(i);
             RequestParam requestParam = null;
             // Handling @RequestParam annotations on parameters
             for (Annotation ann : argAnns) {
@@ -177,27 +184,27 @@ public class DubboApiDocsAnnotationScanner implements ApplicationListener<Applic
                 // Not a basic type, handling properties in method parameters
                 List<ParamBean> apiParamsList = processField(argClass);
                 if (apiParamsList != null && !apiParamsList.isEmpty()) {
-                    prarmListItem.put("prarmInfo", apiParamsList);
+                    paramListItem.setParamInfo(apiParamsList);
                 }
             } else {
                 // Is the basic type
                 Parameter methodParameter = parameters[i];
-                prarmListItem.put("name", methodParameter.getName());
-                prarmListItem.put("htmlType", paramBean.getHtmlType().name());
-                prarmListItem.put("allowableValues", paramBean.getAllowableValues());
+                paramListItem.setName(methodParameter.getName());
+                paramListItem.setHtmlType(paramBean.getHtmlType().name());
+                paramListItem.setAllowableValues(paramBean.getAllowableValues());
                 if (requestParam != null) {
-
                     // Handling requestparam annotations on parameters
-                    prarmListItem.put("nameCh", requestParam.value());
-                    prarmListItem.put("description", requestParam.description());
-                    prarmListItem.put("example", requestParam.example());
-                    prarmListItem.put("defaultValue", requestParam.defaultValue());
-                    prarmListItem.put("required", requestParam.required());
+                    paramListItem.setDocName(requestParam.value());
+                    paramListItem.setDescription(requestParam.description());
+                    paramListItem.setExample(requestParam.example());
+                    paramListItem.setDefaultValue(requestParam.defaultValue());
+                    paramListItem.setRequired(requestParam.required());
                 } else {
-                    prarmListItem.put("required", false);
+                    paramListItem.setRequired(false);
                 }
             }
         }
+        apiParamsAndResp.setMethodParamInfo(methodParamInfoSb.toString());
     }
 
     /**
@@ -217,7 +224,7 @@ public class DubboApiDocsAnnotationScanner implements ApplicationListener<Applic
             if (field.isAnnotationPresent(RequestParam.class)) {
                 // Handling @RequestParam annotations on properties
                 requestParam = field.getAnnotation(RequestParam.class);
-                paramBean.setNameCh(requestParam.value());
+                paramBean.setDocName(requestParam.value());
                 paramBean.setRequired(requestParam.required());
                 paramBean.setDescription(requestParam.description());
                 paramBean.setExample(requestParam.example());
@@ -246,63 +253,63 @@ public class DubboApiDocsAnnotationScanner implements ApplicationListener<Applic
      *
      * @param classType  classType
      * @param annotation annotation
-     * @param prarm      prarm
+     * @param param      param
      * @return org.apache.dubbo.apidocs.core.beans.ParamBean
      */
-    private ParamBean processHtmlType(Class<?> classType, RequestParam annotation, ParamBean prarm) {
-        if (prarm == null) {
-            prarm = new ParamBean();
+    private ParamBean processHtmlType(Class<?> classType, RequestParam annotation, ParamBean param) {
+        if (param == null) {
+            param = new ParamBean();
         }
         if (annotation != null) {
-            prarm.setAllowableValues(annotation.allowableValues());
+            param.setAllowableValues(annotation.allowableValues());
         }
         // Is there any allowed values
-        boolean hasAllowableValues = (prarm.getAllowableValues() != null && prarm.getAllowableValues().length > 0);
+        boolean hasAllowableValues = (param.getAllowableValues() != null && param.getAllowableValues().length > 0);
         // Processed or not
         boolean processed = false;
         if (Integer.class.isAssignableFrom(classType)) {
-            prarm.setHtmlType(HtmlTypeEnum.NUMBER_INTEGER);
+            param.setHtmlType(HtmlTypeEnum.NUMBER_INTEGER);
             processed = true;
         } else if (Byte.class.isAssignableFrom(classType)) {
-            prarm.setHtmlType(HtmlTypeEnum.TEXT_BYTE);
+            param.setHtmlType(HtmlTypeEnum.TEXT_BYTE);
             processed = true;
         } else if (Long.class.isAssignableFrom(classType)) {
-            prarm.setHtmlType(HtmlTypeEnum.NUMBER_INTEGER);
+            param.setHtmlType(HtmlTypeEnum.NUMBER_INTEGER);
             processed = true;
         } else if (Double.class.isAssignableFrom(classType)) {
-            prarm.setHtmlType(HtmlTypeEnum.NUMBER_DECIMAL);
+            param.setHtmlType(HtmlTypeEnum.NUMBER_DECIMAL);
             processed = true;
         } else if (Float.class.isAssignableFrom(classType)) {
-            prarm.setHtmlType(HtmlTypeEnum.NUMBER_DECIMAL);
+            param.setHtmlType(HtmlTypeEnum.NUMBER_DECIMAL);
             processed = true;
         } else if (String.class.isAssignableFrom(classType)) {
-            prarm.setHtmlType(HtmlTypeEnum.TEXT);
+            param.setHtmlType(HtmlTypeEnum.TEXT);
             processed = true;
         } else if (Character.class.isAssignableFrom(classType)) {
-            prarm.setHtmlType(HtmlTypeEnum.TEXT_CHAR);
+            param.setHtmlType(HtmlTypeEnum.TEXT_CHAR);
             processed = true;
         } else if (Short.class.isAssignableFrom(classType)) {
-            prarm.setHtmlType(HtmlTypeEnum.NUMBER_INTEGER);
+            param.setHtmlType(HtmlTypeEnum.NUMBER_INTEGER);
             processed = true;
         }
         if (processed) {
             // Processed, time to return
             if (hasAllowableValues) {
                 // Allowed values has value, change to select
-                prarm.setHtmlType(HtmlTypeEnum.SELECT);
+                param.setHtmlType(HtmlTypeEnum.SELECT);
             }
-            return prarm;
+            return param;
         }
 
         // haven't dealt with it. Go on
         if (Boolean.class.isAssignableFrom(classType)) {
-            prarm.setHtmlType(HtmlTypeEnum.SELECT);
+            param.setHtmlType(HtmlTypeEnum.SELECT);
             // Boolean can only be true / false. No matter what the previous allowed value is, it is forced to replace
-            prarm.setAllowableValues(new String[]{"true", "false"});
+            param.setAllowableValues(new String[]{"true", "false"});
             processed = true;
         } else if (Enum.class.isAssignableFrom(classType)) {
             // process enum
-            prarm.setHtmlType(HtmlTypeEnum.SELECT);
+            param.setHtmlType(HtmlTypeEnum.SELECT);
             if (!hasAllowableValues) {
                 // If there is no optional value, it is taken from the enumeration.
                 //TODO If there is an optional value, it is necessary
@@ -318,12 +325,12 @@ public class DubboApiDocsAnnotationScanner implements ApplicationListener<Applic
                 } catch (NoSuchMethodException | IllegalAccessException | InvocationTargetException e) {
                     log.error("", e);
                 }
-                prarm.setAllowableValues(enumAllowableValues);
+                param.setAllowableValues(enumAllowableValues);
             }
             processed = true;
         }
         if (processed) {
-            return prarm;
+            return param;
         }
         return null;
     }
diff --git a/dubbo-api-docs/dubbo-api-docs-core/src/main/java/org/apache/dubbo/apidocs/core/DubboApiDocsCache.java b/dubbo-api-docs/dubbo-api-docs-core/src/main/java/org/apache/dubbo/apidocs/core/DubboApiDocsCache.java
index 5f028ed..36304f2 100644
--- a/dubbo-api-docs/dubbo-api-docs-core/src/main/java/org/apache/dubbo/apidocs/core/DubboApiDocsCache.java
+++ b/dubbo-api-docs/dubbo-api-docs-core/src/main/java/org/apache/dubbo/apidocs/core/DubboApiDocsCache.java
@@ -16,6 +16,8 @@
  */
 package org.apache.dubbo.apidocs.core;
 
+import org.apache.dubbo.apidocs.core.beans.ApiCacheItem;
+import org.apache.dubbo.apidocs.core.beans.ModuleCacheItem;
 import org.apache.dubbo.apidocs.utils.ClassTypeUtil;
 
 import com.alibaba.fastjson.JSON;
@@ -36,7 +38,7 @@ public class DubboApiDocsCache {
     /**
      * module cache.
      */
-    private static Map<String, Map<String, Object>> apiModulesCache = new ConcurrentHashMap<>(16);
+    private static Map<String, ModuleCacheItem> apiModulesCache = new ConcurrentHashMap<>(16);
     /**
      * module cache.
      */
@@ -45,32 +47,32 @@ public class DubboApiDocsCache {
     /**
      * API details cache in module.
      */
-    private static Map<String, Map<String, Object>> apiParamsAndRespCache = new ConcurrentHashMap<>(16);
+    private static Map<String, ApiCacheItem> apiParamsAndRespCache = new ConcurrentHashMap<>(16);
     /**
      * API details cache in module.
      */
     private static Map<String, String> apiParamsAndRespStrCache = new ConcurrentHashMap<>(16);
 
-    private static List<Map<String, Object>> allApiModuleInfo = null;
+    private static List<ModuleCacheItem> allApiModuleInfo = null;
 
     private static String basicApiModuleInfo = null;
 
-    public static void addApiModule(String key, Map<String, Object> moduleCacheItem) {
+    public static void addApiModule(String key, ModuleCacheItem moduleCacheItem) {
         apiModulesCache.put(key, moduleCacheItem);
     }
 
-    public static void addApiParamsAndResp(String key, Map<String, Object> apiParamsAndResp) {
+    public static void addApiParamsAndResp(String key, ApiCacheItem apiParamsAndResp) {
         apiParamsAndRespCache.put(key, apiParamsAndResp);
     }
 
-    public static Map<String, Object> getApiModule(String key) {
+    public static ModuleCacheItem getApiModule(String key) {
         return apiModulesCache.get(key);
     }
 
     public static String getApiModuleStr(String key) {
         String result = apiModulesStrCache.get(key);
         if (result == null) {
-            Map<String, Object> temp = apiModulesCache.get(key);
+            ModuleCacheItem temp = apiModulesCache.get(key);
             if (temp != null) {
                 result = JSON.toJSONString(temp, ClassTypeUtil.FAST_JSON_FEATURES);
                 apiModulesStrCache.put(key, result);
@@ -79,14 +81,14 @@ public class DubboApiDocsCache {
         return result;
     }
 
-    public static Map<String, Object> getApiParamsAndResp(String key) {
+    public static ApiCacheItem getApiParamsAndResp(String key) {
         return apiParamsAndRespCache.get(key);
     }
 
     public static String getApiParamsAndRespStr(String key) {
         String result = apiParamsAndRespStrCache.get(key);
         if (result == null) {
-            Map<String, Object> temp = apiParamsAndRespCache.get(key);
+            ApiCacheItem temp = apiParamsAndRespCache.get(key);
             if (temp != null) {
                 result = JSON.toJSONString(temp, ClassTypeUtil.FAST_JSON_FEATURES);
                 apiParamsAndRespStrCache.put(key, result);
@@ -97,7 +99,7 @@ public class DubboApiDocsCache {
 
     public static String getBasicApiModuleInfo() {
         if (basicApiModuleInfo == null) {
-            List<Map<String, Object>> tempList = new ArrayList<>(apiModulesCache.size());
+            List<ModuleCacheItem> tempList = new ArrayList<>(apiModulesCache.size());
             apiModulesCache.forEach((k, v) -> {
                 tempList.add(v);
             });
@@ -106,17 +108,10 @@ public class DubboApiDocsCache {
         return basicApiModuleInfo;
     }
 
-    public static List<Map<String, Object>> getAllApiModuleInfo() {
+    public static List<ModuleCacheItem> getAllApiModuleInfo() {
         if (allApiModuleInfo == null) {
             allApiModuleInfo = new ArrayList<>(apiModulesCache.size());
             apiModulesCache.forEach((k, v) -> {
-                List<Map<String, Object>> apiList = (List<Map<String, Object>>) v.get("moduleApiList");
-                if ( null != apiList && !apiList.isEmpty()) {
-                    for (Map<String, Object> apiInfo : apiList) {
-                        Map<String, Object> apiParams = getApiParamsAndResp(v.get("moduleClassName") + "." + apiInfo.get("apiName"));
-                        apiInfo.putAll(apiParams);
-                    }
-                }
                 allApiModuleInfo.add(v);
             });
         }
diff --git a/dubbo-api-docs/dubbo-api-docs-core/src/main/java/org/apache/dubbo/apidocs/core/beans/ApiCacheItem.java b/dubbo-api-docs/dubbo-api-docs-core/src/main/java/org/apache/dubbo/apidocs/core/beans/ApiCacheItem.java
new file mode 100644
index 0000000..4732cef
--- /dev/null
+++ b/dubbo-api-docs/dubbo-api-docs-core/src/main/java/org/apache/dubbo/apidocs/core/beans/ApiCacheItem.java
@@ -0,0 +1,39 @@
+package org.apache.dubbo.apidocs.core.beans;
+
+import lombok.Getter;
+import lombok.Setter;
+
+import java.util.List;
+import java.util.Map;
+
+/**
+ * api cache item.
+ *
+ * @author klw(213539 @ qq.com)
+ * @date 2020/11/20 16:22
+ */
+@Getter
+@Setter
+public class ApiCacheItem {
+
+    private Boolean async;
+
+    private String apiName;
+
+    private String apiDocName;
+
+    private String apiVersion;
+
+    private String description;
+
+    private String apiRespDec;
+
+    private String apiModelClass;
+
+    private List<ApiParamsCacheItem> params;
+
+    private String response;
+
+    private String methodParamInfo;
+
+}
diff --git a/dubbo-api-docs/dubbo-api-docs-core/src/main/java/org/apache/dubbo/apidocs/core/beans/ApiParamsCacheItem.java b/dubbo-api-docs/dubbo-api-docs-core/src/main/java/org/apache/dubbo/apidocs/core/beans/ApiParamsCacheItem.java
new file mode 100644
index 0000000..89880fe
--- /dev/null
+++ b/dubbo-api-docs/dubbo-api-docs-core/src/main/java/org/apache/dubbo/apidocs/core/beans/ApiParamsCacheItem.java
@@ -0,0 +1,40 @@
+package org.apache.dubbo.apidocs.core.beans;
+
+import lombok.Getter;
+import lombok.Setter;
+
+import java.util.List;
+
+/**
+ * api params cache item.
+ *
+ * @author klw(213539 @ qq.com)
+ * @date 2020/11/20 16:46
+ */
+@Getter
+@Setter
+public class ApiParamsCacheItem {
+
+    private String name;
+
+    private String docName;
+
+    private String htmlType;
+
+    private String[] allowableValues;
+
+    private String paramType;
+
+    private Integer paramIndex;
+
+    private List<ParamBean> paramInfo;
+
+    private String description;
+
+    private String example;
+
+    private String defaultValue;
+
+    private Boolean required;
+
+}
diff --git a/dubbo-api-docs/dubbo-api-docs-core/src/main/java/org/apache/dubbo/apidocs/core/beans/ModuleCacheItem.java b/dubbo-api-docs/dubbo-api-docs-core/src/main/java/org/apache/dubbo/apidocs/core/beans/ModuleCacheItem.java
new file mode 100644
index 0000000..cdf8b61
--- /dev/null
+++ b/dubbo-api-docs/dubbo-api-docs-core/src/main/java/org/apache/dubbo/apidocs/core/beans/ModuleCacheItem.java
@@ -0,0 +1,26 @@
+package org.apache.dubbo.apidocs.core.beans;
+
+import lombok.Getter;
+import lombok.Setter;
+
+import java.util.List;
+
+/**
+ * api module cache item.
+ *
+ * @author klw(213539 @ qq.com)
+ * @date 2020/11/20 15:21
+ */
+@Getter
+@Setter
+public class ModuleCacheItem {
+
+    private String moduleDocName;
+
+    private String moduleClassName;
+
+    private String moduleVersion;
+
+    private List<ApiCacheItem> moduleApiList;
+
+}
diff --git a/dubbo-api-docs/dubbo-api-docs-core/src/main/java/org/apache/dubbo/apidocs/core/beans/ParamBean.java b/dubbo-api-docs/dubbo-api-docs-core/src/main/java/org/apache/dubbo/apidocs/core/beans/ParamBean.java
index abac9a8..02206ec 100644
--- a/dubbo-api-docs/dubbo-api-docs-core/src/main/java/org/apache/dubbo/apidocs/core/beans/ParamBean.java
+++ b/dubbo-api-docs/dubbo-api-docs-core/src/main/java/org/apache/dubbo/apidocs/core/beans/ParamBean.java
@@ -39,7 +39,7 @@ public class ParamBean {
     /**
      * parameter name, for display.
      */
-    private String nameCh;
+    private String docName;
 
     /**
      * required.
diff --git a/dubbo-api-docs/dubbo-api-docs-core/src/main/java/org/apache/dubbo/apidocs/core/providers/DubboDocProviderImpl.java b/dubbo-api-docs/dubbo-api-docs-core/src/main/java/org/apache/dubbo/apidocs/core/providers/DubboDocProviderImpl.java
index 5179765..92b24ca 100644
--- a/dubbo-api-docs/dubbo-api-docs-core/src/main/java/org/apache/dubbo/apidocs/core/providers/DubboDocProviderImpl.java
+++ b/dubbo-api-docs/dubbo-api-docs-core/src/main/java/org/apache/dubbo/apidocs/core/providers/DubboDocProviderImpl.java
@@ -17,12 +17,12 @@
 package org.apache.dubbo.apidocs.core.providers;
 
 import org.apache.dubbo.apidocs.core.DubboApiDocsCache;
+import org.apache.dubbo.apidocs.core.beans.ModuleCacheItem;
 import org.apache.dubbo.config.annotation.DubboService;
 
 import lombok.extern.slf4j.Slf4j;
 
 import java.util.List;
-import java.util.Map;
 
 /**
  * The api implementation of Dubbo doc.
@@ -39,7 +39,7 @@ public class DubboDocProviderImpl implements IDubboDocProvider {
     }
 
     @Override
-    public List<Map<String, Object>> apiModuleListAndApiInfo() {
+    public List<ModuleCacheItem> apiModuleListAndApiInfo() {
         return DubboApiDocsCache.getAllApiModuleInfo();
     }
 
diff --git a/dubbo-api-docs/dubbo-api-docs-core/src/main/java/org/apache/dubbo/apidocs/core/providers/IDubboDocProvider.java b/dubbo-api-docs/dubbo-api-docs-core/src/main/java/org/apache/dubbo/apidocs/core/providers/IDubboDocProvider.java
index 1e7af23..92bb416 100644
--- a/dubbo-api-docs/dubbo-api-docs-core/src/main/java/org/apache/dubbo/apidocs/core/providers/IDubboDocProvider.java
+++ b/dubbo-api-docs/dubbo-api-docs-core/src/main/java/org/apache/dubbo/apidocs/core/providers/IDubboDocProvider.java
@@ -16,8 +16,9 @@
  */
 package org.apache.dubbo.apidocs.core.providers;
 
+import org.apache.dubbo.apidocs.core.beans.ModuleCacheItem;
+
 import java.util.List;
-import java.util.Map;
 
 /**
  * The api used by Dubbo doc, get the parsed API information.
@@ -40,7 +41,7 @@ public interface IDubboDocProvider {
      * @param
      * @return java.lang.String
      */
-    List<Map<String, Object>> apiModuleListAndApiInfo();
+    List<ModuleCacheItem> apiModuleListAndApiInfo();
 
     /**
      * Get module information according to the complete class name of Dubbo provider interface.
diff --git a/dubbo-api-docs/dubbo-api-docs-examples/examples-api/src/main/java/org/apache/dubbo/apidocs/examples/api/ISyncDemo.java b/dubbo-api-docs/dubbo-api-docs-examples/examples-api/src/main/java/org/apache/dubbo/apidocs/examples/api/ISyncDemo.java
index 59064a0..9cf5255 100644
--- a/dubbo-api-docs/dubbo-api-docs-examples/examples-api/src/main/java/org/apache/dubbo/apidocs/examples/api/ISyncDemo.java
+++ b/dubbo-api-docs/dubbo-api-docs-examples/examples-api/src/main/java/org/apache/dubbo/apidocs/examples/api/ISyncDemo.java
@@ -45,19 +45,19 @@ public interface ISyncDemo {
     /**
      * request and response parameters are Strings
      * @Date 2020/2/4 0:02
-     * @param: prarm1
-     * @param: prarm2
+     * @param: param1
+     * @param: param2
      * @return java.lang.String
      */
-    String demoApi2(String prarm1, String prarm2);
+    String demoApi2(String param1, String param2);
 
     /**
      * Without Dubbo doc annotation, no document will be generated
      * @Date 2020/2/4 0:22
-     * @param: prarm1
+     * @param: param1
      * @return java.lang.String
      */
-    String demoApi3(String prarm1);
+    String demoApi3(String param1);
 
     /**
      * Nonparametric method with Dubbo doc annotation
diff --git a/dubbo-api-docs/dubbo-api-docs-examples/examples-provider/src/main/java/org/apache/dubbo/apidocs/examples/api/impl/SyncDemoImpl.java b/dubbo-api-docs/dubbo-api-docs-examples/examples-provider/src/main/java/org/apache/dubbo/apidocs/examples/api/impl/SyncDemoImpl.java
index 07f13b5..fd21ef4 100644
--- a/dubbo-api-docs/dubbo-api-docs-examples/examples-provider/src/main/java/org/apache/dubbo/apidocs/examples/api/impl/SyncDemoImpl.java
+++ b/dubbo-api-docs/dubbo-api-docs-examples/examples-provider/src/main/java/org/apache/dubbo/apidocs/examples/api/impl/SyncDemoImpl.java
@@ -56,13 +56,13 @@ public class SyncDemoImpl implements ISyncDemo {
 
     @ApiDoc(value = "request and response parameters are Strings", responseClassDescription="A string")
     @Override
-    public String demoApi2(@RequestParam(value = "Parameter 1", required = true) String prarm1, String prarm2) {
+    public String demoApi2(@RequestParam(value = "Parameter 1", required = true) String param1, String param2) {
         log.info(" called demoApi2");
         return "demoApi2";
     }
 
     @Override
-    public String demoApi3(String prarm1) {
+    public String demoApi3(String param1) {
         return null;
     }
 
diff --git a/dubbo-api-docs/dubbo-api-docs-ui-server/src/main/java/org/apache/dubbo/apidocs/controller/DubboApiDocsController.java b/dubbo-api-docs/dubbo-api-docs-ui-server/src/main/java/org/apache/dubbo/apidocs/controller/DubboApiDocsController.java
index a4f5da1..0e84797 100644
--- a/dubbo-api-docs/dubbo-api-docs-ui-server/src/main/java/org/apache/dubbo/apidocs/controller/DubboApiDocsController.java
+++ b/dubbo-api-docs/dubbo-api-docs-ui-server/src/main/java/org/apache/dubbo/apidocs/controller/DubboApiDocsController.java
@@ -18,7 +18,7 @@ package org.apache.dubbo.apidocs.controller;
 
 import org.apache.dubbo.apidocs.controller.vo.ApiInfoRequest;
 import org.apache.dubbo.apidocs.controller.vo.CallDubboServiceRequest;
-import org.apache.dubbo.apidocs.controller.vo.CallDubboServiceRequestInterfacePrarm;
+import org.apache.dubbo.apidocs.controller.vo.CallDubboServiceRequestInterfaceParam;
 import org.apache.dubbo.apidocs.editor.CustomDateEditor;
 import org.apache.dubbo.apidocs.editor.CustomLocalDateEditor;
 import org.apache.dubbo.apidocs.editor.CustomLocalDateTimeEditor;
@@ -91,49 +91,49 @@ public class DubboApiDocsController {
 
     @ApiOperation(value = "request dubbo api", notes = "request dubbo api", httpMethod = "POST", produces = "application/json")
     @PostMapping("/requestDubbo")
-    public Mono<String> callDubboService(CallDubboServiceRequest dubboCfg, @RequestBody List<CallDubboServiceRequestInterfacePrarm> methodPrarms){
-        String[] prarmTypes = null;
-        Object[] prarmValues = null;
-        if(CollectionUtils.isNotEmpty(methodPrarms)){
-            prarmTypes = new String[methodPrarms.size()];
-            prarmValues = new Object[methodPrarms.size()];
-            for(int i = 0; i < methodPrarms.size(); i++){
-                CallDubboServiceRequestInterfacePrarm prarm = methodPrarms.get(i);
-                prarmTypes[i] = prarm.getPrarmType();
-                Object prarmValue = prarm.getPrarmValue();
-                if(isBaseType(prarm.getPrarmType()) && null != prarmValue){
-                    if(prarmValue instanceof Map){
-                        Map<?, ?> tempMap = (Map<?, ?>) prarmValue;
+    public Mono<String> callDubboService(CallDubboServiceRequest dubboCfg, @RequestBody List<CallDubboServiceRequestInterfaceParam> methodParams){
+        String[] paramTypes = null;
+        Object[] paramValues = null;
+        if(CollectionUtils.isNotEmpty(methodParams)){
+            paramTypes = new String[methodParams.size()];
+            paramValues = new Object[methodParams.size()];
+            for(int i = 0; i < methodParams.size(); i++){
+                CallDubboServiceRequestInterfaceParam param = methodParams.get(i);
+                paramTypes[i] = param.getParamType();
+                Object paramValue = param.getParamValue();
+                if(isBaseType(param.getParamType()) && null != paramValue){
+                    if(paramValue instanceof Map){
+                        Map<?, ?> tempMap = (Map<?, ?>) paramValue;
                         if(!tempMap.isEmpty()) {
                             this.emptyString2Null(tempMap);
-                            prarmValues[i] = tempMap.values().stream().findFirst().orElse(null);
+                            paramValues[i] = tempMap.values().stream().findFirst().orElse(null);
                         }
                     } else {
-                        prarmValues[i] = emptyString2Null(prarmValue);
+                        paramValues[i] = emptyString2Null(paramValue);
                     }
                 } else {
-                    this.emptyString2Null(prarmValue);
-                    prarmValues[i] = prarmValue;
+                    this.emptyString2Null(paramValue);
+                    paramValues[i] = paramValue;
                 }
             }
         }
-        if (null == prarmTypes) {
-            prarmTypes = new String[0];
+        if (null == paramTypes) {
+            paramTypes = new String[0];
         }
-        if (null == prarmValues) {
-            prarmValues = new Object[0];
+        if (null == paramValues) {
+            paramValues = new Object[0];
         }
         CompletableFuture<Object> future = DubboGenericUtil.invoke(dubboCfg.getRegistryCenterUrl(), dubboCfg.getInterfaceClassName(),
-                dubboCfg.getMethodName(), dubboCfg.isAsync(), prarmTypes, prarmValues);
+                dubboCfg.getMethodName(), dubboCfg.isAsync(), paramTypes, paramValues);
         return Mono.fromFuture(future).map( o -> JSON.toJSONString(o, CLASS_NAME_PRE_FILTER));
     }
 
-    private Object emptyString2Null(Object prarmValue){
-        if(null != prarmValue) {
-            if (prarmValue instanceof String && StringUtils.isBlank((String) prarmValue)) {
+    private Object emptyString2Null(Object paramValue){
+        if(null != paramValue) {
+            if (paramValue instanceof String && StringUtils.isBlank((String) paramValue)) {
                 return null;
-            } else if (prarmValue instanceof Map) {
-                Map<String, Object> tempMap = (Map<String, Object>) prarmValue;
+            } else if (paramValue instanceof Map) {
+                Map<String, Object> tempMap = (Map<String, Object>) paramValue;
                 tempMap.forEach((k, v) -> {
                     if (v != null && v instanceof String && StringUtils.isBlank((String) v)) {
                         tempMap.put(k, null);
@@ -143,7 +143,7 @@ public class DubboApiDocsController {
                 });
             }
         }
-        return prarmValue;
+        return paramValue;
     }
 
     @ApiOperation(value = "Get basic information of all modules, excluding API parameter information", notes = "Get basic information of all modules, excluding API parameter information", httpMethod = "GET", produces = "application/json")
@@ -166,12 +166,12 @@ public class DubboApiDocsController {
         req.setMethodName("apiParamsResponseInfo");
         req.setAsync(false);
 
-        List<CallDubboServiceRequestInterfacePrarm> methodPrarms = new ArrayList<>(1);
-        CallDubboServiceRequestInterfacePrarm prarm = new CallDubboServiceRequestInterfacePrarm();
-        prarm.setPrarmType(String.class.getName());
-        prarm.setPrarmValue(apiInfoRequest.getApiName());
-        methodPrarms.add(prarm);
-        return callDubboService(req, methodPrarms);
+        List<CallDubboServiceRequestInterfaceParam> methodParams = new ArrayList<>(1);
+        CallDubboServiceRequestInterfaceParam param = new CallDubboServiceRequestInterfaceParam();
+        param.setParamType(String.class.getName());
+        param.setParamValue(apiInfoRequest.getApiName());
+        methodParams.add(param);
+        return callDubboService(req, methodParams);
     }
 
     private static boolean isBaseType(String typeStr) {
diff --git a/dubbo-api-docs/dubbo-api-docs-ui-server/src/main/java/org/apache/dubbo/apidocs/controller/vo/CallDubboServiceRequestInterfacePrarm.java b/dubbo-api-docs/dubbo-api-docs-ui-server/src/main/java/org/apache/dubbo/apidocs/controller/vo/CallDubboServiceRequestInterfaceParam.java
similarity index 91%
rename from dubbo-api-docs/dubbo-api-docs-ui-server/src/main/java/org/apache/dubbo/apidocs/controller/vo/CallDubboServiceRequestInterfacePrarm.java
rename to dubbo-api-docs/dubbo-api-docs-ui-server/src/main/java/org/apache/dubbo/apidocs/controller/vo/CallDubboServiceRequestInterfaceParam.java
index 3cf6d0f..44f3bce 100644
--- a/dubbo-api-docs/dubbo-api-docs-ui-server/src/main/java/org/apache/dubbo/apidocs/controller/vo/CallDubboServiceRequestInterfacePrarm.java
+++ b/dubbo-api-docs/dubbo-api-docs-ui-server/src/main/java/org/apache/dubbo/apidocs/controller/vo/CallDubboServiceRequestInterfaceParam.java
@@ -27,12 +27,12 @@ import lombok.Setter;
  */
 @Getter
 @Setter
-public class CallDubboServiceRequestInterfacePrarm {
+public class CallDubboServiceRequestInterfaceParam {
 
     @ApiParam(value = "Parameter type (full package path), such as: java.lang.String", required = true)
-    private String prarmType;
+    private String paramType;
 
     @ApiParam(value = "Parameter value", required = true)
-    private Object prarmValue;
+    private Object paramValue;
 
 }
diff --git a/dubbo-api-docs/dubbo-api-docs-ui-server/src/main/java/org/apache/dubbo/apidocs/utils/DubboGenericUtil.java b/dubbo-api-docs/dubbo-api-docs-ui-server/src/main/java/org/apache/dubbo/apidocs/utils/DubboGenericUtil.java
index 613d79d..1c085bc 100644
--- a/dubbo-api-docs/dubbo-api-docs-ui-server/src/main/java/org/apache/dubbo/apidocs/utils/DubboGenericUtil.java
+++ b/dubbo-api-docs/dubbo-api-docs-ui-server/src/main/java/org/apache/dubbo/apidocs/utils/DubboGenericUtil.java
@@ -127,22 +127,22 @@ public class DubboGenericUtil {
      * @param: methodName
      * @param: async  Whether the provider is asynchronous is to directly return the {@link CompletableFuture}
      * returned by the provider, not to wrap it as {@link CompletableFuture}
-     * @param: prarmTypes
-     * @param: prarmValues
+     * @param: paramTypes
+     * @param: paramValues
      * @return java.util.concurrent.CompletableFuture<java.lang.Object>
      */
     public static CompletableFuture<Object> invoke(String address, String interfaceName,
-                                                  String methodName, boolean async, String[] prarmTypes,
-                                                  Object[] prarmValues) {
+                                                  String methodName, boolean async, String[] paramTypes,
+                                                  Object[] paramValues) {
         CompletableFuture future = null;
         ReferenceConfig<GenericService> reference = getReferenceConfig(address, interfaceName);
         if (null != reference) {
             GenericService genericService = reference.get();
             if (null != genericService) {
                 if(async){
-                    future = genericService.$invokeAsync(methodName, prarmTypes, prarmValues);
+                    future = genericService.$invokeAsync(methodName, paramTypes, paramValues);
                 } else {
-                    future = CompletableFuture.supplyAsync(() -> genericService.$invoke(methodName, prarmTypes, prarmValues), executor);
+                    future = CompletableFuture.supplyAsync(() -> genericService.$invoke(methodName, paramTypes, paramValues), executor);
                 }
             }
         }
@@ -155,18 +155,18 @@ public class DubboGenericUtil {
      * @param: address
      * @param: interfaceName
      * @param: methodName
-     * @param: prarmTypes
-     * @param: prarmValues
+     * @param: paramTypes
+     * @param: paramValues
      * @return java.lang.Object
      */
     public static Object invokeSync(String address, String interfaceName,
-                                                   String methodName, String[] prarmTypes,
-                                                   Object[] prarmValues) {
+                                                   String methodName, String[] paramTypes,
+                                                   Object[] paramValues) {
         ReferenceConfig<GenericService> reference = getReferenceConfig(address, interfaceName);
         if (null != reference) {
             GenericService genericService = reference.get();
             if (null != genericService) {
-                return genericService.$invoke(methodName, prarmTypes, prarmValues);
+                return genericService.$invoke(methodName, paramTypes, paramValues);
             }
         }
         return null;
diff --git a/dubbo-api-docs/dubbo-api-docs-ui-server/src/main/resources/static/js/index.js b/dubbo-api-docs/dubbo-api-docs-ui-server/src/main/resources/static/js/index.js
index a7ab576..496947b 100644
--- a/dubbo-api-docs/dubbo-api-docs-ui-server/src/main/resources/static/js/index.js
+++ b/dubbo-api-docs/dubbo-api-docs-ui-server/src/main/resources/static/js/index.js
@@ -109,4 +109,4 @@ var t;return e.defineLocale("zh-cn",{months:"\u4e00\u6708_\u4e8c\u6708_\u4e09\u6
  *
  * This source code is licensed under the MIT license found in the
  * LICENSE file in the root directory of this source tree.
- */var r="function"==typeof Symbol&&Symbol.for,o=r?Symbol.for("react.element"):60103,a=r?Symbol.for("react.portal"):60106,i=r?Symbol.for("react.fragment"):60107,s=r?Symbol.for("react.strict_mode"):60108,u=r?Symbol.for("react.profiler"):60114,l=r?Symbol.for("react.provider"):60109,c=r?Symbol.for("react.context"):60110,f=r?Symbol.for("react.async_mode"):60111,p=r?Symbol.for("react.concurrent_mode"):60111,d=r?Symbol.for("react.forward_ref"):60112,h=r?Symbol.for("react.suspense"):60113,v=r?S [...]
\ No newline at end of file
+ */var r="function"==typeof Symbol&&Symbol.for,o=r?Symbol.for("react.element"):60103,a=r?Symbol.for("react.portal"):60106,i=r?Symbol.for("react.fragment"):60107,s=r?Symbol.for("react.strict_mode"):60108,u=r?Symbol.for("react.profiler"):60114,l=r?Symbol.for("react.provider"):60109,c=r?Symbol.for("react.context"):60110,f=r?Symbol.for("react.async_mode"):60111,p=r?Symbol.for("react.concurrent_mode"):60111,d=r?Symbol.for("react.forward_ref"):60112,h=r?Symbol.for("react.suspense"):60113,v=r?S [...]
\ No newline at end of file
diff --git a/dubbo-api-docs/dubbo-api-docs-ui/src/layouts/BasicLayout/index.tsx b/dubbo-api-docs/dubbo-api-docs-ui/src/layouts/BasicLayout/index.tsx
index beeacc4..255eb95 100644
--- a/dubbo-api-docs/dubbo-api-docs-ui/src/layouts/BasicLayout/index.tsx
+++ b/dubbo-api-docs/dubbo-api-docs-ui/src/layouts/BasicLayout/index.tsx
@@ -52,7 +52,7 @@ export default function BasicLayout(props: {
     if(response && response != ''){
       const menuData = JSON.parse(response);
       menuData.sort((a,b) => {
-        return a.moduleChName > b.moduleChName;
+        return a.moduleDocName > b.moduleDocName;
       });
       for(let i = 0; i < menuData.length; i++){
         const menu = menuData[i];
@@ -60,7 +60,7 @@ export default function BasicLayout(props: {
           return a.apiName > b.apiName;
         });
         const menu2 = {
-          name: menu.moduleChName,
+          name: menu.moduleDocName,
           path: '',
           icon: 'cascades',
           children: new Array(),
@@ -69,7 +69,7 @@ export default function BasicLayout(props: {
         for(let j = 0; j < menuItems.length; j++){
           const menuItem = menuItems[j];
           const menuItem2 = {
-            name: menuItem.apiChName,
+            name: menuItem.apiDocName,
             path: `/apiForm?apiName=${menu.moduleClassName}.${menuItem.apiName}&dubboIp=${dubboIp}&dubboPort=${dubboPort}`,
           };
           menu2.children.push(menuItem2);
diff --git a/dubbo-api-docs/dubbo-api-docs-ui/src/locales/en-US.json b/dubbo-api-docs/dubbo-api-docs-ui/src/locales/en-US.json
index 7548477..d220b43 100644
--- a/dubbo-api-docs/dubbo-api-docs-ui/src/locales/en-US.json
+++ b/dubbo-api-docs/dubbo-api-docs-ui/src/locales/en-US.json
@@ -11,16 +11,17 @@
     "api404Err": "Interface name is incorrect, interface parameters and response information are not found",
     "apiRespDecShowLabel": "Api Info",
     "apiNameShowLabel": "Api Name",
+    "apiMethodParamInfoLabel": "Api method parameters",
     "apiVersionShowLabel": "Api Version",
     "apiDescriptionShowLabel": "Api Description",
     "isAsyncFormLabel": "Whether to call asynchronously (this parameter cannot be modified, according to whether to display asynchronously defined by the interface)",
     "apiModuleFormLabel": "Api module (this parameter cannot be modified)",
     "apiFunctionNameFormLabel": "Api function name(this parameter cannot be modified)",
     "registryCenterUrlFormLabel": "Registry address. If it is empty, Dubbo provider IP and port will be used for direct connection",
-    "prarmNameLabel": "Parameter name",
-    "prarmPathLabel": "Parameter path",
-    "prarmDescriptionLabel": "Description",
-    "prarmRequiredLabel": "This parameter is required",
+    "paramNameLabel": "Parameter name",
+    "paramPathLabel": "Parameter path",
+    "paramDescriptionLabel": "Description",
+    "paramRequiredLabel": "This parameter is required",
     "doTestBtn": "Do Test",
     "responseLabel": "Response",
     "responseExampleLabel": "Response Example",
@@ -29,6 +30,6 @@
     "requireTip": "There are required items not filled in",
     "requestApiErrorTip": "There is an exception in the request interface. Please check the submitted data, especially the JSON class data and the enumeration part",
     "unsupportedHtmlTypeTip": "Temporarily unsupported HTML type"
-    
+
   }
 }
diff --git a/dubbo-api-docs/dubbo-api-docs-ui/src/locales/zh-CN.json b/dubbo-api-docs/dubbo-api-docs-ui/src/locales/zh-CN.json
index b008bc6..41c8e37 100644
--- a/dubbo-api-docs/dubbo-api-docs-ui/src/locales/zh-CN.json
+++ b/dubbo-api-docs/dubbo-api-docs-ui/src/locales/zh-CN.json
@@ -11,16 +11,17 @@
     "api404Err": "接口名称不正确,没有查找到接口参数和响应信息",
     "apiRespDecShowLabel": "接口说明",
     "apiNameShowLabel": "接口名称",
+    "apiMethodParamInfoLabel": "接口参数",
     "apiVersionShowLabel": "接口版本",
     "apiDescriptionShowLabel": "接口描述",
     "isAsyncFormLabel": "是否异步调用(此参数不可修改,根据接口定义的是否异步显示)",
     "apiModuleFormLabel": "接口模块(此参数不可修改)",
     "apiFunctionNameFormLabel": "接口方法名(此参数不可修改)",
     "registryCenterUrlFormLabel": "注册中心地址, 如果为空将使用Dubbo 提供者Ip和端口进行直连",
-    "prarmNameLabel": "参数名",
-    "prarmPathLabel": "参数位置",
-    "prarmDescriptionLabel": "说明",
-    "prarmRequiredLabel": "该参数为必填",
+    "paramNameLabel": "参数名",
+    "paramPathLabel": "参数位置",
+    "paramDescriptionLabel": "说明",
+    "paramRequiredLabel": "该参数为必填",
     "doTestBtn": "测试",
     "responseLabel": "响应",
     "responseExampleLabel": "响应示例",
@@ -29,6 +30,6 @@
     "requireTip": "有未填写的必填项",
     "requestApiErrorTip": "请求接口发生异常,请检查提交的数据,特别是JSON类数据和其中的枚举部分",
     "unsupportedHtmlTypeTip": "暂不支持的HTML类型"
-    
+
   }
 }
diff --git a/dubbo-api-docs/dubbo-api-docs-ui/src/pages/ApiForm/index.tsx b/dubbo-api-docs/dubbo-api-docs-ui/src/pages/ApiForm/index.tsx
index 8a9cf2d..3c80855 100644
--- a/dubbo-api-docs/dubbo-api-docs-ui/src/pages/ApiForm/index.tsx
+++ b/dubbo-api-docs/dubbo-api-docs-ui/src/pages/ApiForm/index.tsx
@@ -128,10 +128,10 @@ class ApiForm extends React.Component {
           var formItem = new Map();
           formItem.set('name', paramItem.name);
           formItem.set('htmlType', paramItem.htmlType);
-          formItem.set('paramType', paramItem.prarmType);
-          formItem.set('javaType', paramItem.prarmType);
-          formItem.set('paramIndex', paramItem.prarmIndex);
-          formItem.set('nameCh', paramItem.nameCh);
+          formItem.set('paramType', paramItem.paramType);
+          formItem.set('javaType', paramItem.paramType);
+          formItem.set('paramIndex', paramItem.paramIndex);
+          formItem.set('docName', paramItem.docName);
           formItem.set('description', paramItem.description);
           formItem.set('example', paramItem.example);
           formItem.set('defaultValue', paramItem.defaultValue);
@@ -140,22 +140,22 @@ class ApiForm extends React.Component {
           formsArray.push(formItem);
         } else {
           // No htmltype, that's an object
-          var prarmInfoArray = paramItem.prarmInfo;
-          for(var j = 0; j < prarmInfoArray.length; j++){
-            var prarmInfoItem = prarmInfoArray[j];
+          var paramInfoArray = paramItem.paramInfo;
+          for(var j = 0; j < paramInfoArray.length; j++){
+            var paramInfoItem = paramInfoArray[j];
             var formItem = new Map();
-            formItem.set('name', prarmInfoItem.name);
-            formItem.set('htmlType', prarmInfoItem.htmlType);
-            formItem.set('paramType', paramItem.prarmType);
-            formItem.set('javaType', prarmInfoItem.javaType);
-            formItem.set('paramIndex', paramItem.prarmIndex);
-            formItem.set('nameCh', prarmInfoItem.nameCh);
-            formItem.set('description', prarmInfoItem.description);
-            formItem.set('example', prarmInfoItem.example);
-            formItem.set('defaultValue', prarmInfoItem.defaultValue);
-            formItem.set('allowableValues', prarmInfoItem.allowableValues);
-            formItem.set('subParamsJson', prarmInfoItem.subParamsJson);
-            formItem.set('required', prarmInfoItem.required);
+            formItem.set('name', paramInfoItem.name);
+            formItem.set('htmlType', paramInfoItem.htmlType);
+            formItem.set('paramType', paramItem.paramType);
+            formItem.set('javaType', paramInfoItem.javaType);
+            formItem.set('paramIndex', paramItem.paramIndex);
+            formItem.set('docName', paramInfoItem.docName);
+            formItem.set('description', paramInfoItem.description);
+            formItem.set('example', paramInfoItem.example);
+            formItem.set('defaultValue', paramInfoItem.defaultValue);
+            formItem.set('allowableValues', paramInfoItem.allowableValues);
+            formItem.set('subParamsJson', paramInfoItem.subParamsJson);
+            formItem.set('required', paramInfoItem.required);
             formsArray.push(formItem);
           }
         }
@@ -166,7 +166,7 @@ class ApiForm extends React.Component {
             <Form.Item
               key='formItemAsync'
               label={this.state.locale.isAsyncFormLabel}>
-              <Select 
+              <Select
                 id='formItemAsync'
                 name='formItemAsync'
                 style={{ marginLeft: 5, width: '100px' }}
@@ -218,21 +218,21 @@ class ApiForm extends React.Component {
                 return (
                   <div key={'formDiv' + index} style={{ marginTop: 20 }}>
                     <div style={{ width: '1000px', height:'220px' }}>
-                      <div style={{ float: 'left', border: '2px solid rgb(228 224 224)', 
+                      <div style={{ float: 'left', border: '2px solid rgb(228 224 224)',
                             width: '400px', height: '100%', overflowY: 'auto', overflowX: 'hidden'}}>
                         <Timeline>
-                          <Timeline.Item style={{wordBreak: 'break-word'}} title={this.state.locale.prarmNameLabel} content={item.get('name')} state="process"/>
-                          <Timeline.Item style={{wordBreak: 'break-word'}} title={this.state.locale.prarmPathLabel} content={item.get('paramType') + "#" + item.get('name')} state="process"/>
-                          <Timeline.Item style={{wordBreak: 'break-word'}} title={this.state.locale.prarmDescriptionLabel} content={item.get('description')} state="process"/>
+                          <Timeline.Item style={{wordBreak: 'break-word'}} title={this.state.locale.paramNameLabel} content={item.get('name')} state="process"/>
+                          <Timeline.Item style={{wordBreak: 'break-word'}} title={this.state.locale.paramPathLabel} content={item.get('paramType') + "#" + item.get('name')} state="process"/>
+                          <Timeline.Item style={{wordBreak: 'break-word'}} title={this.state.locale.paramDescriptionLabel} content={item.get('description')} state="process"/>
                         </Timeline>
                       </div>
                       <div style={{float: "left"}}>
-                        <Form.Item 
-                          help={item.get('required') ? this.state.locale.prarmRequiredLabel : ''}
+                        <Form.Item
+                          help={item.get('required') ? this.state.locale.paramRequiredLabel : ''}
                           key={'formItem' + index}
                           required={item.get('required')}
                           style={{padding: '5px'}}
-                          label={item.get('nameCh')}
+                          label={item.get('docName')}
                         >
                         {
                           this.buildFormItem(item)
@@ -279,14 +279,14 @@ class ApiForm extends React.Component {
             </div>
           </div>
         </div>
-        
+
       );
     } else {
       return (
         <h1>{this.state.locale.LoadingLabel}</h1>
       );
     }
-    
+
   }
 
   buildResponseInfoView(){
@@ -309,13 +309,13 @@ class ApiForm extends React.Component {
         throw 'dataNotJson';
       }
       return (
-        <ReactJson 
+        <ReactJson
         style={{ marginLeft: 5, minWidth: '580px' }}
-          name={false} 
+          name={false}
           theme='apathy'
           iconStyle='square'
           displayDataTypes={true}
-          src={responseInfoJsonObj} 
+          src={responseInfoJsonObj}
         />
       );
     } catch (e) {
@@ -345,13 +345,13 @@ class ApiForm extends React.Component {
         throw 'dataNotJson';
       }
       return (
-        <ReactJson 
+        <ReactJson
           style={{ marginLeft: 5, minWidth: '580px' }}
-          name={false} 
+          name={false}
           theme='apathy'
           iconStyle='square'
           displayDataTypes={true}
-          src={this.state.responseData} 
+          src={this.state.responseData}
         />
       );
     } catch (e) {
@@ -388,9 +388,9 @@ class ApiForm extends React.Component {
     tempMap.forEach((value, key) => {
       var postDataItem = {};
       postData[key.split('@@')[1]] = postDataItem;
-      postDataItem['prarmType'] = key.split('@@')[0];
+      postDataItem['paramType'] = key.split('@@')[0];
       var postDataItemValue = {};
-      postDataItem['prarmValue'] = postDataItemValue;
+      postDataItem['paramValue'] = postDataItemValue;
       value.forEach(element => {
         var elementName = element.name.split('@@')[3];
         if(element.tagName == 'TEXTAREA'){
@@ -420,7 +420,7 @@ class ApiForm extends React.Component {
         registryCenterUrl: registryCenterUrl
       },
       headers: {
-        'Content-Type': 'application/json; charset=UTF-8' 
+        'Content-Type': 'application/json; charset=UTF-8'
       },
       data: JSON.stringify(postData),
     }).catch(error => {
@@ -437,10 +437,13 @@ class ApiForm extends React.Component {
   showApiInfo(){
     return (
       <div>
-        <h1>{this.state.locale.apiNameShowLabel}: <span>{this.state.apiInfoData.apiChName + '(' + this.state.apiName + ')'}</span></h1>
-        <h1>{this.state.locale.apiRespDecShowLabel}: <span>{this.state.apiInfoData.apiRespDec}</span></h1>
-        <h1>{this.state.locale.apiVersionShowLabel}: <span>{this.state.apiInfoData.apiVersion}</span></h1>
-        <h1>{this.state.locale.apiDescriptionShowLabel}: <span>{this.state.apiInfoData.apiDescription}</span></h1>
+        <Timeline>
+          <Timeline.Item style={{wordBreak: 'break-word'}} title={this.state.locale.apiNameShowLabel} content={this.state.apiInfoData.apiDocName + '(' + this.state.apiName + ')'} state="success" />
+          <Timeline.Item style={{wordBreak: 'break-word'}} title={this.state.locale.apiMethodParamInfoLabel} content={this.state.apiInfoData.methodParamInfo} state="success" />
+          <Timeline.Item style={{wordBreak: 'break-word'}} title={this.state.locale.apiRespDecShowLabel} content={this.state.apiInfoData.apiRespDec} state="success" />
+          <Timeline.Item style={{wordBreak: 'break-word'}} title={this.state.locale.apiVersionShowLabel} content={this.state.apiInfoData.apiVersion} state="success" />
+          <Timeline.Item style={{wordBreak: 'break-word'}} title={this.state.locale.apiDescriptionShowLabel} content={this.state.apiInfoData.apiDescription} state="success" />
+        </Timeline>
       </div>
     );
   }
@@ -508,7 +511,7 @@ class ApiForm extends React.Component {
 
   buildReactJson(item){
     return (
-      <ReactJson 
+      <ReactJson
         onEdit={o => {
           console.log(o);
         }}
@@ -517,9 +520,9 @@ class ApiForm extends React.Component {
         }}
         onDelete={o => {
           console.log(o);
-        }} 
-        name={false} 
-        src={[{'abc': 123, 'cde': 'wdsfasdf'},{'abc': 123, 'cde': 'wdsfasdf'}]} 
+        }}
+        name={false}
+        src={[{'abc': 123, 'cde': 'wdsfasdf'},{'abc': 123, 'cde': 'wdsfasdf'}]}
       />
     )
   }
@@ -550,7 +553,7 @@ class ApiForm extends React.Component {
       dataSource.push(dsItem);
     }
     return (
-      <Select 
+      <Select
         name={item.get('paramType') + '@@' + item.get('paramIndex') + '@@' + item.get('javaType') + "@@" + item.get('name')}
         className={'dubbo-doc-form-item-class'}
         style={{ marginLeft: 5, width: '400px' }}
@@ -572,7 +575,7 @@ class ApiForm extends React.Component {
         break;
       case 'NUMBER_INTEGER':
         return this.buildNumberInteger(item);
-        break;  
+        break;
       case 'NUMBER_DECIMAL':
         return this.buildNumberDecimal(item);
         break;
@@ -608,9 +611,9 @@ class ApiForm extends React.Component {
           </div>
         </Loading>
       </div>
-     
+
     );
   }
 };
 
-export default ApiForm;
\ No newline at end of file
+export default ApiForm;


[dubbo-spi-extensions] 13/39: 修改README.md,修改打包脚本,修改部分名称, 调整pom

Posted by li...@apache.org.
This is an automated email from the ASF dual-hosted git repository.

liujun pushed a commit to branch 2.7.x
in repository https://gitbox.apache.org/repos/asf/dubbo-spi-extensions.git

commit 213b1dc72f20cfbf206322e55fdfe55e46ef6bde
Author: qq213539 <21...@qq.com>
AuthorDate: Sun Nov 15 21:10:42 2020 +0800

    修改README.md,修改打包脚本,修改部分名称, 调整pom
---
 dubbo-api-docs/README.md                           |  69 +++++------------
 dubbo-api-docs/README_ch.md                        |  71 +++++------------
 dubbo-api-docs/distribution/bin/shutdown.cmd       |   2 +-
 dubbo-api-docs/distribution/bin/startup.cmd        |   2 +-
 dubbo-api-docs/distribution/bin/startup.sh         |   4 +-
 dubbo-api-docs/distribution/pom.xml                |   4 +-
 dubbo-api-docs/dubbo-api-docs-annotations/pom.xml  |   2 +-
 dubbo-api-docs/dubbo-api-docs-core/pom.xml         |   2 +-
 .../dubbo-api-docs-examples/examples-api/pom.xml   |   2 +-
 .../examples-provider-sca/pom.xml                  |   2 +-
 .../examples-provider/pom.xml                      |   2 +-
 dubbo-api-docs/dubbo-api-docs-examples/pom.xml     |   2 +-
 dubbo-api-docs/dubbo-api-docs-ui-server/pom.xml    |  34 ++++-----
 .../src/main/resources/application.yml             |   2 +-
 .../src/main/resources/banner.txt                  |  13 ++--
 .../src/main/resources/log4j2.xml                  |   2 +-
 .../src/main/resources/static/css/index.css        |   2 +-
 .../src/main/resources/static/js/index.js          |  85 ++++++++++++---------
 dubbo-api-docs/pom.xml                             |  16 +++-
 dubbo-api-docs/readmeImgs/DubboDoc.png             | Bin 0 -> 74904 bytes
 20 files changed, 137 insertions(+), 181 deletions(-)

diff --git a/dubbo-api-docs/README.md b/dubbo-api-docs/README.md
index 1a61dab..cb86f20 100644
--- a/dubbo-api-docs/README.md
+++ b/dubbo-api-docs/README.md
@@ -4,24 +4,8 @@
 
 Dubbo api documents, test tools, generate documents according to annotations, and provide test functions
 
-Only some annotations are needed to generate documents similar to swagger, without turning a non web's dubbo project into a web project.
+Adding some annotations can generate a swagger like document without turning a non web Dubbo project into a web project
 
-Welcome everyone to make complaints about it~
-
-At present, the function of the first version is relatively rough (the interface is also rough), and the user experience is not very good. It will be gradually optimized later, and all kinds of PR are welcome~
-
-
-
-```
-When testing Dubbo providers, I always thought that if Dubbo had a document + testing 
-tool similar to swagger
-I've also found that several of them are based on springfox, and will add some restful 
-interfaces to Dubbo project,if your Dubbo service itself is started through a web container 
-or mixed with web projects, that's fine.
-But my Dubbo projects are all non web projects. For those with obsessive-compulsive disorder, 
-it is a little unacceptable to turn the project into a web project for the purpose of documentation,
-so I have the idea of doing it myself...
-```
 ## Version planning
 ### First edition
 * Parsing annotations and generating UI
@@ -31,18 +15,18 @@ so I have the idea of doing it myself...
 * Add tabs
 * It can save the test and facilitate the next direct loading test
 * Some exceptions are handled as friendly text prompts
-* Add remark.md and show it in the front end
-* Add changelog.md and show it in the front end
+* Add apiRemark.md and show it in the front end
+* Add apiChangelog.md and show it in the front end
 ### Follow up edition
-* Demand  based on own use and issue planning
+* According to user requirements and issue planning
 * Planning according to Dubbo upgrading
 ## Registry center suppor
 * In theory, all registries supported by Dubbo support
 
 ## How to use?
-1. Dubbo doc annotation added to method parameters of Dubbo project
-   * Dubbo provider project introduces Dubbo doc core
-   * If Dubbo's interface and parameters are a separate jar package project, introduce Dubbo doc annotations
+1. Dubbo api docs annotation added to method parameters of Dubbo project
+   * Dubbo provider project introduces dubbo-api-docs-core
+   * If Dubbo's interface and parameters are a separate jar package project, introduce dubbo-api-docs-annotations
 
 ### Current Version: Same as Dubbo version
 ```
@@ -58,19 +42,19 @@ so I have the idea of doing it myself...
     <version>${dubbo-version}</version>
 </dependency>
 ```
-2.Download dubbo-doc-ui-server [Download](https://github.com/KeRan213539/dubboDoc/releases)
+2.Download dubbo-doc-ui-server [Download](https://github.com/apache/dubbo-spi-extensions/releases)
 
-3. Start dubbo-doc-ui-server
+3. Start dubbo-api-docs-ui-server
 
 4. Visit: http:// localhost:8888
    * Port can be modified in application.yml
-   * swagger-ui http:// localhost:8888/swagger-ui.html
+   * swagger-ui http:// localhost:8888/swagger-ui/
 ### Annotation use
-* @DubboApiModule class annotation: dubbo API module information, used to mark the purpose of an interface class module
+* @ApiModule class annotation: dubbo API module information, used to mark the purpose of an interface class module
     * value: module name
     * apiInterface: Provider implemented interface
     * version: module version
-* @DubboApi method annotation: dubbo API information, used to mark the purpose of an dubbo API
+* @ApiDoc method annotation: dubbo API information, used to mark the purpose of an dubbo API
     * value: API name
     * description: API description(HTML tags available)
     * version: API version
@@ -88,14 +72,13 @@ so I have the idea of doing it myself...
 * @ResponseProperty Class attribute annotation: mark response parameters
     * value: parameter name
     * example: example
-### dubbo-doc-ui
+### dubbo-api-docs-ui
 * Get API list direct connection: 
 > Because Dubbo services with different functions may be registered in the same registration center, 
 > but the name of the interface used by Dubbo doc is the same, so the interface of Dubbo doc uses direct 
 connection to obtain the list of different interfaces of different functions.
 
 * The test can be connected directly or through the registration center
-### swagger-ui TODO
 
 ### Use note
 * The response bean (the return type of the interface) supports custom generics, but only one generic placeholder.
@@ -103,30 +86,14 @@ connection to obtain the list of different interfaces of different functions.
 * The API's synchronous / asynchronous is from org.apache.dubbo.config.annotation.Service.async
 
 ## Project structure
-* dubbo-doc-annotations: Document generation annotation project
-* dubbo-doc-core: Responsible for annotation analysis and document information acquisition interface (Dubbo API)
-* dubbo-doc-ui-server: Web service, responsible for displaying doc and providing testing function
-* dubbo-doc-console: The front-end project will be packaged into Dubbo doc UI server project when it is published
-* dubbo-doc-examples: Use example
+* dubbo-api-docs-annotations: Document generation annotation project
+* dubbo-api-docs-core: Responsible for annotation analysis and document information acquisition interface (Dubbo API)
+* dubbo-api-docs-ui-server: Web service, responsible for displaying doc and providing testing function
+* dubbo-api-docs-ui: The front-end project will be packaged into Dubbo doc UI server project when it is published
+* dubbo-api-docs-examples: Use example
 * readmeImgs: Pictures used by README.md
 
 ## Major dependent version
 * spring-boot: 2.3.4.RELEASE
 * dubbo: apache dubbo 2.7.8
 * icework in front(iceworks 4.0)
-
-## What did Dubbo Doc do ?
-### Annotations
-* Define annotations to describe interfaces and parameters
-### In Dubbo projects that need to generate documentation and tests
-* Parsing annotations and caching
-* Add Dubbo API used by Dubbo doc to obtain interface information
-###  dubbo-doc-ui-server
-* Web service
-* Restful API used by front-end UI to obtain interface information (interface list, information of specified interface)
-* Request the restful API of the Dubbo service (using the method of Dubbo generalization call)
-* Save the test and display it next time (implemented in the Second Edition)
-### dubbo-doc-console(Package to dubbo-doc-ui-server when publishing)
-* Get the interface list and display it according to the specified Dubbo service IP and port (direct connection Dubbo service)
-* Get the interface information according to the specified interface and generate the form with DOC (similar to swagger)
-* Show API request response
\ No newline at end of file
diff --git a/dubbo-api-docs/README_ch.md b/dubbo-api-docs/README_ch.md
index 91351ef..fa75434 100644
--- a/dubbo-api-docs/README_ch.md
+++ b/dubbo-api-docs/README_ch.md
@@ -2,22 +2,10 @@
 
 [English](./README.md)
 
-[Gitee镜像](https://gitee.com/213539/dubboDoc)
-
 dubbo 接口文档、测试工具,根据注解生成文档,并提供测试功能.
 
-功能参考 swagger+springfox, 只需要加一些注解就能生成类似swagger的文档, 不会把非web的dubbo项目变为web项目.
-
-欢迎大家吐槽~
+增加一些注解就能生成类似swagger的文档, 不会把非web的dubbo项目变为web项目.
 
-目前第一版功能比较粗糙(界面也粗糙),用户体验不是很好,后面会慢慢优化,也欢迎各种PR~
-
-```
-在测试dubbo提供者的时候,一直在想如果dubbo有一个类似swagger的文档+测试工具就好了.
-也找了一下,找到的几个都是基于springfox的,会在dubbo项目中加一些restful接口,
-如果你的dubbo服务本身就是通过web容器启动或者混合有web项目那还好.
-但是我这边的dubbo项目都是非web项目,对于有强迫症的我来说,为了文档要把项目变成web项目有点无法接受,就有了自己动手的想法...
-```
 ## 版本规划
 ### 第一版
 * 解析注解并生成界面
@@ -27,18 +15,18 @@ dubbo 接口文档、测试工具,根据注解生成文档,并提供测试功能
 * 增加标签页
 * 能保存测试,方便下次直接加载测试
 * 部分异常处理为友好的文字提示
-* 增加 remark.md 并在前端展示
-* 增加 changelog.md 并在前端展示
+* 增加 apiRemark.md 并在前端展示
+* 增加 apiChangelog.md 并在前端展示
 ### 后续版本
-* 根据自用产生的需求和issue规划
+* 根据用户需求和issue规划
 * 根据dubbo升级情况规划
 ## 注册中心支持
 * 理论上dubbo支持的所有注册中心都支持
 
 ## 如何使用?
-1. dubbo项目的方法参数中加上 dubbo doc注解
-   * dubbo提供者项目引入 dubbo-doc-core
-   * 如果dubbo的接口和参数是一个单独的jar包项目,引入dubbo-doc-annotations
+1. dubbo项目的方法参数中加上 dubbo api docs注解
+   * dubbo提供者项目引入 dubbo-api-docs-core
+   * 如果dubbo的接口和参数是一个单独的jar包项目,引入dubbo-api-docs-annotations
    
 ### 当前版本: 同Dubbo版本号
 ```
@@ -50,25 +38,23 @@ dubbo 接口文档、测试工具,根据注解生成文档,并提供测试功能
 
 <dependency>
     <groupId>org.apache.dubbo</groupId>
-                <artifactId>dubbo-api-docs-core</artifactId>
+    <artifactId>dubbo-api-docs-core</artifactId>
     <version>${dubbo-version}</version>
 </dependency>
 ```
-2.下载 dubbo-doc-ui-server [下载地址](https://github.com/KeRan213539/dubboDoc/releases)
-
-[国内用户可到码云下载](https://gitee.com/213539/dubboDoc/releases)
+2.下载 dubbo-api-docs-ui-server [下载地址](https://github.com/apache/dubbo-spi-extensions/releases)
 
-3. 启动 dubbo-doc-ui-server
+3. 启动 dubbo-api-docs-ui-server
 
 4. 访问: http:// localhost:8888
    * application.yml 中可以修改端口
-   * swagger-ui http:// localhost:8888/swagger-ui.html
+   * swagger-ui http:// localhost:8888/swagger-ui/
 ### 注解使用
-* @DubboApiModule 类注解: dubbo接口模块信息,用于标注一个接口类模块的用途
+* @ApiModule 类注解: dubbo接口模块信息,用于标注一个接口类模块的用途
     * value: 模块名称
     * apiInterface: 提供者实现的接口
     * version: 模块版本
-* @DubboApi 方法注解: dubbo 接口信息,用于标注一个接口的用途
+* @ApiDoc 方法注解: dubbo 接口信息,用于标注一个接口的用途
     * value: 接口名称
     * description: 接口描述(可使用html标签)
     * version: 接口版本
@@ -86,11 +72,10 @@ dubbo 接口文档、测试工具,根据注解生成文档,并提供测试功能
 * @ResponseProperty 类属性注解: 标注响应参数
     * value: 参数名
     * example: 示例
-### dubbo-doc-ui
+### dubbo-api-docs-ui
 * 获取接口列表直连: 由于可能不同功能的dubbo服务都会注册到同一个注册中心,但是dubbo doc
 使用的接口名是一样的,所以dubbo doc的接口采用直连方式以获取到不同功能服务的不同接口列表
 * 测试可以直连或者走注册中心
-### swagger-ui TODO
 
 ### 使用注意
 * 响应bean(接口的返回类型)支持自定义泛型, 但只支持一个泛型占位符
@@ -99,11 +84,11 @@ dubbo 接口文档、测试工具,根据注解生成文档,并提供测试功能
 * 接口的同步/异步取自 org.apache.dubbo.config.annotation.Service.async
 
 ## 项目结构
-* dubbo-doc-annotations: 文档生成辅助注解项目
-* dubbo-doc-core: 负责注解解析,文档信息获取接口(dubbo接口)
-* dubbo-doc-ui-server: web服务,负责展示doc,并提供测试功能
-* dubbo-doc-console: 前端项目, 发布时会打包到 dubbo-doc-ui-server 项目中
-* dubbo-doc-examples: 使用示例
+* dubbo-api-docs-annotations: 文档生成辅助注解项目
+* dubbo-api-docs-core: 负责注解解析,文档信息获取接口(dubbo接口)
+* dubbo-api-docs-ui-server: web服务,负责展示doc,并提供测试功能
+* dubbo-api-docs-ui: 前端项目, 发布时会打包到 dubbo-doc-ui-server 项目中
+* dubbo-api-docs-examples: 使用示例
 * readmeImgs: README.md 用到的图片
 
 ## 主要依赖版本
@@ -111,20 +96,4 @@ dubbo 接口文档、测试工具,根据注解生成文档,并提供测试功能
 * dubbo: apache dubbo 2.7.8
 * 前端使用飞冰(iceworks 4.0)
 
-## Dubbo Doc 做了什么?
-### 注解
-* 定义一些注解用于描述接口和参数的注解
-### 在需要生成文档和测试的 dubbo 项目中
-* 解析注解并缓存
-* 增加dubbo doc使用的获取接口信息的 dubbo 接口
-###  dubbo-doc-ui-server
-* web服务
-* 前端ui使用的获取接口信息的 web 接口(接口列表, 指定接口的信息)
-* 请求 dubbo 服务的web接口(使用 dubbo 泛化调用的方式)
-* 保存测试,并可在下次展现(第二版实现)
-### dubbo-doc-console(发布时打包到 dubbo-doc-ui-server 中)
-* 根据指定的dubbo服务IP和端口获取接口列表并展示(直连dubbo服务)
-* 根据指定的接口获取接口信息并生成带doc的表单(类似swagger)
-* 展示接口请求的响应
-
-![界面](https://github.com/KeRan213539/dubboDoc/blob/develop/readmeImgs/DubboDoc.png)
\ No newline at end of file
+![界面](./readmeImgs/DubboDoc.png)
\ No newline at end of file
diff --git a/dubbo-api-docs/distribution/bin/shutdown.cmd b/dubbo-api-docs/distribution/bin/shutdown.cmd
index 60fb33f..9eb749d 100644
--- a/dubbo-api-docs/distribution/bin/shutdown.cmd
+++ b/dubbo-api-docs/distribution/bin/shutdown.cmd
@@ -21,6 +21,6 @@ set "PATH=%JAVA_HOME%\bin;%PATH%"
 
 echo killing dubbo Doc server
 
-for /f "tokens=1" %%i in ('jps -m ^| find "dubbo.doc"') do ( taskkill /F /PID %%i )
+for /f "tokens=1" %%i in ('jps -m ^| find "dubbo.api.docs"') do ( taskkill /F /PID %%i )
 
 echo Done!
diff --git a/dubbo-api-docs/distribution/bin/startup.cmd b/dubbo-api-docs/distribution/bin/startup.cmd
index 6f91812..d748ab2 100644
--- a/dubbo-api-docs/distribution/bin/startup.cmd
+++ b/dubbo-api-docs/distribution/bin/startup.cmd
@@ -28,4 +28,4 @@ set "JAVA_OPT=%JAVA_OPT% -Xms512m -Xmx512m -Xmn256m"
 
 set "JAVA_OPT=%JAVA_OPT% -jar %BASE_DIR%\lib\%SERVER%.jar"
 
-call "%JAVA%" %JAVA_OPT% dubbo.doc %*
+call "%JAVA%" %JAVA_OPT% dubbo.api.docs %*
diff --git a/dubbo-api-docs/distribution/bin/startup.sh b/dubbo-api-docs/distribution/bin/startup.sh
index 039757e..c3fd3aa 100644
--- a/dubbo-api-docs/distribution/bin/startup.sh
+++ b/dubbo-api-docs/distribution/bin/startup.sh
@@ -47,11 +47,11 @@ if [ -z "$JAVA_HOME" ]; then
         error_exit "Please set the JAVA_HOME variable in your environment, We need java(x64)! jdk8 or later is better!"
   fi
 fi
-export SERVER="dubbo-doc-ui-server"
+export SERVER="dubbo-api-docs-ui-server"
 export JAVA_HOME
 export JAVA="$JAVA_HOME/bin/java"
 export BASE_DIR=`cd $(dirname $0)/..; pwd`
 JAVA_OPT="${JAVA_OPT} -Xms512m -Xmx512m -Xmn256m"
 JAVA_OPT="${JAVA_OPT} -jar ${BASE_DIR}/lib/${SERVER}.jar"
-nohup $JAVA ${JAVA_OPT} dubbo.doc >> ${BASE_DIR}/logs/catlog.out 2>&1 &
+nohup $JAVA ${JAVA_OPT} dubbo.api.docs >> ${BASE_DIR}/logs/catlog.out 2>&1 &
 echo "${SERVER} is starting,you can check the ${BASE_DIR}/logs/catlog.out"
\ No newline at end of file
diff --git a/dubbo-api-docs/distribution/pom.xml b/dubbo-api-docs/distribution/pom.xml
index 5bf2aa5..72a573c 100644
--- a/dubbo-api-docs/distribution/pom.xml
+++ b/dubbo-api-docs/distribution/pom.xml
@@ -22,7 +22,7 @@
     <parent>
         <groupId>org.apache.dubbo</groupId>
         <artifactId>dubbo-api-docs</artifactId>
-        <version>2.7.9-SNAPSHOT</version>
+        <version>${revision}</version>
         <relativePath>../pom.xml</relativePath>
     </parent>
 
@@ -40,7 +40,7 @@
     </dependencies>
     <profiles>
         <profile>
-            <id>release-dubboDoc</id>
+            <id>release-dubboApiDocs</id>
             <dependencies>
                 <dependency>
                     <groupId>org.apache.dubbo</groupId>
diff --git a/dubbo-api-docs/dubbo-api-docs-annotations/pom.xml b/dubbo-api-docs/dubbo-api-docs-annotations/pom.xml
index 3437ad5..45b8615 100644
--- a/dubbo-api-docs/dubbo-api-docs-annotations/pom.xml
+++ b/dubbo-api-docs/dubbo-api-docs-annotations/pom.xml
@@ -21,7 +21,7 @@
     <parent>
         <groupId>org.apache.dubbo</groupId>
         <artifactId>dubbo-api-docs</artifactId>
-        <version>2.7.9-SNAPSHOT</version>
+        <version>${revision}</version>
         <relativePath>../pom.xml</relativePath>
     </parent>
 
diff --git a/dubbo-api-docs/dubbo-api-docs-core/pom.xml b/dubbo-api-docs/dubbo-api-docs-core/pom.xml
index c251cd2..ff4fcde 100644
--- a/dubbo-api-docs/dubbo-api-docs-core/pom.xml
+++ b/dubbo-api-docs/dubbo-api-docs-core/pom.xml
@@ -22,7 +22,7 @@
     <parent>
         <groupId>org.apache.dubbo</groupId>
         <artifactId>dubbo-api-docs</artifactId>
-        <version>2.7.9-SNAPSHOT</version>
+        <version>${revision}</version>
         <relativePath>../pom.xml</relativePath>
     </parent>
 
diff --git a/dubbo-api-docs/dubbo-api-docs-examples/examples-api/pom.xml b/dubbo-api-docs/dubbo-api-docs-examples/examples-api/pom.xml
index 252a1df..961cb5c 100644
--- a/dubbo-api-docs/dubbo-api-docs-examples/examples-api/pom.xml
+++ b/dubbo-api-docs/dubbo-api-docs-examples/examples-api/pom.xml
@@ -21,7 +21,7 @@
     <parent>
         <groupId>org.apache.dubbo.examples.apidocs</groupId>
         <artifactId>dubbo-api-docs-examples</artifactId>
-        <version>2.7.9-SNAPSHOT</version>
+        <version>${revision}</version>
         <relativePath>../pom.xml</relativePath>
     </parent>
 
diff --git a/dubbo-api-docs/dubbo-api-docs-examples/examples-provider-sca/pom.xml b/dubbo-api-docs/dubbo-api-docs-examples/examples-provider-sca/pom.xml
index 00d09d5..6cd0781 100644
--- a/dubbo-api-docs/dubbo-api-docs-examples/examples-provider-sca/pom.xml
+++ b/dubbo-api-docs/dubbo-api-docs-examples/examples-provider-sca/pom.xml
@@ -21,7 +21,7 @@
     <parent>
         <groupId>org.apache.dubbo.examples.apidocs</groupId>
         <artifactId>dubbo-api-docs-examples</artifactId>
-        <version>2.7.9-SNAPSHOT</version>
+        <version>${revision}</version>
         <relativePath>../pom.xml</relativePath>
     </parent>
 
diff --git a/dubbo-api-docs/dubbo-api-docs-examples/examples-provider/pom.xml b/dubbo-api-docs/dubbo-api-docs-examples/examples-provider/pom.xml
index acc63d4..c3bd6c5 100644
--- a/dubbo-api-docs/dubbo-api-docs-examples/examples-provider/pom.xml
+++ b/dubbo-api-docs/dubbo-api-docs-examples/examples-provider/pom.xml
@@ -21,7 +21,7 @@
     <parent>
         <groupId>org.apache.dubbo.examples.apidocs</groupId>
         <artifactId>dubbo-api-docs-examples</artifactId>
-        <version>2.7.9-SNAPSHOT</version>
+        <version>${revision}</version>
         <relativePath>../pom.xml</relativePath>
     </parent>
 
diff --git a/dubbo-api-docs/dubbo-api-docs-examples/pom.xml b/dubbo-api-docs/dubbo-api-docs-examples/pom.xml
index bf7686b..61862fe 100644
--- a/dubbo-api-docs/dubbo-api-docs-examples/pom.xml
+++ b/dubbo-api-docs/dubbo-api-docs-examples/pom.xml
@@ -21,7 +21,7 @@
     <parent>
         <groupId>org.apache.dubbo</groupId>
         <artifactId>dubbo-api-docs</artifactId>
-        <version>2.7.9-SNAPSHOT</version>
+        <version>${revision}</version>
         <relativePath>../pom.xml</relativePath>
     </parent>
 
diff --git a/dubbo-api-docs/dubbo-api-docs-ui-server/pom.xml b/dubbo-api-docs/dubbo-api-docs-ui-server/pom.xml
index 9044a7d..7698683 100644
--- a/dubbo-api-docs/dubbo-api-docs-ui-server/pom.xml
+++ b/dubbo-api-docs/dubbo-api-docs-ui-server/pom.xml
@@ -17,29 +17,28 @@
  -->
 <project xmlns="http://maven.apache.org/POM/4.0.0" xmlns:xsi="http://www.w3.org/2001/XMLSchema-instance" xsi:schemaLocation="http://maven.apache.org/POM/4.0.0 http://maven.apache.org/xsd/maven-4.0.0.xsd">
     <modelVersion>4.0.0</modelVersion>
-    <groupId>org.apache.dubbo</groupId>
+
+    <parent>
+        <groupId>org.apache.dubbo</groupId>
+        <artifactId>dubbo-api-docs</artifactId>
+        <version>${revision}</version>
+        <relativePath>../pom.xml</relativePath>
+    </parent>
+
     <artifactId>dubbo-api-docs-ui-server</artifactId>
-    <version>2.7.9-SNAPSHOT</version>
     <packaging>jar</packaging>
     <name>dubbo-api-docs-ui-server</name>
     <description>Web ui, responsible for displaying doc and providing testing function</description>
 
-    <parent>
-        <groupId>org.springframework.boot</groupId>
-        <artifactId>spring-boot-starter-parent</artifactId>
-        <version>2.3.4.RELEASE</version>
-        <relativePath />
-    </parent>
-
     <properties>
     </properties>
-    
+
     <dependencyManagement>
         <dependencies>
             <dependency>
-                <groupId>org.apache.dubbo</groupId>
-                <artifactId>dubbo-api-docs</artifactId>
-                <version>2.7.9-SNAPSHOT</version>
+                <groupId>org.springframework.boot</groupId>
+                <artifactId>spring-boot-starter-parent</artifactId>
+                <version>${spring-boot.version}</version>
                 <type>pom</type>
                 <scope>import</scope>
             </dependency>
@@ -219,11 +218,6 @@
         </dependency>
 
         <dependency>
-            <groupId>org.projectlombok</groupId>
-            <artifactId>lombok</artifactId>
-        </dependency>
-
-        <dependency>
             <groupId>commons-io</groupId>
             <artifactId>commons-io</artifactId>
         </dependency>
@@ -242,9 +236,9 @@
 
     <profiles>
         <profile>
-            <id>release-dubboDoc</id>
+            <id>release-dubboApiDocs</id>
             <build>
-                <finalName>dubbo-doc-ui-server</finalName>
+                <finalName>dubbo-api-docs-ui-server</finalName>
                 <plugins>
                     <plugin>
                         <artifactId>maven-jar-plugin</artifactId>
diff --git a/dubbo-api-docs/dubbo-api-docs-ui-server/src/main/resources/application.yml b/dubbo-api-docs/dubbo-api-docs-ui-server/src/main/resources/application.yml
index a482c54..76231ff 100644
--- a/dubbo-api-docs/dubbo-api-docs-ui-server/src/main/resources/application.yml
+++ b/dubbo-api-docs/dubbo-api-docs-ui-server/src/main/resources/application.yml
@@ -2,7 +2,7 @@ server:
   port: 8888
 spring:
   application:
-    name: dubbo-doc-ui-server
+    name: dubbo-api-docs-ui-server
 dubbo:
   reference:
     heartbeat: 1000
diff --git a/dubbo-api-docs/dubbo-api-docs-ui-server/src/main/resources/banner.txt b/dubbo-api-docs/dubbo-api-docs-ui-server/src/main/resources/banner.txt
index ca3cb3e..86690cb 100644
--- a/dubbo-api-docs/dubbo-api-docs-ui-server/src/main/resources/banner.txt
+++ b/dubbo-api-docs/dubbo-api-docs-ui-server/src/main/resources/banner.txt
@@ -1,6 +1,7 @@
-  _____        _     _                         _____ _____    _____
- |  __ \      | |   | |                  /\   |  __ \_   _|  |  __ \
- | |  | |_   _| |__ | |__    ___       /  \  | |__) || |    | |  | | ___   ___ ___
- | |  | | | | | '_ \| '_ \ / _  \     / /\ \ |  ___/ | |    | |  | |/ _ \ / __/ __|
- | |__| | |_| | |_) | |_) | (_) |   / ____ \| |    _| |_   | |__| | (_) | (__\__ \
- |_____/ \__,_|_.__/|_.__/ \___/  /_/    \_\_|   |_____|  |_____/ \___/ \___|___/
+  _____        _     _                        _____ _____      _____
+ |  __ \      | |   | |                 /\   |  __ \_   _|    |  __ \
+ | |  | |_   _| |__ | |__   ___        /  \  | |__) || |      | |  | | ___   ___ ___
+ | |  | | | | | '_ \| '_ \ / _ \      / /\ \ |  ___/ | |      | |  | |/ _ \ / __/ __|
+ | |__| | |_| | |_) | |_) | (_) |    / ____ \| |    _| |_     | |__| | (_) | (__\__ \
+ |_____/ \__,_|_.__/|_.__/ \___/    /_/    \_\_|   |_____|    |_____/ \___/ \___|___/
+
diff --git a/dubbo-api-docs/dubbo-api-docs-ui-server/src/main/resources/log4j2.xml b/dubbo-api-docs/dubbo-api-docs-ui-server/src/main/resources/log4j2.xml
index 929bc5e..8bd3515 100644
--- a/dubbo-api-docs/dubbo-api-docs-ui-server/src/main/resources/log4j2.xml
+++ b/dubbo-api-docs/dubbo-api-docs-ui-server/src/main/resources/log4j2.xml
@@ -1,7 +1,7 @@
 <?xml version="1.0" encoding="UTF-8"?>
 <Configuration status="WARN" monitorInterval="600" shutdownHook="disable">
     <Properties>
-        <Property name="logDir" value="/home/weihu/deploy/logs/dubbo-doc/" />
+        <Property name="logDir" value="/home/weihu/deploy/logs/dubbo-api-docs/" />
         <Property name="genericPattern" value="[dubboDoc]-%d{yyyy-MM-dd HH:mm:ss.SSS} [%t] %-5level %logger{36} - %msg%n" />
         <Property name="genericFilePattern" value="%d{yyyy-MM-dd HH:mm}-%i" />
     </Properties>
diff --git a/dubbo-api-docs/dubbo-api-docs-ui-server/src/main/resources/static/css/index.css b/dubbo-api-docs/dubbo-api-docs-ui-server/src/main/resources/static/css/index.css
index 98a1ac6..6642125 100644
--- a/dubbo-api-docs/dubbo-api-docs-ui-server/src/main/resources/static/css/index.css
+++ b/dubbo-api-docs/dubbo-api-docs-ui-server/src/main/resources/static/css/index.css
@@ -1 +1 @@
-.next-sr-only{position:absolute;width:1px;height:1px;padding:0;overflow:hidden;clip:rect(0,0,0,0);white-space:nowrap;border:0;margin:-1px}/*! normalize.css v7.0.0 | MIT License | github.com/necolas/normalize.css */html{line-height:1.15;-ms-text-size-adjust:100%;-webkit-text-size-adjust:100%}body{margin:0}article,aside,footer,header,nav,section{display:block}h1{font-size:2em;margin:.67em 0}figcaption,figure,main{display:block}figure{margin:1em 40px}hr{-webkit-box-sizing:content-box;box-si [...]
\ No newline at end of file
+.next-sr-only{position:absolute;width:1px;height:1px;padding:0;overflow:hidden;clip:rect(0,0,0,0);white-space:nowrap;border:0;margin:-1px}/*! normalize.css v7.0.0 | MIT License | github.com/necolas/normalize.css */html{line-height:1.15;-ms-text-size-adjust:100%;-webkit-text-size-adjust:100%}body{margin:0}article,aside,footer,header,nav,section{display:block}h1{font-size:2em;margin:.67em 0}figcaption,figure,main{display:block}figure{margin:1em 40px}hr{-webkit-box-sizing:content-box;box-si [...]
\ No newline at end of file
diff --git a/dubbo-api-docs/dubbo-api-docs-ui-server/src/main/resources/static/js/index.js b/dubbo-api-docs/dubbo-api-docs-ui-server/src/main/resources/static/js/index.js
index 948c8b0..a7ab576 100644
--- a/dubbo-api-docs/dubbo-api-docs-ui-server/src/main/resources/static/js/index.js
+++ b/dubbo-api-docs/dubbo-api-docs-ui-server/src/main/resources/static/js/index.js
@@ -1,26 +1,26 @@
-!function(e){var t={};function n(r){if(t[r])return t[r].exports;var o=t[r]={i:r,l:!1,exports:{}};return e[r].call(o.exports,o,o.exports,n),o.l=!0,o.exports}n.m=e,n.c=t,n.d=function(e,t,r){n.o(e,t)||Object.defineProperty(e,t,{enumerable:!0,get:r})},n.r=function(e){"undefined"!=typeof Symbol&&Symbol.toStringTag&&Object.defineProperty(e,Symbol.toStringTag,{value:"Module"}),Object.defineProperty(e,"__esModule",{value:!0})},n.t=function(e,t){if(1&t&&(e=n(e)),8&t)return e;if(4&t&&"object"==typ [...]
+!function(e){var t={};function n(r){if(t[r])return t[r].exports;var o=t[r]={i:r,l:!1,exports:{}};return e[r].call(o.exports,o,o.exports,n),o.l=!0,o.exports}n.m=e,n.c=t,n.d=function(e,t,r){n.o(e,t)||Object.defineProperty(e,t,{enumerable:!0,get:r})},n.r=function(e){"undefined"!=typeof Symbol&&Symbol.toStringTag&&Object.defineProperty(e,Symbol.toStringTag,{value:"Module"}),Object.defineProperty(e,"__esModule",{value:!0})},n.t=function(e,t){if(1&t&&(e=n(e)),8&t)return e;if(4&t&&"object"==typ [...]
 /*!
   Copyright (c) 2017 Jed Watson.
   Licensed under the MIT License (MIT), see
   http://jedwatson.github.io/classnames
-*/!function(){"use strict";var n={}.hasOwnProperty;function a(){for(var e=[],t=0;t<arguments.length;t++){var r=arguments[t];if(r){var o=typeof r;if("string"===o||"number"===o)e.push(r);else if(Array.isArray(r)&&r.length){var i=a.apply(null,r);i&&e.push(i)}else if("object"===o)for(var s in r)n.call(r,s)&&r[s]&&e.push(s)}}return e.join(" ")}e.exports?(a.default=a,e.exports=a):void 0===(o=function(){return a}.apply(t,r=[]))||(e.exports=o)}()},function(e,t,n){"use strict";t.__esModule=!0;var [...]
+*/!function(){"use strict";var n={}.hasOwnProperty;function a(){for(var e=[],t=0;t<arguments.length;t++){var r=arguments[t];if(r){var o=typeof r;if("string"===o||"number"===o)e.push(r);else if(Array.isArray(r)&&r.length){var i=a.apply(null,r);i&&e.push(i)}else if("object"===o)for(var s in r)n.call(r,s)&&r[s]&&e.push(s)}}return e.join(" ")}e.exports?(a.default=a,e.exports=a):void 0===(o=function(){return a}.apply(t,r=[]))||(e.exports=o)}()},function(e,t,n){"use strict";t.__esModule=!0;var [...]
 /*! *****************************************************************************
-Copyright (c) Microsoft Corporation. All rights reserved.
-Licensed 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
+Copyright (c) Microsoft Corporation.
 
-THIS CODE IS PROVIDED ON AN *AS IS* BASIS, WITHOUT WARRANTIES OR CONDITIONS OF ANY
-KIND, EITHER EXPRESS OR IMPLIED, INCLUDING WITHOUT LIMITATION ANY IMPLIED
-WARRANTIES OR CONDITIONS OF TITLE, FITNESS FOR A PARTICULAR PURPOSE,
-MERCHANTABLITY OR NON-INFRINGEMENT.
+Permission to use, copy, modify, and/or distribute this software for any
+purpose with or without fee is hereby granted.
 
-See the Apache Version 2.0 License for specific language governing permissions
-and limitations under the License.
+THE SOFTWARE IS PROVIDED "AS IS" AND THE AUTHOR DISCLAIMS ALL WARRANTIES WITH
+REGARD TO THIS SOFTWARE INCLUDING ALL IMPLIED WARRANTIES OF MERCHANTABILITY
+AND FITNESS. IN NO EVENT SHALL THE AUTHOR BE LIABLE FOR ANY SPECIAL, DIRECT,
+INDIRECT, OR CONSEQUENTIAL DAMAGES OR ANY DAMAGES WHATSOEVER RESULTING FROM
+LOSS OF USE, DATA OR PROFITS, WHETHER IN AN ACTION OF CONTRACT, NEGLIGENCE OR
+OTHER TORTIOUS ACTION, ARISING OUT OF OR IN CONNECTION WITH THE USE OR
+PERFORMANCE OF THIS SOFTWARE.
 ***************************************************************************** */
-var r=function(e,t){return(r=Object.setPrototypeOf||{__proto__:[]}instanceof Array&&function(e,t){e.__proto__=t}||function(e,t){for(var n in t)t.hasOwnProperty(n)&&(e[n]=t[n])})(e,t)};function o(e,t){function n(){this.constructor=e}r(e,t),e.prototype=null===t?Object.create(t):(n.prototype=t.prototype,new n)}var a=function(){return(a=Object.assign||function e(t){for(var n,r=1,o=arguments.length;r<o;r++)for(var a in n=arguments[r])Object.prototype.hasOwnProperty.call(n,a)&&(t[a]=n[a]);retu [...]
+var r=function(e,t){return(r=Object.setPrototypeOf||{__proto__:[]}instanceof Array&&function(e,t){e.__proto__=t}||function(e,t){for(var n in t)t.hasOwnProperty(n)&&(e[n]=t[n])})(e,t)};function o(e,t){function n(){this.constructor=e}r(e,t),e.prototype=null===t?Object.create(t):(n.prototype=t.prototype,new n)}var a=function(){return(a=Object.assign||function e(t){for(var n,r=1,o=arguments.length;r<o;r++)for(var a in n=arguments[r])Object.prototype.hasOwnProperty.call(n,a)&&(t[a]=n[a]);retu [...]
 /*!
- * jQuery JavaScript Library v3.4.1
+ * jQuery JavaScript Library v3.5.1
  * https://jquery.com/
  *
  * Includes Sizzle.js
@@ -30,66 +30,83 @@ var r=function(e,t){return(r=Object.setPrototypeOf||{__proto__:[]}instanceof Arr
  * Released under the MIT license
  * https://jquery.org/license
  *
- * Date: 2019-05-01T21:04Z
- */!function(t,n){"use strict";"object"==typeof e.exports?e.exports=t.document?n(t,!0):function(e){if(!e.document)throw new Error("jQuery requires a window with a document");return n(e)}:n(t)}("undefined"!=typeof window?window:this,(function(n,a){"use strict";var i=[],s=n.document,l=Object.getPrototypeOf,u=i.slice,c=i.concat,f=i.push,p=i.indexOf,d={},h=d.toString,v=d.hasOwnProperty,m=v.toString,y=m.call(Object),g={},b=function e(t){return"function"==typeof t&&"number"!=typeof t.nodeType} [...]
+ * Date: 2020-05-04T22:49Z
+ */!function(t,n){"use strict";"object"==typeof e.exports?e.exports=t.document?n(t,!0):function(e){if(!e.document)throw new Error("jQuery requires a window with a document");return n(e)}:n(t)}("undefined"!=typeof window?window:this,(function(n,a){"use strict";var i=[],s=Object.getPrototypeOf,u=i.slice,l=i.flat?function(e){return i.flat.call(e)}:function(e){return i.concat.apply([],e)},c=i.push,f=i.indexOf,p={},d=p.toString,h=p.hasOwnProperty,v=h.toString,m=v.call(Object),y={},g=function  [...]
 /*!
- * Sizzle CSS Selector Engine v2.3.4
+ * Sizzle CSS Selector Engine v2.3.5
  * https://sizzlejs.com/
  *
  * Copyright JS Foundation and other contributors
  * Released under the MIT license
  * https://js.foundation/
  *
- * Date: 2019-04-08
+ * Date: 2020-03-14
  */
-function(e){var t,n,r,o,a,i,s,l,u,c,f,p,d,h,v,m,y,g,b,w="sizzle"+1*new Date,x=e.document,E=0,_=0,C=le(),S=le(),k=le(),O=le(),T=function(e,t){return e===t&&(f=!0),0},P={}.hasOwnProperty,j=[],A=j.pop,N=j.push,M=j.push,D=j.slice,L=function(e,t){for(var n=0,r=e.length;n<r;n++)if(e[n]===t)return n;return-1},R="checked|selected|async|autofocus|autoplay|controls|defer|disabled|hidden|ismap|loop|multiple|open|readonly|required|scoped",I="[\\x20\\t\\r\\n\\f]",F="(?:\\\\.|[\\w-]|[^\0-\\xa0])+",z=" [...]
+function(e){var t,n,r,o,a,i,s,u,l,c,f,p,d,h,v,m,y,g,b,w="sizzle"+1*new Date,x=e.document,E=0,_=0,O=ue(),S=ue(),C=ue(),k=ue(),P=function(e,t){return e===t&&(f=!0),0},T={}.hasOwnProperty,j=[],A=j.pop,N=j.push,M=j.push,D=j.slice,R=function(e,t){for(var n=0,r=e.length;n<r;n++)if(e[n]===t)return n;return-1},L="checked|selected|async|autofocus|autoplay|controls|defer|disabled|hidden|ismap|loop|multiple|open|readonly|required|scoped",I="[\\x20\\t\\r\\n\\f]",F="(?:\\\\[\\da-fA-F]{1,6}"+I+"?|\\\\ [...]
+/*
+object-assign
+(c) Sindre Sorhus
+@license MIT
+*/var r=Object.getOwnPropertySymbols,o=Object.prototype.hasOwnProperty,a=Object.prototype.propertyIsEnumerable;function i(e){if(null==e)throw new TypeError("Object.assign cannot be called with null or undefined");return Object(e)}function s(){try{if(!Object.assign)return!1;var e=new String("abc"),t;if(e[5]="de","5"===Object.getOwnPropertyNames(e)[0])return!1;for(var n={},r=0;r<10;r++)n["_"+String.fromCharCode(r)]=r;if("0123456789"!==Object.getOwnPropertyNames(n).map((function(e){return n [...]
 /*!
  * cookie
  * Copyright(c) 2012-2014 Roman Shtylman
  * Copyright(c) 2015 Douglas Christopher Wilson
  * MIT Licensed
- */t.parse=s,t.serialize=l;var r=decodeURIComponent,o=encodeURIComponent,a=/; */,i=/^[\u0009\u0020-\u007e\u0080-\u00ff]+$/;function s(e,t){if("string"!=typeof e)throw new TypeError("argument str must be a string");for(var n={},o=t||{},i=e.split(a),s=o.decode||r,l=0;l<i.length;l++){var c=i[l],f=c.indexOf("=");if(!(f<0)){var p=c.substr(0,f).trim(),d=c.substr(++f,c.length).trim();'"'==d[0]&&(d=d.slice(1,-1)),null==n[p]&&(n[p]=u(d,s))}}return n}function l(e,t,n){var r=n||{},a=r.encode||o;if( [...]
-/*
-object-assign
-(c) Sindre Sorhus
-@license MIT
-*/var r=Object.getOwnPropertySymbols,o=Object.prototype.hasOwnProperty,a=Object.prototype.propertyIsEnumerable;function i(e){if(null==e)throw new TypeError("Object.assign cannot be called with null or undefined");return Object(e)}function s(){try{if(!Object.assign)return!1;var e=new String("abc"),t;if(e[5]="de","5"===Object.getOwnPropertyNames(e)[0])return!1;for(var n={},r=0;r<10;r++)n["_"+String.fromCharCode(r)]=r;if("0123456789"!==Object.getOwnPropertyNames(n).map((function(e){return n [...]
-/** @license React v16.13.0
+ */t.parse=s,t.serialize=u;var r=decodeURIComponent,o=encodeURIComponent,a=/; */,i=/^[\u0009\u0020-\u007e\u0080-\u00ff]+$/;function s(e,t){if("string"!=typeof e)throw new TypeError("argument str must be a string");for(var n={},o=t||{},i=e.split(a),s=o.decode||r,u=0;u<i.length;u++){var c=i[u],f=c.indexOf("=");if(!(f<0)){var p=c.substr(0,f).trim(),d=c.substr(++f,c.length).trim();'"'==d[0]&&(d=d.slice(1,-1)),null==n[p]&&(n[p]=l(d,s))}}return n}function u(e,t,n){var r=n||{},a=r.encode||o;if( [...]
+//! version : 2.29.1
+//! authors : Tim Wood, Iskren Chernev, Moment.js contributors
+//! license : MIT
+//! momentjs.com
+r=this,o=function(){"use strict";var t,r;function o(){return t.apply(null,arguments)}function a(e){t=e}function i(e){return e instanceof Array||"[object Array]"===Object.prototype.toString.call(e)}function s(e){return null!=e&&"[object Object]"===Object.prototype.toString.call(e)}function u(e,t){return Object.prototype.hasOwnProperty.call(e,t)}function l(e){if(Object.getOwnPropertyNames)return 0===Object.getOwnPropertyNames(e).length;var t;for(t in e)if(u(e,t))return!1;return!0}function  [...]
+//! moment.js
+o.version="2.29.1",a($n),o.fn=la,o.min=Qn,o.max=er,o.now=tr,o.utc=v,o.unix=ca,o.months=ya,o.isDate=p,o.locale=vn,o.invalid=b,o.duration=Pr,o.isMoment=O,o.weekdays=ba,o.parseZone=fa,o.localeData=gn,o.isDuration=sr,o.monthsShort=ga,o.weekdaysMin=xa,o.defineLocale=mn,o.updateLocale=yn,o.locales=bn,o.weekdaysShort=wa,o.normalizeUnits=oe,o.relativeTimeRounding=oi,o.relativeTimeThreshold=ai,o.calendarFormat=Ur,o.prototype=la,o.HTML5_FMT={DATETIME_LOCAL:"YYYY-MM-DDTHH:mm",DATETIME_LOCAL_SECONDS [...]
+//! moment.js locale configuration
+var t;return e.defineLocale("zh-cn",{months:"\u4e00\u6708_\u4e8c\u6708_\u4e09\u6708_\u56db\u6708_\u4e94\u6708_\u516d\u6708_\u4e03\u6708_\u516b\u6708_\u4e5d\u6708_\u5341\u6708_\u5341\u4e00\u6708_\u5341\u4e8c\u6708".split("_"),monthsShort:"1\u6708_2\u6708_3\u6708_4\u6708_5\u6708_6\u6708_7\u6708_8\u6708_9\u6708_10\u6708_11\u6708_12\u6708".split("_"),weekdays:"\u661f\u671f\u65e5_\u661f\u671f\u4e00_\u661f\u671f\u4e8c_\u661f\u671f\u4e09_\u661f\u671f\u56db_\u661f\u671f\u4e94_\u661f\u671f\u516d" [...]
+/** @license React v16.14.0
  * react.production.min.js
  *
  * Copyright (c) Facebook, Inc. and its affiliates.
  *
  * This source code is licensed under the MIT license found in the
  * LICENSE file in the root directory of this source tree.
- */var r=n(247),o="function"==typeof Symbol&&Symbol.for,a=o?Symbol.for("react.element"):60103,i=o?Symbol.for("react.portal"):60106,s=o?Symbol.for("react.fragment"):60107,l=o?Symbol.for("react.strict_mode"):60108,u=o?Symbol.for("react.profiler"):60114,c=o?Symbol.for("react.provider"):60109,f=o?Symbol.for("react.context"):60110,p=o?Symbol.for("react.forward_ref"):60112,d=o?Symbol.for("react.suspense"):60113,h=o?Symbol.for("react.memo"):60115,v=o?Symbol.for("react.lazy"):60116,m="function"= [...]
-/** @license React v16.13.0
+ */var r=n(189),o="function"==typeof Symbol&&Symbol.for,a=o?Symbol.for("react.element"):60103,i=o?Symbol.for("react.portal"):60106,s=o?Symbol.for("react.fragment"):60107,u=o?Symbol.for("react.strict_mode"):60108,l=o?Symbol.for("react.profiler"):60114,c=o?Symbol.for("react.provider"):60109,f=o?Symbol.for("react.context"):60110,p=o?Symbol.for("react.forward_ref"):60112,d=o?Symbol.for("react.suspense"):60113,h=o?Symbol.for("react.memo"):60115,v=o?Symbol.for("react.lazy"):60116,m="function"= [...]
+/** @license React v16.14.0
  * react-dom.production.min.js
  *
  * Copyright (c) Facebook, Inc. and its affiliates.
  *
  * This source code is licensed under the MIT license found in the
  * LICENSE file in the root directory of this source tree.
- */var r=n(1),o=n(247),a=n(525);function i(e){for(var t="https://reactjs.org/docs/error-decoder.html?invariant="+e,n=1;n<arguments.length;n++)t+="&args[]="+encodeURIComponent(arguments[n]);return"Minified React error #"+e+"; visit "+t+" for the full message or use the non-minified dev environment for full errors and additional helpful warnings."}if(!r)throw Error(i(227));function s(e,t,n,r,o,a,i,s,l){var u=Array.prototype.slice.call(arguments,3);try{t.apply(n,u)}catch(e){this.onError(e)} [...]
-/** @license React v0.19.0
+ */var r=n(1),o=n(189),a=n(562);function i(e){for(var t="https://reactjs.org/docs/error-decoder.html?invariant="+e,n=1;n<arguments.length;n++)t+="&args[]="+encodeURIComponent(arguments[n]);return"Minified React error #"+e+"; visit "+t+" for the full message or use the non-minified dev environment for full errors and additional helpful warnings."}if(!r)throw Error(i(227));function s(e,t,n,r,o,a,i,s,u){var l=Array.prototype.slice.call(arguments,3);try{t.apply(n,l)}catch(e){this.onError(e)} [...]
+/** @license React v0.19.1
  * scheduler.production.min.js
  *
  * Copyright (c) Facebook, Inc. and its affiliates.
  *
  * This source code is licensed under the MIT license found in the
  * LICENSE file in the root directory of this source tree.
- */var r,o,a,i,s;if("undefined"==typeof window||"function"!=typeof MessageChannel){var l=null,u=null,c=function(){if(null!==l)try{var e=t.unstable_now();l(!0,e),l=null}catch(e){throw setTimeout(c,0),e}},f=Date.now();t.unstable_now=function(){return Date.now()-f},r=function(e){null!==l?setTimeout(r,0,e):(l=e,setTimeout(c,0))},o=function(e,t){u=setTimeout(e,t)},a=function(){clearTimeout(u)},i=function(){return!1},s=t.unstable_forceFrameRate=function(){}}else{var p=window.performance,d=wind [...]
+ */var r,o,a,i,s;if("undefined"==typeof window||"function"!=typeof MessageChannel){var u=null,l=null,c=function(){if(null!==u)try{var e=t.unstable_now();u(!0,e),u=null}catch(e){throw setTimeout(c,0),e}},f=Date.now();t.unstable_now=function(){return Date.now()-f},r=function(e){null!==u?setTimeout(r,0,e):(u=e,setTimeout(c,0))},o=function(e,t){l=setTimeout(e,t)},a=function(){clearTimeout(l)},i=function(){return!1},s=t.unstable_forceFrameRate=function(){}}else{var p=window.performance,d=wind [...]
+/** @license React v16.14.0
+ * react-dom-server.browser.production.min.js
+ *
+ * Copyright (c) Facebook, Inc. and its affiliates.
+ *
+ * This source code is licensed under the MIT license found in the
+ * LICENSE file in the root directory of this source tree.
+ */var r=n(189),o=n(1);function a(e){for(var t="https://reactjs.org/docs/error-decoder.html?invariant="+e,n=1;n<arguments.length;n++)t+="&args[]="+encodeURIComponent(arguments[n]);return"Minified React error #"+e+"; visit "+t+" for the full message or use the non-minified dev environment for full errors and additional helpful warnings."}var i="function"==typeof Symbol&&Symbol.for,s=i?Symbol.for("react.portal"):60106,u=i?Symbol.for("react.fragment"):60107,l=i?Symbol.for("react.strict_mode [...]
 /*!
  * escape-html
  * Copyright(c) 2012-2013 TJ Holowaychuk
  * Copyright(c) 2015 Andreas Lubbe
  * Copyright(c) 2015 Tiancheng "Timothy" Gu
  * MIT Licensed
- */var r=/["'&<>]/;function o(e){var t=""+e,n=r.exec(t),o;if(!n)return t;var a="",i=0,s=0;for(i=n.index;i<t.length;i++){switch(t.charCodeAt(i)){case 34:o="&quot;";break;case 38:o="&amp;";break;case 39:o="&#39;";break;case 60:o="&lt;";break;case 62:o="&gt;";break;default:continue}s!==i&&(a+=t.substring(s,i)),s=i+1,a+=o}return s!==i?a+t.substring(s,i):a}e.exports=o},function(e,t,n){"use strict";t.decode=t.parse=n(561),t.encode=t.stringify=n(562)},function(e,t,n){"use strict";function r(e,t [...]
-/** @license React v16.13.0
+ */var r=/["'&<>]/;function o(e){var t=""+e,n=r.exec(t),o;if(!n)return t;var a="",i=0,s=0;for(i=n.index;i<t.length;i++){switch(t.charCodeAt(i)){case 34:o="&quot;";break;case 38:o="&amp;";break;case 39:o="&#39;";break;case 60:o="&lt;";break;case 62:o="&gt;";break;default:continue}s!==i&&(a+=t.substring(s,i)),s=i+1,a+=o}return s!==i?a+t.substring(s,i):a}e.exports=o},function(e,t,n){"use strict";t.decode=t.parse=n(597),t.encode=t.stringify=n(598)},function(e,t,n){"use strict";function r(e,t [...]
+/** @license React v16.13.1
  * react-is.production.min.js
  *
  * Copyright (c) Facebook, Inc. and its affiliates.
  *
  * This source code is licensed under the MIT license found in the
  * LICENSE file in the root directory of this source tree.
- */var r="function"==typeof Symbol&&Symbol.for,o=r?Symbol.for("react.element"):60103,a=r?Symbol.for("react.portal"):60106,i=r?Symbol.for("react.fragment"):60107,s=r?Symbol.for("react.strict_mode"):60108,l=r?Symbol.for("react.profiler"):60114,u=r?Symbol.for("react.provider"):60109,c=r?Symbol.for("react.context"):60110,f=r?Symbol.for("react.async_mode"):60111,p=r?Symbol.for("react.concurrent_mode"):60111,d=r?Symbol.for("react.forward_ref"):60112,h=r?Symbol.for("react.suspense"):60113,v=r?S [...]
\ No newline at end of file
+ */var r="function"==typeof Symbol&&Symbol.for,o=r?Symbol.for("react.element"):60103,a=r?Symbol.for("react.portal"):60106,i=r?Symbol.for("react.fragment"):60107,s=r?Symbol.for("react.strict_mode"):60108,u=r?Symbol.for("react.profiler"):60114,l=r?Symbol.for("react.provider"):60109,c=r?Symbol.for("react.context"):60110,f=r?Symbol.for("react.async_mode"):60111,p=r?Symbol.for("react.concurrent_mode"):60111,d=r?Symbol.for("react.forward_ref"):60112,h=r?Symbol.for("react.suspense"):60113,v=r?S [...]
\ No newline at end of file
diff --git a/dubbo-api-docs/pom.xml b/dubbo-api-docs/pom.xml
index 323ab37..9b81e6c 100644
--- a/dubbo-api-docs/pom.xml
+++ b/dubbo-api-docs/pom.xml
@@ -18,12 +18,13 @@
          xsi:schemaLocation="http://maven.apache.org/POM/4.0.0 http://maven.apache.org/maven-v4_0_0.xsd">
     <modelVersion>4.0.0</modelVersion>
     <parent>
-        <groupId>org.apache.dubbo</groupId>
-        <artifactId>dubbo-parent</artifactId>
-        <version>2.7.9-SNAPSHOT</version>
-        <relativePath />
+        <groupId>org.apache</groupId>
+        <artifactId>apache</artifactId>
+        <version>19</version>
     </parent>
+    <groupId>org.apache.dubbo</groupId>
     <artifactId>dubbo-api-docs</artifactId>
+    <version>${revision}</version>
     <packaging>pom</packaging>
     <name>${project.artifactId}</name>
     <description>Dubbo interface documentation, testing tools</description>
@@ -56,6 +57,13 @@
                 <type>pom</type>
                 <scope>import</scope>
             </dependency>
+            <dependency>
+                <groupId>org.apache.dubbo</groupId>
+                <artifactId>dubbo-parent</artifactId>
+                <version>${revision}</version>
+                <type>pom</type>
+                <scope>import</scope>
+            </dependency>
 
             <!-- Internal libs -->
             <dependency>
diff --git a/dubbo-api-docs/readmeImgs/DubboDoc.png b/dubbo-api-docs/readmeImgs/DubboDoc.png
new file mode 100644
index 0000000..4a5ab40
Binary files /dev/null and b/dubbo-api-docs/readmeImgs/DubboDoc.png differ


[dubbo-spi-extensions] 30/39: Merge pull request #4 from KeRan213539/modify-docs-examples

Posted by li...@apache.org.
This is an automated email from the ASF dual-hosted git repository.

liujun pushed a commit to branch 2.7.x
in repository https://gitbox.apache.org/repos/asf/dubbo-spi-extensions.git

commit 51f0c03232bde4384eb083803a929f84ab59505a
Merge: b916ed7 5f91e79
Author: Ian Luo <ia...@gmail.com>
AuthorDate: Thu Dec 24 20:21:25 2020 +0800

    Merge pull request #4 from KeRan213539/modify-docs-examples
    
    新增quick start demo, 修改bug

 .../core/DubboApiDocsAnnotationScanner.java        | 19 +++---
 .../dubbo/apidocs/core/beans/ApiCacheItem.java     | 16 ++++++
 .../apidocs/core/beans/ApiParamsCacheItem.java     | 16 ++++++
 .../dubbo/apidocs/core/beans/ModuleCacheItem.java  | 16 ++++++
 .../apache/dubbo/apidocs/utils/ClassTypeUtil.java  | 16 +++---
 .../apache/dubbo/apidocs/utils/SimpleTypeImpl.java | 16 ++++++
 .../apidocs/examples/api/IQuickStartDemo.java      | 36 ++++++++++++
 .../examples/params/QuickStartRequestBean.java     | 67 ++++++++++++++++++++++
 .../examples/params/QuickStartRespBean.java        | 52 +++++++++++++++++
 .../examples-provider-sca/pom.xml                  | 12 ++++
 .../examples-provider/pom.xml                      | 13 +++++
 .../examples/api/impl/QuickStartDemoImpl.java      | 42 ++++++++++++++
 12 files changed, 304 insertions(+), 17 deletions(-)


[dubbo-spi-extensions] 15/39: dubbo版本降到2.7.8; 调整前端UI

Posted by li...@apache.org.
This is an automated email from the ASF dual-hosted git repository.

liujun pushed a commit to branch 2.7.x
in repository https://gitbox.apache.org/repos/asf/dubbo-spi-extensions.git

commit 31dbe2ec73d6d181ab14a4f52cf8bcf57710d073
Author: qq213539 <21...@qq.com>
AuthorDate: Thu Nov 19 09:48:34 2020 +0800

    dubbo版本降到2.7.8; 调整前端UI
---
 .../apidocs/examples/params/DemoParamBean1.java    | 10 ++++++--
 .../dubbo-api-docs-ui/src/locales/en-US.json       |  2 ++
 .../dubbo-api-docs-ui/src/locales/zh-CN.json       |  2 ++
 .../dubbo-api-docs-ui/src/pages/ApiForm/index.tsx  | 29 ++++++++++++----------
 dubbo-api-docs/pom.xml                             | 28 ++++++++++-----------
 5 files changed, 42 insertions(+), 29 deletions(-)

diff --git a/dubbo-api-docs/dubbo-api-docs-examples/examples-api/src/main/java/org/apache/dubbo/apidocs/examples/params/DemoParamBean1.java b/dubbo-api-docs/dubbo-api-docs-examples/examples-api/src/main/java/org/apache/dubbo/apidocs/examples/params/DemoParamBean1.java
index 8617515..b1025ea 100644
--- a/dubbo-api-docs/dubbo-api-docs-examples/examples-api/src/main/java/org/apache/dubbo/apidocs/examples/params/DemoParamBean1.java
+++ b/dubbo-api-docs/dubbo-api-docs-examples/examples-api/src/main/java/org/apache/dubbo/apidocs/examples/params/DemoParamBean1.java
@@ -33,10 +33,16 @@ import java.util.Map;
 @Setter
 public class DemoParamBean1 {
 
-    @RequestParam("Name")
+    @RequestParam(value = "Name", description = "说明测试说明测试说明测试说明测试说明测试说明测试说明测试说明测试说明测试" +
+            "说明测试说明测试说明测试说明测试说明测试说明测试说明测试说明测试说明测试说明测试说明测试说明测试说明测试说明测试说明测" +
+            "说明测试说明测试说明测试说明测试说明测试说明测试说明测试说明测试说明测试说明测试说明测试说明测试说明测试说明测试说明测" +
+            "说明测试说明测试说明测试说明测试说明测试说明测试说明测试说明测试说明测试说明测试说明测试说明测试说明测试说明测试说明测" +
+            "说明测试说明测试说明测试说明测试说明测试说明测试说明测试说明测试说明测试说明测试说明测试说明测试说明测试说明测试说明测" +
+            "试说明测试说明测试说明测试说明测试说明测试说明测试说明测试说明测试说明测试")
     private String name;
 
-    @RequestParam("Age")
+    @RequestParam(value = "Age", description = "test description test description test description test description" +
+            " test description test description")
     private Integer age;
 
     private Boolean man;
diff --git a/dubbo-api-docs/dubbo-api-docs-ui/src/locales/en-US.json b/dubbo-api-docs/dubbo-api-docs-ui/src/locales/en-US.json
index e252ab6..7548477 100644
--- a/dubbo-api-docs/dubbo-api-docs-ui/src/locales/en-US.json
+++ b/dubbo-api-docs/dubbo-api-docs-ui/src/locales/en-US.json
@@ -18,6 +18,8 @@
     "apiFunctionNameFormLabel": "Api function name(this parameter cannot be modified)",
     "registryCenterUrlFormLabel": "Registry address. If it is empty, Dubbo provider IP and port will be used for direct connection",
     "prarmNameLabel": "Parameter name",
+    "prarmPathLabel": "Parameter path",
+    "prarmDescriptionLabel": "Description",
     "prarmRequiredLabel": "This parameter is required",
     "doTestBtn": "Do Test",
     "responseLabel": "Response",
diff --git a/dubbo-api-docs/dubbo-api-docs-ui/src/locales/zh-CN.json b/dubbo-api-docs/dubbo-api-docs-ui/src/locales/zh-CN.json
index 4434103..b008bc6 100644
--- a/dubbo-api-docs/dubbo-api-docs-ui/src/locales/zh-CN.json
+++ b/dubbo-api-docs/dubbo-api-docs-ui/src/locales/zh-CN.json
@@ -18,6 +18,8 @@
     "apiFunctionNameFormLabel": "接口方法名(此参数不可修改)",
     "registryCenterUrlFormLabel": "注册中心地址, 如果为空将使用Dubbo 提供者Ip和端口进行直连",
     "prarmNameLabel": "参数名",
+    "prarmPathLabel": "参数位置",
+    "prarmDescriptionLabel": "说明",
     "prarmRequiredLabel": "该参数为必填",
     "doTestBtn": "测试",
     "responseLabel": "响应",
diff --git a/dubbo-api-docs/dubbo-api-docs-ui/src/pages/ApiForm/index.tsx b/dubbo-api-docs/dubbo-api-docs-ui/src/pages/ApiForm/index.tsx
index 5c33b5b..8a9cf2d 100644
--- a/dubbo-api-docs/dubbo-api-docs-ui/src/pages/ApiForm/index.tsx
+++ b/dubbo-api-docs/dubbo-api-docs-ui/src/pages/ApiForm/index.tsx
@@ -24,6 +24,7 @@ import {
   Input,
   Loading,
   Select,
+  Timeline,
 } from '@alifd/next';
 import $ from 'jquery';
 import ReactJson from 'react-json-view';
@@ -216,12 +217,14 @@ class ApiForm extends React.Component {
               formsArray.map((item, index) => {
                 return (
                   <div key={'formDiv' + index} style={{ marginTop: 20 }}>
-                    {this.state.locale.prarmNameLabel + ': ' + item.get('name')}
                     <div style={{ width: '1000px', height:'220px' }}>
-                      <div style={{ float: 'left', border: '2px solid #cccccc', 
-                            width: '300px', height: '100%', padding: '5px' }}>
-                        Description:<br />
-                        {item.get('description')}
+                      <div style={{ float: 'left', border: '2px solid rgb(228 224 224)', 
+                            width: '400px', height: '100%', overflowY: 'auto', overflowX: 'hidden'}}>
+                        <Timeline>
+                          <Timeline.Item style={{wordBreak: 'break-word'}} title={this.state.locale.prarmNameLabel} content={item.get('name')} state="process"/>
+                          <Timeline.Item style={{wordBreak: 'break-word'}} title={this.state.locale.prarmPathLabel} content={item.get('paramType') + "#" + item.get('name')} state="process"/>
+                          <Timeline.Item style={{wordBreak: 'break-word'}} title={this.state.locale.prarmDescriptionLabel} content={item.get('description')} state="process"/>
+                        </Timeline>
                       </div>
                       <div style={{float: "left"}}>
                         <Form.Item 
@@ -244,7 +247,7 @@ class ApiForm extends React.Component {
             <Form.Submit
               type={'primary'}
               validate
-              style={{ marginLeft: 20, marginTop: 20, width: '600px' }}
+              style={{ marginLeft: 20, marginTop: 20, width: '580px' }}
               onClick={ this.doTestApi.bind(this) }
             >
               {this.state.locale.doTestBtn}
@@ -291,7 +294,7 @@ class ApiForm extends React.Component {
       return (
         <Input.TextArea
           readOnly
-          style={{ marginLeft: 5, minWidth: '600px' }}
+          style={{ marginLeft: 5, minWidth: '580px' }}
           rows={10}
         />
       );
@@ -307,7 +310,7 @@ class ApiForm extends React.Component {
       }
       return (
         <ReactJson 
-        style={{ marginLeft: 5, minWidth: '600px' }}
+        style={{ marginLeft: 5, minWidth: '580px' }}
           name={false} 
           theme='apathy'
           iconStyle='square'
@@ -319,7 +322,7 @@ class ApiForm extends React.Component {
       return (
         <Input.TextArea
           readOnly
-          style={{ marginLeft: 5, minWidth: '600px' }}
+          style={{ marginLeft: 5, minWidth: '580px' }}
           rows={10}
           defaultValue={this.state.responseInfo}
         />
@@ -332,7 +335,7 @@ class ApiForm extends React.Component {
       return (
         <Input.TextArea
           readOnly
-          style={{ marginLeft: 5, minWidth: '600px' }}
+          style={{ marginLeft: 5, minWidth: '580px' }}
           rows={10}
         />
       );
@@ -343,7 +346,7 @@ class ApiForm extends React.Component {
       }
       return (
         <ReactJson 
-          style={{ marginLeft: 5, minWidth: '600px' }}
+          style={{ marginLeft: 5, minWidth: '580px' }}
           name={false} 
           theme='apathy'
           iconStyle='square'
@@ -354,7 +357,7 @@ class ApiForm extends React.Component {
     } catch (e) {
       return (
         <Input.TextArea
-          style={{ marginLeft: 5, minWidth: '600px' }}
+          style={{ marginLeft: 5, minWidth: '580px' }}
           rows={10}
           readOnly
           value={this.state.responseData}
@@ -526,7 +529,7 @@ class ApiForm extends React.Component {
       <Input.TextArea
         name={item.get('paramType') + '@@' + item.get('paramIndex') + '@@' + item.get('javaType') + "@@" + item.get('name')}
         className={'dubbo-doc-form-item-class'}
-        style={{ marginLeft: 5, width: '600px' }}
+        style={{ marginLeft: 5, width: '580px' }}
         rows={10}
         placeholder={item.get('example')}
         defaultValue={JSON.stringify(JSON.parse(item.get('subParamsJson')), null, 4)}
diff --git a/dubbo-api-docs/pom.xml b/dubbo-api-docs/pom.xml
index 9b81e6c..5c70aa5 100644
--- a/dubbo-api-docs/pom.xml
+++ b/dubbo-api-docs/pom.xml
@@ -29,7 +29,7 @@
     <name>${project.artifactId}</name>
     <description>Dubbo interface documentation, testing tools</description>
     <properties>
-        <revision>2.7.9-SNAPSHOT</revision>
+        <revision>2.7.8-SNAPSHOT</revision>
         <project.build.jdkVersion>1.8</project.build.jdkVersion>
         <argLine>-Dfile.encoding=UTF-8</argLine>
         <project.build.sourceEncoding>UTF-8</project.build.sourceEncoding>
@@ -40,7 +40,7 @@
         <maven-flatten-version>1.1.0</maven-flatten-version>
 
         <spring-boot.version>2.3.4.RELEASE</spring-boot.version>
-        <dubbo-spring-boot.version>2.7.8</dubbo-spring-boot.version>
+        <dubbo.version>2.7.8</dubbo.version>
         <commons-beanutils.version>1.9.4</commons-beanutils.version>
         <commons-collections.version>4.2</commons-collections.version>
         <disruptor.version>3.4.2</disruptor.version>
@@ -60,7 +60,7 @@
             <dependency>
                 <groupId>org.apache.dubbo</groupId>
                 <artifactId>dubbo-parent</artifactId>
-                <version>${revision}</version>
+                <version>${dubbo.version}</version>
                 <type>pom</type>
                 <scope>import</scope>
             </dependency>
@@ -85,61 +85,61 @@
             <dependency>
                 <groupId>org.apache.dubbo</groupId>
                 <artifactId>dubbo</artifactId>
-                <version>${project.version}</version>
+                <version>${dubbo.version}</version>
             </dependency>
 
             <dependency>
                 <groupId>org.apache.dubbo</groupId>
                 <artifactId>dubbo-registry-nacos</artifactId>
-                <version>${project.version}</version>
+                <version>${dubbo.version}</version>
             </dependency>
 
             <dependency>
                 <groupId>org.apache.dubbo</groupId>
                 <artifactId>dubbo-registry-consul</artifactId>
-                <version>${project.version}</version>
+                <version>${dubbo.version}</version>
             </dependency>
 
             <dependency>
                 <groupId>org.apache.dubbo</groupId>
                 <artifactId>dubbo-registry-default</artifactId>
-                <version>${project.version}</version>
+                <version>${dubbo.version}</version>
             </dependency>
 
             <dependency>
                 <groupId>org.apache.dubbo</groupId>
                 <artifactId>dubbo-registry-etcd3</artifactId>
-                <version>${project.version}</version>
+                <version>${dubbo.version}</version>
             </dependency>
 
             <dependency>
                 <groupId>org.apache.dubbo</groupId>
                 <artifactId>dubbo-registry-multicast</artifactId>
-                <version>${project.version}</version>
+                <version>${dubbo.version}</version>
             </dependency>
 
             <dependency>
                 <groupId>org.apache.dubbo</groupId>
                 <artifactId>dubbo-registry-multiple</artifactId>
-                <version>${project.version}</version>
+                <version>${dubbo.version}</version>
             </dependency>
 
             <dependency>
                 <groupId>org.apache.dubbo</groupId>
                 <artifactId>dubbo-registry-redis</artifactId>
-                <version>${project.version}</version>
+                <version>${dubbo.version}</version>
             </dependency>
 
             <dependency>
                 <groupId>org.apache.dubbo</groupId>
                 <artifactId>dubbo-registry-sofa</artifactId>
-                <version>${project.version}</version>
+                <version>${dubbo.version}</version>
             </dependency>
 
             <dependency>
                 <groupId>org.apache.dubbo</groupId>
                 <artifactId>dubbo-registry-zookeeper</artifactId>
-                <version>${project.version}</version>
+                <version>${dubbo.version}</version>
             </dependency>
 
             <dependency>
@@ -152,7 +152,7 @@
             <dependency>
                 <groupId>org.apache.dubbo</groupId>
                 <artifactId>dubbo-spring-boot-starter</artifactId>
-                <version>${dubbo-spring-boot.version}</version>
+                <version>${dubbo.version}</version>
             </dependency>
 
             <dependency>


[dubbo-spi-extensions] 12/39: UI和UI-Server

Posted by li...@apache.org.
This is an automated email from the ASF dual-hosted git repository.

liujun pushed a commit to branch 2.7.x
in repository https://gitbox.apache.org/repos/asf/dubbo-spi-extensions.git

commit 111419fe2c529c33ff3ea30fce90cb0bfbf35fee
Author: qq213539 <21...@qq.com>
AuthorDate: Sat Nov 14 22:44:24 2020 +0800

    UI和UI-Server
---
 dubbo-api-docs/distribution/LICENSE-BIN            |   334 +
 .../distribution/bin/config/application.yml        |    11 +
 dubbo-api-docs/distribution/bin/log4j2.xml         |    23 +
 dubbo-api-docs/distribution/bin/shutdown.cmd       |    26 +
 dubbo-api-docs/distribution/bin/shutdown.sh        |    31 +
 dubbo-api-docs/distribution/bin/startup.cmd        |    31 +
 dubbo-api-docs/distribution/bin/startup.sh         |    57 +
 dubbo-api-docs/distribution/pom.xml                |    76 +
 .../distribution/release-dubboApiDocs.xml          |    54 +
 .../dubbo/apidocs/core/DubboApiDocsCache.java      |    50 +-
 .../core/providers/DubboDocProviderImpl.java       |     8 +
 .../apidocs/core/providers/IDubboDocProvider.java  |    11 +
 .../apache/dubbo/apidocs/utils/ClassTypeUtil.java  |    13 +-
 .../dubbo/apidocs/examples/api/IAsyncDemo.java     |    29 +-
 .../dubbo/apidocs/examples/api/ISyncDemo.java      |    20 +-
 .../apidocs/examples/params/DemoParamBean3.java    |    43 +
 .../apidocs/examples/params/DemoParamBean4.java    |    39 +
 .../apidocs/examples/api/impl/AsyncDemoImpl.java   |    29 +-
 .../apidocs/examples/api/impl/SyncDemoImpl.java    |    10 +
 .../src/main/resources/application.yml             |     6 +-
 dubbo-api-docs/dubbo-api-docs-ui-server/pom.xml    |   291 +
 .../apidocs/DubboApiDocsUiServerApplication.java}  |    30 +-
 .../apache/dubbo/apidocs/cfg/SwaggerConfig.java    |    62 +
 .../org/apache/dubbo/apidocs/cfg/WebConfig.java}   |    35 +-
 .../apidocs/controller/DubboApiDocsController.java |   191 +
 .../apidocs/controller/vo/ApiInfoRequest.java}     |    38 +-
 .../controller/vo/CallDubboServiceRequest.java}    |    46 +-
 .../vo/CallDubboServiceRequestInterfacePrarm.java} |    35 +-
 .../dubbo/apidocs/editor/CustomDateEditor.java     |   122 +
 .../apidocs/editor/CustomLocalDateEditor.java}     |    36 +-
 .../apidocs/editor/CustomLocalDateTimeEditor.java} |    36 +-
 .../dubbo/apidocs/utils/DubboGenericUtil.java      |   175 +
 .../dubbo/apidocs/utils/LocalDateTimeUtil.java     |    75 +
 .../src/main/resources/application.yml             |    11 +
 .../src/main/resources/banner.txt                  |     6 +
 .../src/main/resources/log4j2.xml                  |    23 +
 .../src/main/resources/static/css/index.css        |     1 +
 .../src/main/resources/static/favicon.png          |   Bin 0 -> 2719 bytes
 .../src/main/resources/static/index.html           |    29 +
 .../src/main/resources/static/js/index.js          |    95 +
 dubbo-api-docs/dubbo-api-docs-ui/.editorconfig     |    12 +
 dubbo-api-docs/dubbo-api-docs-ui/.eslintignore     |    11 +
 dubbo-api-docs/dubbo-api-docs-ui/.eslintrc.js      |     3 +
 dubbo-api-docs/dubbo-api-docs-ui/.gitignore        |    16 +
 dubbo-api-docs/dubbo-api-docs-ui/.prettierignore   |     9 +
 dubbo-api-docs/dubbo-api-docs-ui/.prettierrc.js    |     3 +
 dubbo-api-docs/dubbo-api-docs-ui/.stylelintignore  |     7 +
 dubbo-api-docs/dubbo-api-docs-ui/.stylelintrc.js   |     3 +
 dubbo-api-docs/dubbo-api-docs-ui/README.md         |    14 +
 dubbo-api-docs/dubbo-api-docs-ui/build.json        |    21 +
 dubbo-api-docs/dubbo-api-docs-ui/package-lock.json | 24011 +++++++++++++++++++
 dubbo-api-docs/dubbo-api-docs-ui/package.json      |    51 +
 .../dubbo-api-docs-ui/public/favicon.png           |   Bin 0 -> 2719 bytes
 dubbo-api-docs/dubbo-api-docs-ui/public/index.html |    29 +
 dubbo-api-docs/dubbo-api-docs-ui/src/app.tsx       |   108 +
 .../src/components/NotFound/index.module.scss      |    76 +
 .../src/components/NotFound/index.tsx              |    45 +
 .../src/components/PageLoading/index.jsx           |    24 +
 dubbo-api-docs/dubbo-api-docs-ui/src/constants.js  |    19 +
 dubbo-api-docs/dubbo-api-docs-ui/src/emit.js       |    20 +
 dubbo-api-docs/dubbo-api-docs-ui/src/global.scss   |    39 +
 .../components/Footer/index.module.scss            |    29 +
 .../BasicLayout/components/Footer/index.tsx        |    28 +
 .../BasicLayout/components/PageNav/index.tsx       |    98 +
 .../src/layouts/BasicLayout/index.tsx              |   143 +
 .../dubbo-api-docs-ui/src/locales/en-US.json       |    32 +
 .../dubbo-api-docs-ui/src/locales/zh-CN.json       |    32 +
 .../dubbo-api-docs-ui/src/pages/ApiForm/index.tsx  |   613 +
 .../dubbo-api-docs-ui/src/pages/Home/index.tsx     |    27 +
 dubbo-api-docs/dubbo-api-docs-ui/src/routes.ts     |    28 +
 dubbo-api-docs/dubbo-api-docs-ui/tsconfig.json     |    36 +
 dubbo-api-docs/pom.xml                             |   108 +
 72 files changed, 27740 insertions(+), 193 deletions(-)

diff --git a/dubbo-api-docs/distribution/LICENSE-BIN b/dubbo-api-docs/distribution/LICENSE-BIN
new file mode 100644
index 0000000..3726172
--- /dev/null
+++ b/dubbo-api-docs/distribution/LICENSE-BIN
@@ -0,0 +1,334 @@
+                                 Apache License
+                           Version 2.0, January 2004
+                        http://www.apache.org/licenses/
+
+   TERMS AND CONDITIONS FOR USE, REPRODUCTION, AND DISTRIBUTION
+
+   1. Definitions.
+
+      "License" shall mean the terms and conditions for use, reproduction,
+      and distribution as defined by Sections 1 through 9 of this document.
+
+      "Licensor" shall mean the copyright owner or entity authorized by
+      the copyright owner that is granting the License.
+
+      "Legal Entity" shall mean the union of the acting entity and all
+      other entities that control, are controlled by, or are under common
+      control with that entity. For the purposes of this definition,
+      "control" means (properties) the power, direct or indirect, to cause the
+      direction or management of such entity, whether by contract or
+      otherwise, or (ii) ownership of fifty percent (50%) or more of the
+      outstanding shares, or (iii) beneficial ownership of such entity.
+
+      "You" (or "Your") shall mean an individual or Legal Entity
+      exercising permissions granted by this License.
+
+      "Source" form shall mean the preferred form for making modifications,
+      including but not limited to software source code, documentation
+      source, and configuration files.
+
+      "Object" form shall mean any form resulting from mechanical
+      transformation or translation of a Source form, including but
+      not limited to compiled object code, generated documentation,
+      and conversions to other media types.
+
+      "Work" shall mean the work of authorship, whether in Source or
+      Object form, made available under the License, as indicated by a
+      copyright notice that is included in or attached to the work
+      (an example is provided in the Appendix below).
+
+      "Derivative Works" shall mean any work, whether in Source or Object
+      form, that is based on (or derived from) the Work and for which the
+      editorial revisions, annotations, elaborations, or other modifications
+      represent, as a whole, an original work of authorship. For the purposes
+      of this License, Derivative Works shall not include works that remain
+      separable from, or merely link (or bind by name) to the interfaces of,
+      the Work and Derivative Works thereof.
+
+      "Contribution" shall mean any work of authorship, including
+      the original version of the Work and any modifications or additions
+      to that Work or Derivative Works thereof, that is intentionally
+      submitted to Licensor for inclusion in the Work by the copyright owner
+      or by an individual or Legal Entity authorized to submit on behalf of
+      the copyright owner. For the purposes of this definition, "submitted"
+      means any form of electronic, verbal, or written communication sent
+      to the Licensor or its representatives, including but not limited to
+      communication on electronic mailing lists, source code control systems,
+      and issue tracking systems that are managed by, or on behalf of, the
+      Licensor for the purpose of discussing and improving the Work, but
+      excluding communication that is conspicuously marked or otherwise
+      designated in writing by the copyright owner as "Not a Contribution."
+
+      "Contributor" shall mean Licensor and any individual or Legal Entity
+      on behalf of whom a Contribution has been received by Licensor and
+      subsequently incorporated within the Work.
+
+   2. Grant of Copyright License. Subject to the terms and conditions of
+      this License, each Contributor hereby grants to You a perpetual,
+      worldwide, non-exclusive, no-charge, royalty-free, irrevocable
+      copyright license to reproduce, prepare Derivative Works of,
+      publicly display, publicly perform, sublicense, and distribute the
+      Work and such Derivative Works in Source or Object form.
+
+   3. Grant of Patent License. Subject to the terms and conditions of
+      this License, each Contributor hereby grants to You a perpetual,
+      worldwide, non-exclusive, no-charge, royalty-free, irrevocable
+      (except as stated in this section) patent license to make, have made,
+      use, offer to sell, sell, import, and otherwise transfer the Work,
+      where such license applies only to those patent claims licensable
+      by such Contributor that are necessarily infringed by their
+      Contribution(s) alone or by combination of their Contribution(s)
+      with the Work to which such Contribution(s) was submitted. If You
+      institute patent litigation against any entity (including a
+      cross-claim or counterclaim in a lawsuit) alleging that the Work
+      or a Contribution incorporated within the Work constitutes direct
+      or contributory patent infringement, then any patent licenses
+      granted to You under this License for that Work shall terminate
+      as of the date such litigation is filed.
+
+   4. Redistribution. You may reproduce and distribute copies of the
+      Work or Derivative Works thereof in any medium, with or without
+      modifications, and in Source or Object form, provided that You
+      meet the following conditions:
+
+      (a) You must give any other recipients of the Work or
+          Derivative Works a copy of this License; and
+
+      (b) You must cause any modified files to carry prominent notices
+          stating that You changed the files; and
+
+      (c) You must retain, in the Source form of any Derivative Works
+          that You distribute, all copyright, patent, trademark, and
+          attribution notices from the Source form of the Work,
+          excluding those notices that do not pertain to any part of
+          the Derivative Works; and
+
+      (d) If the Work includes a "NOTICE" text file as part of its
+          distribution, then any Derivative Works that You distribute must
+          include a readable copy of the attribution notices contained
+          within such NOTICE file, excluding those notices that do not
+          pertain to any part of the Derivative Works, in at least one
+          of the following places: within a NOTICE text file distributed
+          as part of the Derivative Works; within the Source form or
+          documentation, if provided along with the Derivative Works; or,
+          within a display generated by the Derivative Works, if and
+          wherever such third-party notices normally appear. The contents
+          of the NOTICE file are for informational purposes only and
+          do not modify the License. You may add Your own attribution
+          notices within Derivative Works that You distribute, alongside
+          or as an addendum to the NOTICE text from the Work, provided
+          that such additional attribution notices cannot be construed
+          as modifying the License.
+
+      You may add Your own copyright statement to Your modifications and
+      may provide additional or different license terms and conditions
+      for use, reproduction, or distribution of Your modifications, or
+      for any such Derivative Works as a whole, provided Your use,
+      reproduction, and distribution of the Work otherwise complies with
+      the conditions stated in this License.
+
+   5. Submission of Contributions. Unless You explicitly state otherwise,
+      any Contribution intentionally submitted for inclusion in the Work
+      by You to the Licensor shall be under the terms and conditions of
+      this License, without any additional terms or conditions.
+      Notwithstanding the above, nothing herein shall supersede or modify
+      the terms of any separate license agreement you may have executed
+      with Licensor regarding such Contributions.
+
+   6. Trademarks. This License does not grant permission to use the trade
+      names, trademarks, service marks, or product names of the Licensor,
+      except as required for reasonable and customary use in describing the
+      origin of the Work and reproducing the content of the NOTICE file.
+
+   7. Disclaimer of Warranty. Unless required by applicable law or
+      agreed to in writing, Licensor provides the Work (and each
+      Contributor provides its Contributions) on an "AS IS" BASIS,
+      WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or
+      implied, including, without limitation, any warranties or conditions
+      of TITLE, NON-INFRINGEMENT, MERCHANTABILITY, or FITNESS FOR A
+      PARTICULAR PURPOSE. You are solely responsible for determining the
+      appropriateness of using or redistributing the Work and assume any
+      risks associated with Your exercise of permissions under this License.
+
+   8. Limitation of Liability. In no event and under no legal theory,
+      whether in tort (including negligence), contract, or otherwise,
+      unless required by applicable law (such as deliberate and grossly
+      negligent acts) or agreed to in writing, shall any Contributor be
+      liable to You for damages, including any direct, indirect, special,
+      incidental, or consequential damages of any character arising as a
+      result of this License or out of the use or inability to use the
+      Work (including but not limited to damages for loss of goodwill,
+      work stoppage, computer failure or malfunction, or any and all
+      other commercial damages or losses), even if such Contributor
+      has been advised of the possibility of such damages.
+
+   9. Accepting Warranty or Additional Liability. While redistributing
+      the Work or Derivative Works thereof, You may choose to offer,
+      and charge a fee for, acceptance of support, warranty, indemnity,
+      or other liability obligations and/or rights consistent with this
+      License. However, in accepting such obligations, You may act only
+      on Your own behalf and on Your sole responsibility, not on behalf
+      of any other Contributor, and only if You agree to indemnify,
+      defend, and hold each Contributor harmless for any liability
+      incurred by, or claims asserted against, such Contributor by reason
+      of your accepting any such warranty or additional liability.
+
+   END OF TERMS AND CONDITIONS
+
+   APPENDIX: How to apply the Apache License to your work.
+
+      To apply the Apache License to your work, attach the following
+      boilerplate notice, with the fields enclosed by brackets "[]"
+      replaced with your own identifying information. (Don't include
+      the brackets!)  The text should be enclosed in the appropriate
+      comment syntax for the file format. We also recommend that a
+      file or class name and description of purpose be included on the
+      same "printed page" as the copyright notice for easier
+      identification within third-party archives.
+
+   Copyright [yyyy] [name of copyright owner]
+
+   Licensed 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.
+
+------
+This product has a bundle logback, which is available under the EPL v1.0 License.
+The source code of logback can be found at https://github.com/qos-ch/logback.
+
+Logback LICENSE
+---------------
+
+Logback: the reliable, generic, fast and flexible logging framework.
+Copyright (C) 1999-2015, QOS.ch. All rights reserved.
+
+This program and the accompanying materials are dual-licensed under
+either the terms of the Eclipse Public License v1.0 as published by
+the Eclipse Foundation
+
+  or (per the licensee's choosing)
+
+under the terms of the GNU Lesser General Public License version 2.1
+as published by the Free Software Foundation.
+
+------
+This product has a bundle slf4j, which is available under the MIT License.
+The source code of slf4j can be found at https://github.com/qos-ch/slf4j.
+
+ Copyright (c) 2004-2017 QOS.ch
+ All rights reserved.
+
+ Permission is hereby granted, free  of charge, to any person obtaining
+ a  copy  of this  software  and  associated  documentation files  (the
+ "Software"), to  deal in  the Software without  restriction, including
+ without limitation  the rights to  use, copy, modify,  merge, publish,
+ distribute,  sublicense, and/or sell  copies of  the Software,  and to
+ permit persons to whom the Software  is furnished to do so, subject to
+ the following conditions:
+
+ The  above  copyright  notice  and  this permission  notice  shall  be
+ included in all copies or substantial portions of the Software.
+
+ THE  SOFTWARE IS  PROVIDED  "AS  IS", WITHOUT  WARRANTY  OF ANY  KIND,
+ EXPRESS OR  IMPLIED, INCLUDING  BUT NOT LIMITED  TO THE  WARRANTIES OF
+ MERCHANTABILITY,    FITNESS    FOR    A   PARTICULAR    PURPOSE    AND
+ NONINFRINGEMENT. IN NO EVENT SHALL THE AUTHORS OR COPYRIGHT HOLDERS BE
+ LIABLE FOR ANY CLAIM, DAMAGES OR OTHER LIABILITY, WHETHER IN AN ACTION
+ OF CONTRACT, TORT OR OTHERWISE,  ARISING FROM, OUT OF OR IN CONNECTION
+ WITH THE SOFTWARE OR THE USE OR OTHER DEALINGS IN THE SOFTWARE.
+
+------
+This product has a bundle fastjson, which is available under the ASL2 License.
+The source code of fastjson can be found at https://github.com/alibaba/fastjson.
+
+ Copyright 1999-2016 Alibaba Group Holding Ltd.
+
+ Licensed 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.
+
+------
+This product has a bundle javassist, which is available under the ASL2 License.
+The source code of javassist can be found at https://github.com/jboss-javassist/javassist.
+
+ Copyright (C) 1999- by Shigeru Chiba, All rights reserved.
+
+ Javassist (JAVA programming ASSISTant) makes Java bytecode manipulation simple.
+ It is a class library for editing bytecodes in Java; it enables Java programs to define a new class
+ at runtime and to modify a class file when the JVM loads it. Unlike other similar bytecode editors,
+ Javassist provides two levels of API: source level and bytecode level. If the users use the source- level API,
+ they can edit a class file without knowledge of the specifications of the Java bytecode.
+ The whole API is designed with only the vocabulary of the Java language.
+ You can even specify inserted bytecode in the form of source text; Javassist compiles it on the fly.
+ On the other hand, the bytecode-level API allows the users to directly edit a class file as other editors.
+
+ This software is distributed under the Mozilla Public License Version 1.1,
+ the GNU Lesser General Public License Version 2.1 or later, or the Apache License Version 2.0.
+
+------
+This product has a bundle jna, which is available under the ASL2 License.
+The source code of jna can be found at https://github.com/java-native-access/jna.
+
+ This copy of JNA is licensed under the
+ Apache (Software) License, version 2.0 ("the License").
+ See the License for details about distribution rights, and the
+ specific rights regarding derivate works.
+
+ You may obtain a copy of the License at:
+
+ http://www.apache.org/licenses/
+
+ A copy is also included in the downloadable source code package
+ containing JNA, in file "AL2.0", under the same directory
+ as this file.
+------
+This product has a bundle guava, which is available under the ASL2 License.
+The source code of guava can be found at https://github.com/google/guava.
+
+ Copyright (C) 2007 The Guava authors 
+
+ Licensed 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.
+------
+This product has a bundle OpenMessaging, which is available under the ASL2 License.
+The source code of OpenMessaging can be found at https://github.com/openmessaging/openmessaging.
+
+ Copyright (C) 2017 The OpenMessaging authors.
+
+ Licensed 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.
+
diff --git a/dubbo-api-docs/distribution/bin/config/application.yml b/dubbo-api-docs/distribution/bin/config/application.yml
new file mode 100644
index 0000000..76231ff
--- /dev/null
+++ b/dubbo-api-docs/distribution/bin/config/application.yml
@@ -0,0 +1,11 @@
+server:
+  port: 8888
+spring:
+  application:
+    name: dubbo-api-docs-ui-server
+dubbo:
+  reference:
+    heartbeat: 1000
+  consumer:
+    timeout: 10000
+    retries: 0
\ No newline at end of file
diff --git a/dubbo-api-docs/distribution/bin/log4j2.xml b/dubbo-api-docs/distribution/bin/log4j2.xml
new file mode 100644
index 0000000..8bd3515
--- /dev/null
+++ b/dubbo-api-docs/distribution/bin/log4j2.xml
@@ -0,0 +1,23 @@
+<?xml version="1.0" encoding="UTF-8"?>
+<Configuration status="WARN" monitorInterval="600" shutdownHook="disable">
+    <Properties>
+        <Property name="logDir" value="/home/weihu/deploy/logs/dubbo-api-docs/" />
+        <Property name="genericPattern" value="[dubboDoc]-%d{yyyy-MM-dd HH:mm:ss.SSS} [%t] %-5level %logger{36} - %msg%n" />
+        <Property name="genericFilePattern" value="%d{yyyy-MM-dd HH:mm}-%i" />
+    </Properties>
+    <Appenders>
+        <Console name="consoleAppender" target="SYSTEM_OUT">
+            <PatternLayout pattern="${genericPattern}" />
+        </Console>
+
+    </Appenders>
+    <Loggers>
+        <asyncRoot level="INFO">
+            <AppenderRef ref="consoleAppender" />
+        </asyncRoot>
+
+        <logger name="org.springframework" level="ERROR" />
+        <logger name="com.alibaba" level="ERROR" />
+        <logger name="org.apache" level="ERROR" />
+    </Loggers>
+</Configuration>
diff --git a/dubbo-api-docs/distribution/bin/shutdown.cmd b/dubbo-api-docs/distribution/bin/shutdown.cmd
new file mode 100644
index 0000000..60fb33f
--- /dev/null
+++ b/dubbo-api-docs/distribution/bin/shutdown.cmd
@@ -0,0 +1,26 @@
+@echo off
+rem Licensed to the Apache Software Foundation (ASF) under one or more
+rem contributor license agreements.  See the NOTICE file distributed with
+rem this work for additional information regarding copyright ownership.
+rem The ASF licenses this file to You under the Apache License, Version 2.0
+rem (the "License"); you may not use this file except in compliance with
+rem the License.  You may obtain a copy of the License at
+rem
+rem http://www.apache.org/licenses/LICENSE-2.0
+rem
+rem Unless required by applicable law or agreed to in writing, software
+rem distributed under the License is distributed on an "AS IS" BASIS,
+rem WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied.
+rem See the License for the specific language governing permissions and
+rem limitations under the License.
+if not exist "%JAVA_HOME%\bin\jps.exe" echo Please set the JAVA_HOME variable in your environment, We need java(x64)! jdk8 or later is better! & EXIT /B 1
+
+setlocal
+
+set "PATH=%JAVA_HOME%\bin;%PATH%"
+
+echo killing dubbo Doc server
+
+for /f "tokens=1" %%i in ('jps -m ^| find "dubbo.doc"') do ( taskkill /F /PID %%i )
+
+echo Done!
diff --git a/dubbo-api-docs/distribution/bin/shutdown.sh b/dubbo-api-docs/distribution/bin/shutdown.sh
new file mode 100644
index 0000000..0b45640
--- /dev/null
+++ b/dubbo-api-docs/distribution/bin/shutdown.sh
@@ -0,0 +1,31 @@
+#!/bin/sh
+
+# 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.
+
+cd `dirname $0`/../lib
+target_dir=`pwd`
+
+pid=`ps ax | grep -i 'dubbo.api.docs' | grep ${target_dir} | grep java | grep -v grep | awk '{print $1}'`
+if [ -z "$pid" ] ; then
+        echo "No dubbo-api-docs-ui-server running."
+        exit -1;
+fi
+
+echo "The dubbo-api-docs-ui-server(${pid}) is running..."
+
+kill ${pid}
+
+echo "Send shutdown request to dubbo-api-docs-ui-server(${pid}) OK"
diff --git a/dubbo-api-docs/distribution/bin/startup.cmd b/dubbo-api-docs/distribution/bin/startup.cmd
new file mode 100644
index 0000000..6f91812
--- /dev/null
+++ b/dubbo-api-docs/distribution/bin/startup.cmd
@@ -0,0 +1,31 @@
+@echo off
+rem Licensed to the Apache Software Foundation (ASF) under one or more
+rem contributor license agreements.  See the NOTICE file distributed with
+rem this work for additional information regarding copyright ownership.
+rem The ASF licenses this file to You under the Apache License, Version 2.0
+rem (the "License"); you may not use this file except in compliance with
+rem the License.  You may obtain a copy of the License at
+rem
+rem http://www.apache.org/licenses/LICENSE-2.0
+rem
+rem Unless required by applicable law or agreed to in writing, software
+rem distributed under the License is distributed on an "AS IS" BASIS,
+rem WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied.
+rem See the License for the specific language governing permissions and
+rem limitations under the License.
+if not exist "%JAVA_HOME%\bin\java.exe" echo Please set the JAVA_HOME variable in your environment, We need java(x64)! jdk8 or later is better! & EXIT /B 1
+set "JAVA=%JAVA_HOME%\bin\java.exe"
+
+setlocal enabledelayedexpansion
+set BASE_DIR=%~dp0
+rem added double quotation marks to avoid the issue caused by the folder names containing spaces.
+rem removed the last 5 chars(which means \bin\) to get the base DIR.
+set BASE_DIR=%BASE_DIR:~0,-5%
+
+set SERVER=dubbo-api-docs-ui-server
+
+set "JAVA_OPT=%JAVA_OPT% -Xms512m -Xmx512m -Xmn256m"
+
+set "JAVA_OPT=%JAVA_OPT% -jar %BASE_DIR%\lib\%SERVER%.jar"
+
+call "%JAVA%" %JAVA_OPT% dubbo.doc %*
diff --git a/dubbo-api-docs/distribution/bin/startup.sh b/dubbo-api-docs/distribution/bin/startup.sh
new file mode 100644
index 0000000..039757e
--- /dev/null
+++ b/dubbo-api-docs/distribution/bin/startup.sh
@@ -0,0 +1,57 @@
+#!/bin/sh
+
+# 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.
+
+cygwin=false
+darwin=false
+os400=false
+case "`uname`" in
+CYGWIN*) cygwin=true;;
+Darwin*) darwin=true;;
+OS400*) os400=true;;
+esac
+[ ! -e "$JAVA_HOME/bin/java" ] && JAVA_HOME=$HOME/jdk/java
+[ ! -e "$JAVA_HOME/bin/java" ] && JAVA_HOME=/usr/java
+[ ! -e "$JAVA_HOME/bin/java" ] && JAVA_HOME=/opt/taobao/java
+[ ! -e "$JAVA_HOME/bin/java" ] && unset JAVA_HOME
+
+if [ -z "$JAVA_HOME" ]; then
+  if $darwin; then
+
+    if [ -x '/usr/libexec/java_home' ] ; then
+      export JAVA_HOME=`/usr/libexec/java_home`
+
+    elif [ -d "/System/Library/Frameworks/JavaVM.framework/Versions/CurrentJDK/Home" ]; then
+      export JAVA_HOME="/System/Library/Frameworks/JavaVM.framework/Versions/CurrentJDK/Home"
+    fi
+  else
+    JAVA_PATH=`dirname $(readlink -f $(which javac))`
+    if [ "x$JAVA_PATH" != "x" ]; then
+      export JAVA_HOME=`dirname $JAVA_PATH 2>/dev/null`
+    fi
+  fi
+  if [ -z "$JAVA_HOME" ]; then
+        error_exit "Please set the JAVA_HOME variable in your environment, We need java(x64)! jdk8 or later is better!"
+  fi
+fi
+export SERVER="dubbo-doc-ui-server"
+export JAVA_HOME
+export JAVA="$JAVA_HOME/bin/java"
+export BASE_DIR=`cd $(dirname $0)/..; pwd`
+JAVA_OPT="${JAVA_OPT} -Xms512m -Xmx512m -Xmn256m"
+JAVA_OPT="${JAVA_OPT} -jar ${BASE_DIR}/lib/${SERVER}.jar"
+nohup $JAVA ${JAVA_OPT} dubbo.doc >> ${BASE_DIR}/logs/catlog.out 2>&1 &
+echo "${SERVER} is starting,you can check the ${BASE_DIR}/logs/catlog.out"
\ No newline at end of file
diff --git a/dubbo-api-docs/distribution/pom.xml b/dubbo-api-docs/distribution/pom.xml
new file mode 100644
index 0000000..5bf2aa5
--- /dev/null
+++ b/dubbo-api-docs/distribution/pom.xml
@@ -0,0 +1,76 @@
+<?xml version="1.0" encoding="UTF-8"?>
+<!--
+  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.
+ -->
+<project xmlns="http://maven.apache.org/POM/4.0.0"
+         xmlns:xsi="http://www.w3.org/2001/XMLSchema-instance"
+         xsi:schemaLocation="http://maven.apache.org/POM/4.0.0 http://maven.apache.org/xsd/maven-4.0.0.xsd">
+
+    <parent>
+        <groupId>org.apache.dubbo</groupId>
+        <artifactId>dubbo-api-docs</artifactId>
+        <version>2.7.9-SNAPSHOT</version>
+        <relativePath>../pom.xml</relativePath>
+    </parent>
+
+    <modelVersion>4.0.0</modelVersion>
+
+    <artifactId>dubbo-api-docs-distribution</artifactId>
+    <name>dubbo-api-docs-distribution ${project.version}</name>
+    <packaging>pom</packaging>
+
+    <dependencies>
+        <dependency>
+            <groupId>org.apache.dubbo</groupId>
+            <artifactId>dubbo-api-docs-ui-server</artifactId>
+        </dependency>
+    </dependencies>
+    <profiles>
+        <profile>
+            <id>release-dubboDoc</id>
+            <dependencies>
+                <dependency>
+                    <groupId>org.apache.dubbo</groupId>
+                    <artifactId>dubbo-api-docs-ui-server</artifactId>
+                </dependency>
+            </dependencies>
+            <build>
+                <plugins>
+                    <plugin>
+                        <artifactId>maven-assembly-plugin</artifactId>
+                        <version>3.0.0</version>
+                        <configuration>
+                            <descriptors>
+                                <descriptor>release-dubboApiDocs.xml</descriptor>
+                            </descriptors>
+                            <tarLongFileMode>posix</tarLongFileMode>
+                        </configuration>
+                        <executions>
+                            <execution>
+                                <id>make-assembly</id>
+                                <phase>install</phase>
+                                <goals>
+                                    <goal>single</goal>
+                                </goals>
+                            </execution>
+                        </executions>
+                    </plugin>
+                </plugins>
+                <finalName>dubboApiDocs</finalName>
+            </build>
+        </profile>
+    </profiles>
+</project>
diff --git a/dubbo-api-docs/distribution/release-dubboApiDocs.xml b/dubbo-api-docs/distribution/release-dubboApiDocs.xml
new file mode 100644
index 0000000..837d40c
--- /dev/null
+++ b/dubbo-api-docs/distribution/release-dubboApiDocs.xml
@@ -0,0 +1,54 @@
+<?xml version="1.0" encoding="UTF-8"?>
+<!--
+  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.
+ -->
+<assembly>
+    <id>ui-server-${project.version}</id>
+    <includeBaseDirectory>true</includeBaseDirectory>
+    <formats>
+        <format>dir</format>
+        <format>zip</format>
+    </formats>
+    <fileSets>
+
+        <fileSet>
+            <includes>
+                <include>bin/**</include>
+            </includes>
+            <fileMode>0755</fileMode>
+        </fileSet>
+    </fileSets>
+    <files>
+        <file>
+            <source>LICENSE-BIN</source>
+            <destName>LICENSE</destName>
+        </file>
+        <file>
+            <!--打好的jar包名称和放置目录-->
+            <source>../dubbo-api-docs-ui-server/target/dubbo-api-docs-ui-server.jar</source>
+            <outputDirectory>./lib/</outputDirectory>
+        </file>
+    </files>
+
+    <moduleSets>
+        <moduleSet>
+            <useAllReactorProjects>true</useAllReactorProjects>
+            <includes>
+                <include>org.apache.dubbo:dubbo-api-docs-ui-server</include>
+            </includes>
+        </moduleSet>
+    </moduleSets>
+</assembly>
diff --git a/dubbo-api-docs/dubbo-api-docs-core/src/main/java/org/apache/dubbo/apidocs/core/DubboApiDocsCache.java b/dubbo-api-docs/dubbo-api-docs-core/src/main/java/org/apache/dubbo/apidocs/core/DubboApiDocsCache.java
index e3b5b6d..5f028ed 100644
--- a/dubbo-api-docs/dubbo-api-docs-core/src/main/java/org/apache/dubbo/apidocs/core/DubboApiDocsCache.java
+++ b/dubbo-api-docs/dubbo-api-docs-core/src/main/java/org/apache/dubbo/apidocs/core/DubboApiDocsCache.java
@@ -27,7 +27,8 @@ import java.util.concurrent.ConcurrentHashMap;
 
 /**
  * dubbo doc cache.
- * @author klw(213539@qq.com)
+ *
+ * @author klw(213539 @ qq.com)
  * 2020/10/29 17:40
  */
 public class DubboApiDocsCache {
@@ -50,25 +51,27 @@ public class DubboApiDocsCache {
      */
     private static Map<String, String> apiParamsAndRespStrCache = new ConcurrentHashMap<>(16);
 
-    private static String allApiModuleInfo = null;
+    private static List<Map<String, Object>> allApiModuleInfo = null;
+
+    private static String basicApiModuleInfo = null;
 
-    public static void addApiModule(String key, Map<String, Object> moduleCacheItem){
+    public static void addApiModule(String key, Map<String, Object> moduleCacheItem) {
         apiModulesCache.put(key, moduleCacheItem);
     }
 
-    public static void addApiParamsAndResp(String key, Map<String, Object> apiParamsAndResp){
+    public static void addApiParamsAndResp(String key, Map<String, Object> apiParamsAndResp) {
         apiParamsAndRespCache.put(key, apiParamsAndResp);
     }
 
-    public static Map<String, Object> getApiModule(String key){
+    public static Map<String, Object> getApiModule(String key) {
         return apiModulesCache.get(key);
     }
 
-    public static String getApiModuleStr(String key){
+    public static String getApiModuleStr(String key) {
         String result = apiModulesStrCache.get(key);
-        if(result == null){
+        if (result == null) {
             Map<String, Object> temp = apiModulesCache.get(key);
-            if(temp != null) {
+            if (temp != null) {
                 result = JSON.toJSONString(temp, ClassTypeUtil.FAST_JSON_FEATURES);
                 apiModulesStrCache.put(key, result);
             }
@@ -76,15 +79,15 @@ public class DubboApiDocsCache {
         return result;
     }
 
-    public static Map<String, Object> getApiParamsAndResp(String key){
+    public static Map<String, Object> getApiParamsAndResp(String key) {
         return apiParamsAndRespCache.get(key);
     }
 
-    public static String getApiParamsAndRespStr(String key){
+    public static String getApiParamsAndRespStr(String key) {
         String result = apiParamsAndRespStrCache.get(key);
-        if(result == null){
+        if (result == null) {
             Map<String, Object> temp = apiParamsAndRespCache.get(key);
-            if(temp != null) {
+            if (temp != null) {
                 result = JSON.toJSONString(temp, ClassTypeUtil.FAST_JSON_FEATURES);
                 apiParamsAndRespStrCache.put(key, result);
             }
@@ -92,13 +95,30 @@ public class DubboApiDocsCache {
         return result;
     }
 
-    public static String getAllApiModuleInfo(){
-        if(allApiModuleInfo == null){
+    public static String getBasicApiModuleInfo() {
+        if (basicApiModuleInfo == null) {
             List<Map<String, Object>> tempList = new ArrayList<>(apiModulesCache.size());
             apiModulesCache.forEach((k, v) -> {
                 tempList.add(v);
             });
-            allApiModuleInfo = JSON.toJSONString(tempList, ClassTypeUtil.FAST_JSON_FEATURES);
+            basicApiModuleInfo = JSON.toJSONString(tempList, ClassTypeUtil.FAST_JSON_FEATURES);
+        }
+        return basicApiModuleInfo;
+    }
+
+    public static List<Map<String, Object>> getAllApiModuleInfo() {
+        if (allApiModuleInfo == null) {
+            allApiModuleInfo = new ArrayList<>(apiModulesCache.size());
+            apiModulesCache.forEach((k, v) -> {
+                List<Map<String, Object>> apiList = (List<Map<String, Object>>) v.get("moduleApiList");
+                if ( null != apiList && !apiList.isEmpty()) {
+                    for (Map<String, Object> apiInfo : apiList) {
+                        Map<String, Object> apiParams = getApiParamsAndResp(v.get("moduleClassName") + "." + apiInfo.get("apiName"));
+                        apiInfo.putAll(apiParams);
+                    }
+                }
+                allApiModuleInfo.add(v);
+            });
         }
         return allApiModuleInfo;
     }
diff --git a/dubbo-api-docs/dubbo-api-docs-core/src/main/java/org/apache/dubbo/apidocs/core/providers/DubboDocProviderImpl.java b/dubbo-api-docs/dubbo-api-docs-core/src/main/java/org/apache/dubbo/apidocs/core/providers/DubboDocProviderImpl.java
index d8cfb2b..5179765 100644
--- a/dubbo-api-docs/dubbo-api-docs-core/src/main/java/org/apache/dubbo/apidocs/core/providers/DubboDocProviderImpl.java
+++ b/dubbo-api-docs/dubbo-api-docs-core/src/main/java/org/apache/dubbo/apidocs/core/providers/DubboDocProviderImpl.java
@@ -21,6 +21,9 @@ import org.apache.dubbo.config.annotation.DubboService;
 
 import lombok.extern.slf4j.Slf4j;
 
+import java.util.List;
+import java.util.Map;
+
 /**
  * The api implementation of Dubbo doc.
  * @author klw(213539@qq.com)
@@ -32,6 +35,11 @@ public class DubboDocProviderImpl implements IDubboDocProvider {
 
     @Override
     public String apiModuleList() {
+        return DubboApiDocsCache.getBasicApiModuleInfo();
+    }
+
+    @Override
+    public List<Map<String, Object>> apiModuleListAndApiInfo() {
         return DubboApiDocsCache.getAllApiModuleInfo();
     }
 
diff --git a/dubbo-api-docs/dubbo-api-docs-core/src/main/java/org/apache/dubbo/apidocs/core/providers/IDubboDocProvider.java b/dubbo-api-docs/dubbo-api-docs-core/src/main/java/org/apache/dubbo/apidocs/core/providers/IDubboDocProvider.java
index 38899dc..1e7af23 100644
--- a/dubbo-api-docs/dubbo-api-docs-core/src/main/java/org/apache/dubbo/apidocs/core/providers/IDubboDocProvider.java
+++ b/dubbo-api-docs/dubbo-api-docs-core/src/main/java/org/apache/dubbo/apidocs/core/providers/IDubboDocProvider.java
@@ -16,6 +16,9 @@
  */
 package org.apache.dubbo.apidocs.core.providers;
 
+import java.util.List;
+import java.util.Map;
+
 /**
  * The api used by Dubbo doc, get the parsed API information.
  * @author klw(213539@qq.com)
@@ -32,6 +35,14 @@ public interface IDubboDocProvider {
     String apiModuleList();
 
     /**
+     * Get all information of all modules , including API parameter information.
+     * 2020/11/9 9:53
+     * @param
+     * @return java.lang.String
+     */
+    List<Map<String, Object>> apiModuleListAndApiInfo();
+
+    /**
      * Get module information according to the complete class name of Dubbo provider interface.
      * 2020/10/30 16:38
      * @param apiInterfaceClassName
diff --git a/dubbo-api-docs/dubbo-api-docs-core/src/main/java/org/apache/dubbo/apidocs/utils/ClassTypeUtil.java b/dubbo-api-docs/dubbo-api-docs-core/src/main/java/org/apache/dubbo/apidocs/utils/ClassTypeUtil.java
index cdb872c..137b908 100644
--- a/dubbo-api-docs/dubbo-api-docs-core/src/main/java/org/apache/dubbo/apidocs/utils/ClassTypeUtil.java
+++ b/dubbo-api-docs/dubbo-api-docs-core/src/main/java/org/apache/dubbo/apidocs/utils/ClassTypeUtil.java
@@ -27,11 +27,13 @@ import java.time.LocalDate;
 import java.time.LocalDateTime;
 import java.util.*;
 import java.util.concurrent.CompletableFuture;
+
 import org.apache.dubbo.apidocs.annotations.*;
 
 /**
  * Java class tool class, special for Dubbo doc.
- * @author klw(213539@qq.com)
+ *
+ * @author klw(213539 @ qq.com)
  * 2020/10/29 18:08
  */
 @Slf4j
@@ -70,8 +72,9 @@ public class ClassTypeUtil {
     /**
      * Instantiate class and its fields.
      * 2020/10/29 18:08
-     * @param genericType genericType
-     * @param classType classType
+     *
+     * @param genericType  genericType
+     * @param classType    classType
      * @param processCount processCount
      * @return java.lang.Object
      */
@@ -221,6 +224,7 @@ public class ClassTypeUtil {
     /**
      * Check if it is a basic data type.
      * 2020/10/29 18:09
+     *
      * @param o
      * @return boolean
      */
@@ -242,8 +246,9 @@ public class ClassTypeUtil {
     /**
      * Get all fields in the class.
      * 2020/10/29 18:10
+     *
      * @param fieldList fieldList
-     * @param classz classz
+     * @param classz    classz
      * @return java.util.List<java.lang.reflect.Field>
      */
     public static List<Field> getAllFields(List<Field> fieldList, Class<?> classz) {
diff --git a/dubbo-api-docs/dubbo-api-docs-examples/examples-api/src/main/java/org/apache/dubbo/apidocs/examples/api/IAsyncDemo.java b/dubbo-api-docs/dubbo-api-docs-examples/examples-api/src/main/java/org/apache/dubbo/apidocs/examples/api/IAsyncDemo.java
index 1d953aa..50426ce 100644
--- a/dubbo-api-docs/dubbo-api-docs-examples/examples-api/src/main/java/org/apache/dubbo/apidocs/examples/api/IAsyncDemo.java
+++ b/dubbo-api-docs/dubbo-api-docs-examples/examples-api/src/main/java/org/apache/dubbo/apidocs/examples/api/IAsyncDemo.java
@@ -18,6 +18,8 @@ package org.apache.dubbo.apidocs.examples.api;
 
 import org.apache.dubbo.apidocs.examples.params.DemoParamBean1;
 import org.apache.dubbo.apidocs.examples.params.DemoParamBean2;
+import org.apache.dubbo.apidocs.examples.params.DemoParamBean3;
+import org.apache.dubbo.apidocs.examples.params.DemoParamBean4;
 import org.apache.dubbo.apidocs.examples.responses.DemoRespBean1;
 
 import java.util.List;
@@ -32,58 +34,59 @@ import java.util.concurrent.CompletableFuture;
 public interface IAsyncDemo {
 
     /**
-     * @author klw(213539@qq.com)
-     * request and response parameters are beans
-     * @Date 2020/2/4 0:01
-     * @param: param
-     * @return top.klw8.alita.examples.dubbodoc.responses.DemoRespBean1
+     * request and response parameters are beans.
+     * 2020/11/14 22:21
+     * @param param1
+     * @param param2
+     * @return java.util.concurrent.CompletableFuture<org.apache.dubbo.apidocs.examples.responses.DemoRespBean1>
      */
     CompletableFuture<DemoRespBean1> demoApi1(DemoParamBean1 param1, DemoParamBean2 param2);
 
     /**
-     * @author klw(213539@qq.com)
      * Map without generics
      */
     CompletableFuture<Map> demoApi6();
 
     /**
-     * @author klw(213539@qq.com)
      * Map generic with Object
      */
     CompletableFuture<Map<Object, Object>> demoApi7();
 
     /**
-     * @author klw(213539@qq.com)
      * List without generics
      */
     CompletableFuture<List> demoApi10();
 
     /**
-     * @author klw(213539@qq.com)
      * List generic with Object
      */
     CompletableFuture<List<Object>> demoApi9();
 
     /**
-     * @author klw(213539@qq.com)
      * Object
      */
     CompletableFuture<Object> demoApi8();
 
     /**
-     * @author klw(213539@qq.com)
      * Integer
      */
     CompletableFuture<Integer> demoApi11();
 
 
     /**
-     * @author klw(213539@qq.com)
      * many generics
-     * @Date 2020/7/30 17:02
      * @param:
      * @return java.util.concurrent.CompletableFuture<java.util.List<java.util.List<java.lang.String>>>
      */
     CompletableFuture<List<List<String>>> demoApi12();
 
+    /**
+     * Simple test.
+     * 2020/11/13 10:11
+     * @param param1
+     * @param param2
+     * @return java.util.concurrent.CompletableFuture<org.apache.dubbo.apidocs.examples.params.DemoParamBean3>
+     */
+    CompletableFuture<DemoParamBean3> demoApi13(DemoParamBean3 param1, DemoParamBean4 param2);
+
 }
diff --git a/dubbo-api-docs/dubbo-api-docs-examples/examples-api/src/main/java/org/apache/dubbo/apidocs/examples/api/ISyncDemo.java b/dubbo-api-docs/dubbo-api-docs-examples/examples-api/src/main/java/org/apache/dubbo/apidocs/examples/api/ISyncDemo.java
index f842140..59064a0 100644
--- a/dubbo-api-docs/dubbo-api-docs-examples/examples-api/src/main/java/org/apache/dubbo/apidocs/examples/api/ISyncDemo.java
+++ b/dubbo-api-docs/dubbo-api-docs-examples/examples-api/src/main/java/org/apache/dubbo/apidocs/examples/api/ISyncDemo.java
@@ -18,6 +18,8 @@ package org.apache.dubbo.apidocs.examples.api;
 
 import org.apache.dubbo.apidocs.examples.params.DemoParamBean1;
 import org.apache.dubbo.apidocs.examples.params.DemoParamBean2;
+import org.apache.dubbo.apidocs.examples.params.DemoParamBean3;
+import org.apache.dubbo.apidocs.examples.params.DemoParamBean4;
 import org.apache.dubbo.apidocs.examples.responses.BaseResponse;
 import org.apache.dubbo.apidocs.examples.responses.DemoRespBean1;
 
@@ -32,10 +34,11 @@ import java.util.Map;
 public interface ISyncDemo {
 
     /**
-     * request and response parameters are beans
-     * @Date 2020/2/4 0:01
-     * @param: param
-     * @return top.klw8.alita.examples.dubbodoc.responses.DemoRespBean1
+     * request and response parameters are beans.
+     * 2020/11/14 22:21
+     * @param param1
+     * @param param2
+     * @return org.apache.dubbo.apidocs.examples.responses.DemoRespBean1
      */
     DemoRespBean1 demoApi1(DemoParamBean1 param1, DemoParamBean2 param2);
 
@@ -94,4 +97,13 @@ public interface ISyncDemo {
      */
     Object demoApi8();
 
+    /**
+     * Simple test.
+     * 2020/11/13 10:11
+     * @param param1
+     * @param param2
+     * @return org.apache.dubbo.apidocs.examples.params.DemoParamBean3
+     */
+    DemoParamBean3 demoApi13(DemoParamBean3 param1, DemoParamBean4 param2);
+
 }
diff --git a/dubbo-api-docs/dubbo-api-docs-examples/examples-api/src/main/java/org/apache/dubbo/apidocs/examples/params/DemoParamBean3.java b/dubbo-api-docs/dubbo-api-docs-examples/examples-api/src/main/java/org/apache/dubbo/apidocs/examples/params/DemoParamBean3.java
new file mode 100644
index 0000000..9139197
--- /dev/null
+++ b/dubbo-api-docs/dubbo-api-docs-examples/examples-api/src/main/java/org/apache/dubbo/apidocs/examples/params/DemoParamBean3.java
@@ -0,0 +1,43 @@
+/*
+ * 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.apidocs.examples.params;
+
+import org.apache.dubbo.apidocs.annotations.RequestParam;
+import org.apache.dubbo.apidocs.annotations.ResponseProperty;
+
+import lombok.Getter;
+import lombok.Setter;
+
+/**
+ * DemoParamBean3.
+ *
+ * @author klw(213539 @ qq.com)
+ * @date 2020/11/13 9:56
+ */
+@Getter
+@Setter
+public class DemoParamBean3 {
+
+    @RequestParam("a string")
+    @ResponseProperty("result a string")
+    private String string;
+
+    @RequestParam("a DemoParamBean4")
+    @ResponseProperty("result a bean4")
+    private DemoParamBean4 bean4;
+
+}
diff --git a/dubbo-api-docs/dubbo-api-docs-examples/examples-api/src/main/java/org/apache/dubbo/apidocs/examples/params/DemoParamBean4.java b/dubbo-api-docs/dubbo-api-docs-examples/examples-api/src/main/java/org/apache/dubbo/apidocs/examples/params/DemoParamBean4.java
new file mode 100644
index 0000000..6b5f716
--- /dev/null
+++ b/dubbo-api-docs/dubbo-api-docs-examples/examples-api/src/main/java/org/apache/dubbo/apidocs/examples/params/DemoParamBean4.java
@@ -0,0 +1,39 @@
+/*
+ * Licensed to the Apache Software Foundation (ASF) under one or more
+ * contributor license agreements.  See the NOTICE file distributed with
+ * this work for additional information regarding copyright ownership.
+ * The ASF licenses this file to You under the Apache License, Version 2.0
+ * (the "License"); you may not use this file except in compliance with
+ * the License.  You may obtain a copy of the License at
+ *
+ *     http://www.apache.org/licenses/LICENSE-2.0
+ *
+ * Unless required by applicable law or agreed to in writing, software
+ * distributed under the License is distributed on an "AS IS" BASIS,
+ * WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied.
+ * See the License for the specific language governing permissions and
+ * limitations under the License.
+ */
+package org.apache.dubbo.apidocs.examples.params;
+
+import org.apache.dubbo.apidocs.annotations.RequestParam;
+import org.apache.dubbo.apidocs.annotations.ResponseProperty;
+
+import lombok.Getter;
+import lombok.Setter;
+
+/**
+ * DemoParamBean4.
+ *
+ * @author klw(213539 @ qq.com)
+ * @date 2020/11/13 9:56
+ */
+@Getter
+@Setter
+public class DemoParamBean4 {
+
+    @RequestParam("a string")
+    @ResponseProperty("result a string")
+    private String bean4Str;
+
+}
diff --git a/dubbo-api-docs/dubbo-api-docs-examples/examples-provider/src/main/java/org/apache/dubbo/apidocs/examples/api/impl/AsyncDemoImpl.java b/dubbo-api-docs/dubbo-api-docs-examples/examples-provider/src/main/java/org/apache/dubbo/apidocs/examples/api/impl/AsyncDemoImpl.java
index 9706290..bde2bf8 100644
--- a/dubbo-api-docs/dubbo-api-docs-examples/examples-provider/src/main/java/org/apache/dubbo/apidocs/examples/api/impl/AsyncDemoImpl.java
+++ b/dubbo-api-docs/dubbo-api-docs-examples/examples-provider/src/main/java/org/apache/dubbo/apidocs/examples/api/impl/AsyncDemoImpl.java
@@ -21,6 +21,8 @@ import org.apache.dubbo.apidocs.annotations.ApiModule;
 import org.apache.dubbo.apidocs.examples.api.IAsyncDemo;
 import org.apache.dubbo.apidocs.examples.params.DemoParamBean1;
 import org.apache.dubbo.apidocs.examples.params.DemoParamBean2;
+import org.apache.dubbo.apidocs.examples.params.DemoParamBean3;
+import org.apache.dubbo.apidocs.examples.params.DemoParamBean4;
 import org.apache.dubbo.apidocs.examples.responses.DemoRespBean1;
 import org.apache.dubbo.config.annotation.DubboService;
 
@@ -34,7 +36,8 @@ import java.util.concurrent.ScheduledThreadPoolExecutor;
 
 /**
  * Asynchronous demo implementation.
- * @author klw(213539@qq.com)
+ *
+ * @author klw(213539 @ qq.com)
  * 2020/10/30 14:54
  */
 @DubboService(async = true)
@@ -56,44 +59,52 @@ public class AsyncDemoImpl implements IAsyncDemo {
     }
 
     @Override
-    @ApiDoc(value = "Map without generics", responseClassDescription="Map without generics")
+    @ApiDoc(value = "Map without generics", responseClassDescription = "Map without generics")
     public CompletableFuture<Map> demoApi6() {
         return null;
     }
 
     @Override
-    @ApiDoc(value = "Map generic with Object", responseClassDescription="Map generic with Object")
+    @ApiDoc(value = "Map generic with Object", responseClassDescription = "Map generic with Object")
     public CompletableFuture<Map<Object, Object>> demoApi7() {
         return null;
     }
 
     @Override
-    @ApiDoc(value = "List without generics", responseClassDescription="List without generics")
+    @ApiDoc(value = "List without generics", responseClassDescription = "List without generics")
     public CompletableFuture<List> demoApi10() {
         return null;
     }
 
     @Override
-    @ApiDoc(value = "List generic with Object", responseClassDescription="List generic with Object")
+    @ApiDoc(value = "List generic with Object", responseClassDescription = "List generic with Object")
     public CompletableFuture<List<Object>> demoApi9() {
         return null;
     }
 
     @Override
-    @ApiDoc(value = "Object", responseClassDescription="Object")
+    @ApiDoc(value = "Object", responseClassDescription = "Object")
     public CompletableFuture<Object> demoApi8() {
         return null;
     }
 
     @Override
-    @ApiDoc(value = "Integer", responseClassDescription="Integer")
+    @ApiDoc(value = "Integer", responseClassDescription = "Integer")
     public CompletableFuture<Integer> demoApi11() {
         return null;
     }
 
     @Override
-    @ApiDoc(value = "many generics", responseClassDescription="many generics")
-    public CompletableFuture<List<List<String>>> demoApi12(){
+    @ApiDoc(value = "many generics", responseClassDescription = "many generics")
+    public CompletableFuture<List<List<String>>> demoApi12() {
         return null;
     }
+
+    @Override
+    @ApiDoc(value = "Simple test", responseClassDescription = "Simple test")
+    public CompletableFuture<DemoParamBean3> demoApi13(DemoParamBean3 param1, DemoParamBean4 param2) {
+        DemoParamBean3 result = new DemoParamBean3();
+        result.setString("demoApi13 result");
+        return CompletableFuture.supplyAsync(() -> result, EXECUTOR);
+    }
 }
diff --git a/dubbo-api-docs/dubbo-api-docs-examples/examples-provider/src/main/java/org/apache/dubbo/apidocs/examples/api/impl/SyncDemoImpl.java b/dubbo-api-docs/dubbo-api-docs-examples/examples-provider/src/main/java/org/apache/dubbo/apidocs/examples/api/impl/SyncDemoImpl.java
index 243a2e3..07f13b5 100644
--- a/dubbo-api-docs/dubbo-api-docs-examples/examples-provider/src/main/java/org/apache/dubbo/apidocs/examples/api/impl/SyncDemoImpl.java
+++ b/dubbo-api-docs/dubbo-api-docs-examples/examples-provider/src/main/java/org/apache/dubbo/apidocs/examples/api/impl/SyncDemoImpl.java
@@ -24,6 +24,8 @@ import org.apache.dubbo.apidocs.annotations.RequestParam;
 import org.apache.dubbo.apidocs.examples.api.ISyncDemo;
 import org.apache.dubbo.apidocs.examples.params.DemoParamBean1;
 import org.apache.dubbo.apidocs.examples.params.DemoParamBean2;
+import org.apache.dubbo.apidocs.examples.params.DemoParamBean3;
+import org.apache.dubbo.apidocs.examples.params.DemoParamBean4;
 import org.apache.dubbo.apidocs.examples.responses.BaseResponse;
 import org.apache.dubbo.apidocs.examples.responses.DemoRespBean1;
 import org.apache.dubbo.config.annotation.DubboService;
@@ -113,4 +115,12 @@ public class SyncDemoImpl implements ISyncDemo {
     public Object demoApi8() {
         return null;
     }
+
+    @Override
+    @ApiDoc(value = "Simple test", responseClassDescription = "Simple test")
+    public DemoParamBean3 demoApi13(DemoParamBean3 param1, DemoParamBean4 param2) {
+        DemoParamBean3 result = new DemoParamBean3();
+        result.setString("demoApi13 result");
+        return result;
+    }
 }
diff --git a/dubbo-api-docs/dubbo-api-docs-examples/examples-provider/src/main/resources/application.yml b/dubbo-api-docs/dubbo-api-docs-examples/examples-provider/src/main/resources/application.yml
index 87423b4..ae4c2fa 100644
--- a/dubbo-api-docs/dubbo-api-docs-examples/examples-provider/src/main/resources/application.yml
+++ b/dubbo-api-docs/dubbo-api-docs-examples/examples-provider/src/main/resources/application.yml
@@ -1,6 +1,6 @@
 spring:
   application:
-    name: dubbo-doc-example-provider
+    name: dubbo-api-docs-example-provider
   profiles:
     active: dev
 dubbo:
@@ -12,4 +12,6 @@ dubbo:
     port: 20881
     name: dubbo
   application:
-    name: dubbo-doc-example-provider
\ No newline at end of file
+    name: dubbo-api-docs-example-provider
+  metadata-report:
+    address: nacos://127.0.0.1:8848
\ No newline at end of file
diff --git a/dubbo-api-docs/dubbo-api-docs-ui-server/pom.xml b/dubbo-api-docs/dubbo-api-docs-ui-server/pom.xml
new file mode 100644
index 0000000..9044a7d
--- /dev/null
+++ b/dubbo-api-docs/dubbo-api-docs-ui-server/pom.xml
@@ -0,0 +1,291 @@
+<?xml version="1.0" encoding="UTF-8"?>
+<!--
+  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.
+ -->
+<project xmlns="http://maven.apache.org/POM/4.0.0" xmlns:xsi="http://www.w3.org/2001/XMLSchema-instance" xsi:schemaLocation="http://maven.apache.org/POM/4.0.0 http://maven.apache.org/xsd/maven-4.0.0.xsd">
+    <modelVersion>4.0.0</modelVersion>
+    <groupId>org.apache.dubbo</groupId>
+    <artifactId>dubbo-api-docs-ui-server</artifactId>
+    <version>2.7.9-SNAPSHOT</version>
+    <packaging>jar</packaging>
+    <name>dubbo-api-docs-ui-server</name>
+    <description>Web ui, responsible for displaying doc and providing testing function</description>
+
+    <parent>
+        <groupId>org.springframework.boot</groupId>
+        <artifactId>spring-boot-starter-parent</artifactId>
+        <version>2.3.4.RELEASE</version>
+        <relativePath />
+    </parent>
+
+    <properties>
+    </properties>
+    
+    <dependencyManagement>
+        <dependencies>
+            <dependency>
+                <groupId>org.apache.dubbo</groupId>
+                <artifactId>dubbo-api-docs</artifactId>
+                <version>2.7.9-SNAPSHOT</version>
+                <type>pom</type>
+                <scope>import</scope>
+            </dependency>
+        </dependencies>
+    </dependencyManagement>
+
+    <dependencies>
+
+        <!--
+        [Begin] Solve the spring fox problem temporarily
+        Spring fox relies on 1.2.0 but doesn't work. It works under 2.0.0
+        <dependency>
+            <groupId>org.springframework.plugin</groupId>
+            <artifactId>spring-plugin-core</artifactId>
+            <version>2.0.0.RELEASE</version>
+        </dependency>
+        <dependency>
+            <groupId>org.springframework.plugin</groupId>
+            <artifactId>spring-plugin-metadata</artifactId>
+            <version>2.0.0.RELEASE</version>
+        </dependency>
+        [End] Solve the spring fox problem temporarily -->
+
+        <dependency>
+            <groupId>org.springframework.boot</groupId>
+            <artifactId>spring-boot-starter-webflux</artifactId>
+            <exclusions>
+                <exclusion>
+                    <groupId>org.springframework.boot</groupId>
+                    <artifactId>spring-boot-starter-logging</artifactId>
+                </exclusion>
+            </exclusions>
+        </dependency>
+
+        <dependency>
+            <groupId>org.apache.logging.log4j</groupId>
+            <artifactId>log4j-1.2-api</artifactId>
+        </dependency>
+
+        <dependency>
+            <groupId>org.apache.logging.log4j</groupId>
+            <artifactId>log4j-slf4j-impl</artifactId>
+        </dependency>
+        <dependency>
+            <groupId>org.slf4j</groupId>
+            <artifactId>jcl-over-slf4j</artifactId>
+        </dependency>
+        <dependency>
+            <groupId>com.lmax</groupId>
+            <artifactId>disruptor</artifactId>
+        </dependency>
+
+        <dependency>
+            <groupId>org.apache.dubbo</groupId>
+            <artifactId>dubbo</artifactId>
+        </dependency>
+
+        <dependency>
+            <groupId>org.apache.dubbo</groupId>
+            <artifactId>dubbo-registry-nacos</artifactId>
+            <exclusions>
+                <exclusion>
+                    <artifactId>log4j</artifactId>
+                    <groupId>log4j</groupId>
+                </exclusion>
+                <exclusion>
+                    <groupId>org.apache.dubbo</groupId>
+                    <artifactId>dubbo-remoting-api</artifactId>
+                </exclusion>
+                <exclusion>
+                    <artifactId>dubbo-common</artifactId>
+                    <groupId>org.apache.dubbo</groupId>
+                </exclusion>
+            </exclusions>
+        </dependency>
+
+        <dependency>
+            <groupId>org.apache.dubbo</groupId>
+            <artifactId>dubbo-registry-consul</artifactId>
+        </dependency>
+
+        <dependency>
+            <groupId>org.apache.dubbo</groupId>
+            <artifactId>dubbo-registry-default</artifactId>
+        </dependency>
+
+        <dependency>
+            <groupId>org.apache.dubbo</groupId>
+            <artifactId>dubbo-registry-etcd3</artifactId>
+            <exclusions>
+                <exclusion>
+                    <artifactId>log4j</artifactId>
+                    <groupId>log4j</groupId>
+                </exclusion>
+                <exclusion>
+                    <groupId>org.apache.dubbo</groupId>
+                    <artifactId>dubbo-remoting-api</artifactId>
+                </exclusion>
+                <exclusion>
+                    <artifactId>dubbo-common</artifactId>
+                    <groupId>org.apache.dubbo</groupId>
+                </exclusion>
+            </exclusions>
+        </dependency>
+
+        <dependency>
+            <groupId>org.apache.dubbo</groupId>
+            <artifactId>dubbo-registry-multicast</artifactId>
+        </dependency>
+
+        <dependency>
+            <groupId>org.apache.dubbo</groupId>
+            <artifactId>dubbo-registry-multiple</artifactId>
+        </dependency>
+
+        <dependency>
+            <groupId>org.apache.dubbo</groupId>
+            <artifactId>dubbo-registry-redis</artifactId>
+            <exclusions>
+                <exclusion>
+                    <artifactId>log4j</artifactId>
+                    <groupId>log4j</groupId>
+                </exclusion>
+                <exclusion>
+                    <groupId>org.apache.dubbo</groupId>
+                    <artifactId>dubbo-remoting-api</artifactId>
+                </exclusion>
+                <exclusion>
+                    <artifactId>dubbo-common</artifactId>
+                    <groupId>org.apache.dubbo</groupId>
+                </exclusion>
+            </exclusions>
+        </dependency>
+
+        <dependency>
+            <groupId>org.apache.dubbo</groupId>
+            <artifactId>dubbo-registry-sofa</artifactId>
+        </dependency>
+
+        <dependency>
+            <groupId>org.apache.dubbo</groupId>
+            <artifactId>dubbo-registry-zookeeper</artifactId>
+            <exclusions>
+                <exclusion>
+                    <artifactId>slf4j-log4j12</artifactId>
+                    <groupId>org.slf4j</groupId>
+                </exclusion>
+                <exclusion>
+                    <artifactId>log4j</artifactId>
+                    <groupId>log4j</groupId>
+                </exclusion>
+                <exclusion>
+                    <groupId>org.apache.dubbo</groupId>
+                    <artifactId>dubbo-remoting-api</artifactId>
+                </exclusion>
+                <exclusion>
+                    <artifactId>dubbo-common</artifactId>
+                    <groupId>org.apache.dubbo</groupId>
+                </exclusion>
+            </exclusions>
+        </dependency>
+
+        <dependency>
+            <groupId>com.alibaba.nacos</groupId>
+            <artifactId>nacos-api</artifactId>
+            <scope>compile</scope>
+        </dependency>
+
+        <dependency>
+            <groupId>com.alibaba.nacos</groupId>
+            <artifactId>nacos-client</artifactId>
+        </dependency>
+
+        <dependency>
+            <groupId>io.springfox</groupId>
+            <artifactId>springfox-boot-starter</artifactId>
+        </dependency>
+
+        <dependency>
+            <groupId>org.projectlombok</groupId>
+            <artifactId>lombok</artifactId>
+        </dependency>
+
+        <dependency>
+            <groupId>commons-io</groupId>
+            <artifactId>commons-io</artifactId>
+        </dependency>
+
+        <dependency>
+            <groupId>commons-beanutils</groupId>
+            <artifactId>commons-beanutils</artifactId>
+        </dependency>
+
+        <dependency>
+            <groupId>org.apache.commons</groupId>
+            <artifactId>commons-collections4</artifactId>
+        </dependency>
+
+    </dependencies>
+
+    <profiles>
+        <profile>
+            <id>release-dubboDoc</id>
+            <build>
+                <finalName>dubbo-doc-ui-server</finalName>
+                <plugins>
+                    <plugin>
+                        <artifactId>maven-jar-plugin</artifactId>
+                        <configuration>
+                            <archive>
+                                <manifest>
+                                    <addDefaultImplementationEntries>true</addDefaultImplementationEntries>
+                                    <addDefaultSpecificationEntries>true</addDefaultSpecificationEntries>
+                                </manifest>
+                            </archive>
+                        </configuration>
+                    </plugin>
+                    <plugin>
+                        <groupId>org.springframework.boot</groupId>
+                        <artifactId>spring-boot-maven-plugin</artifactId>
+                        <configuration>
+                            <mainClass>org.apache.dubbo.apidocs.DubboApiDocsUiServerApplication</mainClass>
+                            <layout>ZIP</layout>
+                        </configuration>
+                        <executions>
+                            <execution>
+                                <goals>
+                                    <goal>repackage</goal>
+                                </goals>
+                            </execution>
+                        </executions>
+                    </plugin>
+                    <plugin>
+                        <groupId>org.apache.maven.plugins</groupId>
+                        <artifactId>maven-jar-plugin</artifactId>
+                        <configuration>
+                            <excludes>
+                                <exclude>**/application.yml</exclude>
+                                <exclude>**/log4j2.xml</exclude>
+                                <exclude>**/rebel.xml</exclude>
+                            </excludes>
+                        </configuration>
+                    </plugin>
+                </plugins>
+            </build>
+        </profile>
+    </profiles>
+
+</project>
\ No newline at end of file
diff --git a/dubbo-api-docs/dubbo-api-docs-core/src/main/java/org/apache/dubbo/apidocs/core/providers/DubboDocProviderImpl.java b/dubbo-api-docs/dubbo-api-docs-ui-server/src/main/java/org/apache/dubbo/apidocs/DubboApiDocsUiServerApplication.java
similarity index 51%
copy from dubbo-api-docs/dubbo-api-docs-core/src/main/java/org/apache/dubbo/apidocs/core/providers/DubboDocProviderImpl.java
copy to dubbo-api-docs/dubbo-api-docs-ui-server/src/main/java/org/apache/dubbo/apidocs/DubboApiDocsUiServerApplication.java
index d8cfb2b..a8a7c65 100644
--- a/dubbo-api-docs/dubbo-api-docs-core/src/main/java/org/apache/dubbo/apidocs/core/providers/DubboDocProviderImpl.java
+++ b/dubbo-api-docs/dubbo-api-docs-ui-server/src/main/java/org/apache/dubbo/apidocs/DubboApiDocsUiServerApplication.java
@@ -14,34 +14,24 @@
  * See the License for the specific language governing permissions and
  * limitations under the License.
  */
-package org.apache.dubbo.apidocs.core.providers;
+package org.apache.dubbo.apidocs;
 
-import org.apache.dubbo.apidocs.core.DubboApiDocsCache;
-import org.apache.dubbo.config.annotation.DubboService;
+import org.springframework.boot.SpringApplication;
+import org.springframework.boot.autoconfigure.SpringBootApplication;
+import org.springframework.context.ConfigurableApplicationContext;
 
-import lombok.extern.slf4j.Slf4j;
 
 /**
- * The api implementation of Dubbo doc.
+ * Start Dubbo doc ui server.
  * @author klw(213539@qq.com)
- * 2020/10/29 17:38
+ * 2020/11/14 20:41
  */
-@Slf4j
-@DubboService
-public class DubboDocProviderImpl implements IDubboDocProvider {
+@SpringBootApplication
+public class DubboApiDocsUiServerApplication {
 
-    @Override
-    public String apiModuleList() {
-        return DubboApiDocsCache.getAllApiModuleInfo();
-    }
 
-    @Override
-    public String apiModuleInfo(String apiInterfaceClassName) {
-        return DubboApiDocsCache.getApiModuleStr(apiInterfaceClassName);
+    public static void main(String[] args) {
+        ConfigurableApplicationContext ctx = SpringApplication.run(DubboApiDocsUiServerApplication.class);
     }
 
-    @Override
-    public String apiParamsResponseInfo(String apiInterfaceClassNameMethodName) {
-        return DubboApiDocsCache.getApiParamsAndRespStr(apiInterfaceClassNameMethodName);
-    }
 }
diff --git a/dubbo-api-docs/dubbo-api-docs-ui-server/src/main/java/org/apache/dubbo/apidocs/cfg/SwaggerConfig.java b/dubbo-api-docs/dubbo-api-docs-ui-server/src/main/java/org/apache/dubbo/apidocs/cfg/SwaggerConfig.java
new file mode 100644
index 0000000..5a1dbe9
--- /dev/null
+++ b/dubbo-api-docs/dubbo-api-docs-ui-server/src/main/java/org/apache/dubbo/apidocs/cfg/SwaggerConfig.java
@@ -0,0 +1,62 @@
+/*
+ * 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.apidocs.cfg;
+
+
+import io.swagger.annotations.Api;
+import org.springframework.context.annotation.Bean;
+import org.springframework.context.annotation.Configuration;
+import springfox.documentation.builders.ApiInfoBuilder;
+import springfox.documentation.builders.PathSelectors;
+import springfox.documentation.builders.RequestHandlerSelectors;
+import springfox.documentation.service.*;
+import springfox.documentation.spi.DocumentationType;
+import springfox.documentation.spring.web.plugins.Docket;
+import springfox.documentation.swagger2.annotations.EnableSwagger2;
+import springfox.documentation.swagger2.annotations.EnableSwagger2WebFlux;
+
+/**
+ * swagger config.
+ * @author klw(213539@qq.com)
+ * 2020/11/14 20:42
+ */
+@Configuration
+@EnableSwagger2
+public class SwaggerConfig {
+
+    public static final String VERSION = "1.0.0";
+
+    protected ApiInfo apiInfo() {
+        return new ApiInfoBuilder().title("Dubbo API docs").description("&nbsp;")
+                .license("Apache 2.0")
+                .licenseUrl("http://www.apache.org/licenses/LICENSE-2.0.html")
+                .termsOfServiceUrl("").version(VERSION)
+                .build();
+    }
+
+    @Bean
+    public Docket customImplementationDevHelper() {
+        return new Docket(DocumentationType.SWAGGER_2)
+                .groupName("【Dubbo API docs】")
+                .select()
+                .paths(PathSelectors.ant("/**"))
+                .apis(RequestHandlerSelectors.withClassAnnotation(Api.class))
+                .build()
+                .apiInfo(apiInfo());
+    }
+    
+}
diff --git a/dubbo-api-docs/dubbo-api-docs-core/src/main/java/org/apache/dubbo/apidocs/core/providers/DubboDocProviderImpl.java b/dubbo-api-docs/dubbo-api-docs-ui-server/src/main/java/org/apache/dubbo/apidocs/cfg/WebConfig.java
similarity index 52%
copy from dubbo-api-docs/dubbo-api-docs-core/src/main/java/org/apache/dubbo/apidocs/core/providers/DubboDocProviderImpl.java
copy to dubbo-api-docs/dubbo-api-docs-ui-server/src/main/java/org/apache/dubbo/apidocs/cfg/WebConfig.java
index d8cfb2b..87b4062 100644
--- a/dubbo-api-docs/dubbo-api-docs-core/src/main/java/org/apache/dubbo/apidocs/core/providers/DubboDocProviderImpl.java
+++ b/dubbo-api-docs/dubbo-api-docs-ui-server/src/main/java/org/apache/dubbo/apidocs/cfg/WebConfig.java
@@ -14,34 +14,29 @@
  * See the License for the specific language governing permissions and
  * limitations under the License.
  */
-package org.apache.dubbo.apidocs.core.providers;
+package org.apache.dubbo.apidocs.cfg;
 
-import org.apache.dubbo.apidocs.core.DubboApiDocsCache;
-import org.apache.dubbo.config.annotation.DubboService;
-
-import lombok.extern.slf4j.Slf4j;
+import org.springframework.stereotype.Component;
+import org.springframework.web.server.ServerWebExchange;
+import org.springframework.web.server.WebFilter;
+import org.springframework.web.server.WebFilterChain;
+import reactor.core.publisher.Mono;
 
 /**
- * The api implementation of Dubbo doc.
+ * web config.
  * @author klw(213539@qq.com)
- * 2020/10/29 17:38
+ * 2020/11/14 20:44
  */
-@Slf4j
-@DubboService
-public class DubboDocProviderImpl implements IDubboDocProvider {
+@Component
+public class WebConfig implements WebFilter {
 
     @Override
-    public String apiModuleList() {
-        return DubboApiDocsCache.getAllApiModuleInfo();
-    }
+    public Mono<Void> filter(ServerWebExchange exchange, WebFilterChain chain) {
+        if (exchange.getRequest().getURI().getPath().equals("/")) {
+            return chain.filter(exchange.mutate().request(exchange.getRequest().mutate().path("/index.html").build()).build());
+        }
 
-    @Override
-    public String apiModuleInfo(String apiInterfaceClassName) {
-        return DubboApiDocsCache.getApiModuleStr(apiInterfaceClassName);
+        return chain.filter(exchange);
     }
 
-    @Override
-    public String apiParamsResponseInfo(String apiInterfaceClassNameMethodName) {
-        return DubboApiDocsCache.getApiParamsAndRespStr(apiInterfaceClassNameMethodName);
-    }
 }
diff --git a/dubbo-api-docs/dubbo-api-docs-ui-server/src/main/java/org/apache/dubbo/apidocs/controller/DubboApiDocsController.java b/dubbo-api-docs/dubbo-api-docs-ui-server/src/main/java/org/apache/dubbo/apidocs/controller/DubboApiDocsController.java
new file mode 100644
index 0000000..a4f5da1
--- /dev/null
+++ b/dubbo-api-docs/dubbo-api-docs-ui-server/src/main/java/org/apache/dubbo/apidocs/controller/DubboApiDocsController.java
@@ -0,0 +1,191 @@
+/*
+ * 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.apidocs.controller;
+
+import org.apache.dubbo.apidocs.controller.vo.ApiInfoRequest;
+import org.apache.dubbo.apidocs.controller.vo.CallDubboServiceRequest;
+import org.apache.dubbo.apidocs.controller.vo.CallDubboServiceRequestInterfacePrarm;
+import org.apache.dubbo.apidocs.editor.CustomDateEditor;
+import org.apache.dubbo.apidocs.editor.CustomLocalDateEditor;
+import org.apache.dubbo.apidocs.editor.CustomLocalDateTimeEditor;
+import org.apache.dubbo.apidocs.utils.DubboGenericUtil;
+
+import com.alibaba.fastjson.JSON;
+import com.alibaba.fastjson.serializer.SimplePropertyPreFilter;
+import io.swagger.annotations.Api;
+import io.swagger.annotations.ApiOperation;
+import lombok.extern.slf4j.Slf4j;
+import org.apache.commons.collections4.CollectionUtils;
+import org.apache.commons.lang3.StringUtils;
+import org.springframework.beans.factory.annotation.Value;
+import org.springframework.beans.propertyeditors.StringTrimmerEditor;
+import org.springframework.web.bind.WebDataBinder;
+import org.springframework.web.bind.annotation.*;
+import reactor.core.publisher.Mono;
+
+import javax.annotation.PostConstruct;
+import java.time.LocalDate;
+import java.time.LocalDateTime;
+import java.util.*;
+import java.util.concurrent.CompletableFuture;
+
+/**
+ * dubbo doc ui server api.
+ * @author klw(213539@qq.com)
+ * 2020/11/14 20:23
+ */
+@Api(tags = {"alita-restful-API--demoAPI"})
+@RestController
+@Slf4j
+@RequestMapping("/api")
+public class DubboApiDocsController {
+
+    private static final SimplePropertyPreFilter CLASS_NAME_PRE_FILTER = new SimplePropertyPreFilter(HashMap.class);
+    static {
+        // Remove the "class" attribute from the returned result
+        CLASS_NAME_PRE_FILTER.getExcludes().add("class");
+    }
+
+    /**
+     * retries for dubbo provider.
+     */
+    @Value("${dubbo.consumer.retries:2}")
+    private int retries;
+
+    /**
+     * timeout.
+     */
+    @Value("${dubbo.consumer.timeout:1000}")
+    private int timeout;
+
+    @InitBinder
+    public void initBinder(WebDataBinder binder) {
+        binder.registerCustomEditor(String.class, new StringTrimmerEditor(true));
+        binder.registerCustomEditor(Date.class, new CustomDateEditor());
+        binder.registerCustomEditor(LocalDate.class, new CustomLocalDateEditor());
+        binder.registerCustomEditor(LocalDateTime.class, new CustomLocalDateTimeEditor());
+    }
+
+    /**
+     * Set timeout and retries for {@link DubboGenericUtil}.
+     * 2020/11/14 20:26
+     */
+    @PostConstruct
+    public void setRetriesAndTimeout(){
+        DubboGenericUtil.setRetriesAndTimeout(retries, timeout);
+    }
+
+    @ApiOperation(value = "request dubbo api", notes = "request dubbo api", httpMethod = "POST", produces = "application/json")
+    @PostMapping("/requestDubbo")
+    public Mono<String> callDubboService(CallDubboServiceRequest dubboCfg, @RequestBody List<CallDubboServiceRequestInterfacePrarm> methodPrarms){
+        String[] prarmTypes = null;
+        Object[] prarmValues = null;
+        if(CollectionUtils.isNotEmpty(methodPrarms)){
+            prarmTypes = new String[methodPrarms.size()];
+            prarmValues = new Object[methodPrarms.size()];
+            for(int i = 0; i < methodPrarms.size(); i++){
+                CallDubboServiceRequestInterfacePrarm prarm = methodPrarms.get(i);
+                prarmTypes[i] = prarm.getPrarmType();
+                Object prarmValue = prarm.getPrarmValue();
+                if(isBaseType(prarm.getPrarmType()) && null != prarmValue){
+                    if(prarmValue instanceof Map){
+                        Map<?, ?> tempMap = (Map<?, ?>) prarmValue;
+                        if(!tempMap.isEmpty()) {
+                            this.emptyString2Null(tempMap);
+                            prarmValues[i] = tempMap.values().stream().findFirst().orElse(null);
+                        }
+                    } else {
+                        prarmValues[i] = emptyString2Null(prarmValue);
+                    }
+                } else {
+                    this.emptyString2Null(prarmValue);
+                    prarmValues[i] = prarmValue;
+                }
+            }
+        }
+        if (null == prarmTypes) {
+            prarmTypes = new String[0];
+        }
+        if (null == prarmValues) {
+            prarmValues = new Object[0];
+        }
+        CompletableFuture<Object> future = DubboGenericUtil.invoke(dubboCfg.getRegistryCenterUrl(), dubboCfg.getInterfaceClassName(),
+                dubboCfg.getMethodName(), dubboCfg.isAsync(), prarmTypes, prarmValues);
+        return Mono.fromFuture(future).map( o -> JSON.toJSONString(o, CLASS_NAME_PRE_FILTER));
+    }
+
+    private Object emptyString2Null(Object prarmValue){
+        if(null != prarmValue) {
+            if (prarmValue instanceof String && StringUtils.isBlank((String) prarmValue)) {
+                return null;
+            } else if (prarmValue instanceof Map) {
+                Map<String, Object> tempMap = (Map<String, Object>) prarmValue;
+                tempMap.forEach((k, v) -> {
+                    if (v != null && v instanceof String && StringUtils.isBlank((String) v)) {
+                        tempMap.put(k, null);
+                    } else {
+                        this.emptyString2Null(v);
+                    }
+                });
+            }
+        }
+        return prarmValue;
+    }
+
+    @ApiOperation(value = "Get basic information of all modules, excluding API parameter information", notes = "Get basic information of all modules, excluding API parameter information", httpMethod = "GET", produces = "application/json")
+    @GetMapping("/apiModuleList")
+    public Mono<String> apiModuleList(ApiInfoRequest apiInfoRequest){
+        CallDubboServiceRequest req = new CallDubboServiceRequest();
+        req.setRegistryCenterUrl("dubbo://" + apiInfoRequest.getDubboIp() + ":" + apiInfoRequest.getDubboPort());
+        req.setInterfaceClassName("org.apache.dubbo.apidocs.core.providers.IDubboDocProvider");
+        req.setMethodName("apiModuleList");
+        req.setAsync(false);
+        return callDubboService(req, null);
+    }
+
+    @ApiOperation(value = "Get the parameter information of the specified API", notes = "Get the parameter information of the specified API", httpMethod = "GET", produces = "application/json")
+    @GetMapping("/apiParamsResp")
+    public Mono<String> apiParamsResp(ApiInfoRequest apiInfoRequest){
+        CallDubboServiceRequest req = new CallDubboServiceRequest();
+        req.setRegistryCenterUrl("dubbo://" + apiInfoRequest.getDubboIp() + ":" + apiInfoRequest.getDubboPort());
+        req.setInterfaceClassName("org.apache.dubbo.apidocs.core.providers.IDubboDocProvider");
+        req.setMethodName("apiParamsResponseInfo");
+        req.setAsync(false);
+
+        List<CallDubboServiceRequestInterfacePrarm> methodPrarms = new ArrayList<>(1);
+        CallDubboServiceRequestInterfacePrarm prarm = new CallDubboServiceRequestInterfacePrarm();
+        prarm.setPrarmType(String.class.getName());
+        prarm.setPrarmValue(apiInfoRequest.getApiName());
+        methodPrarms.add(prarm);
+        return callDubboService(req, methodPrarms);
+    }
+
+    private static boolean isBaseType(String typeStr) {
+        if ("java.lang.Integer".equals(typeStr) ||
+                "java.lang.Byte".equals(typeStr) ||
+                "java.lang.Long".equals(typeStr) ||
+                "java.lang.Double".equals(typeStr) ||
+                "java.lang.Float".equals(typeStr) ||
+                "java.lang.Character".equals(typeStr) ||
+                "java.lang.Short".equals(typeStr) ||
+                "java.lang.Boolean".equals(typeStr) ||
+                "java.lang.String".equals(typeStr)) {
+            return true;
+        }
+        return false;
+    }
+}
diff --git a/dubbo-api-docs/dubbo-api-docs-core/src/main/java/org/apache/dubbo/apidocs/core/providers/DubboDocProviderImpl.java b/dubbo-api-docs/dubbo-api-docs-ui-server/src/main/java/org/apache/dubbo/apidocs/controller/vo/ApiInfoRequest.java
similarity index 51%
copy from dubbo-api-docs/dubbo-api-docs-core/src/main/java/org/apache/dubbo/apidocs/core/providers/DubboDocProviderImpl.java
copy to dubbo-api-docs/dubbo-api-docs-ui-server/src/main/java/org/apache/dubbo/apidocs/controller/vo/ApiInfoRequest.java
index d8cfb2b..5896de5 100644
--- a/dubbo-api-docs/dubbo-api-docs-core/src/main/java/org/apache/dubbo/apidocs/core/providers/DubboDocProviderImpl.java
+++ b/dubbo-api-docs/dubbo-api-docs-ui-server/src/main/java/org/apache/dubbo/apidocs/controller/vo/ApiInfoRequest.java
@@ -14,34 +14,28 @@
  * See the License for the specific language governing permissions and
  * limitations under the License.
  */
-package org.apache.dubbo.apidocs.core.providers;
+package org.apache.dubbo.apidocs.controller.vo;
 
-import org.apache.dubbo.apidocs.core.DubboApiDocsCache;
-import org.apache.dubbo.config.annotation.DubboService;
-
-import lombok.extern.slf4j.Slf4j;
+import io.swagger.annotations.ApiParam;
+import lombok.Getter;
+import lombok.Setter;
 
 /**
- * The api implementation of Dubbo doc.
+ * Obtain the API module list and the request parameters of the API parameter information interface.
  * @author klw(213539@qq.com)
- * 2020/10/29 17:38
+ * 2020/11/14 20:45
  */
-@Slf4j
-@DubboService
-public class DubboDocProviderImpl implements IDubboDocProvider {
+@Getter
+@Setter
+public class ApiInfoRequest {
+
+    @ApiParam(value = "IP of Dubbo provider", required = true)
+    private String dubboIp;
 
-    @Override
-    public String apiModuleList() {
-        return DubboApiDocsCache.getAllApiModuleInfo();
-    }
+    @ApiParam(value = "Port of Dubbo provider", required = true)
+    private String dubboPort;
 
-    @Override
-    public String apiModuleInfo(String apiInterfaceClassName) {
-        return DubboApiDocsCache.getApiModuleStr(apiInterfaceClassName);
-    }
+    @ApiParam(value = "API full name (interface class full name. Method name), which must be passed when getting API parameter information")
+    private String apiName;
 
-    @Override
-    public String apiParamsResponseInfo(String apiInterfaceClassNameMethodName) {
-        return DubboApiDocsCache.getApiParamsAndRespStr(apiInterfaceClassNameMethodName);
-    }
 }
diff --git a/dubbo-api-docs/dubbo-api-docs-core/src/main/java/org/apache/dubbo/apidocs/core/providers/DubboDocProviderImpl.java b/dubbo-api-docs/dubbo-api-docs-ui-server/src/main/java/org/apache/dubbo/apidocs/controller/vo/CallDubboServiceRequest.java
similarity index 51%
copy from dubbo-api-docs/dubbo-api-docs-core/src/main/java/org/apache/dubbo/apidocs/core/providers/DubboDocProviderImpl.java
copy to dubbo-api-docs/dubbo-api-docs-ui-server/src/main/java/org/apache/dubbo/apidocs/controller/vo/CallDubboServiceRequest.java
index d8cfb2b..f81653c 100644
--- a/dubbo-api-docs/dubbo-api-docs-core/src/main/java/org/apache/dubbo/apidocs/core/providers/DubboDocProviderImpl.java
+++ b/dubbo-api-docs/dubbo-api-docs-ui-server/src/main/java/org/apache/dubbo/apidocs/controller/vo/CallDubboServiceRequest.java
@@ -14,34 +14,32 @@
  * See the License for the specific language governing permissions and
  * limitations under the License.
  */
-package org.apache.dubbo.apidocs.core.providers;
+package org.apache.dubbo.apidocs.controller.vo;
 
-import org.apache.dubbo.apidocs.core.DubboApiDocsCache;
-import org.apache.dubbo.config.annotation.DubboService;
+import io.swagger.annotations.ApiParam;
+import lombok.Getter;
+import lombok.Setter;
 
-import lombok.extern.slf4j.Slf4j;
 
 /**
- * The api implementation of Dubbo doc.
+ * Call Dubbo api to request parameters.
  * @author klw(213539@qq.com)
- * 2020/10/29 17:38
+ * 2020/11/14 20:46
  */
-@Slf4j
-@DubboService
-public class DubboDocProviderImpl implements IDubboDocProvider {
-
-    @Override
-    public String apiModuleList() {
-        return DubboApiDocsCache.getAllApiModuleInfo();
-    }
-
-    @Override
-    public String apiModuleInfo(String apiInterfaceClassName) {
-        return DubboApiDocsCache.getApiModuleStr(apiInterfaceClassName);
-    }
-
-    @Override
-    public String apiParamsResponseInfo(String apiInterfaceClassNameMethodName) {
-        return DubboApiDocsCache.getApiParamsAndRespStr(apiInterfaceClassNameMethodName);
-    }
+@Getter
+@Setter
+public class CallDubboServiceRequest {
+
+    @ApiParam(value = "Address of registration center, such as: nacos://127.0.0.1:8848", required = true)
+    private String registryCenterUrl;
+
+    @ApiParam(value = "Dubbo interface full package path", required = true)
+    private String interfaceClassName;
+
+    @ApiParam(value = "Method name of the service", required = true)
+    private String methodName;
+
+    @ApiParam(value = "Whether to call asynchronously, false by default")
+    private boolean async = false;
+
 }
diff --git a/dubbo-api-docs/dubbo-api-docs-core/src/main/java/org/apache/dubbo/apidocs/core/providers/DubboDocProviderImpl.java b/dubbo-api-docs/dubbo-api-docs-ui-server/src/main/java/org/apache/dubbo/apidocs/controller/vo/CallDubboServiceRequestInterfacePrarm.java
similarity index 51%
copy from dubbo-api-docs/dubbo-api-docs-core/src/main/java/org/apache/dubbo/apidocs/core/providers/DubboDocProviderImpl.java
copy to dubbo-api-docs/dubbo-api-docs-ui-server/src/main/java/org/apache/dubbo/apidocs/controller/vo/CallDubboServiceRequestInterfacePrarm.java
index d8cfb2b..3cf6d0f 100644
--- a/dubbo-api-docs/dubbo-api-docs-core/src/main/java/org/apache/dubbo/apidocs/core/providers/DubboDocProviderImpl.java
+++ b/dubbo-api-docs/dubbo-api-docs-ui-server/src/main/java/org/apache/dubbo/apidocs/controller/vo/CallDubboServiceRequestInterfacePrarm.java
@@ -14,34 +14,25 @@
  * See the License for the specific language governing permissions and
  * limitations under the License.
  */
-package org.apache.dubbo.apidocs.core.providers;
+package org.apache.dubbo.apidocs.controller.vo;
 
-import org.apache.dubbo.apidocs.core.DubboApiDocsCache;
-import org.apache.dubbo.config.annotation.DubboService;
-
-import lombok.extern.slf4j.Slf4j;
+import io.swagger.annotations.ApiParam;
+import lombok.Getter;
+import lombok.Setter;
 
 /**
- * The api implementation of Dubbo doc.
+ * Parameters passed to duboo service api.
  * @author klw(213539@qq.com)
- * 2020/10/29 17:38
+ * 2020/11/14 20:46
  */
-@Slf4j
-@DubboService
-public class DubboDocProviderImpl implements IDubboDocProvider {
+@Getter
+@Setter
+public class CallDubboServiceRequestInterfacePrarm {
 
-    @Override
-    public String apiModuleList() {
-        return DubboApiDocsCache.getAllApiModuleInfo();
-    }
+    @ApiParam(value = "Parameter type (full package path), such as: java.lang.String", required = true)
+    private String prarmType;
 
-    @Override
-    public String apiModuleInfo(String apiInterfaceClassName) {
-        return DubboApiDocsCache.getApiModuleStr(apiInterfaceClassName);
-    }
+    @ApiParam(value = "Parameter value", required = true)
+    private Object prarmValue;
 
-    @Override
-    public String apiParamsResponseInfo(String apiInterfaceClassNameMethodName) {
-        return DubboApiDocsCache.getApiParamsAndRespStr(apiInterfaceClassNameMethodName);
-    }
 }
diff --git a/dubbo-api-docs/dubbo-api-docs-ui-server/src/main/java/org/apache/dubbo/apidocs/editor/CustomDateEditor.java b/dubbo-api-docs/dubbo-api-docs-ui-server/src/main/java/org/apache/dubbo/apidocs/editor/CustomDateEditor.java
new file mode 100644
index 0000000..f29bced
--- /dev/null
+++ b/dubbo-api-docs/dubbo-api-docs-ui-server/src/main/java/org/apache/dubbo/apidocs/editor/CustomDateEditor.java
@@ -0,0 +1,122 @@
+/*
+ * 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.apidocs.editor;
+
+import org.slf4j.Logger;
+import org.slf4j.LoggerFactory;
+import org.springframework.util.StringUtils;
+
+import java.beans.PropertyEditorSupport;
+import java.text.ParseException;
+import java.text.SimpleDateFormat;
+import java.util.Date;
+import java.util.regex.Pattern;
+
+/**
+ * Date editor for controller.
+ * @author klw(213539@qq.com)
+ * 2020/11/14 20:47
+ */
+public class CustomDateEditor extends PropertyEditorSupport {
+
+    protected Logger logger = LoggerFactory.getLogger(this.getClass());
+
+    @Override
+    public void setAsText(String text) throws IllegalArgumentException {
+        if (!StringUtils.hasText(text)) {
+            setValue(null);
+        } else {
+            setValue(this.dateAdapter(text));
+        }
+    }
+
+    @Override
+    public String getAsText() {
+        Date value = (Date) getValue();
+        SimpleDateFormat dateFormat = new SimpleDateFormat("yyyy-MM-dd HH:mm:ss");
+        return (value != null ? dateFormat.format(value) : "");
+    }
+
+    /**
+     * String to date adaptation method.
+     * 2020/11/14 20:59
+     * @param dateStr
+     * @return java.util.Date
+     */
+    public static Date dateAdapter(String dateStr) {
+        Date date = null;
+
+        if (!(null == dateStr || "".equals(dateStr))) {
+            try {
+                long timeLong = Long.parseLong(dateStr);
+                date = new Date(timeLong);
+
+                return date;
+            } catch (Exception e) {
+
+            }
+
+            if (dateStr.contains("CST")) {
+                date = new Date(dateStr);
+            } else if (dateStr.contains("Z")) {
+                dateStr = dateStr.replace("\"", "");
+                dateStr = dateStr.replace("Z", " UTC");
+                SimpleDateFormat utcFormat = new SimpleDateFormat("yyyy-MM-dd'T'HH:mm:ss.SSS Z");
+                try {
+                    date = utcFormat.parse(dateStr);
+                } catch (ParseException e) {
+                    e.printStackTrace();
+                }
+            } else {
+                dateStr = dateStr.replace("年", "-").replace("月", "-").replace("日", "").replaceAll("/", "-").replaceAll("\\.", "-").trim();
+                String fm = "";
+
+                // determine date format
+                if (Pattern.compile("^[0-9]{4}-[0-9]{2}-[0-9]{2}.*").matcher(dateStr).matches()) {
+                    fm = "yyyy-MM-dd";
+                } else if (Pattern.compile("^[0-9]{4}-[0-9]{1}-[0-9]+.*||^[0-9]{4}-[0-9]+-[0-9]{1}.*").matcher(dateStr).matches()) {
+                    fm = "yyyy-M-d";
+                } else if (Pattern.compile("^[0-9]{2}-[0-9]{2}-[0-9]{2}.*").matcher(dateStr).matches()) {
+                    fm = "yy-MM-dd";
+                } else if (Pattern.compile("^[0-9]{2}-[0-9]{1}-[0-9]+.*||^[0-9]{2}-[0-9]+-[0-9]{1}.*").matcher(dateStr).matches()) {
+                    fm = "yy-M-d";
+                }
+
+                // determine time format
+                if (Pattern.compile(".*[ ][0-9]{2}").matcher(dateStr).matches()) {
+                    fm += " HH";
+                } else if (Pattern.compile(".*[ ][0-9]{2}:[0-9]{2}").matcher(dateStr).matches()) {
+                    fm += " HH:mm";
+                } else if (Pattern.compile(".*[ ][0-9]{2}:[0-9]{2}:[0-9]{2}").matcher(dateStr).matches()) {
+                    fm += " HH:mm:ss";
+                } else if (Pattern.compile(".*[ ][0-9]{2}:[0-9]{2}:[0-9]{2}:[0-9]{0,3}").matcher(dateStr).matches()) {
+                    fm += " HH:mm:ss:sss";
+                }
+
+                if (!"".equals(fm)) {
+                    try {
+                        date = new SimpleDateFormat(fm).parse(dateStr);
+                    } catch (ParseException e) {
+                        throw new IllegalArgumentException(dateStr + " cannot be converted to date format!");
+                    }
+                }
+            }
+        }
+
+        return date;
+    }
+}
diff --git a/dubbo-api-docs/dubbo-api-docs-core/src/main/java/org/apache/dubbo/apidocs/core/providers/DubboDocProviderImpl.java b/dubbo-api-docs/dubbo-api-docs-ui-server/src/main/java/org/apache/dubbo/apidocs/editor/CustomLocalDateEditor.java
similarity index 53%
copy from dubbo-api-docs/dubbo-api-docs-core/src/main/java/org/apache/dubbo/apidocs/core/providers/DubboDocProviderImpl.java
copy to dubbo-api-docs/dubbo-api-docs-ui-server/src/main/java/org/apache/dubbo/apidocs/editor/CustomLocalDateEditor.java
index d8cfb2b..08fb508 100644
--- a/dubbo-api-docs/dubbo-api-docs-core/src/main/java/org/apache/dubbo/apidocs/core/providers/DubboDocProviderImpl.java
+++ b/dubbo-api-docs/dubbo-api-docs-ui-server/src/main/java/org/apache/dubbo/apidocs/editor/CustomLocalDateEditor.java
@@ -14,34 +14,32 @@
  * See the License for the specific language governing permissions and
  * limitations under the License.
  */
-package org.apache.dubbo.apidocs.core.providers;
+package org.apache.dubbo.apidocs.editor;
 
-import org.apache.dubbo.apidocs.core.DubboApiDocsCache;
-import org.apache.dubbo.config.annotation.DubboService;
 
-import lombok.extern.slf4j.Slf4j;
+import org.apache.dubbo.apidocs.utils.LocalDateTimeUtil;
+
+import java.beans.PropertyEditorSupport;
+import java.time.LocalDate;
+import java.time.format.DateTimeFormatter;
 
 /**
- * The api implementation of Dubbo doc.
+ * Localdate editor for controller.
  * @author klw(213539@qq.com)
- * 2020/10/29 17:38
+ * 2020/11/14 20:59
  */
-@Slf4j
-@DubboService
-public class DubboDocProviderImpl implements IDubboDocProvider {
+public class CustomLocalDateEditor extends PropertyEditorSupport {
 
     @Override
-    public String apiModuleList() {
-        return DubboApiDocsCache.getAllApiModuleInfo();
+    public void setAsText(String text) throws IllegalArgumentException {
+        setValue(LocalDateTimeUtil.formatToLD(text));
     }
-
-    @Override
-    public String apiModuleInfo(String apiInterfaceClassName) {
-        return DubboApiDocsCache.getApiModuleStr(apiInterfaceClassName);
-    }
-
+    
     @Override
-    public String apiParamsResponseInfo(String apiInterfaceClassNameMethodName) {
-        return DubboApiDocsCache.getApiParamsAndRespStr(apiInterfaceClassNameMethodName);
+    public String getAsText() {
+        LocalDate date = (LocalDate)getValue();
+        return date.format(DateTimeFormatter.ofPattern("yyyy-MM-dd"));
     }
+    
+    
 }
diff --git a/dubbo-api-docs/dubbo-api-docs-core/src/main/java/org/apache/dubbo/apidocs/core/providers/DubboDocProviderImpl.java b/dubbo-api-docs/dubbo-api-docs-ui-server/src/main/java/org/apache/dubbo/apidocs/editor/CustomLocalDateTimeEditor.java
similarity index 53%
copy from dubbo-api-docs/dubbo-api-docs-core/src/main/java/org/apache/dubbo/apidocs/core/providers/DubboDocProviderImpl.java
copy to dubbo-api-docs/dubbo-api-docs-ui-server/src/main/java/org/apache/dubbo/apidocs/editor/CustomLocalDateTimeEditor.java
index d8cfb2b..6f87a54 100644
--- a/dubbo-api-docs/dubbo-api-docs-core/src/main/java/org/apache/dubbo/apidocs/core/providers/DubboDocProviderImpl.java
+++ b/dubbo-api-docs/dubbo-api-docs-ui-server/src/main/java/org/apache/dubbo/apidocs/editor/CustomLocalDateTimeEditor.java
@@ -14,34 +14,32 @@
  * See the License for the specific language governing permissions and
  * limitations under the License.
  */
-package org.apache.dubbo.apidocs.core.providers;
+package org.apache.dubbo.apidocs.editor;
 
-import org.apache.dubbo.apidocs.core.DubboApiDocsCache;
-import org.apache.dubbo.config.annotation.DubboService;
 
-import lombok.extern.slf4j.Slf4j;
+import org.apache.dubbo.apidocs.utils.LocalDateTimeUtil;
+
+import java.beans.PropertyEditorSupport;
+import java.time.LocalDateTime;
+import java.time.format.DateTimeFormatter;
 
 /**
- * The api implementation of Dubbo doc.
+ * LocalDateTime editor for controller.
  * @author klw(213539@qq.com)
- * 2020/10/29 17:38
+ * 2020/11/14 20:59
  */
-@Slf4j
-@DubboService
-public class DubboDocProviderImpl implements IDubboDocProvider {
+public class CustomLocalDateTimeEditor extends PropertyEditorSupport {
 
     @Override
-    public String apiModuleList() {
-        return DubboApiDocsCache.getAllApiModuleInfo();
+    public void setAsText(String text) throws IllegalArgumentException {
+        setValue(LocalDateTimeUtil.formatToLDT(text));
     }
-
-    @Override
-    public String apiModuleInfo(String apiInterfaceClassName) {
-        return DubboApiDocsCache.getApiModuleStr(apiInterfaceClassName);
-    }
-
+    
     @Override
-    public String apiParamsResponseInfo(String apiInterfaceClassNameMethodName) {
-        return DubboApiDocsCache.getApiParamsAndRespStr(apiInterfaceClassNameMethodName);
+    public String getAsText() {
+	LocalDateTime date = (LocalDateTime)getValue();
+	return date.format(DateTimeFormatter.ofPattern("yyyy-MM-dd HH:mm:ss"));
     }
+    
+    
 }
diff --git a/dubbo-api-docs/dubbo-api-docs-ui-server/src/main/java/org/apache/dubbo/apidocs/utils/DubboGenericUtil.java b/dubbo-api-docs/dubbo-api-docs-ui-server/src/main/java/org/apache/dubbo/apidocs/utils/DubboGenericUtil.java
new file mode 100644
index 0000000..613d79d
--- /dev/null
+++ b/dubbo-api-docs/dubbo-api-docs-ui-server/src/main/java/org/apache/dubbo/apidocs/utils/DubboGenericUtil.java
@@ -0,0 +1,175 @@
+/*
+ * 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.apidocs.utils;
+
+import org.apache.dubbo.config.ApplicationConfig;
+import org.apache.dubbo.config.ReferenceConfig;
+import org.apache.dubbo.config.RegistryConfig;
+import org.apache.dubbo.rpc.service.GenericService;
+
+import java.util.Map;
+import java.util.concurrent.CompletableFuture;
+import java.util.concurrent.ConcurrentHashMap;
+import java.util.concurrent.ExecutorService;
+import java.util.concurrent.Executors;
+
+/**
+ * Dubbo operation related tool class.
+ * @author klw(213539@qq.com)
+ * 2020/11/14 21:00
+ */
+public class DubboGenericUtil {
+
+    /**
+     * Current application information.
+     */
+    private static ApplicationConfig application;
+
+    /**
+     * Registry information cache.
+     */
+    private static Map<String, RegistryConfig> registryConfigCache;
+
+    /**
+     * Dubbo service interface proxy cache.
+     */
+    private static Map<String, ReferenceConfig<GenericService>> referenceCache;
+
+    private static final ExecutorService executor;
+
+    /**
+     * Default retries.
+     */
+    private static int retries = 2;
+
+    /**
+     * Default timeout.
+     */
+    private static int timeout = 1000;
+
+    static{
+        // T (number of threads) = N (number of server cores) * u (expected CPU utilization) * (1 + E (waiting time) / C (calculation time))
+        executor = Executors.newFixedThreadPool(Runtime.getRuntime().availableProcessors() * 40 * (1 + 5 / 2));
+        application = new ApplicationConfig();
+        application.setName("alita-dubbo-debug-tool");
+        registryConfigCache = new ConcurrentHashMap<>();
+        referenceCache = new ConcurrentHashMap<>();
+    }
+
+    public static void setRetriesAndTimeout(int retries, int timeout){
+        DubboGenericUtil.retries = retries;
+        DubboGenericUtil.timeout = timeout;
+    }
+
+    /**
+     * Get registry information.
+     * 2020/11/14 21:01
+     * @param address address Address of Registration Center
+     * @return org.apache.dubbo.config.RegistryConfig
+     */
+    private static RegistryConfig getRegistryConfig(String address) {
+        RegistryConfig registryConfig = registryConfigCache.get(address);
+        if (null == registryConfig) {
+            registryConfig = new RegistryConfig();
+            registryConfig.setAddress(address);
+            registryConfig.setRegister(false);
+            registryConfigCache.put(address, registryConfig);
+        }
+        return registryConfig;
+    }
+
+    /**
+     * Get proxy object for dubbo service.
+     * 2019/9/19 17:43
+     * @param: address  address Address of Registration Center
+     * @param: interfaceName  Interface full package path
+     * @return org.apache.dubbo.config.ReferenceConfig<org.apache.dubbo.rpc.service.GenericService>
+     */
+    private static ReferenceConfig<GenericService> getReferenceConfig(String address, String interfaceName) {
+        ReferenceConfig<GenericService> referenceConfig = referenceCache.get(address + "/" + interfaceName);
+        if (null == referenceConfig) {
+            referenceConfig = new ReferenceConfig<>();
+            referenceConfig.setRetries(retries);
+            referenceConfig.setTimeout(timeout);
+            referenceConfig.setApplication(application);
+            if(address.startsWith("dubbo")){
+                referenceConfig.setUrl(address);
+            } else {
+                referenceConfig.setRegistry(getRegistryConfig(address));
+            }
+            referenceConfig.setInterface(interfaceName);
+            // Declared as a generic interface
+            referenceConfig.setGeneric(true);
+            referenceCache.put(address + "/" + interfaceName, referenceConfig);
+        }
+        return referenceConfig;
+    }
+
+    /**
+     * Call duboo provider and return {@link CompletableFuture}.
+     * 2020/3/1 14:55
+     * @param: address
+     * @param: interfaceName
+     * @param: methodName
+     * @param: async  Whether the provider is asynchronous is to directly return the {@link CompletableFuture}
+     * returned by the provider, not to wrap it as {@link CompletableFuture}
+     * @param: prarmTypes
+     * @param: prarmValues
+     * @return java.util.concurrent.CompletableFuture<java.lang.Object>
+     */
+    public static CompletableFuture<Object> invoke(String address, String interfaceName,
+                                                  String methodName, boolean async, String[] prarmTypes,
+                                                  Object[] prarmValues) {
+        CompletableFuture future = null;
+        ReferenceConfig<GenericService> reference = getReferenceConfig(address, interfaceName);
+        if (null != reference) {
+            GenericService genericService = reference.get();
+            if (null != genericService) {
+                if(async){
+                    future = genericService.$invokeAsync(methodName, prarmTypes, prarmValues);
+                } else {
+                    future = CompletableFuture.supplyAsync(() -> genericService.$invoke(methodName, prarmTypes, prarmValues), executor);
+                }
+            }
+        }
+        return future;
+    }
+
+    /**
+     * Synchronous call provider. The provider must provide synchronous api.
+     * 2020/3/1 14:58
+     * @param: address
+     * @param: interfaceName
+     * @param: methodName
+     * @param: prarmTypes
+     * @param: prarmValues
+     * @return java.lang.Object
+     */
+    public static Object invokeSync(String address, String interfaceName,
+                                                   String methodName, String[] prarmTypes,
+                                                   Object[] prarmValues) {
+        ReferenceConfig<GenericService> reference = getReferenceConfig(address, interfaceName);
+        if (null != reference) {
+            GenericService genericService = reference.get();
+            if (null != genericService) {
+                return genericService.$invoke(methodName, prarmTypes, prarmValues);
+            }
+        }
+        return null;
+    }
+
+}
diff --git a/dubbo-api-docs/dubbo-api-docs-ui-server/src/main/java/org/apache/dubbo/apidocs/utils/LocalDateTimeUtil.java b/dubbo-api-docs/dubbo-api-docs-ui-server/src/main/java/org/apache/dubbo/apidocs/utils/LocalDateTimeUtil.java
new file mode 100644
index 0000000..0fd69e8
--- /dev/null
+++ b/dubbo-api-docs/dubbo-api-docs-ui-server/src/main/java/org/apache/dubbo/apidocs/utils/LocalDateTimeUtil.java
@@ -0,0 +1,75 @@
+/*
+ * 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.apidocs.utils;
+
+import java.time.*;
+import java.time.format.DateTimeFormatter;
+import java.time.temporal.ChronoUnit;
+import java.time.temporal.TemporalUnit;
+import java.util.Date;
+
+
+/**
+ * Date time tool class of LocalDateTime.
+ * @author klw(213539@qq.com)
+ * 2020/11/14 21:02
+ */
+public class LocalDateTimeUtil {
+
+    /**
+     * Create a LocalDateTime based on the passed in string date and the corresponding format.
+     * @param dateStr
+     * @param dateFormatter
+     * @return
+     */
+    public static LocalDateTime formatToLDT(String dateStr, String dateFormatter) {
+        //yyyy-MM-dd HH:mm:ss
+        return LocalDateTime.parse(dateStr, DateTimeFormatter.ofPattern(dateFormatter));
+    }
+
+    /**
+     * Create LocalDateTime from a string in the format "yyyy-MM-dd HH:mm:ss".
+     * @param dateStr
+     * @return
+     */
+    public static LocalDateTime formatToLDT(String dateStr) {
+        return formatToLDT(dateStr, "yyyy-MM-dd HH:mm:ss");
+    }
+
+    /**
+     * Create a LocalDate based on the passed in string date and the corresponding format.
+     * @param dateStr
+     * @param dateFormatter
+     * @return
+     */
+    public static LocalDate formatToLD(String dateStr, String dateFormatter) {
+        return LocalDate.parse(dateStr, DateTimeFormatter.ofPattern(dateFormatter));
+    }
+
+    /**
+     * Create LocalDate from a string in the format "yyyy-MM-dd".
+     * @param dateStr
+     * @return
+     */
+    public static LocalDate formatToLD(String dateStr) {
+        return formatToLD(dateStr, "yyyy-MM-dd");
+    }
+
+
+
+
+}
diff --git a/dubbo-api-docs/dubbo-api-docs-ui-server/src/main/resources/application.yml b/dubbo-api-docs/dubbo-api-docs-ui-server/src/main/resources/application.yml
new file mode 100644
index 0000000..a482c54
--- /dev/null
+++ b/dubbo-api-docs/dubbo-api-docs-ui-server/src/main/resources/application.yml
@@ -0,0 +1,11 @@
+server:
+  port: 8888
+spring:
+  application:
+    name: dubbo-doc-ui-server
+dubbo:
+  reference:
+    heartbeat: 1000
+  consumer:
+    timeout: 10000
+    retries: 0
\ No newline at end of file
diff --git a/dubbo-api-docs/dubbo-api-docs-ui-server/src/main/resources/banner.txt b/dubbo-api-docs/dubbo-api-docs-ui-server/src/main/resources/banner.txt
new file mode 100644
index 0000000..ca3cb3e
--- /dev/null
+++ b/dubbo-api-docs/dubbo-api-docs-ui-server/src/main/resources/banner.txt
@@ -0,0 +1,6 @@
+  _____        _     _                         _____ _____    _____
+ |  __ \      | |   | |                  /\   |  __ \_   _|  |  __ \
+ | |  | |_   _| |__ | |__    ___       /  \  | |__) || |    | |  | | ___   ___ ___
+ | |  | | | | | '_ \| '_ \ / _  \     / /\ \ |  ___/ | |    | |  | |/ _ \ / __/ __|
+ | |__| | |_| | |_) | |_) | (_) |   / ____ \| |    _| |_   | |__| | (_) | (__\__ \
+ |_____/ \__,_|_.__/|_.__/ \___/  /_/    \_\_|   |_____|  |_____/ \___/ \___|___/
diff --git a/dubbo-api-docs/dubbo-api-docs-ui-server/src/main/resources/log4j2.xml b/dubbo-api-docs/dubbo-api-docs-ui-server/src/main/resources/log4j2.xml
new file mode 100644
index 0000000..929bc5e
--- /dev/null
+++ b/dubbo-api-docs/dubbo-api-docs-ui-server/src/main/resources/log4j2.xml
@@ -0,0 +1,23 @@
+<?xml version="1.0" encoding="UTF-8"?>
+<Configuration status="WARN" monitorInterval="600" shutdownHook="disable">
+    <Properties>
+        <Property name="logDir" value="/home/weihu/deploy/logs/dubbo-doc/" />
+        <Property name="genericPattern" value="[dubboDoc]-%d{yyyy-MM-dd HH:mm:ss.SSS} [%t] %-5level %logger{36} - %msg%n" />
+        <Property name="genericFilePattern" value="%d{yyyy-MM-dd HH:mm}-%i" />
+    </Properties>
+    <Appenders>
+        <Console name="consoleAppender" target="SYSTEM_OUT">
+            <PatternLayout pattern="${genericPattern}" />
+        </Console>
+
+    </Appenders>
+    <Loggers>
+        <asyncRoot level="INFO">
+            <AppenderRef ref="consoleAppender" />
+        </asyncRoot>
+
+        <logger name="org.springframework" level="ERROR" />
+        <logger name="com.alibaba" level="ERROR" />
+        <logger name="org.apache" level="ERROR" />
+    </Loggers>
+</Configuration>
diff --git a/dubbo-api-docs/dubbo-api-docs-ui-server/src/main/resources/static/css/index.css b/dubbo-api-docs/dubbo-api-docs-ui-server/src/main/resources/static/css/index.css
new file mode 100644
index 0000000..98a1ac6
--- /dev/null
+++ b/dubbo-api-docs/dubbo-api-docs-ui-server/src/main/resources/static/css/index.css
@@ -0,0 +1 @@
+.next-sr-only{position:absolute;width:1px;height:1px;padding:0;overflow:hidden;clip:rect(0,0,0,0);white-space:nowrap;border:0;margin:-1px}/*! normalize.css v7.0.0 | MIT License | github.com/necolas/normalize.css */html{line-height:1.15;-ms-text-size-adjust:100%;-webkit-text-size-adjust:100%}body{margin:0}article,aside,footer,header,nav,section{display:block}h1{font-size:2em;margin:.67em 0}figcaption,figure,main{display:block}figure{margin:1em 40px}hr{-webkit-box-sizing:content-box;box-si [...]
\ No newline at end of file
diff --git a/dubbo-api-docs/dubbo-api-docs-ui-server/src/main/resources/static/favicon.png b/dubbo-api-docs/dubbo-api-docs-ui-server/src/main/resources/static/favicon.png
new file mode 100644
index 0000000..a2605c5
Binary files /dev/null and b/dubbo-api-docs/dubbo-api-docs-ui-server/src/main/resources/static/favicon.png differ
diff --git a/dubbo-api-docs/dubbo-api-docs-ui-server/src/main/resources/static/index.html b/dubbo-api-docs/dubbo-api-docs-ui-server/src/main/resources/static/index.html
new file mode 100644
index 0000000..e1bf09d
--- /dev/null
+++ b/dubbo-api-docs/dubbo-api-docs-ui-server/src/main/resources/static/index.html
@@ -0,0 +1,29 @@
+<!DOCTYPE html>
+<!--
+ * 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.
+  -->
+<html>
+  <head>
+    <meta charset="utf-8" />
+    <meta http-equiv="x-ua-compatible" content="ie=edge,chrome=1" />
+    <meta name="viewport" content="width=device-width" />
+    <title>Dubbo Doc</title>
+  <link rel="shortcut icon" href="./favicon.png"><link href="./css/index.css" rel="stylesheet"></head>
+
+  <body>
+    <div id="icestark-container"></div>
+  <script type="text/javascript" src="./js/index.js"></script></body>
+</html>
diff --git a/dubbo-api-docs/dubbo-api-docs-ui-server/src/main/resources/static/js/index.js b/dubbo-api-docs/dubbo-api-docs-ui-server/src/main/resources/static/js/index.js
new file mode 100644
index 0000000..948c8b0
--- /dev/null
+++ b/dubbo-api-docs/dubbo-api-docs-ui-server/src/main/resources/static/js/index.js
@@ -0,0 +1,95 @@
+!function(e){var t={};function n(r){if(t[r])return t[r].exports;var o=t[r]={i:r,l:!1,exports:{}};return e[r].call(o.exports,o,o.exports,n),o.l=!0,o.exports}n.m=e,n.c=t,n.d=function(e,t,r){n.o(e,t)||Object.defineProperty(e,t,{enumerable:!0,get:r})},n.r=function(e){"undefined"!=typeof Symbol&&Symbol.toStringTag&&Object.defineProperty(e,Symbol.toStringTag,{value:"Module"}),Object.defineProperty(e,"__esModule",{value:!0})},n.t=function(e,t){if(1&t&&(e=n(e)),8&t)return e;if(4&t&&"object"==typ [...]
+/*!
+  Copyright (c) 2017 Jed Watson.
+  Licensed under the MIT License (MIT), see
+  http://jedwatson.github.io/classnames
+*/!function(){"use strict";var n={}.hasOwnProperty;function a(){for(var e=[],t=0;t<arguments.length;t++){var r=arguments[t];if(r){var o=typeof r;if("string"===o||"number"===o)e.push(r);else if(Array.isArray(r)&&r.length){var i=a.apply(null,r);i&&e.push(i)}else if("object"===o)for(var s in r)n.call(r,s)&&r[s]&&e.push(s)}}return e.join(" ")}e.exports?(a.default=a,e.exports=a):void 0===(o=function(){return a}.apply(t,r=[]))||(e.exports=o)}()},function(e,t,n){"use strict";t.__esModule=!0;var [...]
+/*! *****************************************************************************
+Copyright (c) Microsoft Corporation. All rights reserved.
+Licensed 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
+
+THIS CODE IS PROVIDED ON AN *AS IS* BASIS, WITHOUT WARRANTIES OR CONDITIONS OF ANY
+KIND, EITHER EXPRESS OR IMPLIED, INCLUDING WITHOUT LIMITATION ANY IMPLIED
+WARRANTIES OR CONDITIONS OF TITLE, FITNESS FOR A PARTICULAR PURPOSE,
+MERCHANTABLITY OR NON-INFRINGEMENT.
+
+See the Apache Version 2.0 License for specific language governing permissions
+and limitations under the License.
+***************************************************************************** */
+var r=function(e,t){return(r=Object.setPrototypeOf||{__proto__:[]}instanceof Array&&function(e,t){e.__proto__=t}||function(e,t){for(var n in t)t.hasOwnProperty(n)&&(e[n]=t[n])})(e,t)};function o(e,t){function n(){this.constructor=e}r(e,t),e.prototype=null===t?Object.create(t):(n.prototype=t.prototype,new n)}var a=function(){return(a=Object.assign||function e(t){for(var n,r=1,o=arguments.length;r<o;r++)for(var a in n=arguments[r])Object.prototype.hasOwnProperty.call(n,a)&&(t[a]=n[a]);retu [...]
+/*!
+ * jQuery JavaScript Library v3.4.1
+ * https://jquery.com/
+ *
+ * Includes Sizzle.js
+ * https://sizzlejs.com/
+ *
+ * Copyright JS Foundation and other contributors
+ * Released under the MIT license
+ * https://jquery.org/license
+ *
+ * Date: 2019-05-01T21:04Z
+ */!function(t,n){"use strict";"object"==typeof e.exports?e.exports=t.document?n(t,!0):function(e){if(!e.document)throw new Error("jQuery requires a window with a document");return n(e)}:n(t)}("undefined"!=typeof window?window:this,(function(n,a){"use strict";var i=[],s=n.document,l=Object.getPrototypeOf,u=i.slice,c=i.concat,f=i.push,p=i.indexOf,d={},h=d.toString,v=d.hasOwnProperty,m=v.toString,y=m.call(Object),g={},b=function e(t){return"function"==typeof t&&"number"!=typeof t.nodeType} [...]
+/*!
+ * Sizzle CSS Selector Engine v2.3.4
+ * https://sizzlejs.com/
+ *
+ * Copyright JS Foundation and other contributors
+ * Released under the MIT license
+ * https://js.foundation/
+ *
+ * Date: 2019-04-08
+ */
+function(e){var t,n,r,o,a,i,s,l,u,c,f,p,d,h,v,m,y,g,b,w="sizzle"+1*new Date,x=e.document,E=0,_=0,C=le(),S=le(),k=le(),O=le(),T=function(e,t){return e===t&&(f=!0),0},P={}.hasOwnProperty,j=[],A=j.pop,N=j.push,M=j.push,D=j.slice,L=function(e,t){for(var n=0,r=e.length;n<r;n++)if(e[n]===t)return n;return-1},R="checked|selected|async|autofocus|autoplay|controls|defer|disabled|hidden|ismap|loop|multiple|open|readonly|required|scoped",I="[\\x20\\t\\r\\n\\f]",F="(?:\\\\.|[\\w-]|[^\0-\\xa0])+",z=" [...]
+/*!
+ * cookie
+ * Copyright(c) 2012-2014 Roman Shtylman
+ * Copyright(c) 2015 Douglas Christopher Wilson
+ * MIT Licensed
+ */t.parse=s,t.serialize=l;var r=decodeURIComponent,o=encodeURIComponent,a=/; */,i=/^[\u0009\u0020-\u007e\u0080-\u00ff]+$/;function s(e,t){if("string"!=typeof e)throw new TypeError("argument str must be a string");for(var n={},o=t||{},i=e.split(a),s=o.decode||r,l=0;l<i.length;l++){var c=i[l],f=c.indexOf("=");if(!(f<0)){var p=c.substr(0,f).trim(),d=c.substr(++f,c.length).trim();'"'==d[0]&&(d=d.slice(1,-1)),null==n[p]&&(n[p]=u(d,s))}}return n}function l(e,t,n){var r=n||{},a=r.encode||o;if( [...]
+/*
+object-assign
+(c) Sindre Sorhus
+@license MIT
+*/var r=Object.getOwnPropertySymbols,o=Object.prototype.hasOwnProperty,a=Object.prototype.propertyIsEnumerable;function i(e){if(null==e)throw new TypeError("Object.assign cannot be called with null or undefined");return Object(e)}function s(){try{if(!Object.assign)return!1;var e=new String("abc"),t;if(e[5]="de","5"===Object.getOwnPropertyNames(e)[0])return!1;for(var n={},r=0;r<10;r++)n["_"+String.fromCharCode(r)]=r;if("0123456789"!==Object.getOwnPropertyNames(n).map((function(e){return n [...]
+/** @license React v16.13.0
+ * react.production.min.js
+ *
+ * Copyright (c) Facebook, Inc. and its affiliates.
+ *
+ * This source code is licensed under the MIT license found in the
+ * LICENSE file in the root directory of this source tree.
+ */var r=n(247),o="function"==typeof Symbol&&Symbol.for,a=o?Symbol.for("react.element"):60103,i=o?Symbol.for("react.portal"):60106,s=o?Symbol.for("react.fragment"):60107,l=o?Symbol.for("react.strict_mode"):60108,u=o?Symbol.for("react.profiler"):60114,c=o?Symbol.for("react.provider"):60109,f=o?Symbol.for("react.context"):60110,p=o?Symbol.for("react.forward_ref"):60112,d=o?Symbol.for("react.suspense"):60113,h=o?Symbol.for("react.memo"):60115,v=o?Symbol.for("react.lazy"):60116,m="function"= [...]
+/** @license React v16.13.0
+ * react-dom.production.min.js
+ *
+ * Copyright (c) Facebook, Inc. and its affiliates.
+ *
+ * This source code is licensed under the MIT license found in the
+ * LICENSE file in the root directory of this source tree.
+ */var r=n(1),o=n(247),a=n(525);function i(e){for(var t="https://reactjs.org/docs/error-decoder.html?invariant="+e,n=1;n<arguments.length;n++)t+="&args[]="+encodeURIComponent(arguments[n]);return"Minified React error #"+e+"; visit "+t+" for the full message or use the non-minified dev environment for full errors and additional helpful warnings."}if(!r)throw Error(i(227));function s(e,t,n,r,o,a,i,s,l){var u=Array.prototype.slice.call(arguments,3);try{t.apply(n,u)}catch(e){this.onError(e)} [...]
+/** @license React v0.19.0
+ * scheduler.production.min.js
+ *
+ * Copyright (c) Facebook, Inc. and its affiliates.
+ *
+ * This source code is licensed under the MIT license found in the
+ * LICENSE file in the root directory of this source tree.
+ */var r,o,a,i,s;if("undefined"==typeof window||"function"!=typeof MessageChannel){var l=null,u=null,c=function(){if(null!==l)try{var e=t.unstable_now();l(!0,e),l=null}catch(e){throw setTimeout(c,0),e}},f=Date.now();t.unstable_now=function(){return Date.now()-f},r=function(e){null!==l?setTimeout(r,0,e):(l=e,setTimeout(c,0))},o=function(e,t){u=setTimeout(e,t)},a=function(){clearTimeout(u)},i=function(){return!1},s=t.unstable_forceFrameRate=function(){}}else{var p=window.performance,d=wind [...]
+/*!
+ * escape-html
+ * Copyright(c) 2012-2013 TJ Holowaychuk
+ * Copyright(c) 2015 Andreas Lubbe
+ * Copyright(c) 2015 Tiancheng "Timothy" Gu
+ * MIT Licensed
+ */var r=/["'&<>]/;function o(e){var t=""+e,n=r.exec(t),o;if(!n)return t;var a="",i=0,s=0;for(i=n.index;i<t.length;i++){switch(t.charCodeAt(i)){case 34:o="&quot;";break;case 38:o="&amp;";break;case 39:o="&#39;";break;case 60:o="&lt;";break;case 62:o="&gt;";break;default:continue}s!==i&&(a+=t.substring(s,i)),s=i+1,a+=o}return s!==i?a+t.substring(s,i):a}e.exports=o},function(e,t,n){"use strict";t.decode=t.parse=n(561),t.encode=t.stringify=n(562)},function(e,t,n){"use strict";function r(e,t [...]
+/** @license React v16.13.0
+ * react-is.production.min.js
+ *
+ * Copyright (c) Facebook, Inc. and its affiliates.
+ *
+ * This source code is licensed under the MIT license found in the
+ * LICENSE file in the root directory of this source tree.
+ */var r="function"==typeof Symbol&&Symbol.for,o=r?Symbol.for("react.element"):60103,a=r?Symbol.for("react.portal"):60106,i=r?Symbol.for("react.fragment"):60107,s=r?Symbol.for("react.strict_mode"):60108,l=r?Symbol.for("react.profiler"):60114,u=r?Symbol.for("react.provider"):60109,c=r?Symbol.for("react.context"):60110,f=r?Symbol.for("react.async_mode"):60111,p=r?Symbol.for("react.concurrent_mode"):60111,d=r?Symbol.for("react.forward_ref"):60112,h=r?Symbol.for("react.suspense"):60113,v=r?S [...]
\ No newline at end of file
diff --git a/dubbo-api-docs/dubbo-api-docs-ui/.editorconfig b/dubbo-api-docs/dubbo-api-docs-ui/.editorconfig
new file mode 100644
index 0000000..5760be5
--- /dev/null
+++ b/dubbo-api-docs/dubbo-api-docs-ui/.editorconfig
@@ -0,0 +1,12 @@
+# http://editorconfig.org
+root = true
+
+[*]
+indent_style = space
+indent_size = 2
+charset = utf-8
+trim_trailing_whitespace = true
+insert_final_newline = true
+
+[*.md]
+trim_trailing_whitespace = false
diff --git a/dubbo-api-docs/dubbo-api-docs-ui/.eslintignore b/dubbo-api-docs/dubbo-api-docs-ui/.eslintignore
new file mode 100644
index 0000000..3b437e6
--- /dev/null
+++ b/dubbo-api-docs/dubbo-api-docs-ui/.eslintignore
@@ -0,0 +1,11 @@
+# 忽略目录
+build/
+tests/
+demo/
+
+# node 覆盖率文件
+coverage/
+
+# 忽略文件
+**/*-min.js
+**/*.min.js
diff --git a/dubbo-api-docs/dubbo-api-docs-ui/.eslintrc.js b/dubbo-api-docs/dubbo-api-docs-ui/.eslintrc.js
new file mode 100644
index 0000000..54a71d5
--- /dev/null
+++ b/dubbo-api-docs/dubbo-api-docs-ui/.eslintrc.js
@@ -0,0 +1,3 @@
+const { eslint } = require('@ice/spec');
+
+module.exports = eslint;
\ No newline at end of file
diff --git a/dubbo-api-docs/dubbo-api-docs-ui/.gitignore b/dubbo-api-docs/dubbo-api-docs-ui/.gitignore
new file mode 100644
index 0000000..7c3f84e
--- /dev/null
+++ b/dubbo-api-docs/dubbo-api-docs-ui/.gitignore
@@ -0,0 +1,16 @@
+# dependencies
+/node_modules
+
+# production
+/build
+/dist
+
+# misc
+.idea/
+.happypack
+.DS_Store
+.ice
+
+npm-debug.log*
+yarn-debug.log*
+yarn-error.log*
diff --git a/dubbo-api-docs/dubbo-api-docs-ui/.prettierignore b/dubbo-api-docs/dubbo-api-docs-ui/.prettierignore
new file mode 100644
index 0000000..f238d06
--- /dev/null
+++ b/dubbo-api-docs/dubbo-api-docs-ui/.prettierignore
@@ -0,0 +1,9 @@
+build/
+tests/
+demo/
+.ice/
+coverage/
+**/*-min.js
+**/*.min.js
+package-lock.json
+yarn.lock
\ No newline at end of file
diff --git a/dubbo-api-docs/dubbo-api-docs-ui/.prettierrc.js b/dubbo-api-docs/dubbo-api-docs-ui/.prettierrc.js
new file mode 100644
index 0000000..2d68f3f
--- /dev/null
+++ b/dubbo-api-docs/dubbo-api-docs-ui/.prettierrc.js
@@ -0,0 +1,3 @@
+const { prettier } = require('@ice/spec');
+
+module.exports = prettier;
diff --git a/dubbo-api-docs/dubbo-api-docs-ui/.stylelintignore b/dubbo-api-docs/dubbo-api-docs-ui/.stylelintignore
new file mode 100644
index 0000000..82af6f6
--- /dev/null
+++ b/dubbo-api-docs/dubbo-api-docs-ui/.stylelintignore
@@ -0,0 +1,7 @@
+# 忽略目录
+build/
+tests/
+demo/
+
+# node 覆盖率文件
+coverage/
diff --git a/dubbo-api-docs/dubbo-api-docs-ui/.stylelintrc.js b/dubbo-api-docs/dubbo-api-docs-ui/.stylelintrc.js
new file mode 100644
index 0000000..eeb605b
--- /dev/null
+++ b/dubbo-api-docs/dubbo-api-docs-ui/.stylelintrc.js
@@ -0,0 +1,3 @@
+const { stylelint } = require('@ice/spec');
+
+module.exports = stylelint;
diff --git a/dubbo-api-docs/dubbo-api-docs-ui/README.md b/dubbo-api-docs/dubbo-api-docs-ui/README.md
new file mode 100644
index 0000000..8a340fb
--- /dev/null
+++ b/dubbo-api-docs/dubbo-api-docs-ui/README.md
@@ -0,0 +1,14 @@
+# ice-stark-layout
+
+## 使用
+
+- 启动调试服务: `npm start`
+- 构建 dist: `npm run build`
+
+## 目录结构
+
+- 应用配置: `src/app.js`
+- 路由配置: `src/routes.js`
+- 布局文件: `src/layouts`
+- 通用组件: `src/components`
+- 页面文件: `src/pages`
diff --git a/dubbo-api-docs/dubbo-api-docs-ui/build.json b/dubbo-api-docs/dubbo-api-docs-ui/build.json
new file mode 100644
index 0000000..b2d2470
--- /dev/null
+++ b/dubbo-api-docs/dubbo-api-docs-ui/build.json
@@ -0,0 +1,21 @@
+{
+  "publicPath": "./",
+  "plugins": [
+    "build-plugin-icestark",
+    ["build-plugin-fusion", {
+      "themePackage": "@alifd/theme-design-pro",
+      "themeConfig": {
+        "nextPrefix": "next-icestark-"
+      }
+    }],
+    ["build-plugin-moment-locales", {
+      "locales": ["zh-cn"]
+    }]
+  ],
+  "proxy": {
+	  "/api/**": {
+      "enable": true,
+      "target": "http://localhost:8888"
+    }
+  }
+}
diff --git a/dubbo-api-docs/dubbo-api-docs-ui/package-lock.json b/dubbo-api-docs/dubbo-api-docs-ui/package-lock.json
new file mode 100644
index 0000000..23a69d1
--- /dev/null
+++ b/dubbo-api-docs/dubbo-api-docs-ui/package-lock.json
@@ -0,0 +1,24011 @@
+{
+  "name": "@icedesign/stark-layout-scaffold",
+  "version": "3.0.6",
+  "lockfileVersion": 1,
+  "requires": true,
+  "dependencies": {
+    "@ahooksjs/use-request": {
+      "version": "2.8.1",
+      "resolved": "https://registry.npm.taobao.org/@ahooksjs/use-request/download/@ahooksjs/use-request-2.8.1.tgz",
+      "integrity": "sha1-vwamM2jfGFm2t5qUZhLrDSiJq28=",
+      "dev": true,
+      "requires": {
+        "lodash.debounce": "^4.0.8",
+        "lodash.throttle": "^4.1.1"
+      }
+    },
+    "@alib/build-scripts": {
+      "version": "0.1.29",
+      "resolved": "https://registry.npm.taobao.org/@alib/build-scripts/download/@alib/build-scripts-0.1.29.tgz",
+      "integrity": "sha1-RreUu/XBA7gvAOXdnfGaWKdEJYE=",
+      "dev": true,
+      "requires": {
+        "address": "^1.1.0",
+        "camelcase": "^5.3.1",
+        "chalk": "^2.4.1",
+        "chokidar": "^3.3.1",
+        "commander": "^2.19.0",
+        "deepmerge": "^4.0.0",
+        "detect-port": "^1.3.0",
+        "fs-extra": "^8.1.0",
+        "jest": "^26.4.2",
+        "json5": "^2.1.3",
+        "lodash": "^4.17.15",
+        "npmlog": "^4.1.2",
+        "react-dev-utils": "^9.0.4",
+        "semver": "^7.3.2",
+        "webpack": "^4.27.1",
+        "webpack-dev-server": "^3.7.2",
+        "yargs-parser": "^14.0.0"
+      },
+      "dependencies": {
+        "camelcase": {
+          "version": "5.3.1",
+          "resolved": "https://registry.npm.taobao.org/camelcase/download/camelcase-5.3.1.tgz?cache=0&sync_timestamp=1603921882890&other_urls=https%3A%2F%2Fregistry.npm.taobao.org%2Fcamelcase%2Fdownload%2Fcamelcase-5.3.1.tgz",
+          "integrity": "sha1-48mzFWnhBoEd8kL3FXJaH0xJQyA=",
+          "dev": true
+        },
+        "commander": {
+          "version": "2.20.3",
+          "resolved": "https://registry.npm.taobao.org/commander/download/commander-2.20.3.tgz?cache=0&sync_timestamp=1603599627620&other_urls=https%3A%2F%2Fregistry.npm.taobao.org%2Fcommander%2Fdownload%2Fcommander-2.20.3.tgz",
+          "integrity": "sha1-/UhehMA+tIgcIHIrpIA16FMa6zM=",
+          "dev": true
+        },
+        "json5": {
+          "version": "2.1.3",
+          "resolved": "https://registry.npm.taobao.org/json5/download/json5-2.1.3.tgz",
+          "integrity": "sha1-ybD3+pIzv+WAf+ZvzzpWF+1ZfUM=",
+          "dev": true,
+          "requires": {
+            "minimist": "^1.2.5"
+          }
+        },
+        "yargs-parser": {
+          "version": "14.0.0",
+          "resolved": "https://registry.npm.taobao.org/yargs-parser/download/yargs-parser-14.0.0.tgz?cache=0&sync_timestamp=1604886694625&other_urls=https%3A%2F%2Fregistry.npm.taobao.org%2Fyargs-parser%2Fdownload%2Fyargs-parser-14.0.0.tgz",
+          "integrity": "sha1-QuJXd7BnGOyZ6sLDqYrT3nO2gY8=",
+          "dev": true,
+          "requires": {
+            "camelcase": "^5.0.0",
+            "decamelize": "^1.2.0"
+          }
+        }
+      }
+    },
+    "@alifd/field": {
+      "version": "1.4.5",
+      "resolved": "https://registry.npm.taobao.org/@alifd/field/download/@alifd/field-1.4.5.tgz",
+      "integrity": "sha1-Hh5eg8FDY31u/pLrkdzenginOp8=",
+      "requires": {
+        "@alifd/validate": "^1.2.0",
+        "prop-types": "^15.5.8"
+      }
+    },
+    "@alifd/fusion-collector": {
+      "version": "1.3.5",
+      "resolved": "https://registry.npm.taobao.org/@alifd/fusion-collector/download/@alifd/fusion-collector-1.3.5.tgz",
+      "integrity": "sha1-gUc5qFKla8MkmFLVHKfFinln9NY=",
+      "dev": true,
+      "requires": {
+        "@babel/runtime": "^7.8.4",
+        "glob": "^7.1.2",
+        "graceful-fs": "^4.1.11",
+        "ice-npm-utils": "^1.4.1",
+        "ini": "^1.3.5"
+      }
+    },
+    "@alifd/next": {
+      "version": "1.21.8",
+      "resolved": "https://registry.npm.taobao.org/@alifd/next/download/@alifd/next-1.21.8.tgz",
+      "integrity": "sha1-yQGzKFTL3pmqq42S5Oc1IEpB7nw=",
+      "requires": {
+        "@alifd/field": "~1.4.1",
+        "@alifd/validate": "~1.2.0",
+        "babel-runtime": "^6.26.0",
+        "classnames": "^2.2.3",
+        "hoist-non-react-statics": "^2.1.0",
+        "lodash.clonedeep": "^4.5.0",
+        "prop-types": "^15.6.0",
+        "react-lifecycles-compat": "^3.0.4",
+        "react-transition-group": "^2.2.1",
+        "shallow-element-equals": "^1.0.1"
+      }
+    },
+    "@alifd/theme-design-pro": {
+      "version": "0.6.2",
+      "resolved": "https://registry.npm.taobao.org/@alifd/theme-design-pro/download/@alifd/theme-design-pro-0.6.2.tgz",
+      "integrity": "sha1-qaoxJgIooS2NlfvwTog/d1oO5Fs=",
+      "requires": {
+        "@alifd/next": "~1.19.22"
+      },
+      "dependencies": {
+        "@alifd/field": {
+          "version": "1.3.5",
+          "resolved": "https://registry.npm.taobao.org/@alifd/field/download/@alifd/field-1.3.5.tgz",
+          "integrity": "sha1-uPNwuNnbwquirIX2pZiezVHzZnM=",
+          "requires": {
+            "@alifd/validate": "^1.1.3",
+            "prop-types": "^15.5.8"
+          }
+        },
+        "@alifd/next": {
+          "version": "1.19.31",
+          "resolved": "https://registry.npm.taobao.org/@alifd/next/download/@alifd/next-1.19.31.tgz",
+          "integrity": "sha1-5DFSQ3UK/28KWZUOcvneDS/NblQ=",
+          "requires": {
+            "@alifd/field": "~1.3.3",
+            "@alifd/validate": "~1.1.4",
+            "babel-runtime": "^6.26.0",
+            "classnames": "^2.2.3",
+            "hoist-non-react-statics": "^2.1.0",
+            "prop-types": "^15.6.0",
+            "react-lifecycles-compat": "^3.0.4",
+            "react-transition-group": "^2.2.1",
+            "shallow-element-equals": "^1.0.1"
+          }
+        },
+        "@alifd/validate": {
+          "version": "1.1.5",
+          "resolved": "https://registry.npm.taobao.org/@alifd/validate/download/@alifd/validate-1.1.5.tgz",
+          "integrity": "sha1-5EiWeFBRGCy5TbfsKzOpm0yGlDo="
+        }
+      }
+    },
+    "@alifd/validate": {
+      "version": "1.2.0",
+      "resolved": "https://registry.npm.taobao.org/@alifd/validate/download/@alifd/validate-1.2.0.tgz",
+      "integrity": "sha1-JS4K3STmTv1U/mEbqMZtAUfYUPY="
+    },
+    "@babel/code-frame": {
+      "version": "7.10.4",
+      "resolved": "https://registry.npm.taobao.org/@babel/code-frame/download/@babel/code-frame-7.10.4.tgz",
+      "integrity": "sha1-Fo2ho26Q2miujUnA8bSMfGJJITo=",
+      "dev": true,
+      "requires": {
+        "@babel/highlight": "^7.10.4"
+      }
+    },
+    "@babel/compat-data": {
+      "version": "7.12.5",
+      "resolved": "https://registry.npm.taobao.org/@babel/compat-data/download/@babel/compat-data-7.12.5.tgz?cache=0&sync_timestamp=1604441103552&other_urls=https%3A%2F%2Fregistry.npm.taobao.org%2F%40babel%2Fcompat-data%2Fdownload%2F%40babel%2Fcompat-data-7.12.5.tgz",
+      "integrity": "sha1-9W2wxLsbu/IhtOgTRaq0FB58sOk=",
+      "dev": true
+    },
+    "@babel/core": {
+      "version": "7.12.3",
+      "resolved": "https://registry.npm.taobao.org/@babel/core/download/@babel/core-7.12.3.tgz",
+      "integrity": "sha1-G0NohOHjv/b7EyjcArIIdZ3pKtg=",
+      "dev": true,
+      "requires": {
+        "@babel/code-frame": "^7.10.4",
+        "@babel/generator": "^7.12.1",
+        "@babel/helper-module-transforms": "^7.12.1",
+        "@babel/helpers": "^7.12.1",
+        "@babel/parser": "^7.12.3",
+        "@babel/template": "^7.10.4",
+        "@babel/traverse": "^7.12.1",
+        "@babel/types": "^7.12.1",
+        "convert-source-map": "^1.7.0",
+        "debug": "^4.1.0",
+        "gensync": "^1.0.0-beta.1",
+        "json5": "^2.1.2",
+        "lodash": "^4.17.19",
+        "resolve": "^1.3.2",
+        "semver": "^5.4.1",
+        "source-map": "^0.5.0"
+      },
+      "dependencies": {
+        "json5": {
+          "version": "2.1.3",
+          "resolved": "https://registry.npm.taobao.org/json5/download/json5-2.1.3.tgz",
+          "integrity": "sha1-ybD3+pIzv+WAf+ZvzzpWF+1ZfUM=",
+          "dev": true,
+          "requires": {
+            "minimist": "^1.2.5"
+          }
+        },
+        "semver": {
+          "version": "5.7.1",
+          "resolved": "https://registry.npm.taobao.org/semver/download/semver-5.7.1.tgz",
+          "integrity": "sha1-qVT5Ma66UI0we78Gnv8MAclhFvc=",
+          "dev": true
+        }
+      }
+    },
+    "@babel/generator": {
+      "version": "7.12.5",
+      "resolved": "https://registry.npm.taobao.org/@babel/generator/download/@babel/generator-7.12.5.tgz?cache=0&sync_timestamp=1604441076223&other_urls=https%3A%2F%2Fregistry.npm.taobao.org%2F%40babel%2Fgenerator%2Fdownload%2F%40babel%2Fgenerator-7.12.5.tgz",
+      "integrity": "sha1-osUN5ci21wirlb5eYFOTbBiEpN4=",
+      "dev": true,
+      "requires": {
+        "@babel/types": "^7.12.5",
+        "jsesc": "^2.5.1",
+        "source-map": "^0.5.0"
+      }
+    },
+    "@babel/helper-annotate-as-pure": {
+      "version": "7.10.4",
+      "resolved": "https://registry.npm.taobao.org/@babel/helper-annotate-as-pure/download/@babel/helper-annotate-as-pure-7.10.4.tgz?cache=0&sync_timestamp=1593522826156&other_urls=https%3A%2F%2Fregistry.npm.taobao.org%2F%40babel%2Fhelper-annotate-as-pure%2Fdownload%2F%40babel%2Fhelper-annotate-as-pure-7.10.4.tgz",
+      "integrity": "sha1-W/DUlaP3V6w72ki1vzs7ownHK6M=",
+      "dev": true,
+      "requires": {
+        "@babel/types": "^7.10.4"
+      }
+    },
+    "@babel/helper-builder-binary-assignment-operator-visitor": {
+      "version": "7.10.4",
+      "resolved": "https://registry.npm.taobao.org/@babel/helper-builder-binary-assignment-operator-visitor/download/@babel/helper-builder-binary-assignment-operator-visitor-7.10.4.tgz",
+      "integrity": "sha1-uwt18xv5jL+f8UPBrleLhydK4aM=",
+      "dev": true,
+      "requires": {
+        "@babel/helper-explode-assignable-expression": "^7.10.4",
+        "@babel/types": "^7.10.4"
+      }
+    },
+    "@babel/helper-builder-react-jsx": {
+      "version": "7.10.4",
+      "resolved": "https://registry.npm.taobao.org/@babel/helper-builder-react-jsx/download/@babel/helper-builder-react-jsx-7.10.4.tgz?cache=0&sync_timestamp=1593522969703&other_urls=https%3A%2F%2Fregistry.npm.taobao.org%2F%40babel%2Fhelper-builder-react-jsx%2Fdownload%2F%40babel%2Fhelper-builder-react-jsx-7.10.4.tgz",
+      "integrity": "sha1-gJXN2/+Fjm+pwyba7lSi8nMsHV0=",
+      "dev": true,
+      "requires": {
+        "@babel/helper-annotate-as-pure": "^7.10.4",
+        "@babel/types": "^7.10.4"
+      }
+    },
+    "@babel/helper-builder-react-jsx-experimental": {
+      "version": "7.12.4",
+      "resolved": "https://registry.npm.taobao.org/@babel/helper-builder-react-jsx-experimental/download/@babel/helper-builder-react-jsx-experimental-7.12.4.tgz",
+      "integrity": "sha1-VfwerVJCyqDKKHXcuO7W0xHlD0g=",
+      "dev": true,
+      "requires": {
+        "@babel/helper-annotate-as-pure": "^7.10.4",
+        "@babel/helper-module-imports": "^7.12.1",
+        "@babel/types": "^7.12.1"
+      }
+    },
+    "@babel/helper-compilation-targets": {
+      "version": "7.12.5",
+      "resolved": "https://registry.npm.taobao.org/@babel/helper-compilation-targets/download/@babel/helper-compilation-targets-7.12.5.tgz?cache=0&sync_timestamp=1604441105017&other_urls=https%3A%2F%2Fregistry.npm.taobao.org%2F%40babel%2Fhelper-compilation-targets%2Fdownload%2F%40babel%2Fhelper-compilation-targets-7.12.5.tgz",
+      "integrity": "sha1-y0cMdhmNtqJOnbyJhydWMeXSmDE=",
+      "dev": true,
+      "requires": {
+        "@babel/compat-data": "^7.12.5",
+        "@babel/helper-validator-option": "^7.12.1",
+        "browserslist": "^4.14.5",
+        "semver": "^5.5.0"
+      },
+      "dependencies": {
+        "semver": {
+          "version": "5.7.1",
+          "resolved": "https://registry.npm.taobao.org/semver/download/semver-5.7.1.tgz",
+          "integrity": "sha1-qVT5Ma66UI0we78Gnv8MAclhFvc=",
+          "dev": true
+        }
+      }
+    },
+    "@babel/helper-create-class-features-plugin": {
+      "version": "7.12.1",
+      "resolved": "https://registry.npm.taobao.org/@babel/helper-create-class-features-plugin/download/@babel/helper-create-class-features-plugin-7.12.1.tgz?cache=0&sync_timestamp=1602802060378&other_urls=https%3A%2F%2Fregistry.npm.taobao.org%2F%40babel%2Fhelper-create-class-features-plugin%2Fdownload%2F%40babel%2Fhelper-create-class-features-plugin-7.12.1.tgz",
+      "integrity": "sha1-PEWZj0Me3UqSFMXx060USKYTf24=",
+      "dev": true,
+      "requires": {
+        "@babel/helper-function-name": "^7.10.4",
+        "@babel/helper-member-expression-to-functions": "^7.12.1",
+        "@babel/helper-optimise-call-expression": "^7.10.4",
+        "@babel/helper-replace-supers": "^7.12.1",
+        "@babel/helper-split-export-declaration": "^7.10.4"
+      }
+    },
+    "@babel/helper-create-regexp-features-plugin": {
+      "version": "7.12.1",
+      "resolved": "https://registry.npm.taobao.org/@babel/helper-create-regexp-features-plugin/download/@babel/helper-create-regexp-features-plugin-7.12.1.tgz?cache=0&sync_timestamp=1602800231050&other_urls=https%3A%2F%2Fregistry.npm.taobao.org%2F%40babel%2Fhelper-create-regexp-features-plugin%2Fdownload%2F%40babel%2Fhelper-create-regexp-features-plugin-7.12.1.tgz",
+      "integrity": "sha1-GLEwLUZ3+dxHQP6MntlmgOKdN+g=",
+      "dev": true,
+      "requires": {
+        "@babel/helper-annotate-as-pure": "^7.10.4",
+        "@babel/helper-regex": "^7.10.4",
+        "regexpu-core": "^4.7.1"
+      }
+    },
+    "@babel/helper-define-map": {
+      "version": "7.10.5",
+      "resolved": "https://registry.npm.taobao.org/@babel/helper-define-map/download/@babel/helper-define-map-7.10.5.tgz",
+      "integrity": "sha1-tTwQ23imQIABUmkrEzkxR6y5uzA=",
+      "dev": true,
+      "requires": {
+        "@babel/helper-function-name": "^7.10.4",
+        "@babel/types": "^7.10.5",
+        "lodash": "^4.17.19"
+      }
+    },
+    "@babel/helper-explode-assignable-expression": {
+      "version": "7.12.1",
+      "resolved": "https://registry.npm.taobao.org/@babel/helper-explode-assignable-expression/download/@babel/helper-explode-assignable-expression-7.12.1.tgz?cache=0&sync_timestamp=1602800239433&other_urls=https%3A%2F%2Fregistry.npm.taobao.org%2F%40babel%2Fhelper-explode-assignable-expression%2Fdownload%2F%40babel%2Fhelper-explode-assignable-expression-7.12.1.tgz",
+      "integrity": "sha1-gAakZmlcSthqKl8vsVtfLDGtVjM=",
+      "dev": true,
+      "requires": {
+        "@babel/types": "^7.12.1"
+      }
+    },
+    "@babel/helper-function-name": {
+      "version": "7.10.4",
+      "resolved": "https://registry.npm.taobao.org/@babel/helper-function-name/download/@babel/helper-function-name-7.10.4.tgz?cache=0&sync_timestamp=1593522836308&other_urls=https%3A%2F%2Fregistry.npm.taobao.org%2F%40babel%2Fhelper-function-name%2Fdownload%2F%40babel%2Fhelper-function-name-7.10.4.tgz",
+      "integrity": "sha1-0tOyDFmtjEcRL6fSqUvAnV74Lxo=",
+      "dev": true,
+      "requires": {
+        "@babel/helper-get-function-arity": "^7.10.4",
+        "@babel/template": "^7.10.4",
+        "@babel/types": "^7.10.4"
+      }
+    },
+    "@babel/helper-get-function-arity": {
+      "version": "7.10.4",
+      "resolved": "https://registry.npm.taobao.org/@babel/helper-get-function-arity/download/@babel/helper-get-function-arity-7.10.4.tgz?cache=0&sync_timestamp=1593522827189&other_urls=https%3A%2F%2Fregistry.npm.taobao.org%2F%40babel%2Fhelper-get-function-arity%2Fdownload%2F%40babel%2Fhelper-get-function-arity-7.10.4.tgz",
+      "integrity": "sha1-mMHL6g4jMvM/mkZhuM4VBbLBm6I=",
+      "dev": true,
+      "requires": {
+        "@babel/types": "^7.10.4"
+      }
+    },
+    "@babel/helper-hoist-variables": {
+      "version": "7.10.4",
+      "resolved": "https://registry.npm.taobao.org/@babel/helper-hoist-variables/download/@babel/helper-hoist-variables-7.10.4.tgz?cache=0&sync_timestamp=1593522826778&other_urls=https%3A%2F%2Fregistry.npm.taobao.org%2F%40babel%2Fhelper-hoist-variables%2Fdownload%2F%40babel%2Fhelper-hoist-variables-7.10.4.tgz",
+      "integrity": "sha1-1JsAHR1aaMpeZgTdoBpil/fJOB4=",
+      "dev": true,
+      "requires": {
+        "@babel/types": "^7.10.4"
+      }
+    },
+    "@babel/helper-member-expression-to-functions": {
+      "version": "7.12.1",
+      "resolved": "https://registry.npm.taobao.org/@babel/helper-member-expression-to-functions/download/@babel/helper-member-expression-to-functions-7.12.1.tgz?cache=0&sync_timestamp=1602800239601&other_urls=https%3A%2F%2Fregistry.npm.taobao.org%2F%40babel%2Fhelper-member-expression-to-functions%2Fdownload%2F%40babel%2Fhelper-member-expression-to-functions-7.12.1.tgz",
+      "integrity": "sha1-+6Dy/P8/ugDm7LZku15uJuLWFlw=",
+      "dev": true,
+      "requires": {
+        "@babel/types": "^7.12.1"
+      }
+    },
+    "@babel/helper-module-imports": {
+      "version": "7.12.5",
+      "resolved": "https://registry.npm.taobao.org/@babel/helper-module-imports/download/@babel/helper-module-imports-7.12.5.tgz?cache=0&sync_timestamp=1604441076449&other_urls=https%3A%2F%2Fregistry.npm.taobao.org%2F%40babel%2Fhelper-module-imports%2Fdownload%2F%40babel%2Fhelper-module-imports-7.12.5.tgz",
+      "integrity": "sha1-G/wCKfeUmI927QpNTpCGCFC1Tfs=",
+      "dev": true,
+      "requires": {
+        "@babel/types": "^7.12.5"
+      }
+    },
+    "@babel/helper-module-transforms": {
+      "version": "7.12.1",
+      "resolved": "https://registry.npm.taobao.org/@babel/helper-module-transforms/download/@babel/helper-module-transforms-7.12.1.tgz?cache=0&sync_timestamp=1602802059560&other_urls=https%3A%2F%2Fregistry.npm.taobao.org%2F%40babel%2Fhelper-module-transforms%2Fdownload%2F%40babel%2Fhelper-module-transforms-7.12.1.tgz",
+      "integrity": "sha1-eVT+xx9bMsSOSzA7Q3w0RT/XJHw=",
+      "dev": true,
+      "requires": {
+        "@babel/helper-module-imports": "^7.12.1",
+        "@babel/helper-replace-supers": "^7.12.1",
+        "@babel/helper-simple-access": "^7.12.1",
+        "@babel/helper-split-export-declaration": "^7.11.0",
+        "@babel/helper-validator-identifier": "^7.10.4",
+        "@babel/template": "^7.10.4",
+        "@babel/traverse": "^7.12.1",
+        "@babel/types": "^7.12.1",
+        "lodash": "^4.17.19"
+      }
+    },
+    "@babel/helper-optimise-call-expression": {
+      "version": "7.10.4",
+      "resolved": "https://registry.npm.taobao.org/@babel/helper-optimise-call-expression/download/@babel/helper-optimise-call-expression-7.10.4.tgz?cache=0&sync_timestamp=1593522827576&other_urls=https%3A%2F%2Fregistry.npm.taobao.org%2F%40babel%2Fhelper-optimise-call-expression%2Fdownload%2F%40babel%2Fhelper-optimise-call-expression-7.10.4.tgz",
+      "integrity": "sha1-UNyWQT1ZT5lad5BZBbBYk813lnM=",
+      "dev": true,
+      "requires": {
+        "@babel/types": "^7.10.4"
+      }
+    },
+    "@babel/helper-plugin-utils": {
+      "version": "7.10.4",
+      "resolved": "https://registry.npm.taobao.org/@babel/helper-plugin-utils/download/@babel/helper-plugin-utils-7.10.4.tgz?cache=0&sync_timestamp=1593521148758&other_urls=https%3A%2F%2Fregistry.npm.taobao.org%2F%40babel%2Fhelper-plugin-utils%2Fdownload%2F%40babel%2Fhelper-plugin-utils-7.10.4.tgz",
+      "integrity": "sha1-L3WoMSadT2d95JmG3/WZJ1M883U=",
+      "dev": true
+    },
+    "@babel/helper-regex": {
+      "version": "7.10.5",
+      "resolved": "https://registry.npm.taobao.org/@babel/helper-regex/download/@babel/helper-regex-7.10.5.tgz?cache=0&sync_timestamp=1594751535064&other_urls=https%3A%2F%2Fregistry.npm.taobao.org%2F%40babel%2Fhelper-regex%2Fdownload%2F%40babel%2Fhelper-regex-7.10.5.tgz",
+      "integrity": "sha1-Mt+7eYmQc8QVVXBToZvQVarlCuA=",
+      "dev": true,
+      "requires": {
+        "lodash": "^4.17.19"
+      }
+    },
+    "@babel/helper-remap-async-to-generator": {
+      "version": "7.12.1",
+      "resolved": "https://registry.npm.taobao.org/@babel/helper-remap-async-to-generator/download/@babel/helper-remap-async-to-generator-7.12.1.tgz?cache=0&sync_timestamp=1602800240049&other_urls=https%3A%2F%2Fregistry.npm.taobao.org%2F%40babel%2Fhelper-remap-async-to-generator%2Fdownload%2F%40babel%2Fhelper-remap-async-to-generator-7.12.1.tgz",
+      "integrity": "sha1-jE27+RYxT2BH3AXmoiFwdCODR/0=",
+      "dev": true,
+      "requires": {
+        "@babel/helper-annotate-as-pure": "^7.10.4",
+        "@babel/helper-wrap-function": "^7.10.4",
+        "@babel/types": "^7.12.1"
+      }
+    },
+    "@babel/helper-replace-supers": {
+      "version": "7.12.5",
+      "resolved": "https://registry.npm.taobao.org/@babel/helper-replace-supers/download/@babel/helper-replace-supers-7.12.5.tgz",
+      "integrity": "sha1-8AmhdUO7u84WsGIGrnO2PT/KaNk=",
+      "dev": true,
+      "requires": {
+        "@babel/helper-member-expression-to-functions": "^7.12.1",
+        "@babel/helper-optimise-call-expression": "^7.10.4",
+        "@babel/traverse": "^7.12.5",
+        "@babel/types": "^7.12.5"
+      }
+    },
+    "@babel/helper-simple-access": {
+      "version": "7.12.1",
+      "resolved": "https://registry.npm.taobao.org/@babel/helper-simple-access/download/@babel/helper-simple-access-7.12.1.tgz?cache=0&sync_timestamp=1602802050087&other_urls=https%3A%2F%2Fregistry.npm.taobao.org%2F%40babel%2Fhelper-simple-access%2Fdownload%2F%40babel%2Fhelper-simple-access-7.12.1.tgz",
+      "integrity": "sha1-MkJ+WqYVR9OOsebq9f0UJv2tkTY=",
+      "dev": true,
+      "requires": {
+        "@babel/types": "^7.12.1"
+      }
+    },
+    "@babel/helper-skip-transparent-expression-wrappers": {
+      "version": "7.12.1",
+      "resolved": "https://registry.npm.taobao.org/@babel/helper-skip-transparent-expression-wrappers/download/@babel/helper-skip-transparent-expression-wrappers-7.12.1.tgz",
+      "integrity": "sha1-Ri3GOn5DWt6EaDhcY9K4TM5LPL8=",
+      "dev": true,
+      "requires": {
+        "@babel/types": "^7.12.1"
+      }
+    },
+    "@babel/helper-split-export-declaration": {
+      "version": "7.11.0",
+      "resolved": "https://registry.npm.taobao.org/@babel/helper-split-export-declaration/download/@babel/helper-split-export-declaration-7.11.0.tgz?cache=0&sync_timestamp=1596144786980&other_urls=https%3A%2F%2Fregistry.npm.taobao.org%2F%40babel%2Fhelper-split-export-declaration%2Fdownload%2F%40babel%2Fhelper-split-export-declaration-7.11.0.tgz",
+      "integrity": "sha1-+KSRJErPamdhWKxCBykRuoOtCZ8=",
+      "dev": true,
+      "requires": {
+        "@babel/types": "^7.11.0"
+      }
+    },
+    "@babel/helper-validator-identifier": {
+      "version": "7.10.4",
+      "resolved": "https://registry.npm.taobao.org/@babel/helper-validator-identifier/download/@babel/helper-validator-identifier-7.10.4.tgz",
+      "integrity": "sha1-p4x6clHgH2FlEtMbEK3PUq2l4NI=",
+      "dev": true
+    },
+    "@babel/helper-validator-option": {
+      "version": "7.12.1",
+      "resolved": "https://registry.npm.taobao.org/@babel/helper-validator-option/download/@babel/helper-validator-option-7.12.1.tgz?cache=0&sync_timestamp=1602801773085&other_urls=https%3A%2F%2Fregistry.npm.taobao.org%2F%40babel%2Fhelper-validator-option%2Fdownload%2F%40babel%2Fhelper-validator-option-7.12.1.tgz",
+      "integrity": "sha1-F1VnOAw+d9YP+YpUuwFf548heNk=",
+      "dev": true
+    },
+    "@babel/helper-wrap-function": {
+      "version": "7.12.3",
+      "resolved": "https://registry.npm.taobao.org/@babel/helper-wrap-function/download/@babel/helper-wrap-function-7.12.3.tgz",
+      "integrity": "sha1-MzIzn8TR+78cJ9eVjCfTRwjpkNk=",
+      "dev": true,
+      "requires": {
+        "@babel/helper-function-name": "^7.10.4",
+        "@babel/template": "^7.10.4",
+        "@babel/traverse": "^7.10.4",
+        "@babel/types": "^7.10.4"
+      }
+    },
+    "@babel/helpers": {
+      "version": "7.12.5",
+      "resolved": "https://registry.npm.taobao.org/@babel/helpers/download/@babel/helpers-7.12.5.tgz",
+      "integrity": "sha1-Ghukp2jZtYMQ7aUWxEmRP+ZHEW4=",
+      "dev": true,
+      "requires": {
+        "@babel/template": "^7.10.4",
+        "@babel/traverse": "^7.12.5",
+        "@babel/types": "^7.12.5"
+      }
+    },
+    "@babel/highlight": {
+      "version": "7.10.4",
+      "resolved": "https://registry.npm.taobao.org/@babel/highlight/download/@babel/highlight-7.10.4.tgz?cache=0&sync_timestamp=1593522818552&other_urls=https%3A%2F%2Fregistry.npm.taobao.org%2F%40babel%2Fhighlight%2Fdownload%2F%40babel%2Fhighlight-7.10.4.tgz",
+      "integrity": "sha1-fRvf1ldTU4+r5sOFls23bZrGAUM=",
+      "dev": true,
+      "requires": {
+        "@babel/helper-validator-identifier": "^7.10.4",
+        "chalk": "^2.0.0",
+        "js-tokens": "^4.0.0"
+      }
+    },
+    "@babel/parser": {
+      "version": "7.12.5",
+      "resolved": "https://registry.npm.taobao.org/@babel/parser/download/@babel/parser-7.12.5.tgz?cache=0&sync_timestamp=1604441237314&other_urls=https%3A%2F%2Fregistry.npm.taobao.org%2F%40babel%2Fparser%2Fdownload%2F%40babel%2Fparser-7.12.5.tgz",
+      "integrity": "sha1-tK8y3dRzwL+mQ71/8HKLjnG4HqA=",
+      "dev": true
+    },
+    "@babel/plugin-proposal-async-generator-functions": {
+      "version": "7.12.1",
+      "resolved": "https://registry.npm.taobao.org/@babel/plugin-proposal-async-generator-functions/download/@babel/plugin-proposal-async-generator-functions-7.12.1.tgz?cache=0&sync_timestamp=1602800241810&other_urls=https%3A%2F%2Fregistry.npm.taobao.org%2F%40babel%2Fplugin-proposal-async-generator-functions%2Fdownload%2F%40babel%2Fplugin-proposal-async-generator-functions-7.12.1.tgz",
+      "integrity": "sha1-3GwRcOJ9isqZ/2X0klvQaxyQVQ4=",
+      "dev": true,
+      "requires": {
+        "@babel/helper-plugin-utils": "^7.10.4",
+        "@babel/helper-remap-async-to-generator": "^7.12.1",
+        "@babel/plugin-syntax-async-generators": "^7.8.0"
+      }
+    },
+    "@babel/plugin-proposal-class-properties": {
+      "version": "7.12.1",
+      "resolved": "https://registry.npm.taobao.org/@babel/plugin-proposal-class-properties/download/@babel/plugin-proposal-class-properties-7.12.1.tgz?cache=0&sync_timestamp=1602802062562&other_urls=https%3A%2F%2Fregistry.npm.taobao.org%2F%40babel%2Fplugin-proposal-class-properties%2Fdownload%2F%40babel%2Fplugin-proposal-class-properties-7.12.1.tgz",
+      "integrity": "sha1-oIL/VB8qKaSCEGW4rdk0bAwW5d4=",
+      "dev": true,
+      "requires": {
+        "@babel/helper-create-class-features-plugin": "^7.12.1",
+        "@babel/helper-plugin-utils": "^7.10.4"
+      }
+    },
+    "@babel/plugin-proposal-decorators": {
+      "version": "7.12.1",
+      "resolved": "https://registry.npm.taobao.org/@babel/plugin-proposal-decorators/download/@babel/plugin-proposal-decorators-7.12.1.tgz?cache=0&sync_timestamp=1602800229034&other_urls=https%3A%2F%2Fregistry.npm.taobao.org%2F%40babel%2Fplugin-proposal-decorators%2Fdownload%2F%40babel%2Fplugin-proposal-decorators-7.12.1.tgz",
+      "integrity": "sha1-WScUOf7UFFRWxBBnRQVDruMy0V8=",
+      "dev": true,
+      "requires": {
+        "@babel/helper-create-class-features-plugin": "^7.12.1",
+        "@babel/helper-plugin-utils": "^7.10.4",
+        "@babel/plugin-syntax-decorators": "^7.12.1"
+      }
+    },
+    "@babel/plugin-proposal-do-expressions": {
+      "version": "7.12.1",
+      "resolved": "https://registry.npm.taobao.org/@babel/plugin-proposal-do-expressions/download/@babel/plugin-proposal-do-expressions-7.12.1.tgz?cache=0&sync_timestamp=1602806865634&other_urls=https%3A%2F%2Fregistry.npm.taobao.org%2F%40babel%2Fplugin-proposal-do-expressions%2Fdownload%2F%40babel%2Fplugin-proposal-do-expressions-7.12.1.tgz",
+      "integrity": "sha1-jX8bxTLYFoFHVVwm49uSLMDf0vg=",
+      "dev": true,
+      "requires": {
+        "@babel/helper-plugin-utils": "^7.10.4",
+        "@babel/plugin-syntax-do-expressions": "^7.12.1"
+      }
+    },
+    "@babel/plugin-proposal-dynamic-import": {
+      "version": "7.12.1",
+      "resolved": "https://registry.npm.taobao.org/@babel/plugin-proposal-dynamic-import/download/@babel/plugin-proposal-dynamic-import-7.12.1.tgz?cache=0&sync_timestamp=1602800231856&other_urls=https%3A%2F%2Fregistry.npm.taobao.org%2F%40babel%2Fplugin-proposal-dynamic-import%2Fdownload%2F%40babel%2Fplugin-proposal-dynamic-import-7.12.1.tgz",
+      "integrity": "sha1-Q+tcKjSH7NmMXI6otf22midJstw=",
+      "dev": true,
+      "requires": {
+        "@babel/helper-plugin-utils": "^7.10.4",
+        "@babel/plugin-syntax-dynamic-import": "^7.8.0"
+      }
+    },
+    "@babel/plugin-proposal-export-default-from": {
+      "version": "7.12.1",
+      "resolved": "https://registry.npm.taobao.org/@babel/plugin-proposal-export-default-from/download/@babel/plugin-proposal-export-default-from-7.12.1.tgz?cache=0&sync_timestamp=1602806866408&other_urls=https%3A%2F%2Fregistry.npm.taobao.org%2F%40babel%2Fplugin-proposal-export-default-from%2Fdownload%2F%40babel%2Fplugin-proposal-export-default-from-7.12.1.tgz",
+      "integrity": "sha1-xuYtZoqKvP4NKLgvVgOV/sthHFo=",
+      "dev": true,
+      "requires": {
+        "@babel/helper-plugin-utils": "^7.10.4",
+        "@babel/plugin-syntax-export-default-from": "^7.12.1"
+      }
+    },
+    "@babel/plugin-proposal-export-namespace-from": {
+      "version": "7.12.1",
+      "resolved": "https://registry.npm.taobao.org/@babel/plugin-proposal-export-namespace-from/download/@babel/plugin-proposal-export-namespace-from-7.12.1.tgz?cache=0&sync_timestamp=1602801775633&other_urls=https%3A%2F%2Fregistry.npm.taobao.org%2F%40babel%2Fplugin-proposal-export-namespace-from%2Fdownload%2F%40babel%2Fplugin-proposal-export-namespace-from-7.12.1.tgz",
+      "integrity": "sha1-i5uPN2stiPXdd05NJKXMLjZ5ttQ=",
+      "dev": true,
+      "requires": {
+        "@babel/helper-plugin-utils": "^7.10.4",
+        "@babel/plugin-syntax-export-namespace-from": "^7.8.3"
+      }
+    },
+    "@babel/plugin-proposal-function-bind": {
+      "version": "7.12.1",
+      "resolved": "https://registry.npm.taobao.org/@babel/plugin-proposal-function-bind/download/@babel/plugin-proposal-function-bind-7.12.1.tgz?cache=0&sync_timestamp=1602806866031&other_urls=https%3A%2F%2Fregistry.npm.taobao.org%2F%40babel%2Fplugin-proposal-function-bind%2Fdownload%2F%40babel%2Fplugin-proposal-function-bind-7.12.1.tgz",
+      "integrity": "sha1-i4kbQS/7yOj/P9TfZ7jUu+WUcAQ=",
+      "dev": true,
+      "requires": {
+        "@babel/helper-plugin-utils": "^7.10.4",
+        "@babel/plugin-syntax-function-bind": "^7.12.1"
+      }
+    },
+    "@babel/plugin-proposal-function-sent": {
+      "version": "7.12.1",
+      "resolved": "https://registry.npm.taobao.org/@babel/plugin-proposal-function-sent/download/@babel/plugin-proposal-function-sent-7.12.1.tgz",
+      "integrity": "sha1-jzAqqKtfAK9slKPhEI+jXRUxlRA=",
+      "dev": true,
+      "requires": {
+        "@babel/helper-plugin-utils": "^7.10.4",
+        "@babel/helper-wrap-function": "^7.10.4",
+        "@babel/plugin-syntax-function-sent": "^7.12.1"
+      }
+    },
+    "@babel/plugin-proposal-json-strings": {
+      "version": "7.12.1",
+      "resolved": "https://registry.npm.taobao.org/@babel/plugin-proposal-json-strings/download/@babel/plugin-proposal-json-strings-7.12.1.tgz?cache=0&sync_timestamp=1602800231781&other_urls=https%3A%2F%2Fregistry.npm.taobao.org%2F%40babel%2Fplugin-proposal-json-strings%2Fdownload%2F%40babel%2Fplugin-proposal-json-strings-7.12.1.tgz",
+      "integrity": "sha1-1FQjtRdxTu3VYhqd/cA/qfTrJBw=",
+      "dev": true,
+      "requires": {
+        "@babel/helper-plugin-utils": "^7.10.4",
+        "@babel/plugin-syntax-json-strings": "^7.8.0"
+      }
+    },
+    "@babel/plugin-proposal-logical-assignment-operators": {
+      "version": "7.12.1",
+      "resolved": "https://registry.npm.taobao.org/@babel/plugin-proposal-logical-assignment-operators/download/@babel/plugin-proposal-logical-assignment-operators-7.12.1.tgz?cache=0&sync_timestamp=1602801777850&other_urls=https%3A%2F%2Fregistry.npm.taobao.org%2F%40babel%2Fplugin-proposal-logical-assignment-operators%2Fdownload%2F%40babel%2Fplugin-proposal-logical-assignment-operators-7.12.1.tgz",
+      "integrity": "sha1-8sSQ024bPJZZJBA0pdLNUCY6J1E=",
+      "dev": true,
+      "requires": {
+        "@babel/helper-plugin-utils": "^7.10.4",
+        "@babel/plugin-syntax-logical-assignment-operators": "^7.10.4"
+      }
+    },
+    "@babel/plugin-proposal-nullish-coalescing-operator": {
+      "version": "7.12.1",
+      "resolved": "https://registry.npm.taobao.org/@babel/plugin-proposal-nullish-coalescing-operator/download/@babel/plugin-proposal-nullish-coalescing-operator-7.12.1.tgz?cache=0&sync_timestamp=1602800231580&other_urls=https%3A%2F%2Fregistry.npm.taobao.org%2F%40babel%2Fplugin-proposal-nullish-coalescing-operator%2Fdownload%2F%40babel%2Fplugin-proposal-nullish-coalescing-operator-7.12.1.tgz",
+      "integrity": "sha1-PtT/8xwBXn8/FGfxkNvlRc17BGw=",
+      "dev": true,
+      "requires": {
+        "@babel/helper-plugin-utils": "^7.10.4",
+        "@babel/plugin-syntax-nullish-coalescing-operator": "^7.8.0"
+      }
+    },
+    "@babel/plugin-proposal-numeric-separator": {
+      "version": "7.12.5",
+      "resolved": "https://registry.npm.taobao.org/@babel/plugin-proposal-numeric-separator/download/@babel/plugin-proposal-numeric-separator-7.12.5.tgz?cache=0&sync_timestamp=1604441516252&other_urls=https%3A%2F%2Fregistry.npm.taobao.org%2F%40babel%2Fplugin-proposal-numeric-separator%2Fdownload%2F%40babel%2Fplugin-proposal-numeric-separator-7.12.5.tgz",
+      "integrity": "sha1-sc51cVbUDtedWdRnyysVSlxBSbo=",
+      "dev": true,
+      "requires": {
+        "@babel/helper-plugin-utils": "^7.10.4",
+        "@babel/plugin-syntax-numeric-separator": "^7.10.4"
+      }
+    },
+    "@babel/plugin-proposal-object-rest-spread": {
+      "version": "7.12.1",
+      "resolved": "https://registry.npm.taobao.org/@babel/plugin-proposal-object-rest-spread/download/@babel/plugin-proposal-object-rest-spread-7.12.1.tgz?cache=0&sync_timestamp=1602800240952&other_urls=https%3A%2F%2Fregistry.npm.taobao.org%2F%40babel%2Fplugin-proposal-object-rest-spread%2Fdownload%2F%40babel%2Fplugin-proposal-object-rest-spread-7.12.1.tgz",
+      "integrity": "sha1-3vm9A86g+bcig9rA7CLSicdpEGk=",
+      "dev": true,
+      "requires": {
+        "@babel/helper-plugin-utils": "^7.10.4",
+        "@babel/plugin-syntax-object-rest-spread": "^7.8.0",
+        "@babel/plugin-transform-parameters": "^7.12.1"
+      }
+    },
+    "@babel/plugin-proposal-optional-catch-binding": {
+      "version": "7.12.1",
+      "resolved": "https://registry.npm.taobao.org/@babel/plugin-proposal-optional-catch-binding/download/@babel/plugin-proposal-optional-catch-binding-7.12.1.tgz?cache=0&sync_timestamp=1602800232182&other_urls=https%3A%2F%2Fregistry.npm.taobao.org%2F%40babel%2Fplugin-proposal-optional-catch-binding%2Fdownload%2F%40babel%2Fplugin-proposal-optional-catch-binding-7.12.1.tgz",
+      "integrity": "sha1-zMJCGvZNOq5QtVinHO3pKaWrKUI=",
+      "dev": true,
+      "requires": {
+        "@babel/helper-plugin-utils": "^7.10.4",
+        "@babel/plugin-syntax-optional-catch-binding": "^7.8.0"
+      }
+    },
+    "@babel/plugin-proposal-optional-chaining": {
+      "version": "7.12.1",
+      "resolved": "https://registry.npm.taobao.org/@babel/plugin-proposal-optional-chaining/download/@babel/plugin-proposal-optional-chaining-7.12.1.tgz?cache=0&sync_timestamp=1602800241914&other_urls=https%3A%2F%2Fregistry.npm.taobao.org%2F%40babel%2Fplugin-proposal-optional-chaining%2Fdownload%2F%40babel%2Fplugin-proposal-optional-chaining-7.12.1.tgz",
+      "integrity": "sha1-zOEiID/IoyeUKW/Dd8be2vQ2N5c=",
+      "dev": true,
+      "requires": {
+        "@babel/helper-plugin-utils": "^7.10.4",
+        "@babel/helper-skip-transparent-expression-wrappers": "^7.12.1",
+        "@babel/plugin-syntax-optional-chaining": "^7.8.0"
+      }
+    },
+    "@babel/plugin-proposal-pipeline-operator": {
+      "version": "7.12.1",
+      "resolved": "https://registry.npm.taobao.org/@babel/plugin-proposal-pipeline-operator/download/@babel/plugin-proposal-pipeline-operator-7.12.1.tgz?cache=0&sync_timestamp=1602806869343&other_urls=https%3A%2F%2Fregistry.npm.taobao.org%2F%40babel%2Fplugin-proposal-pipeline-operator%2Fdownload%2F%40babel%2Fplugin-proposal-pipeline-operator-7.12.1.tgz",
+      "integrity": "sha1-S9N3vH5b6S8i8cCLPzljY2vY9KE=",
+      "dev": true,
+      "requires": {
+        "@babel/helper-plugin-utils": "^7.10.4",
+        "@babel/plugin-syntax-pipeline-operator": "^7.12.1"
+      }
+    },
+    "@babel/plugin-proposal-private-methods": {
+      "version": "7.12.1",
+      "resolved": "https://registry.npm.taobao.org/@babel/plugin-proposal-private-methods/download/@babel/plugin-proposal-private-methods-7.12.1.tgz?cache=0&sync_timestamp=1602802060750&other_urls=https%3A%2F%2Fregistry.npm.taobao.org%2F%40babel%2Fplugin-proposal-private-methods%2Fdownload%2F%40babel%2Fplugin-proposal-private-methods-7.12.1.tgz",
+      "integrity": "sha1-hoFPbnohN0yYDBDTi0ST5wP0o4k=",
+      "dev": true,
+      "requires": {
+        "@babel/helper-create-class-features-plugin": "^7.12.1",
+        "@babel/helper-plugin-utils": "^7.10.4"
+      }
+    },
+    "@babel/plugin-proposal-throw-expressions": {
+      "version": "7.12.1",
+      "resolved": "https://registry.npm.taobao.org/@babel/plugin-proposal-throw-expressions/download/@babel/plugin-proposal-throw-expressions-7.12.1.tgz",
+      "integrity": "sha1-Wt9KvH80mi2lMuZjs2JR9gF8Qnk=",
+      "dev": true,
+      "requires": {
+        "@babel/helper-plugin-utils": "^7.10.4",
+        "@babel/plugin-syntax-throw-expressions": "^7.12.1"
+      }
+    },
+    "@babel/plugin-proposal-unicode-property-regex": {
+      "version": "7.12.1",
+      "resolved": "https://registry.npm.taobao.org/@babel/plugin-proposal-unicode-property-regex/download/@babel/plugin-proposal-unicode-property-regex-7.12.1.tgz?cache=0&sync_timestamp=1602800241079&other_urls=https%3A%2F%2Fregistry.npm.taobao.org%2F%40babel%2Fplugin-proposal-unicode-property-regex%2Fdownload%2F%40babel%2Fplugin-proposal-unicode-property-regex-7.12.1.tgz",
+      "integrity": "sha1-Khg5WNQXdluerjNPR3WOXWqC4HI=",
+      "dev": true,
+      "requires": {
+        "@babel/helper-create-regexp-features-plugin": "^7.12.1",
+        "@babel/helper-plugin-utils": "^7.10.4"
+      }
+    },
+    "@babel/plugin-syntax-async-generators": {
+      "version": "7.8.4",
+      "resolved": "https://registry.npm.taobao.org/@babel/plugin-syntax-async-generators/download/@babel/plugin-syntax-async-generators-7.8.4.tgz",
+      "integrity": "sha1-qYP7Gusuw/btBCohD2QOkOeG/g0=",
+      "dev": true,
+      "requires": {
+        "@babel/helper-plugin-utils": "^7.8.0"
+      }
+    },
+    "@babel/plugin-syntax-bigint": {
+      "version": "7.8.3",
+      "resolved": "https://registry.npm.taobao.org/@babel/plugin-syntax-bigint/download/@babel/plugin-syntax-bigint-7.8.3.tgz",
+      "integrity": "sha1-TJpvZp9dDN8bkKFnHpoUa+UwDOo=",
+      "dev": true,
+      "requires": {
+        "@babel/helper-plugin-utils": "^7.8.0"
+      }
+    },
+    "@babel/plugin-syntax-class-properties": {
+      "version": "7.12.1",
+      "resolved": "https://registry.npm.taobao.org/@babel/plugin-syntax-class-properties/download/@babel/plugin-syntax-class-properties-7.12.1.tgz?cache=0&sync_timestamp=1602800231971&other_urls=https%3A%2F%2Fregistry.npm.taobao.org%2F%40babel%2Fplugin-syntax-class-properties%2Fdownload%2F%40babel%2Fplugin-syntax-class-properties-7.12.1.tgz",
+      "integrity": "sha1-vLKXxTZueb663vUJVJzZOwTxmXg=",
+      "dev": true,
+      "requires": {
+        "@babel/helper-plugin-utils": "^7.10.4"
+      }
+    },
+    "@babel/plugin-syntax-decorators": {
+      "version": "7.12.1",
+      "resolved": "https://registry.npm.taobao.org/@babel/plugin-syntax-decorators/download/@babel/plugin-syntax-decorators-7.12.1.tgz?cache=0&sync_timestamp=1602800232071&other_urls=https%3A%2F%2Fregistry.npm.taobao.org%2F%40babel%2Fplugin-syntax-decorators%2Fdownload%2F%40babel%2Fplugin-syntax-decorators-7.12.1.tgz",
+      "integrity": "sha1-gai1NbKER2xBvm3gaFOogCuYxd0=",
+      "dev": true,
+      "requires": {
+        "@babel/helper-plugin-utils": "^7.10.4"
+      }
+    },
+    "@babel/plugin-syntax-do-expressions": {
+      "version": "7.12.1",
+      "resolved": "https://registry.npm.taobao.org/@babel/plugin-syntax-do-expressions/download/@babel/plugin-syntax-do-expressions-7.12.1.tgz?cache=0&sync_timestamp=1602806852526&other_urls=https%3A%2F%2Fregistry.npm.taobao.org%2F%40babel%2Fplugin-syntax-do-expressions%2Fdownload%2F%40babel%2Fplugin-syntax-do-expressions-7.12.1.tgz",
+      "integrity": "sha1-a4Pfq3lUC2aRK1WYYM5tS+T32WA=",
+      "dev": true,
+      "requires": {
+        "@babel/helper-plugin-utils": "^7.10.4"
+      }
+    },
+    "@babel/plugin-syntax-dynamic-import": {
+      "version": "7.8.3",
+      "resolved": "https://registry.npm.taobao.org/@babel/plugin-syntax-dynamic-import/download/@babel/plugin-syntax-dynamic-import-7.8.3.tgz",
+      "integrity": "sha1-Yr+Ysto80h1iYVT8lu5bPLaOrLM=",
+      "dev": true,
+      "requires": {
+        "@babel/helper-plugin-utils": "^7.8.0"
+      }
+    },
+    "@babel/plugin-syntax-export-default-from": {
+      "version": "7.12.1",
+      "resolved": "https://registry.npm.taobao.org/@babel/plugin-syntax-export-default-from/download/@babel/plugin-syntax-export-default-from-7.12.1.tgz?cache=0&sync_timestamp=1602806852333&other_urls=https%3A%2F%2Fregistry.npm.taobao.org%2F%40babel%2Fplugin-syntax-export-default-from%2Fdownload%2F%40babel%2Fplugin-syntax-export-default-from-7.12.1.tgz",
+      "integrity": "sha1-qesxiB9PmhEVo9LG1krD9gFrWp0=",
+      "dev": true,
+      "requires": {
+        "@babel/helper-plugin-utils": "^7.10.4"
+      }
+    },
+    "@babel/plugin-syntax-export-namespace-from": {
+      "version": "7.8.3",
+      "resolved": "https://registry.npm.taobao.org/@babel/plugin-syntax-export-namespace-from/download/@babel/plugin-syntax-export-namespace-from-7.8.3.tgz",
+      "integrity": "sha1-AolkqbqA28CUyRXEh618TnpmRlo=",
+      "dev": true,
+      "requires": {
+        "@babel/helper-plugin-utils": "^7.8.3"
+      }
+    },
+    "@babel/plugin-syntax-flow": {
+      "version": "7.12.1",
+      "resolved": "https://registry.npm.taobao.org/@babel/plugin-syntax-flow/download/@babel/plugin-syntax-flow-7.12.1.tgz",
+      "integrity": "sha1-p3Zw2avm1j6Kyt9MMbsetaUGu90=",
+      "dev": true,
+      "requires": {
+        "@babel/helper-plugin-utils": "^7.10.4"
+      }
+    },
+    "@babel/plugin-syntax-function-bind": {
+      "version": "7.12.1",
+      "resolved": "https://registry.npm.taobao.org/@babel/plugin-syntax-function-bind/download/@babel/plugin-syntax-function-bind-7.12.1.tgz?cache=0&sync_timestamp=1602806852726&other_urls=https%3A%2F%2Fregistry.npm.taobao.org%2F%40babel%2Fplugin-syntax-function-bind%2Fdownload%2F%40babel%2Fplugin-syntax-function-bind-7.12.1.tgz",
+      "integrity": "sha1-HhXaPlaMltq+IVefLWaCHbmKr8w=",
+      "dev": true,
+      "requires": {
+        "@babel/helper-plugin-utils": "^7.10.4"
+      }
+    },
+    "@babel/plugin-syntax-function-sent": {
+      "version": "7.12.1",
+      "resolved": "https://registry.npm.taobao.org/@babel/plugin-syntax-function-sent/download/@babel/plugin-syntax-function-sent-7.12.1.tgz",
+      "integrity": "sha1-tTVTBPCw+wyxvzFZA7980TYI6BE=",
+      "dev": true,
+      "requires": {
+        "@babel/helper-plugin-utils": "^7.10.4"
+      }
+    },
+    "@babel/plugin-syntax-import-meta": {
+      "version": "7.10.4",
+      "resolved": "https://registry.npm.taobao.org/@babel/plugin-syntax-import-meta/download/@babel/plugin-syntax-import-meta-7.10.4.tgz",
+      "integrity": "sha1-7mATSMNw+jNNIge+FYd3SWUh/VE=",
+      "dev": true,
+      "requires": {
+        "@babel/helper-plugin-utils": "^7.10.4"
+      }
+    },
+    "@babel/plugin-syntax-json-strings": {
+      "version": "7.8.3",
+      "resolved": "https://registry.npm.taobao.org/@babel/plugin-syntax-json-strings/download/@babel/plugin-syntax-json-strings-7.8.3.tgz",
+      "integrity": "sha1-AcohtmjNghjJ5kDLbdiMVBKyyWo=",
+      "dev": true,
+      "requires": {
+        "@babel/helper-plugin-utils": "^7.8.0"
+      }
+    },
+    "@babel/plugin-syntax-jsx": {
+      "version": "7.12.1",
+      "resolved": "https://registry.npm.taobao.org/@babel/plugin-syntax-jsx/download/@babel/plugin-syntax-jsx-7.12.1.tgz?cache=0&sync_timestamp=1602800233054&other_urls=https%3A%2F%2Fregistry.npm.taobao.org%2F%40babel%2Fplugin-syntax-jsx%2Fdownload%2F%40babel%2Fplugin-syntax-jsx-7.12.1.tgz",
+      "integrity": "sha1-nZ01fMgYqnrnk1kXwSV/Z2d6CSY=",
+      "dev": true,
+      "requires": {
+        "@babel/helper-plugin-utils": "^7.10.4"
+      }
+    },
+    "@babel/plugin-syntax-logical-assignment-operators": {
+      "version": "7.10.4",
+      "resolved": "https://registry.npm.taobao.org/@babel/plugin-syntax-logical-assignment-operators/download/@babel/plugin-syntax-logical-assignment-operators-7.10.4.tgz?cache=0&sync_timestamp=1593522961558&other_urls=https%3A%2F%2Fregistry.npm.taobao.org%2F%40babel%2Fplugin-syntax-logical-assignment-operators%2Fdownload%2F%40babel%2Fplugin-syntax-logical-assignment-operators-7.10.4.tgz",
+      "integrity": "sha1-ypHvRjA1MESLkGZSusLp/plB9pk=",
+      "dev": true,
+      "requires": {
+        "@babel/helper-plugin-utils": "^7.10.4"
+      }
+    },
+    "@babel/plugin-syntax-nullish-coalescing-operator": {
+      "version": "7.8.3",
+      "resolved": "https://registry.npm.taobao.org/@babel/plugin-syntax-nullish-coalescing-operator/download/@babel/plugin-syntax-nullish-coalescing-operator-7.8.3.tgz",
+      "integrity": "sha1-Fn7XA2iIYIH3S1w2xlqIwDtm0ak=",
+      "dev": true,
+      "requires": {
+        "@babel/helper-plugin-utils": "^7.8.0"
+      }
+    },
+    "@babel/plugin-syntax-numeric-separator": {
+      "version": "7.10.4",
+      "resolved": "https://registry.npm.taobao.org/@babel/plugin-syntax-numeric-separator/download/@babel/plugin-syntax-numeric-separator-7.10.4.tgz?cache=0&sync_timestamp=1593521806492&other_urls=https%3A%2F%2Fregistry.npm.taobao.org%2F%40babel%2Fplugin-syntax-numeric-separator%2Fdownload%2F%40babel%2Fplugin-syntax-numeric-separator-7.10.4.tgz",
+      "integrity": "sha1-ubBws+M1cM2f0Hun+pHA3Te5r5c=",
+      "dev": true,
+      "requires": {
+        "@babel/helper-plugin-utils": "^7.10.4"
+      }
+    },
+    "@babel/plugin-syntax-object-rest-spread": {
+      "version": "7.8.3",
+      "resolved": "https://registry.npm.taobao.org/@babel/plugin-syntax-object-rest-spread/download/@babel/plugin-syntax-object-rest-spread-7.8.3.tgz",
+      "integrity": "sha1-YOIl7cvZimQDMqLnLdPmbxr1WHE=",
+      "dev": true,
+      "requires": {
+        "@babel/helper-plugin-utils": "^7.8.0"
+      }
+    },
+    "@babel/plugin-syntax-optional-catch-binding": {
+      "version": "7.8.3",
+      "resolved": "https://registry.npm.taobao.org/@babel/plugin-syntax-optional-catch-binding/download/@babel/plugin-syntax-optional-catch-binding-7.8.3.tgz",
+      "integrity": "sha1-YRGiZbz7Ag6579D9/X0mQCue1sE=",
+      "dev": true,
+      "requires": {
+        "@babel/helper-plugin-utils": "^7.8.0"
+      }
+    },
+    "@babel/plugin-syntax-optional-chaining": {
+      "version": "7.8.3",
+      "resolved": "https://registry.npm.taobao.org/@babel/plugin-syntax-optional-chaining/download/@babel/plugin-syntax-optional-chaining-7.8.3.tgz",
+      "integrity": "sha1-T2nCq5UWfgGAzVM2YT+MV4j31Io=",
+      "dev": true,
+      "requires": {
+        "@babel/helper-plugin-utils": "^7.8.0"
+      }
+    },
+    "@babel/plugin-syntax-pipeline-operator": {
+      "version": "7.12.1",
+      "resolved": "https://registry.npm.taobao.org/@babel/plugin-syntax-pipeline-operator/download/@babel/plugin-syntax-pipeline-operator-7.12.1.tgz?cache=0&sync_timestamp=1602806853081&other_urls=https%3A%2F%2Fregistry.npm.taobao.org%2F%40babel%2Fplugin-syntax-pipeline-operator%2Fdownload%2F%40babel%2Fplugin-syntax-pipeline-operator-7.12.1.tgz",
+      "integrity": "sha1-YYbx1f64bTFakgpQVqhsmRv0t/Q=",
+      "dev": true,
+      "requires": {
+        "@babel/helper-plugin-utils": "^7.10.4"
+      }
+    },
+    "@babel/plugin-syntax-throw-expressions": {
+      "version": "7.12.1",
+      "resolved": "https://registry.npm.taobao.org/@babel/plugin-syntax-throw-expressions/download/@babel/plugin-syntax-throw-expressions-7.12.1.tgz",
+      "integrity": "sha1-/5ClesWZumhamSdMhmBNh4yUUJQ=",
+      "dev": true,
+      "requires": {
+        "@babel/helper-plugin-utils": "^7.10.4"
+      }
+    },
+    "@babel/plugin-syntax-top-level-await": {
+      "version": "7.12.1",
+      "resolved": "https://registry.npm.taobao.org/@babel/plugin-syntax-top-level-await/download/@babel/plugin-syntax-top-level-await-7.12.1.tgz?cache=0&sync_timestamp=1602800233145&other_urls=https%3A%2F%2Fregistry.npm.taobao.org%2F%40babel%2Fplugin-syntax-top-level-await%2Fdownload%2F%40babel%2Fplugin-syntax-top-level-await-7.12.1.tgz",
+      "integrity": "sha1-3WwLNXrBuxQtmFN0UKMZYl0T0qA=",
+      "dev": true,
+      "requires": {
+        "@babel/helper-plugin-utils": "^7.10.4"
+      }
+    },
+    "@babel/plugin-syntax-typescript": {
+      "version": "7.12.1",
+      "resolved": "https://registry.npm.taobao.org/@babel/plugin-syntax-typescript/download/@babel/plugin-syntax-typescript-7.12.1.tgz",
+      "integrity": "sha1-Rgup13B3ZTgDw90uZz921mtAKeU=",
+      "dev": true,
+      "requires": {
+        "@babel/helper-plugin-utils": "^7.10.4"
+      }
+    },
+    "@babel/plugin-transform-arrow-functions": {
+      "version": "7.12.1",
+      "resolved": "https://registry.npm.taobao.org/@babel/plugin-transform-arrow-functions/download/@babel/plugin-transform-arrow-functions-7.12.1.tgz?cache=0&sync_timestamp=1602800233566&other_urls=https%3A%2F%2Fregistry.npm.taobao.org%2F%40babel%2Fplugin-transform-arrow-functions%2Fdownload%2F%40babel%2Fplugin-transform-arrow-functions-7.12.1.tgz",
+      "integrity": "sha1-gIP/yGrI53f74ktZZ8SyUh88srM=",
+      "dev": true,
+      "requires": {
+        "@babel/helper-plugin-utils": "^7.10.4"
+      }
+    },
+    "@babel/plugin-transform-async-to-generator": {
+      "version": "7.12.1",
+      "resolved": "https://registry.npm.taobao.org/@babel/plugin-transform-async-to-generator/download/@babel/plugin-transform-async-to-generator-7.12.1.tgz?cache=0&sync_timestamp=1602800242155&other_urls=https%3A%2F%2Fregistry.npm.taobao.org%2F%40babel%2Fplugin-transform-async-to-generator%2Fdownload%2F%40babel%2Fplugin-transform-async-to-generator-7.12.1.tgz",
+      "integrity": "sha1-OEmknMKiLpdDy9a1KSbTAzcimvE=",
+      "dev": true,
+      "requires": {
+        "@babel/helper-module-imports": "^7.12.1",
+        "@babel/helper-plugin-utils": "^7.10.4",
+        "@babel/helper-remap-async-to-generator": "^7.12.1"
+      }
+    },
+    "@babel/plugin-transform-block-scoped-functions": {
+      "version": "7.12.1",
+      "resolved": "https://registry.npm.taobao.org/@babel/plugin-transform-block-scoped-functions/download/@babel/plugin-transform-block-scoped-functions-7.12.1.tgz?cache=0&sync_timestamp=1602800233803&other_urls=https%3A%2F%2Fregistry.npm.taobao.org%2F%40babel%2Fplugin-transform-block-scoped-functions%2Fdownload%2F%40babel%2Fplugin-transform-block-scoped-functions-7.12.1.tgz",
+      "integrity": "sha1-8qGjZb3itxEuCm3tkGf918B5Bdk=",
+      "dev": true,
+      "requires": {
+        "@babel/helper-plugin-utils": "^7.10.4"
+      }
+    },
+    "@babel/plugin-transform-block-scoping": {
+      "version": "7.12.1",
+      "resolved": "https://registry.npm.taobao.org/@babel/plugin-transform-block-scoping/download/@babel/plugin-transform-block-scoping-7.12.1.tgz?cache=0&sync_timestamp=1602800233459&other_urls=https%3A%2F%2Fregistry.npm.taobao.org%2F%40babel%2Fplugin-transform-block-scoping%2Fdownload%2F%40babel%2Fplugin-transform-block-scoping-7.12.1.tgz",
+      "integrity": "sha1-8O5yeHS0KiCKSKWGuEw9IiwrvvE=",
+      "dev": true,
+      "requires": {
+        "@babel/helper-plugin-utils": "^7.10.4"
+      }
+    },
+    "@babel/plugin-transform-classes": {
+      "version": "7.12.1",
+      "resolved": "https://registry.npm.taobao.org/@babel/plugin-transform-classes/download/@babel/plugin-transform-classes-7.12.1.tgz?cache=0&sync_timestamp=1602802059995&other_urls=https%3A%2F%2Fregistry.npm.taobao.org%2F%40babel%2Fplugin-transform-classes%2Fdownload%2F%40babel%2Fplugin-transform-classes-7.12.1.tgz",
+      "integrity": "sha1-ZeZQ/K3dPYjdzmfA+DSj1DajLbY=",
+      "dev": true,
+      "requires": {
+        "@babel/helper-annotate-as-pure": "^7.10.4",
+        "@babel/helper-define-map": "^7.10.4",
+        "@babel/helper-function-name": "^7.10.4",
+        "@babel/helper-optimise-call-expression": "^7.10.4",
+        "@babel/helper-plugin-utils": "^7.10.4",
+        "@babel/helper-replace-supers": "^7.12.1",
+        "@babel/helper-split-export-declaration": "^7.10.4",
+        "globals": "^11.1.0"
+      }
+    },
+    "@babel/plugin-transform-computed-properties": {
+      "version": "7.12.1",
+      "resolved": "https://registry.npm.taobao.org/@babel/plugin-transform-computed-properties/download/@babel/plugin-transform-computed-properties-7.12.1.tgz?cache=0&sync_timestamp=1602800233906&other_urls=https%3A%2F%2Fregistry.npm.taobao.org%2F%40babel%2Fplugin-transform-computed-properties%2Fdownload%2F%40babel%2Fplugin-transform-computed-properties-7.12.1.tgz",
+      "integrity": "sha1-1oz2ybf4OKikFEutvpdUHqCQSFI=",
+      "dev": true,
+      "requires": {
+        "@babel/helper-plugin-utils": "^7.10.4"
+      }
+    },
+    "@babel/plugin-transform-destructuring": {
+      "version": "7.12.1",
+      "resolved": "https://registry.npm.taobao.org/@babel/plugin-transform-destructuring/download/@babel/plugin-transform-destructuring-7.12.1.tgz?cache=0&sync_timestamp=1602800233701&other_urls=https%3A%2F%2Fregistry.npm.taobao.org%2F%40babel%2Fplugin-transform-destructuring%2Fdownload%2F%40babel%2Fplugin-transform-destructuring-7.12.1.tgz",
+      "integrity": "sha1-uaVw/g0KjUYBFkE8tPl+jgiy+Ec=",
+      "dev": true,
+      "requires": {
+        "@babel/helper-plugin-utils": "^7.10.4"
+      }
+    },
+    "@babel/plugin-transform-dotall-regex": {
+      "version": "7.12.1",
+      "resolved": "https://registry.npm.taobao.org/@babel/plugin-transform-dotall-regex/download/@babel/plugin-transform-dotall-regex-7.12.1.tgz?cache=0&sync_timestamp=1602800241190&other_urls=https%3A%2F%2Fregistry.npm.taobao.org%2F%40babel%2Fplugin-transform-dotall-regex%2Fdownload%2F%40babel%2Fplugin-transform-dotall-regex-7.12.1.tgz",
+      "integrity": "sha1-odFsFIYoF7ZAnApnjW+Tc8qc2XU=",
+      "dev": true,
+      "requires": {
+        "@babel/helper-create-regexp-features-plugin": "^7.12.1",
+        "@babel/helper-plugin-utils": "^7.10.4"
+      }
+    },
+    "@babel/plugin-transform-duplicate-keys": {
+      "version": "7.12.1",
+      "resolved": "https://registry.npm.taobao.org/@babel/plugin-transform-duplicate-keys/download/@babel/plugin-transform-duplicate-keys-7.12.1.tgz?cache=0&sync_timestamp=1602800235384&other_urls=https%3A%2F%2Fregistry.npm.taobao.org%2F%40babel%2Fplugin-transform-duplicate-keys%2Fdownload%2F%40babel%2Fplugin-transform-duplicate-keys-7.12.1.tgz",
+      "integrity": "sha1-dFZhuropWsBuaGgieXpp+6osoig=",
+      "dev": true,
+      "requires": {
+        "@babel/helper-plugin-utils": "^7.10.4"
+      }
+    },
+    "@babel/plugin-transform-exponentiation-operator": {
+      "version": "7.12.1",
+      "resolved": "https://registry.npm.taobao.org/@babel/plugin-transform-exponentiation-operator/download/@babel/plugin-transform-exponentiation-operator-7.12.1.tgz?cache=0&sync_timestamp=1602800235495&other_urls=https%3A%2F%2Fregistry.npm.taobao.org%2F%40babel%2Fplugin-transform-exponentiation-operator%2Fdownload%2F%40babel%2Fplugin-transform-exponentiation-operator-7.12.1.tgz",
+      "integrity": "sha1-sPLtNWuhvhQo7K8Sj/iiTwKDCuA=",
+      "dev": true,
+      "requires": {
+        "@babel/helper-builder-binary-assignment-operator-visitor": "^7.10.4",
+        "@babel/helper-plugin-utils": "^7.10.4"
+      }
+    },
+    "@babel/plugin-transform-flow-strip-types": {
+      "version": "7.12.1",
+      "resolved": "https://registry.npm.taobao.org/@babel/plugin-transform-flow-strip-types/download/@babel/plugin-transform-flow-strip-types-7.12.1.tgz",
+      "integrity": "sha1-hDDez6frKupUFO1KP6bhZSt9d8Q=",
+      "dev": true,
+      "requires": {
+        "@babel/helper-plugin-utils": "^7.10.4",
+        "@babel/plugin-syntax-flow": "^7.12.1"
+      }
+    },
+    "@babel/plugin-transform-for-of": {
+      "version": "7.12.1",
+      "resolved": "https://registry.npm.taobao.org/@babel/plugin-transform-for-of/download/@babel/plugin-transform-for-of-7.12.1.tgz?cache=0&sync_timestamp=1602800234012&other_urls=https%3A%2F%2Fregistry.npm.taobao.org%2F%40babel%2Fplugin-transform-for-of%2Fdownload%2F%40babel%2Fplugin-transform-for-of-7.12.1.tgz",
+      "integrity": "sha1-B2QPKIZ+0W+VEcmciIKR9WCSHPo=",
+      "dev": true,
+      "requires": {
+        "@babel/helper-plugin-utils": "^7.10.4"
+      }
+    },
+    "@babel/plugin-transform-function-name": {
+      "version": "7.12.1",
+      "resolved": "https://registry.npm.taobao.org/@babel/plugin-transform-function-name/download/@babel/plugin-transform-function-name-7.12.1.tgz?cache=0&sync_timestamp=1602800234134&other_urls=https%3A%2F%2Fregistry.npm.taobao.org%2F%40babel%2Fplugin-transform-function-name%2Fdownload%2F%40babel%2Fplugin-transform-function-name-7.12.1.tgz",
+      "integrity": "sha1-LsdiWMcP4IxtfaFUADpIBiDrpmc=",
+      "dev": true,
+      "requires": {
+        "@babel/helper-function-name": "^7.10.4",
+        "@babel/helper-plugin-utils": "^7.10.4"
+      }
+    },
+    "@babel/plugin-transform-literals": {
+      "version": "7.12.1",
+      "resolved": "https://registry.npm.taobao.org/@babel/plugin-transform-literals/download/@babel/plugin-transform-literals-7.12.1.tgz?cache=0&sync_timestamp=1602800235597&other_urls=https%3A%2F%2Fregistry.npm.taobao.org%2F%40babel%2Fplugin-transform-literals%2Fdownload%2F%40babel%2Fplugin-transform-literals-7.12.1.tgz",
+      "integrity": "sha1-1zuAOiazcBfd+dO7j03Fi/uAb1c=",
+      "dev": true,
+      "requires": {
+        "@babel/helper-plugin-utils": "^7.10.4"
+      }
+    },
+    "@babel/plugin-transform-member-expression-literals": {
+      "version": "7.12.1",
+      "resolved": "https://registry.npm.taobao.org/@babel/plugin-transform-member-expression-literals/download/@babel/plugin-transform-member-expression-literals-7.12.1.tgz?cache=0&sync_timestamp=1602800235819&other_urls=https%3A%2F%2Fregistry.npm.taobao.org%2F%40babel%2Fplugin-transform-member-expression-literals%2Fdownload%2F%40babel%2Fplugin-transform-member-expression-literals-7.12.1.tgz",
+      "integrity": "sha1-SWA4YC2vFRSmTUPY4Xy7J1Xgw60=",
+      "dev": true,
+      "requires": {
+        "@babel/helper-plugin-utils": "^7.10.4"
+      }
+    },
+    "@babel/plugin-transform-modules-amd": {
+      "version": "7.12.1",
+      "resolved": "https://registry.npm.taobao.org/@babel/plugin-transform-modules-amd/download/@babel/plugin-transform-modules-amd-7.12.1.tgz?cache=0&sync_timestamp=1602802064278&other_urls=https%3A%2F%2Fregistry.npm.taobao.org%2F%40babel%2Fplugin-transform-modules-amd%2Fdownload%2F%40babel%2Fplugin-transform-modules-amd-7.12.1.tgz",
+      "integrity": "sha1-MVQwCwJhhWZu67DA7X+EFf789vk=",
+      "dev": true,
+      "requires": {
+        "@babel/helper-module-transforms": "^7.12.1",
+        "@babel/helper-plugin-utils": "^7.10.4",
+        "babel-plugin-dynamic-import-node": "^2.3.3"
+      }
+    },
+    "@babel/plugin-transform-modules-commonjs": {
+      "version": "7.12.1",
+      "resolved": "https://registry.npm.taobao.org/@babel/plugin-transform-modules-commonjs/download/@babel/plugin-transform-modules-commonjs-7.12.1.tgz?cache=0&sync_timestamp=1602802063892&other_urls=https%3A%2F%2Fregistry.npm.taobao.org%2F%40babel%2Fplugin-transform-modules-commonjs%2Fdownload%2F%40babel%2Fplugin-transform-modules-commonjs-7.12.1.tgz",
+      "integrity": "sha1-+kAxJFQmNseGz5tGCg/7tIqG5kg=",
+      "dev": true,
+      "requires": {
+        "@babel/helper-module-transforms": "^7.12.1",
+        "@babel/helper-plugin-utils": "^7.10.4",
+        "@babel/helper-simple-access": "^7.12.1",
+        "babel-plugin-dynamic-import-node": "^2.3.3"
+      }
+    },
+    "@babel/plugin-transform-modules-systemjs": {
+      "version": "7.12.1",
+      "resolved": "https://registry.npm.taobao.org/@babel/plugin-transform-modules-systemjs/download/@babel/plugin-transform-modules-systemjs-7.12.1.tgz?cache=0&sync_timestamp=1602802063412&other_urls=https%3A%2F%2Fregistry.npm.taobao.org%2F%40babel%2Fplugin-transform-modules-systemjs%2Fdownload%2F%40babel%2Fplugin-transform-modules-systemjs-7.12.1.tgz",
+      "integrity": "sha1-Zj/qYg1ZPJPyFKRkzTmb9txoMIY=",
+      "dev": true,
+      "requires": {
+        "@babel/helper-hoist-variables": "^7.10.4",
+        "@babel/helper-module-transforms": "^7.12.1",
+        "@babel/helper-plugin-utils": "^7.10.4",
+        "@babel/helper-validator-identifier": "^7.10.4",
+        "babel-plugin-dynamic-import-node": "^2.3.3"
+      }
+    },
+    "@babel/plugin-transform-modules-umd": {
+      "version": "7.12.1",
+      "resolved": "https://registry.npm.taobao.org/@babel/plugin-transform-modules-umd/download/@babel/plugin-transform-modules-umd-7.12.1.tgz?cache=0&sync_timestamp=1602802064711&other_urls=https%3A%2F%2Fregistry.npm.taobao.org%2F%40babel%2Fplugin-transform-modules-umd%2Fdownload%2F%40babel%2Fplugin-transform-modules-umd-7.12.1.tgz",
+      "integrity": "sha1-61ohjWscaPPWIXuPosyC/sZUeQI=",
+      "dev": true,
+      "requires": {
+        "@babel/helper-module-transforms": "^7.12.1",
+        "@babel/helper-plugin-utils": "^7.10.4"
+      }
+    },
+    "@babel/plugin-transform-named-capturing-groups-regex": {
+      "version": "7.12.1",
+      "resolved": "https://registry.npm.taobao.org/@babel/plugin-transform-named-capturing-groups-regex/download/@babel/plugin-transform-named-capturing-groups-regex-7.12.1.tgz?cache=0&sync_timestamp=1602800241290&other_urls=https%3A%2F%2Fregistry.npm.taobao.org%2F%40babel%2Fplugin-transform-named-capturing-groups-regex%2Fdownload%2F%40babel%2Fplugin-transform-named-capturing-groups-regex-7.12.1.tgz",
+      "integrity": "sha1-tAf1yWvg2fX4hGdJf6grMKw+h1M=",
+      "dev": true,
+      "requires": {
+        "@babel/helper-create-regexp-features-plugin": "^7.12.1"
+      }
+    },
+    "@babel/plugin-transform-new-target": {
+      "version": "7.12.1",
+      "resolved": "https://registry.npm.taobao.org/@babel/plugin-transform-new-target/download/@babel/plugin-transform-new-target-7.12.1.tgz?cache=0&sync_timestamp=1602800235712&other_urls=https%3A%2F%2Fregistry.npm.taobao.org%2F%40babel%2Fplugin-transform-new-target%2Fdownload%2F%40babel%2Fplugin-transform-new-target-7.12.1.tgz",
+      "integrity": "sha1-gAc/Au4bstNlw0FkkOCFyVdZ3sA=",
+      "dev": true,
+      "requires": {
+        "@babel/helper-plugin-utils": "^7.10.4"
+      }
+    },
+    "@babel/plugin-transform-object-super": {
+      "version": "7.12.1",
+      "resolved": "https://registry.npm.taobao.org/@babel/plugin-transform-object-super/download/@babel/plugin-transform-object-super-7.12.1.tgz?cache=0&sync_timestamp=1602802058628&other_urls=https%3A%2F%2Fregistry.npm.taobao.org%2F%40babel%2Fplugin-transform-object-super%2Fdownload%2F%40babel%2Fplugin-transform-object-super-7.12.1.tgz",
+      "integrity": "sha1-TqCGlrjS5lhB0MdwZIKwSL7RBm4=",
+      "dev": true,
+      "requires": {
+        "@babel/helper-plugin-utils": "^7.10.4",
+        "@babel/helper-replace-supers": "^7.12.1"
+      }
+    },
+    "@babel/plugin-transform-parameters": {
+      "version": "7.12.1",
+      "resolved": "https://registry.npm.taobao.org/@babel/plugin-transform-parameters/download/@babel/plugin-transform-parameters-7.12.1.tgz?cache=0&sync_timestamp=1602800236149&other_urls=https%3A%2F%2Fregistry.npm.taobao.org%2F%40babel%2Fplugin-transform-parameters%2Fdownload%2F%40babel%2Fplugin-transform-parameters-7.12.1.tgz",
+      "integrity": "sha1-0uljsDh3FlDJIu/1k3mclthTJV0=",
+      "dev": true,
+      "requires": {
+        "@babel/helper-plugin-utils": "^7.10.4"
+      }
+    },
+    "@babel/plugin-transform-property-literals": {
+      "version": "7.12.1",
+      "resolved": "https://registry.npm.taobao.org/@babel/plugin-transform-property-literals/download/@babel/plugin-transform-property-literals-7.12.1.tgz?cache=0&sync_timestamp=1602800236036&other_urls=https%3A%2F%2Fregistry.npm.taobao.org%2F%40babel%2Fplugin-transform-property-literals%2Fdownload%2F%40babel%2Fplugin-transform-property-literals-7.12.1.tgz",
+      "integrity": "sha1-QbyBIA1zCrtEVquLP71VN7Wa3s0=",
+      "dev": true,
+      "requires": {
+        "@babel/helper-plugin-utils": "^7.10.4"
+      }
+    },
+    "@babel/plugin-transform-react-display-name": {
+      "version": "7.12.1",
+      "resolved": "https://registry.npm.taobao.org/@babel/plugin-transform-react-display-name/download/@babel/plugin-transform-react-display-name-7.12.1.tgz",
+      "integrity": "sha1-HLzQw7HWZIxVN0oi/JtrflNBwA0=",
+      "dev": true,
+      "requires": {
+        "@babel/helper-plugin-utils": "^7.10.4"
+      }
+    },
+    "@babel/plugin-transform-react-jsx": {
+      "version": "7.12.5",
+      "resolved": "https://registry.npm.taobao.org/@babel/plugin-transform-react-jsx/download/@babel/plugin-transform-react-jsx-7.12.5.tgz?cache=0&sync_timestamp=1604441239750&other_urls=https%3A%2F%2Fregistry.npm.taobao.org%2F%40babel%2Fplugin-transform-react-jsx%2Fdownload%2F%40babel%2Fplugin-transform-react-jsx-7.12.5.tgz",
+      "integrity": "sha1-Oe3g4wFZdwVhtpY74UPkCvO94Aw=",
+      "dev": true,
+      "requires": {
+        "@babel/helper-builder-react-jsx": "^7.10.4",
+        "@babel/helper-builder-react-jsx-experimental": "^7.12.1",
+        "@babel/helper-plugin-utils": "^7.10.4",
+        "@babel/plugin-syntax-jsx": "^7.12.1"
+      }
+    },
+    "@babel/plugin-transform-react-jsx-development": {
+      "version": "7.12.5",
+      "resolved": "https://registry.npm.taobao.org/@babel/plugin-transform-react-jsx-development/download/@babel/plugin-transform-react-jsx-development-7.12.5.tgz",
+      "integrity": "sha1-Z33luW2jEEMNbPt/7hahYDr6PVY=",
+      "dev": true,
+      "requires": {
+        "@babel/helper-builder-react-jsx-experimental": "^7.12.1",
+        "@babel/helper-plugin-utils": "^7.10.4",
+        "@babel/plugin-syntax-jsx": "^7.12.1"
+      }
+    },
+    "@babel/plugin-transform-react-jsx-self": {
+      "version": "7.12.1",
+      "resolved": "https://registry.npm.taobao.org/@babel/plugin-transform-react-jsx-self/download/@babel/plugin-transform-react-jsx-self-7.12.1.tgz",
+      "integrity": "sha1-70PLyioU8b0XgH2+Q3b/idcUzyg=",
+      "dev": true,
+      "requires": {
+        "@babel/helper-plugin-utils": "^7.10.4"
+      }
+    },
+    "@babel/plugin-transform-react-jsx-source": {
+      "version": "7.12.1",
+      "resolved": "https://registry.npm.taobao.org/@babel/plugin-transform-react-jsx-source/download/@babel/plugin-transform-react-jsx-source-7.12.1.tgz",
+      "integrity": "sha1-0H3mhj9GjaCAntz3mhqoziqComs=",
+      "dev": true,
+      "requires": {
+        "@babel/helper-plugin-utils": "^7.10.4"
+      }
+    },
+    "@babel/plugin-transform-react-pure-annotations": {
+      "version": "7.12.1",
+      "resolved": "https://registry.npm.taobao.org/@babel/plugin-transform-react-pure-annotations/download/@babel/plugin-transform-react-pure-annotations-7.12.1.tgz",
+      "integrity": "sha1-BdRvCrTRM5rFmt8goUYskbN6GkI=",
+      "dev": true,
+      "requires": {
+        "@babel/helper-annotate-as-pure": "^7.10.4",
+        "@babel/helper-plugin-utils": "^7.10.4"
+      }
+    },
+    "@babel/plugin-transform-regenerator": {
+      "version": "7.12.1",
+      "resolved": "https://registry.npm.taobao.org/@babel/plugin-transform-regenerator/download/@babel/plugin-transform-regenerator-7.12.1.tgz?cache=0&sync_timestamp=1602800236618&other_urls=https%3A%2F%2Fregistry.npm.taobao.org%2F%40babel%2Fplugin-transform-regenerator%2Fdownload%2F%40babel%2Fplugin-transform-regenerator-7.12.1.tgz",
+      "integrity": "sha1-Xwoo2EL2RiKB8GqWToi6jXq0l1M=",
+      "dev": true,
+      "requires": {
+        "regenerator-transform": "^0.14.2"
+      }
+    },
+    "@babel/plugin-transform-reserved-words": {
+      "version": "7.12.1",
+      "resolved": "https://registry.npm.taobao.org/@babel/plugin-transform-reserved-words/download/@babel/plugin-transform-reserved-words-7.12.1.tgz?cache=0&sync_timestamp=1602800236807&other_urls=https%3A%2F%2Fregistry.npm.taobao.org%2F%40babel%2Fplugin-transform-reserved-words%2Fdownload%2F%40babel%2Fplugin-transform-reserved-words-7.12.1.tgz",
+      "integrity": "sha1-b9/IzH7cxCs2p8EhiMZ4fIc63Ng=",
+      "dev": true,
+      "requires": {
+        "@babel/helper-plugin-utils": "^7.10.4"
+      }
+    },
+    "@babel/plugin-transform-runtime": {
+      "version": "7.12.1",
+      "resolved": "https://registry.npm.taobao.org/@babel/plugin-transform-runtime/download/@babel/plugin-transform-runtime-7.12.1.tgz?cache=0&sync_timestamp=1602800227616&other_urls=https%3A%2F%2Fregistry.npm.taobao.org%2F%40babel%2Fplugin-transform-runtime%2Fdownload%2F%40babel%2Fplugin-transform-runtime-7.12.1.tgz",
+      "integrity": "sha1-BLeSBX60YDif9qQZjjd2FOoee6U=",
+      "dev": true,
+      "requires": {
+        "@babel/helper-module-imports": "^7.12.1",
+        "@babel/helper-plugin-utils": "^7.10.4",
+        "resolve": "^1.8.1",
+        "semver": "^5.5.1"
+      },
+      "dependencies": {
+        "semver": {
+          "version": "5.7.1",
+          "resolved": "https://registry.npm.taobao.org/semver/download/semver-5.7.1.tgz",
+          "integrity": "sha1-qVT5Ma66UI0we78Gnv8MAclhFvc=",
+          "dev": true
+        }
+      }
+    },
+    "@babel/plugin-transform-shorthand-properties": {
+      "version": "7.12.1",
+      "resolved": "https://registry.npm.taobao.org/@babel/plugin-transform-shorthand-properties/download/@babel/plugin-transform-shorthand-properties-7.12.1.tgz?cache=0&sync_timestamp=1602800237133&other_urls=https%3A%2F%2Fregistry.npm.taobao.org%2F%40babel%2Fplugin-transform-shorthand-properties%2Fdownload%2F%40babel%2Fplugin-transform-shorthand-properties-7.12.1.tgz",
+      "integrity": "sha1-C/nKxVUPzgz98ENCD2YdZF/cdeM=",
+      "dev": true,
+      "requires": {
+        "@babel/helper-plugin-utils": "^7.10.4"
+      }
+    },
+    "@babel/plugin-transform-spread": {
+      "version": "7.12.1",
+      "resolved": "https://registry.npm.taobao.org/@babel/plugin-transform-spread/download/@babel/plugin-transform-spread-7.12.1.tgz?cache=0&sync_timestamp=1602800242265&other_urls=https%3A%2F%2Fregistry.npm.taobao.org%2F%40babel%2Fplugin-transform-spread%2Fdownload%2F%40babel%2Fplugin-transform-spread-7.12.1.tgz",
+      "integrity": "sha1-Un+fMRvk7H/cK3m7ife/iEs+Hh4=",
+      "dev": true,
+      "requires": {
+        "@babel/helper-plugin-utils": "^7.10.4",
+        "@babel/helper-skip-transparent-expression-wrappers": "^7.12.1"
+      }
+    },
+    "@babel/plugin-transform-sticky-regex": {
+      "version": "7.12.1",
+      "resolved": "https://registry.npm.taobao.org/@babel/plugin-transform-sticky-regex/download/@babel/plugin-transform-sticky-regex-7.12.1.tgz?cache=0&sync_timestamp=1602800237248&other_urls=https%3A%2F%2Fregistry.npm.taobao.org%2F%40babel%2Fplugin-transform-sticky-regex%2Fdownload%2F%40babel%2Fplugin-transform-sticky-regex-7.12.1.tgz",
+      "integrity": "sha1-XCTPUN45bTDpmvyNHHAOi84PXK8=",
+      "dev": true,
+      "requires": {
+        "@babel/helper-plugin-utils": "^7.10.4",
+        "@babel/helper-regex": "^7.10.4"
+      }
+    },
+    "@babel/plugin-transform-template-literals": {
+      "version": "7.12.1",
+      "resolved": "https://registry.npm.taobao.org/@babel/plugin-transform-template-literals/download/@babel/plugin-transform-template-literals-7.12.1.tgz?cache=0&sync_timestamp=1602800237453&other_urls=https%3A%2F%2Fregistry.npm.taobao.org%2F%40babel%2Fplugin-transform-template-literals%2Fdownload%2F%40babel%2Fplugin-transform-template-literals-7.12.1.tgz",
+      "integrity": "sha1-tD7ObtmnnAxxEZ9XbSme8J2UKEM=",
+      "dev": true,
+      "requires": {
+        "@babel/helper-plugin-utils": "^7.10.4"
+      }
+    },
+    "@babel/plugin-transform-typeof-symbol": {
+      "version": "7.12.1",
+      "resolved": "https://registry.npm.taobao.org/@babel/plugin-transform-typeof-symbol/download/@babel/plugin-transform-typeof-symbol-7.12.1.tgz?cache=0&sync_timestamp=1602800237638&other_urls=https%3A%2F%2Fregistry.npm.taobao.org%2F%40babel%2Fplugin-transform-typeof-symbol%2Fdownload%2F%40babel%2Fplugin-transform-typeof-symbol-7.12.1.tgz",
+      "integrity": "sha1-nKa+ND1CUS+8LmgjaoKuZLx694o=",
+      "dev": true,
+      "requires": {
+        "@babel/helper-plugin-utils": "^7.10.4"
+      }
+    },
+    "@babel/plugin-transform-typescript": {
+      "version": "7.12.1",
+      "resolved": "https://registry.npm.taobao.org/@babel/plugin-transform-typescript/download/@babel/plugin-transform-typescript-7.12.1.tgz?cache=0&sync_timestamp=1602802164420&other_urls=https%3A%2F%2Fregistry.npm.taobao.org%2F%40babel%2Fplugin-transform-typescript%2Fdownload%2F%40babel%2Fplugin-transform-typescript-7.12.1.tgz",
+      "integrity": "sha1-2SzAr1BNUQ4mp1Sn28LlyM2cerQ=",
+      "dev": true,
+      "requires": {
+        "@babel/helper-create-class-features-plugin": "^7.12.1",
+        "@babel/helper-plugin-utils": "^7.10.4",
+        "@babel/plugin-syntax-typescript": "^7.12.1"
+      }
+    },
+    "@babel/plugin-transform-unicode-escapes": {
+      "version": "7.12.1",
+      "resolved": "https://registry.npm.taobao.org/@babel/plugin-transform-unicode-escapes/download/@babel/plugin-transform-unicode-escapes-7.12.1.tgz?cache=0&sync_timestamp=1602800237534&other_urls=https%3A%2F%2Fregistry.npm.taobao.org%2F%40babel%2Fplugin-transform-unicode-escapes%2Fdownload%2F%40babel%2Fplugin-transform-unicode-escapes-7.12.1.tgz",
+      "integrity": "sha1-UjK5+BzLBwcLfDw2xnobePGEVwk=",
+      "dev": true,
+      "requires": {
+        "@babel/helper-plugin-utils": "^7.10.4"
+      }
+    },
+    "@babel/plugin-transform-unicode-regex": {
+      "version": "7.12.1",
+      "resolved": "https://registry.npm.taobao.org/@babel/plugin-transform-unicode-regex/download/@babel/plugin-transform-unicode-regex-7.12.1.tgz?cache=0&sync_timestamp=1602800241610&other_urls=https%3A%2F%2Fregistry.npm.taobao.org%2F%40babel%2Fplugin-transform-unicode-regex%2Fdownload%2F%40babel%2Fplugin-transform-unicode-regex-7.12.1.tgz",
+      "integrity": "sha1-zJZh9hOQ21xl4/66zO/Vxqw/rss=",
+      "dev": true,
+      "requires": {
+        "@babel/helper-create-regexp-features-plugin": "^7.12.1",
+        "@babel/helper-plugin-utils": "^7.10.4"
+      }
+    },
+    "@babel/preset-env": {
+      "version": "7.12.1",
+      "resolved": "https://registry.npm.taobao.org/@babel/preset-env/download/@babel/preset-env-7.12.1.tgz?cache=0&sync_timestamp=1602802054477&other_urls=https%3A%2F%2Fregistry.npm.taobao.org%2F%40babel%2Fpreset-env%2Fdownload%2F%40babel%2Fpreset-env-7.12.1.tgz",
+      "integrity": "sha1-nH5cqCoZ78hlOEu0mJFI0u5desI=",
+      "dev": true,
+      "requires": {
+        "@babel/compat-data": "^7.12.1",
+        "@babel/helper-compilation-targets": "^7.12.1",
+        "@babel/helper-module-imports": "^7.12.1",
+        "@babel/helper-plugin-utils": "^7.10.4",
+        "@babel/helper-validator-option": "^7.12.1",
+        "@babel/plugin-proposal-async-generator-functions": "^7.12.1",
+        "@babel/plugin-proposal-class-properties": "^7.12.1",
+        "@babel/plugin-proposal-dynamic-import": "^7.12.1",
+        "@babel/plugin-proposal-export-namespace-from": "^7.12.1",
+        "@babel/plugin-proposal-json-strings": "^7.12.1",
+        "@babel/plugin-proposal-logical-assignment-operators": "^7.12.1",
+        "@babel/plugin-proposal-nullish-coalescing-operator": "^7.12.1",
+        "@babel/plugin-proposal-numeric-separator": "^7.12.1",
+        "@babel/plugin-proposal-object-rest-spread": "^7.12.1",
+        "@babel/plugin-proposal-optional-catch-binding": "^7.12.1",
+        "@babel/plugin-proposal-optional-chaining": "^7.12.1",
+        "@babel/plugin-proposal-private-methods": "^7.12.1",
+        "@babel/plugin-proposal-unicode-property-regex": "^7.12.1",
+        "@babel/plugin-syntax-async-generators": "^7.8.0",
+        "@babel/plugin-syntax-class-properties": "^7.12.1",
+        "@babel/plugin-syntax-dynamic-import": "^7.8.0",
+        "@babel/plugin-syntax-export-namespace-from": "^7.8.3",
+        "@babel/plugin-syntax-json-strings": "^7.8.0",
+        "@babel/plugin-syntax-logical-assignment-operators": "^7.10.4",
+        "@babel/plugin-syntax-nullish-coalescing-operator": "^7.8.0",
+        "@babel/plugin-syntax-numeric-separator": "^7.10.4",
+        "@babel/plugin-syntax-object-rest-spread": "^7.8.0",
+        "@babel/plugin-syntax-optional-catch-binding": "^7.8.0",
+        "@babel/plugin-syntax-optional-chaining": "^7.8.0",
+        "@babel/plugin-syntax-top-level-await": "^7.12.1",
+        "@babel/plugin-transform-arrow-functions": "^7.12.1",
+        "@babel/plugin-transform-async-to-generator": "^7.12.1",
+        "@babel/plugin-transform-block-scoped-functions": "^7.12.1",
+        "@babel/plugin-transform-block-scoping": "^7.12.1",
+        "@babel/plugin-transform-classes": "^7.12.1",
+        "@babel/plugin-transform-computed-properties": "^7.12.1",
+        "@babel/plugin-transform-destructuring": "^7.12.1",
+        "@babel/plugin-transform-dotall-regex": "^7.12.1",
+        "@babel/plugin-transform-duplicate-keys": "^7.12.1",
+        "@babel/plugin-transform-exponentiation-operator": "^7.12.1",
+        "@babel/plugin-transform-for-of": "^7.12.1",
+        "@babel/plugin-transform-function-name": "^7.12.1",
+        "@babel/plugin-transform-literals": "^7.12.1",
+        "@babel/plugin-transform-member-expression-literals": "^7.12.1",
+        "@babel/plugin-transform-modules-amd": "^7.12.1",
+        "@babel/plugin-transform-modules-commonjs": "^7.12.1",
+        "@babel/plugin-transform-modules-systemjs": "^7.12.1",
+        "@babel/plugin-transform-modules-umd": "^7.12.1",
+        "@babel/plugin-transform-named-capturing-groups-regex": "^7.12.1",
+        "@babel/plugin-transform-new-target": "^7.12.1",
+        "@babel/plugin-transform-object-super": "^7.12.1",
+        "@babel/plugin-transform-parameters": "^7.12.1",
+        "@babel/plugin-transform-property-literals": "^7.12.1",
+        "@babel/plugin-transform-regenerator": "^7.12.1",
+        "@babel/plugin-transform-reserved-words": "^7.12.1",
+        "@babel/plugin-transform-shorthand-properties": "^7.12.1",
+        "@babel/plugin-transform-spread": "^7.12.1",
+        "@babel/plugin-transform-sticky-regex": "^7.12.1",
+        "@babel/plugin-transform-template-literals": "^7.12.1",
+        "@babel/plugin-transform-typeof-symbol": "^7.12.1",
+        "@babel/plugin-transform-unicode-escapes": "^7.12.1",
+        "@babel/plugin-transform-unicode-regex": "^7.12.1",
+        "@babel/preset-modules": "^0.1.3",
+        "@babel/types": "^7.12.1",
+        "core-js-compat": "^3.6.2",
+        "semver": "^5.5.0"
+      },
+      "dependencies": {
+        "semver": {
+          "version": "5.7.1",
+          "resolved": "https://registry.npm.taobao.org/semver/download/semver-5.7.1.tgz",
+          "integrity": "sha1-qVT5Ma66UI0we78Gnv8MAclhFvc=",
+          "dev": true
+        }
+      }
+    },
+    "@babel/preset-flow": {
+      "version": "7.12.1",
+      "resolved": "https://registry.npm.taobao.org/@babel/preset-flow/download/@babel/preset-flow-7.12.1.tgz",
+      "integrity": "sha1-GoHTdsWpVJ51NSo4iPjCc0Va6UA=",
+      "dev": true,
+      "requires": {
+        "@babel/helper-plugin-utils": "^7.10.4",
+        "@babel/plugin-transform-flow-strip-types": "^7.12.1"
+      }
+    },
+    "@babel/preset-modules": {
+      "version": "0.1.4",
+      "resolved": "https://registry.npm.taobao.org/@babel/preset-modules/download/@babel/preset-modules-0.1.4.tgz?cache=0&sync_timestamp=1598549645892&other_urls=https%3A%2F%2Fregistry.npm.taobao.org%2F%40babel%2Fpreset-modules%2Fdownload%2F%40babel%2Fpreset-modules-0.1.4.tgz",
+      "integrity": "sha1-Ni8raMZihClw/bXiVP/I/BwuQV4=",
+      "dev": true,
+      "requires": {
+        "@babel/helper-plugin-utils": "^7.0.0",
+        "@babel/plugin-proposal-unicode-property-regex": "^7.4.4",
+        "@babel/plugin-transform-dotall-regex": "^7.4.4",
+        "@babel/types": "^7.4.4",
+        "esutils": "^2.0.2"
+      }
+    },
+    "@babel/preset-react": {
+      "version": "7.12.5",
+      "resolved": "https://registry.npm.taobao.org/@babel/preset-react/download/@babel/preset-react-7.12.5.tgz",
+      "integrity": "sha1-1FYl9l1TYSB4pDhnxcZ1Dnh3LFY=",
+      "dev": true,
+      "requires": {
+        "@babel/helper-plugin-utils": "^7.10.4",
+        "@babel/plugin-transform-react-display-name": "^7.12.1",
+        "@babel/plugin-transform-react-jsx": "^7.12.5",
+        "@babel/plugin-transform-react-jsx-development": "^7.12.5",
+        "@babel/plugin-transform-react-jsx-self": "^7.12.1",
+        "@babel/plugin-transform-react-jsx-source": "^7.12.1",
+        "@babel/plugin-transform-react-pure-annotations": "^7.12.1"
+      }
+    },
+    "@babel/preset-typescript": {
+      "version": "7.12.1",
+      "resolved": "https://registry.npm.taobao.org/@babel/preset-typescript/download/@babel/preset-typescript-7.12.1.tgz?cache=0&sync_timestamp=1602801827867&other_urls=https%3A%2F%2Fregistry.npm.taobao.org%2F%40babel%2Fpreset-typescript%2Fdownload%2F%40babel%2Fpreset-typescript-7.12.1.tgz",
+      "integrity": "sha1-hkgLSDu5f3UDbohk/kBMx4LMMRs=",
+      "dev": true,
+      "requires": {
+        "@babel/helper-plugin-utils": "^7.10.4",
+        "@babel/plugin-transform-typescript": "^7.12.1"
+      }
+    },
+    "@babel/runtime": {
+      "version": "7.12.5",
+      "resolved": "https://registry.npm.taobao.org/@babel/runtime/download/@babel/runtime-7.12.5.tgz?cache=0&sync_timestamp=1604441104026&other_urls=https%3A%2F%2Fregistry.npm.taobao.org%2F%40babel%2Fruntime%2Fdownload%2F%40babel%2Fruntime-7.12.5.tgz",
+      "integrity": "sha1-QQ5+SHRB4bNgwpvnFdhw2bmFiC4=",
+      "requires": {
+        "regenerator-runtime": "^0.13.4"
+      },
+      "dependencies": {
+        "regenerator-runtime": {
+          "version": "0.13.7",
+          "resolved": "https://registry.npm.taobao.org/regenerator-runtime/download/regenerator-runtime-0.13.7.tgz?cache=0&other_urls=https%3A%2F%2Fregistry.npm.taobao.org%2Fregenerator-runtime%2Fdownload%2Fregenerator-runtime-0.13.7.tgz",
+          "integrity": "sha1-ysLazIoepnX+qrrriugziYrkb1U="
+        }
+      }
+    },
+    "@babel/runtime-corejs3": {
+      "version": "7.12.5",
+      "resolved": "https://registry.npm.taobao.org/@babel/runtime-corejs3/download/@babel/runtime-corejs3-7.12.5.tgz",
+      "integrity": "sha1-/+6R2g60xtrggHdOlLpgY2jkFPQ=",
+      "dev": true,
+      "requires": {
+        "core-js-pure": "^3.0.0",
+        "regenerator-runtime": "^0.13.4"
+      },
+      "dependencies": {
+        "regenerator-runtime": {
+          "version": "0.13.7",
+          "resolved": "https://registry.npm.taobao.org/regenerator-runtime/download/regenerator-runtime-0.13.7.tgz?cache=0&other_urls=https%3A%2F%2Fregistry.npm.taobao.org%2Fregenerator-runtime%2Fdownload%2Fregenerator-runtime-0.13.7.tgz",
+          "integrity": "sha1-ysLazIoepnX+qrrriugziYrkb1U=",
+          "dev": true
+        }
+      }
+    },
+    "@babel/template": {
+      "version": "7.10.4",
+      "resolved": "https://registry.npm.taobao.org/@babel/template/download/@babel/template-7.10.4.tgz?cache=0&sync_timestamp=1593522831608&other_urls=https%3A%2F%2Fregistry.npm.taobao.org%2F%40babel%2Ftemplate%2Fdownload%2F%40babel%2Ftemplate-7.10.4.tgz",
+      "integrity": "sha1-MlGZbEIA68cdGo/EBfupQPNrong=",
+      "dev": true,
+      "requires": {
+        "@babel/code-frame": "^7.10.4",
+        "@babel/parser": "^7.10.4",
+        "@babel/types": "^7.10.4"
+      }
+    },
+    "@babel/traverse": {
+      "version": "7.12.5",
+      "resolved": "https://registry.npm.taobao.org/@babel/traverse/download/@babel/traverse-7.12.5.tgz",
+      "integrity": "sha1-eKDGjI6KNeTKz9MduLswPVYG8JU=",
+      "dev": true,
+      "requires": {
+        "@babel/code-frame": "^7.10.4",
+        "@babel/generator": "^7.12.5",
+        "@babel/helper-function-name": "^7.10.4",
+        "@babel/helper-split-export-declaration": "^7.11.0",
+        "@babel/parser": "^7.12.5",
+        "@babel/types": "^7.12.5",
+        "debug": "^4.1.0",
+        "globals": "^11.1.0",
+        "lodash": "^4.17.19"
+      }
+    },
+    "@babel/types": {
+      "version": "7.12.6",
+      "resolved": "https://registry.npm.taobao.org/@babel/types/download/@babel/types-7.12.6.tgz?cache=0&sync_timestamp=1604486339981&other_urls=https%3A%2F%2Fregistry.npm.taobao.org%2F%40babel%2Ftypes%2Fdownload%2F%40babel%2Ftypes-7.12.6.tgz",
+      "integrity": "sha1-rg5V7xzOH7yIHNJvgjTrPmV+3JY=",
+      "dev": true,
+      "requires": {
+        "@babel/helper-validator-identifier": "^7.10.4",
+        "lodash": "^4.17.19",
+        "to-fast-properties": "^2.0.0"
+      }
+    },
+    "@bcoe/v8-coverage": {
+      "version": "0.2.3",
+      "resolved": "https://registry.npm.taobao.org/@bcoe/v8-coverage/download/@bcoe/v8-coverage-0.2.3.tgz",
+      "integrity": "sha1-daLotRy3WKdVPWgEpZMteqznXDk=",
+      "dev": true
+    },
+    "@builder/app-helpers": {
+      "version": "1.0.1",
+      "resolved": "https://registry.npm.taobao.org/@builder/app-helpers/download/@builder/app-helpers-1.0.1.tgz",
+      "integrity": "sha1-7u27x6NwCMkyGJebwDOF0VBMLak=",
+      "dev": true,
+      "requires": {
+        "fs-extra": "^8.1.0",
+        "lodash": "^4.17.20"
+      }
+    },
+    "@builder/user-config": {
+      "version": "0.1.1",
+      "resolved": "https://registry.npm.taobao.org/@builder/user-config/download/@builder/user-config-0.1.1.tgz",
+      "integrity": "sha1-21AHT9yPRdmhjnvfYMIJXula4j0=",
+      "dev": true,
+      "requires": {
+        "@alifd/fusion-collector": "^1.2.5",
+        "@babel/plugin-transform-runtime": "^7.6.2",
+        "@builder/app-helpers": "^1.0.0",
+        "add-asset-html-webpack-plugin": "^3.1.3",
+        "chalk": "^4.0.0",
+        "copy-webpack-plugin": "^5.0.4",
+        "core-js": "^3.3.1",
+        "debug": "^4.1.1",
+        "eslint-loader": "^4.0.0",
+        "eslint-reporting-webpack-plugin": "^0.1.0",
+        "fork-ts-checker-webpack-plugin": "^5.0.5",
+        "friendly-errors-webpack-plugin": "^1.7.0",
+        "fs-extra": "^8.1.0",
+        "loader-utils": "^2.0.0",
+        "lodash": "^4.17.15",
+        "mkcert": "^1.2.0",
+        "path-exists": "^4.0.0",
+        "postcss-plugin-rpx2vw": "^0.0.2",
+        "react-dev-utils": "^10.2.1",
+        "regenerator-runtime": "^0.13.3",
+        "webpack-bundle-analyzer": "^3.6.0",
+        "webpack-dev-mock": "^1.0.1",
+        "webpack-plugin-import": "^0.2.6"
+      },
+      "dependencies": {
+        "ansi-regex": {
+          "version": "5.0.0",
+          "resolved": "https://registry.npm.taobao.org/ansi-regex/download/ansi-regex-5.0.0.tgz",
+          "integrity": "sha1-OIU59VF5vzkznIGvMKZU1p+Hy3U=",
+          "dev": true
+        },
+        "ansi-styles": {
+          "version": "4.3.0",
+          "resolved": "https://registry.npm.taobao.org/ansi-styles/download/ansi-styles-4.3.0.tgz?cache=0&sync_timestamp=1601839122515&other_urls=https%3A%2F%2Fregistry.npm.taobao.org%2Fansi-styles%2Fdownload%2Fansi-styles-4.3.0.tgz",
+          "integrity": "sha1-7dgDYornHATIWuegkG7a00tkiTc=",
+          "dev": true,
+          "requires": {
+            "color-convert": "^2.0.1"
+          }
+        },
+        "browserslist": {
+          "version": "4.10.0",
+          "resolved": "https://registry.npm.taobao.org/browserslist/download/browserslist-4.10.0.tgz?cache=0&sync_timestamp=1604944989360&other_urls=https%3A%2F%2Fregistry.npm.taobao.org%2Fbrowserslist%2Fdownload%2Fbrowserslist-4.10.0.tgz",
+          "integrity": "sha1-8XlzeRPq8NK5jkkmrBymoVy8xqk=",
+          "dev": true,
+          "requires": {
+            "caniuse-lite": "^1.0.30001035",
+            "electron-to-chromium": "^1.3.378",
+            "node-releases": "^1.1.52",
+            "pkg-up": "^3.1.0"
+          }
+        },
+        "chalk": {
+          "version": "4.1.0",
+          "resolved": "https://registry.npm.taobao.org/chalk/download/chalk-4.1.0.tgz",
+          "integrity": "sha1-ThSHCmGNni7dl92DRf2dncMVZGo=",
+          "dev": true,
+          "requires": {
+            "ansi-styles": "^4.1.0",
+            "supports-color": "^7.1.0"
+          }
+        },
+        "cli-width": {
+          "version": "2.2.1",
+          "resolved": "https://registry.npm.taobao.org/cli-width/download/cli-width-2.2.1.tgz",
+          "integrity": "sha1-sEM9C06chH7xiGik7xb9X8gnHEg=",
+          "dev": true
+        },
+        "color-convert": {
+          "version": "2.0.1",
+          "resolved": "https://registry.npm.taobao.org/color-convert/download/color-convert-2.0.1.tgz",
+          "integrity": "sha1-ctOmjVmMm9s68q0ehPIdiWq9TeM=",
+          "dev": true,
+          "requires": {
+            "color-name": "~1.1.4"
+          }
+        },
+        "color-name": {
+          "version": "1.1.4",
+          "resolved": "https://registry.npm.taobao.org/color-name/download/color-name-1.1.4.tgz",
+          "integrity": "sha1-wqCah6y95pVD3m9j+jmVyCbFNqI=",
+          "dev": true
+        },
+        "copy-webpack-plugin": {
+          "version": "5.1.2",
+          "resolved": "https://registry.npm.taobao.org/copy-webpack-plugin/download/copy-webpack-plugin-5.1.2.tgz?cache=0&other_urls=https%3A%2F%2Fregistry.npm.taobao.org%2Fcopy-webpack-plugin%2Fdownload%2Fcopy-webpack-plugin-5.1.2.tgz",
+          "integrity": "sha1-ioieHcr6bJHGzUvhrRWPHTgjuuI=",
+          "dev": true,
+          "requires": {
+            "cacache": "^12.0.3",
+            "find-cache-dir": "^2.1.0",
+            "glob-parent": "^3.1.0",
+            "globby": "^7.1.1",
+            "is-glob": "^4.0.1",
+            "loader-utils": "^1.2.3",
+            "minimatch": "^3.0.4",
+            "normalize-path": "^3.0.0",
+            "p-limit": "^2.2.1",
+            "schema-utils": "^1.0.0",
+            "serialize-javascript": "^4.0.0",
+            "webpack-log": "^2.0.0"
+          },
+          "dependencies": {
+            "loader-utils": {
+              "version": "1.4.0",
+              "resolved": "https://registry.npm.taobao.org/loader-utils/download/loader-utils-1.4.0.tgz",
+              "integrity": "sha1-xXm140yzSxp07cbB+za/o3HVphM=",
+              "dev": true,
+              "requires": {
+                "big.js": "^5.2.2",
+                "emojis-list": "^3.0.0",
+                "json5": "^1.0.1"
+              }
+            }
+          }
+        },
+        "core-js": {
+          "version": "3.7.0",
+          "resolved": "https://registry.npm.taobao.org/core-js/download/core-js-3.7.0.tgz?cache=0&sync_timestamp=1604675498528&other_urls=https%3A%2F%2Fregistry.npm.taobao.org%2Fcore-js%2Fdownload%2Fcore-js-3.7.0.tgz",
+          "integrity": "sha1-sKdhoCSIV3r7+XF55Ggb9JVoUg8=",
+          "dev": true
+        },
+        "cosmiconfig": {
+          "version": "6.0.0",
+          "resolved": "https://registry.npm.taobao.org/cosmiconfig/download/cosmiconfig-6.0.0.tgz?cache=0&sync_timestamp=1596312863119&other_urls=https%3A%2F%2Fregistry.npm.taobao.org%2Fcosmiconfig%2Fdownload%2Fcosmiconfig-6.0.0.tgz",
+          "integrity": "sha1-2k/uhTxS9rHmk19BwaL8UL1KmYI=",
+          "dev": true,
+          "requires": {
+            "@types/parse-json": "^4.0.0",
+            "import-fresh": "^3.1.0",
+            "parse-json": "^5.0.0",
+            "path-type": "^4.0.0",
+            "yaml": "^1.7.2"
+          }
+        },
+        "cross-spawn": {
+          "version": "7.0.1",
+          "resolved": "https://registry.npm.taobao.org/cross-spawn/download/cross-spawn-7.0.1.tgz",
+          "integrity": "sha1-CrVihuD3wk4VPQTMKqAn5DqaXRQ=",
+          "dev": true,
+          "requires": {
+            "path-key": "^3.1.0",
+            "shebang-command": "^2.0.0",
+            "which": "^2.0.1"
+          }
+        },
+        "detect-port-alt": {
+          "version": "1.1.6",
+          "resolved": "https://registry.npm.taobao.org/detect-port-alt/download/detect-port-alt-1.1.6.tgz",
+          "integrity": "sha1-JHB96r6TLUo89iEwICfCsmZWgnU=",
+          "dev": true,
+          "requires": {
+            "address": "^1.0.1",
+            "debug": "^2.6.0"
+          },
+          "dependencies": {
+            "debug": {
+              "version": "2.6.9",
+              "resolved": "https://registry.npm.taobao.org/debug/download/debug-2.6.9.tgz?cache=0&sync_timestamp=1600502871403&other_urls=https%3A%2F%2Fregistry.npm.taobao.org%2Fdebug%2Fdownload%2Fdebug-2.6.9.tgz",
+              "integrity": "sha1-XRKFFd8TT/Mn6QpMk/Tgd6U2NB8=",
+              "dev": true,
+              "requires": {
+                "ms": "2.0.0"
+              }
+            }
+          }
+        },
+        "emoji-regex": {
+          "version": "8.0.0",
+          "resolved": "https://registry.npm.taobao.org/emoji-regex/download/emoji-regex-8.0.0.tgz?cache=0&sync_timestamp=1603212263242&other_urls=https%3A%2F%2Fregistry.npm.taobao.org%2Femoji-regex%2Fdownload%2Femoji-regex-8.0.0.tgz",
+          "integrity": "sha1-6Bj9ac5cz8tARZT4QpY79TFkzDc=",
+          "dev": true
+        },
+        "escape-string-regexp": {
+          "version": "2.0.0",
+          "resolved": "https://registry.npm.taobao.org/escape-string-regexp/download/escape-string-regexp-2.0.0.tgz?cache=0&sync_timestamp=1587627107924&other_urls=https%3A%2F%2Fregistry.npm.taobao.org%2Fescape-string-regexp%2Fdownload%2Fescape-string-regexp-2.0.0.tgz",
+          "integrity": "sha1-owME6Z2qMuI7L9IPUbq9B8/8o0Q=",
+          "dev": true
+        },
+        "filesize": {
+          "version": "6.0.1",
+          "resolved": "https://registry.npm.taobao.org/filesize/download/filesize-6.0.1.tgz",
+          "integrity": "sha1-+FC1CZCcfIb35FDqGQBsMcLtPS8=",
+          "dev": true
+        },
+        "find-up": {
+          "version": "4.1.0",
+          "resolved": "https://registry.npm.taobao.org/find-up/download/find-up-4.1.0.tgz?cache=0&sync_timestamp=1597169862146&other_urls=https%3A%2F%2Fregistry.npm.taobao.org%2Ffind-up%2Fdownload%2Ffind-up-4.1.0.tgz",
+          "integrity": "sha1-l6/n1s3AvFkoWEt8jXsW6KmqXRk=",
+          "dev": true,
+          "requires": {
+            "locate-path": "^5.0.0",
+            "path-exists": "^4.0.0"
+          }
+        },
+        "fork-ts-checker-webpack-plugin": {
+          "version": "5.2.1",
+          "resolved": "https://registry.npm.taobao.org/fork-ts-checker-webpack-plugin/download/fork-ts-checker-webpack-plugin-5.2.1.tgz",
+          "integrity": "sha1-eTJthpeXkG+osk4qvPlCH8gFRQ0=",
+          "dev": true,
+          "requires": {
+            "@babel/code-frame": "^7.8.3",
+            "@types/json-schema": "^7.0.5",
+            "chalk": "^4.1.0",
+            "cosmiconfig": "^6.0.0",
+            "deepmerge": "^4.2.2",
+            "fs-extra": "^9.0.0",
+            "memfs": "^3.1.2",
+            "minimatch": "^3.0.4",
+            "schema-utils": "2.7.0",
+            "semver": "^7.3.2",
+            "tapable": "^1.0.0"
+          },
+          "dependencies": {
+            "fs-extra": {
+              "version": "9.0.1",
+              "resolved": "https://registry.npm.taobao.org/fs-extra/download/fs-extra-9.0.1.tgz?cache=0&other_urls=https%3A%2F%2Fregistry.npm.taobao.org%2Ffs-extra%2Fdownload%2Ffs-extra-9.0.1.tgz",
+              "integrity": "sha1-kQ2gBiQ3ukw5/t2GPxZ1zP78ufw=",
+              "dev": true,
+              "requires": {
+                "at-least-node": "^1.0.0",
+                "graceful-fs": "^4.2.0",
+                "jsonfile": "^6.0.1",
+                "universalify": "^1.0.0"
+              }
+            },
+            "schema-utils": {
+              "version": "2.7.0",
+              "resolved": "https://registry.npm.taobao.org/schema-utils/download/schema-utils-2.7.0.tgz",
+              "integrity": "sha1-FxUfdtjq5n+793lgwzxnatn078c=",
+              "dev": true,
+              "requires": {
+                "@types/json-schema": "^7.0.4",
+                "ajv": "^6.12.2",
+                "ajv-keywords": "^3.4.1"
+              }
+            }
+          }
+        },
+        "globby": {
+          "version": "7.1.1",
+          "resolved": "https://registry.npm.taobao.org/globby/download/globby-7.1.1.tgz",
+          "integrity": "sha1-+yzP+UAfhgCUXfral0QMypcrhoA=",
+          "dev": true,
+          "requires": {
+            "array-union": "^1.0.1",
+            "dir-glob": "^2.0.0",
+            "glob": "^7.1.2",
+            "ignore": "^3.3.5",
+            "pify": "^3.0.0",
+            "slash": "^1.0.0"
+          }
+        },
+        "has-flag": {
+          "version": "4.0.0",
+          "resolved": "https://registry.npm.taobao.org/has-flag/download/has-flag-4.0.0.tgz?cache=0&sync_timestamp=1596294337050&other_urls=https%3A%2F%2Fregistry.npm.taobao.org%2Fhas-flag%2Fdownload%2Fhas-flag-4.0.0.tgz",
+          "integrity": "sha1-lEdx/ZyByBJlxNaUGGDaBrtZR5s=",
+          "dev": true
+        },
+        "ignore": {
+          "version": "3.3.10",
+          "resolved": "https://registry.npm.taobao.org/ignore/download/ignore-3.3.10.tgz",
+          "integrity": "sha1-Cpf7h2mG6AgcYxFg+PnziRV/AEM=",
+          "dev": true
+        },
+        "import-fresh": {
+          "version": "3.2.2",
+          "resolved": "https://registry.npm.taobao.org/import-fresh/download/import-fresh-3.2.2.tgz?cache=0&sync_timestamp=1604256056573&other_urls=https%3A%2F%2Fregistry.npm.taobao.org%2Fimport-fresh%2Fdownload%2Fimport-fresh-3.2.2.tgz",
+          "integrity": "sha1-/BKcFgxdaCNVB/QzGmuq0Ya9vD4=",
+          "dev": true,
+          "requires": {
+            "parent-module": "^1.0.0",
+            "resolve-from": "^4.0.0"
+          }
+        },
+        "inquirer": {
+          "version": "7.0.4",
+          "resolved": "https://registry.npm.taobao.org/inquirer/download/inquirer-7.0.4.tgz",
+          "integrity": "sha1-ma9b3kcVOryiP1x/ww2yR/OdpwM=",
+          "dev": true,
+          "requires": {
+            "ansi-escapes": "^4.2.1",
+            "chalk": "^2.4.2",
+            "cli-cursor": "^3.1.0",
+            "cli-width": "^2.0.0",
+            "external-editor": "^3.0.3",
+            "figures": "^3.0.0",
+            "lodash": "^4.17.15",
+            "mute-stream": "0.0.8",
+            "run-async": "^2.2.0",
+            "rxjs": "^6.5.3",
+            "string-width": "^4.1.0",
+            "strip-ansi": "^5.1.0",
+            "through": "^2.3.6"
+          },
+          "dependencies": {
+            "ansi-regex": {
+              "version": "4.1.0",
+              "resolved": "https://registry.npm.taobao.org/ansi-regex/download/ansi-regex-4.1.0.tgz",
+              "integrity": "sha1-i5+PCM8ay4Q3Vqg5yox+MWjFGZc=",
+              "dev": true
+            },
+            "ansi-styles": {
+              "version": "3.2.1",
+              "resolved": "https://registry.npm.taobao.org/ansi-styles/download/ansi-styles-3.2.1.tgz?cache=0&sync_timestamp=1601839122515&other_urls=https%3A%2F%2Fregistry.npm.taobao.org%2Fansi-styles%2Fdownload%2Fansi-styles-3.2.1.tgz",
+              "integrity": "sha1-QfuyAkPlCxK+DwS43tvwdSDOhB0=",
+              "dev": true,
+              "requires": {
+                "color-convert": "^1.9.0"
+              }
+            },
+            "chalk": {
+              "version": "2.4.2",
+              "resolved": "https://registry.npm.taobao.org/chalk/download/chalk-2.4.2.tgz",
+              "integrity": "sha1-zUJUFnelQzPPVBpJEIwUMrRMlCQ=",
+              "dev": true,
+              "requires": {
+                "ansi-styles": "^3.2.1",
+                "escape-string-regexp": "^1.0.5",
+                "supports-color": "^5.3.0"
+              }
+            },
+            "color-convert": {
+              "version": "1.9.3",
+              "resolved": "https://registry.npm.taobao.org/color-convert/download/color-convert-1.9.3.tgz",
+              "integrity": "sha1-u3GFBpDh8TZWfeYp0tVHHe2kweg=",
+              "dev": true,
+              "requires": {
+                "color-name": "1.1.3"
+              }
+            },
+            "color-name": {
+              "version": "1.1.3",
+              "resolved": "https://registry.npm.taobao.org/color-name/download/color-name-1.1.3.tgz",
+              "integrity": "sha1-p9BVi9icQveV3UIyj3QIMcpTvCU=",
+              "dev": true
+            },
+            "escape-string-regexp": {
+              "version": "1.0.5",
+              "resolved": "https://registry.npm.taobao.org/escape-string-regexp/download/escape-string-regexp-1.0.5.tgz?cache=0&sync_timestamp=1587627107924&other_urls=https%3A%2F%2Fregistry.npm.taobao.org%2Fescape-string-regexp%2Fdownload%2Fescape-string-regexp-1.0.5.tgz",
+              "integrity": "sha1-G2HAViGQqN/2rjuyzwIAyhMLhtQ=",
+              "dev": true
+            },
+            "has-flag": {
+              "version": "3.0.0",
+              "resolved": "https://registry.npm.taobao.org/has-flag/download/has-flag-3.0.0.tgz?cache=0&sync_timestamp=1596294337050&other_urls=https%3A%2F%2Fregistry.npm.taobao.org%2Fhas-flag%2Fdownload%2Fhas-flag-3.0.0.tgz",
+              "integrity": "sha1-tdRU3CGZriJWmfNGfloH87lVuv0=",
+              "dev": true
+            },
+            "strip-ansi": {
+              "version": "5.2.0",
+              "resolved": "https://registry.npm.taobao.org/strip-ansi/download/strip-ansi-5.2.0.tgz",
+              "integrity": "sha1-jJpTb+tq/JYr36WxBKUJHBrZwK4=",
+              "dev": true,
+              "requires": {
+                "ansi-regex": "^4.1.0"
+              }
+            },
+            "supports-color": {
+              "version": "5.5.0",
+              "resolved": "https://registry.npm.taobao.org/supports-color/download/supports-color-5.5.0.tgz?cache=0&sync_timestamp=1598611730985&other_urls=https%3A%2F%2Fregistry.npm.taobao.org%2Fsupports-color%2Fdownload%2Fsupports-color-5.5.0.tgz",
+              "integrity": "sha1-4uaaRKyHcveKHsCzW2id9lMO/I8=",
+              "dev": true,
+              "requires": {
+                "has-flag": "^3.0.0"
+              }
+            }
+          }
+        },
+        "is-fullwidth-code-point": {
+          "version": "3.0.0",
+          "resolved": "https://registry.npm.taobao.org/is-fullwidth-code-point/download/is-fullwidth-code-point-3.0.0.tgz",
+          "integrity": "sha1-8Rb4Bk/pCz94RKOJl8C3UFEmnx0=",
+          "dev": true
+        },
+        "jsonfile": {
+          "version": "6.1.0",
+          "resolved": "https://registry.npm.taobao.org/jsonfile/download/jsonfile-6.1.0.tgz?cache=0&sync_timestamp=1604161933968&other_urls=https%3A%2F%2Fregistry.npm.taobao.org%2Fjsonfile%2Fdownload%2Fjsonfile-6.1.0.tgz",
+          "integrity": "sha1-vFWyY0eTxnnsZAMJTrE2mKbsCq4=",
+          "dev": true,
+          "requires": {
+            "graceful-fs": "^4.1.6",
+            "universalify": "^2.0.0"
+          },
+          "dependencies": {
+            "universalify": {
+              "version": "2.0.0",
+              "resolved": "https://registry.npm.taobao.org/universalify/download/universalify-2.0.0.tgz?cache=0&sync_timestamp=1603180048005&other_urls=https%3A%2F%2Fregistry.npm.taobao.org%2Funiversalify%2Fdownload%2Funiversalify-2.0.0.tgz",
+              "integrity": "sha1-daSYTv7cSwiXXFrrc/Uw0C3yVxc=",
+              "dev": true
+            }
+          }
+        },
+        "loader-utils": {
+          "version": "2.0.0",
+          "resolved": "https://registry.npm.taobao.org/loader-utils/download/loader-utils-2.0.0.tgz",
+          "integrity": "sha1-5MrOW4FtQloWa18JfhDNErNgZLA=",
+          "dev": true,
+          "requires": {
+            "big.js": "^5.2.2",
+            "emojis-list": "^3.0.0",
+            "json5": "^2.1.2"
+          },
+          "dependencies": {
+            "json5": {
+              "version": "2.1.3",
+              "resolved": "https://registry.npm.taobao.org/json5/download/json5-2.1.3.tgz",
+              "integrity": "sha1-ybD3+pIzv+WAf+ZvzzpWF+1ZfUM=",
+              "dev": true,
+              "requires": {
+                "minimist": "^1.2.5"
+              }
+            }
+          }
+        },
+        "locate-path": {
+          "version": "5.0.0",
+          "resolved": "https://registry.npm.taobao.org/locate-path/download/locate-path-5.0.0.tgz",
+          "integrity": "sha1-Gvujlq/WdqbUJQTQpno6frn2KqA=",
+          "dev": true,
+          "requires": {
+            "p-locate": "^4.1.0"
+          }
+        },
+        "ms": {
+          "version": "2.0.0",
+          "resolved": "https://registry.npm.taobao.org/ms/download/ms-2.0.0.tgz",
+          "integrity": "sha1-VgiurfwAvmwpAd9fmGF4jeDVl8g=",
+          "dev": true
+        },
+        "open": {
+          "version": "7.3.0",
+          "resolved": "https://registry.npm.taobao.org/open/download/open-7.3.0.tgz?cache=0&sync_timestamp=1601376312546&other_urls=https%3A%2F%2Fregistry.npm.taobao.org%2Fopen%2Fdownload%2Fopen-7.3.0.tgz",
+          "integrity": "sha1-RUYf3uRkRPNkW24U6zypS4Lhvmk=",
+          "dev": true,
+          "requires": {
+            "is-docker": "^2.0.0",
+            "is-wsl": "^2.1.1"
+          }
+        },
+        "p-limit": {
+          "version": "2.3.0",
+          "resolved": "https://registry.npm.taobao.org/p-limit/download/p-limit-2.3.0.tgz",
+          "integrity": "sha1-PdM8ZHohT9//2DWTPrCG2g3CHbE=",
+          "dev": true,
+          "requires": {
+            "p-try": "^2.0.0"
+          }
+        },
+        "p-locate": {
+          "version": "4.1.0",
+          "resolved": "https://registry.npm.taobao.org/p-locate/download/p-locate-4.1.0.tgz?cache=0&sync_timestamp=1597081508945&other_urls=https%3A%2F%2Fregistry.npm.taobao.org%2Fp-locate%2Fdownload%2Fp-locate-4.1.0.tgz",
+          "integrity": "sha1-o0KLtwiLOmApL2aRkni3wpetTwc=",
+          "dev": true,
+          "requires": {
+            "p-limit": "^2.2.0"
+          }
+        },
+        "p-try": {
+          "version": "2.2.0",
+          "resolved": "https://registry.npm.taobao.org/p-try/download/p-try-2.2.0.tgz",
+          "integrity": "sha1-yyhoVA4xPWHeWPr741zpAE1VQOY=",
+          "dev": true
+        },
+        "parse-json": {
+          "version": "5.1.0",
+          "resolved": "https://registry.npm.taobao.org/parse-json/download/parse-json-5.1.0.tgz?cache=0&sync_timestamp=1598129247474&other_urls=https%3A%2F%2Fregistry.npm.taobao.org%2Fparse-json%2Fdownload%2Fparse-json-5.1.0.tgz",
+          "integrity": "sha1-+WCIzfJKj6qa6poAny2dlCyZlkY=",
+          "dev": true,
+          "requires": {
+            "@babel/code-frame": "^7.0.0",
+            "error-ex": "^1.3.1",
+            "json-parse-even-better-errors": "^2.3.0",
+            "lines-and-columns": "^1.1.6"
+          }
+        },
+        "path-exists": {
+          "version": "4.0.0",
+          "resolved": "https://registry.npm.taobao.org/path-exists/download/path-exists-4.0.0.tgz",
+          "integrity": "sha1-UTvb4tO5XXdi6METfvoZXGxhtbM=",
+          "dev": true
+        },
+        "path-key": {
+          "version": "3.1.1",
+          "resolved": "https://registry.npm.taobao.org/path-key/download/path-key-3.1.1.tgz",
+          "integrity": "sha1-WB9q3mWMu6ZaDTOA3ndTKVBU83U=",
+          "dev": true
+        },
+        "path-type": {
+          "version": "4.0.0",
+          "resolved": "https://registry.npm.taobao.org/path-type/download/path-type-4.0.0.tgz",
+          "integrity": "sha1-hO0BwKe6OAr+CdkKjBgNzZ0DBDs=",
+          "dev": true
+        },
+        "pify": {
+          "version": "3.0.0",
+          "resolved": "https://registry.npm.taobao.org/pify/download/pify-3.0.0.tgz",
+          "integrity": "sha1-5aSs0sEB/fPZpNB/DbxNtJ3SgXY=",
+          "dev": true
+        },
+        "react-dev-utils": {
+          "version": "10.2.1",
+          "resolved": "https://registry.npm.taobao.org/react-dev-utils/download/react-dev-utils-10.2.1.tgz?cache=0&sync_timestamp=1603462727689&other_urls=https%3A%2F%2Fregistry.npm.taobao.org%2Freact-dev-utils%2Fdownload%2Freact-dev-utils-10.2.1.tgz",
+          "integrity": "sha1-9t4yWuJfpNVG0J30uxvv3G3RnBk=",
+          "dev": true,
+          "requires": {
+            "@babel/code-frame": "7.8.3",
+            "address": "1.1.2",
+            "browserslist": "4.10.0",
+            "chalk": "2.4.2",
+            "cross-spawn": "7.0.1",
+            "detect-port-alt": "1.1.6",
+            "escape-string-regexp": "2.0.0",
+            "filesize": "6.0.1",
+            "find-up": "4.1.0",
+            "fork-ts-checker-webpack-plugin": "3.1.1",
+            "global-modules": "2.0.0",
+            "globby": "8.0.2",
+            "gzip-size": "5.1.1",
+            "immer": "1.10.0",
+            "inquirer": "7.0.4",
+            "is-root": "2.1.0",
+            "loader-utils": "1.2.3",
+            "open": "^7.0.2",
+            "pkg-up": "3.1.0",
+            "react-error-overlay": "^6.0.7",
+            "recursive-readdir": "2.2.2",
+            "shell-quote": "1.7.2",
+            "strip-ansi": "6.0.0",
+            "text-table": "0.2.0"
+          },
+          "dependencies": {
+            "@babel/code-frame": {
+              "version": "7.8.3",
+              "resolved": "https://registry.npm.taobao.org/@babel/code-frame/download/@babel/code-frame-7.8.3.tgz",
+              "integrity": "sha1-M+JZA9dIEYFTThLsCiXxa2/PQZ4=",
+              "dev": true,
+              "requires": {
+                "@babel/highlight": "^7.8.3"
+              }
+            },
+            "ansi-styles": {
+              "version": "3.2.1",
+              "resolved": "https://registry.npm.taobao.org/ansi-styles/download/ansi-styles-3.2.1.tgz?cache=0&sync_timestamp=1601839122515&other_urls=https%3A%2F%2Fregistry.npm.taobao.org%2Fansi-styles%2Fdownload%2Fansi-styles-3.2.1.tgz",
+              "integrity": "sha1-QfuyAkPlCxK+DwS43tvwdSDOhB0=",
+              "dev": true,
+              "requires": {
+                "color-convert": "^1.9.0"
+              }
+            },
+            "chalk": {
+              "version": "2.4.2",
+              "resolved": "https://registry.npm.taobao.org/chalk/download/chalk-2.4.2.tgz",
+              "integrity": "sha1-zUJUFnelQzPPVBpJEIwUMrRMlCQ=",
+              "dev": true,
+              "requires": {
+                "ansi-styles": "^3.2.1",
+                "escape-string-regexp": "^1.0.5",
+                "supports-color": "^5.3.0"
+              },
+              "dependencies": {
+                "escape-string-regexp": {
+                  "version": "1.0.5",
+                  "resolved": "https://registry.npm.taobao.org/escape-string-regexp/download/escape-string-regexp-1.0.5.tgz?cache=0&sync_timestamp=1587627107924&other_urls=https%3A%2F%2Fregistry.npm.taobao.org%2Fescape-string-regexp%2Fdownload%2Fescape-string-regexp-1.0.5.tgz",
+                  "integrity": "sha1-G2HAViGQqN/2rjuyzwIAyhMLhtQ=",
+                  "dev": true
+                }
+              }
+            },
+            "color-convert": {
+              "version": "1.9.3",
+              "resolved": "https://registry.npm.taobao.org/color-convert/download/color-convert-1.9.3.tgz",
+              "integrity": "sha1-u3GFBpDh8TZWfeYp0tVHHe2kweg=",
+              "dev": true,
+              "requires": {
+                "color-name": "1.1.3"
+              }
+            },
+            "color-name": {
+              "version": "1.1.3",
+              "resolved": "https://registry.npm.taobao.org/color-name/download/color-name-1.1.3.tgz",
+              "integrity": "sha1-p9BVi9icQveV3UIyj3QIMcpTvCU=",
+              "dev": true
+            },
+            "dir-glob": {
+              "version": "2.0.0",
+              "resolved": "https://registry.npm.taobao.org/dir-glob/download/dir-glob-2.0.0.tgz",
+              "integrity": "sha1-CyBdK2rvmCOMooZZioIE0p0KADQ=",
+              "dev": true,
+              "requires": {
+                "arrify": "^1.0.1",
+                "path-type": "^3.0.0"
+              }
+            },
+            "emojis-list": {
+              "version": "2.1.0",
+              "resolved": "https://registry.npm.taobao.org/emojis-list/download/emojis-list-2.1.0.tgz",
+              "integrity": "sha1-TapNnbAPmBmIDHn6RXrlsJof04k=",
+              "dev": true
+            },
+            "fork-ts-checker-webpack-plugin": {
+              "version": "3.1.1",
+              "resolved": "https://registry.npm.taobao.org/fork-ts-checker-webpack-plugin/download/fork-ts-checker-webpack-plugin-3.1.1.tgz",
+              "integrity": "sha1-oWQsDT5l9QwswXQunAqA9EH4axk=",
+              "dev": true,
+              "requires": {
+                "babel-code-frame": "^6.22.0",
+                "chalk": "^2.4.1",
+                "chokidar": "^3.3.0",
+                "micromatch": "^3.1.10",
+                "minimatch": "^3.0.4",
+                "semver": "^5.6.0",
+                "tapable": "^1.0.0",
+                "worker-rpc": "^0.1.0"
+              }
+            },
+            "globby": {
+              "version": "8.0.2",
+              "resolved": "https://registry.npm.taobao.org/globby/download/globby-8.0.2.tgz",
+              "integrity": "sha1-VpdhnM2VxSdduy1vqkIIfBqUHY0=",
+              "dev": true,
+              "requires": {
+                "array-union": "^1.0.1",
+                "dir-glob": "2.0.0",
+                "fast-glob": "^2.0.2",
+                "glob": "^7.1.2",
+                "ignore": "^3.3.5",
+                "pify": "^3.0.0",
+                "slash": "^1.0.0"
+              }
+            },
+            "has-flag": {
+              "version": "3.0.0",
+              "resolved": "https://registry.npm.taobao.org/has-flag/download/has-flag-3.0.0.tgz?cache=0&sync_timestamp=1596294337050&other_urls=https%3A%2F%2Fregistry.npm.taobao.org%2Fhas-flag%2Fdownload%2Fhas-flag-3.0.0.tgz",
+              "integrity": "sha1-tdRU3CGZriJWmfNGfloH87lVuv0=",
+              "dev": true
+            },
+            "loader-utils": {
+              "version": "1.2.3",
+              "resolved": "https://registry.npm.taobao.org/loader-utils/download/loader-utils-1.2.3.tgz",
+              "integrity": "sha1-H/XcaRHJ8KBiUxpMBLYJQGEIwsc=",
+              "dev": true,
+              "requires": {
+                "big.js": "^5.2.2",
+                "emojis-list": "^2.0.0",
+                "json5": "^1.0.1"
+              }
+            },
+            "path-type": {
+              "version": "3.0.0",
+              "resolved": "https://registry.npm.taobao.org/path-type/download/path-type-3.0.0.tgz",
+              "integrity": "sha1-zvMdyOCho7sNEFwM2Xzzv0f0428=",
+              "dev": true,
+              "requires": {
+                "pify": "^3.0.0"
+              }
+            },
+            "semver": {
+              "version": "5.7.1",
+              "resolved": "https://registry.npm.taobao.org/semver/download/semver-5.7.1.tgz",
+              "integrity": "sha1-qVT5Ma66UI0we78Gnv8MAclhFvc=",
+              "dev": true
+            },
+            "supports-color": {
+              "version": "5.5.0",
+              "resolved": "https://registry.npm.taobao.org/supports-color/download/supports-color-5.5.0.tgz?cache=0&sync_timestamp=1598611730985&other_urls=https%3A%2F%2Fregistry.npm.taobao.org%2Fsupports-color%2Fdownload%2Fsupports-color-5.5.0.tgz",
+              "integrity": "sha1-4uaaRKyHcveKHsCzW2id9lMO/I8=",
+              "dev": true,
+              "requires": {
+                "has-flag": "^3.0.0"
+              }
+            }
+          }
+        },
+        "regenerator-runtime": {
+          "version": "0.13.7",
+          "resolved": "https://registry.npm.taobao.org/regenerator-runtime/download/regenerator-runtime-0.13.7.tgz?cache=0&other_urls=https%3A%2F%2Fregistry.npm.taobao.org%2Fregenerator-runtime%2Fdownload%2Fregenerator-runtime-0.13.7.tgz",
+          "integrity": "sha1-ysLazIoepnX+qrrriugziYrkb1U=",
+          "dev": true
+        },
+        "shebang-command": {
+          "version": "2.0.0",
+          "resolved": "https://registry.npm.taobao.org/shebang-command/download/shebang-command-2.0.0.tgz",
+          "integrity": "sha1-zNCvT4g1+9wmW4JGGq8MNmY/NOo=",
+          "dev": true,
+          "requires": {
+            "shebang-regex": "^3.0.0"
+          }
+        },
+        "shebang-regex": {
+          "version": "3.0.0",
+          "resolved": "https://registry.npm.taobao.org/shebang-regex/download/shebang-regex-3.0.0.tgz",
+          "integrity": "sha1-rhbxZE2HPsrYQ7AwexQzYtTEIXI=",
+          "dev": true
+        },
+        "slash": {
+          "version": "1.0.0",
+          "resolved": "https://registry.npm.taobao.org/slash/download/slash-1.0.0.tgz",
+          "integrity": "sha1-xB8vbDn8FtHNF61LXYlhFK5HDVU=",
+          "dev": true
+        },
+        "string-width": {
+          "version": "4.2.0",
+          "resolved": "https://registry.npm.taobao.org/string-width/download/string-width-4.2.0.tgz",
+          "integrity": "sha1-lSGCxGzHssMT0VluYjmSvRY7crU=",
+          "dev": true,
+          "requires": {
+            "emoji-regex": "^8.0.0",
+            "is-fullwidth-code-point": "^3.0.0",
+            "strip-ansi": "^6.0.0"
+          }
+        },
+        "strip-ansi": {
+          "version": "6.0.0",
+          "resolved": "https://registry.npm.taobao.org/strip-ansi/download/strip-ansi-6.0.0.tgz",
+          "integrity": "sha1-CxVx3XZpzNTz4G4U7x7tJiJa5TI=",
+          "dev": true,
+          "requires": {
+            "ansi-regex": "^5.0.0"
+          }
+        },
+        "supports-color": {
+          "version": "7.2.0",
+          "resolved": "https://registry.npm.taobao.org/supports-color/download/supports-color-7.2.0.tgz?cache=0&sync_timestamp=1598611730985&other_urls=https%3A%2F%2Fregistry.npm.taobao.org%2Fsupports-color%2Fdownload%2Fsupports-color-7.2.0.tgz",
+          "integrity": "sha1-G33NyzK4E4gBs+R4umpRyqiWSNo=",
+          "dev": true,
+          "requires": {
+            "has-flag": "^4.0.0"
+          }
+        },
+        "universalify": {
+          "version": "1.0.0",
+          "resolved": "https://registry.npm.taobao.org/universalify/download/universalify-1.0.0.tgz?cache=0&sync_timestamp=1603180048005&other_urls=https%3A%2F%2Fregistry.npm.taobao.org%2Funiversalify%2Fdownload%2Funiversalify-1.0.0.tgz",
+          "integrity": "sha1-thodoXPoQ1sv48Z9Kbmt+FlL0W0=",
+          "dev": true
+        },
+        "which": {
+          "version": "2.0.2",
+          "resolved": "https://registry.npm.taobao.org/which/download/which-2.0.2.tgz",
+          "integrity": "sha1-fGqN0KY2oDJ+ELWckobu6T8/UbE=",
+          "dev": true,
+          "requires": {
+            "isexe": "^2.0.0"
+          }
+        }
+      }
+    },
+    "@cnakazawa/watch": {
+      "version": "1.0.4",
+      "resolved": "https://registry.npm.taobao.org/@cnakazawa/watch/download/@cnakazawa/watch-1.0.4.tgz",
+      "integrity": "sha1-+GSuhQBND8q29QvpFBxNo2jRZWo=",
+      "dev": true,
+      "requires": {
+        "exec-sh": "^0.3.2",
+        "minimist": "^1.2.0"
+      }
+    },
+    "@commitlint/config-conventional": {
+      "version": "8.3.4",
+      "resolved": "https://registry.npm.taobao.org/@commitlint/config-conventional/download/@commitlint/config-conventional-8.3.4.tgz",
+      "integrity": "sha1-/tE7NxFpBmOxdsH2s5wgWlZWGNI=",
+      "dev": true,
+      "requires": {
+        "conventional-changelog-conventionalcommits": "4.2.1"
+      }
+    },
+    "@formatjs/intl-unified-numberformat": {
+      "version": "3.3.7",
+      "resolved": "https://registry.npm.taobao.org/@formatjs/intl-unified-numberformat/download/@formatjs/intl-unified-numberformat-3.3.7.tgz",
+      "integrity": "sha1-mZWiRWiQgYjnFtgaHeW3ArLuAOI=",
+      "requires": {
+        "@formatjs/intl-utils": "^2.3.0"
+      }
+    },
+    "@formatjs/intl-utils": {
+      "version": "2.3.0",
+      "resolved": "https://registry.npm.taobao.org/@formatjs/intl-utils/download/@formatjs/intl-utils-2.3.0.tgz",
+      "integrity": "sha1-LcjFcETeA0DrU6e6YC5Zq/gNx5k="
+    },
+    "@ice/sandbox": {
+      "version": "1.0.6",
+      "resolved": "https://registry.npm.taobao.org/@ice/sandbox/download/@ice/sandbox-1.0.6.tgz",
+      "integrity": "sha1-z2kKdMJIA2j4eSQ9rOLAEHG5d7c=",
+      "dev": true
+    },
+    "@ice/spec": {
+      "version": "1.0.1",
+      "resolved": "https://registry.npm.taobao.org/@ice/spec/download/@ice/spec-1.0.1.tgz",
+      "integrity": "sha1-tlZSiJ7CdUwYnO1f8VuAbdtiK7M=",
+      "dev": true,
+      "requires": {
+        "@commitlint/config-conventional": "^8.1.0",
+        "@typescript-eslint/eslint-plugin": "^2.20.0",
+        "@typescript-eslint/parser": "^2.20.0",
+        "babel-eslint": "^10.0.2",
+        "eslint-config-airbnb": "^18.0.1",
+        "eslint-config-prettier": "^6.0.0",
+        "eslint-plugin-import": "^2.18.0",
+        "eslint-plugin-jsx-a11y": "^6.2.3",
+        "eslint-plugin-react": "^7.14.2",
+        "eslint-plugin-react-hooks": "^2.4.0",
+        "stylelint-config-css-modules": "^2.2.0",
+        "stylelint-config-prettier": "^8.0.1",
+        "stylelint-config-rational-order": "^0.1.2",
+        "stylelint-config-standard": "^20.0.0",
+        "stylelint-order": "^4.0.0",
+        "stylelint-scss": "^3.14.2"
+      }
+    },
+    "@ice/stark": {
+      "version": "1.6.0",
+      "resolved": "https://registry.npm.taobao.org/@ice/stark/download/@ice/stark-1.6.0.tgz",
+      "integrity": "sha1-IgWzShP9uygXb5e7g42Tlyl8mAo=",
+      "dev": true,
+      "requires": {
+        "@ice/sandbox": "^1.0.4",
+        "lodash.isequal": "^4.5.0",
+        "path-to-regexp": "^1.7.0",
+        "url-parse": "^1.1.9"
+      }
+    },
+    "@ice/stark-app": {
+      "version": "1.2.0",
+      "resolved": "https://registry.npm.taobao.org/@ice/stark-app/download/@ice/stark-app-1.2.0.tgz",
+      "integrity": "sha1-6GcqfazAfe4Ugm3AtTZjki4rn6Y=",
+      "dev": true
+    },
+    "@ice/store": {
+      "version": "1.4.2",
+      "resolved": "https://registry.npm.taobao.org/@ice/store/download/@ice/store-1.4.2.tgz",
+      "integrity": "sha1-t/EOSDic3/Bv14FFFHCL6cWG4AA=",
+      "dev": true,
+      "requires": {
+        "immer": "^6.0.2",
+        "lodash.isfunction": "^3.0.9",
+        "react-redux": "^7.2.0",
+        "redux": "^4.0.5",
+        "redux-thunk": "^2.3.0"
+      },
+      "dependencies": {
+        "immer": {
+          "version": "6.0.9",
+          "resolved": "https://registry.npm.taobao.org/immer/download/immer-6.0.9.tgz?cache=0&sync_timestamp=1603236351037&other_urls=https%3A%2F%2Fregistry.npm.taobao.org%2Fimmer%2Fdownload%2Fimmer-6.0.9.tgz",
+          "integrity": "sha1-ud1puOabOhI5HofbHj/1NdGyZIU=",
+          "dev": true
+        }
+      }
+    },
+    "@icedesign/container": {
+      "version": "1.0.5",
+      "resolved": "https://registry.npm.taobao.org/@icedesign/container/download/@icedesign/container-1.0.5.tgz",
+      "integrity": "sha1-hcV+fZXy5nGt3St3tqy5aItgHZ4=",
+      "requires": {
+        "@alifd/next": "^1.x",
+        "prop-types": "^15.5.8"
+      }
+    },
+    "@icedesign/skin": {
+      "version": "0.1.14",
+      "resolved": "https://registry.npm.taobao.org/@icedesign/skin/download/@icedesign/skin-0.1.14.tgz",
+      "integrity": "sha1-vo5i9Gelouq+efVN4jsJJegw2uI=",
+      "dev": true
+    },
+    "@istanbuljs/load-nyc-config": {
+      "version": "1.1.0",
+      "resolved": "https://registry.npm.taobao.org/@istanbuljs/load-nyc-config/download/@istanbuljs/load-nyc-config-1.1.0.tgz",
+      "integrity": "sha1-/T2x1Z7PfPEh6AZQu4ZxL5tV7O0=",
+      "dev": true,
+      "requires": {
+        "camelcase": "^5.3.1",
+        "find-up": "^4.1.0",
+        "get-package-type": "^0.1.0",
+        "js-yaml": "^3.13.1",
+        "resolve-from": "^5.0.0"
+      },
+      "dependencies": {
+        "camelcase": {
+          "version": "5.3.1",
+          "resolved": "https://registry.npm.taobao.org/camelcase/download/camelcase-5.3.1.tgz?cache=0&sync_timestamp=1603921882890&other_urls=https%3A%2F%2Fregistry.npm.taobao.org%2Fcamelcase%2Fdownload%2Fcamelcase-5.3.1.tgz",
+          "integrity": "sha1-48mzFWnhBoEd8kL3FXJaH0xJQyA=",
+          "dev": true
+        },
+        "find-up": {
+          "version": "4.1.0",
+          "resolved": "https://registry.npm.taobao.org/find-up/download/find-up-4.1.0.tgz?cache=0&sync_timestamp=1597169862146&other_urls=https%3A%2F%2Fregistry.npm.taobao.org%2Ffind-up%2Fdownload%2Ffind-up-4.1.0.tgz",
+          "integrity": "sha1-l6/n1s3AvFkoWEt8jXsW6KmqXRk=",
+          "dev": true,
+          "requires": {
+            "locate-path": "^5.0.0",
+            "path-exists": "^4.0.0"
+          }
+        },
+        "locate-path": {
+          "version": "5.0.0",
+          "resolved": "https://registry.npm.taobao.org/locate-path/download/locate-path-5.0.0.tgz",
+          "integrity": "sha1-Gvujlq/WdqbUJQTQpno6frn2KqA=",
+          "dev": true,
+          "requires": {
+            "p-locate": "^4.1.0"
+          }
+        },
+        "p-limit": {
+          "version": "2.3.0",
+          "resolved": "https://registry.npm.taobao.org/p-limit/download/p-limit-2.3.0.tgz",
+          "integrity": "sha1-PdM8ZHohT9//2DWTPrCG2g3CHbE=",
+          "dev": true,
+          "requires": {
+            "p-try": "^2.0.0"
+          }
+        },
+        "p-locate": {
+          "version": "4.1.0",
+          "resolved": "https://registry.npm.taobao.org/p-locate/download/p-locate-4.1.0.tgz?cache=0&sync_timestamp=1597081508945&other_urls=https%3A%2F%2Fregistry.npm.taobao.org%2Fp-locate%2Fdownload%2Fp-locate-4.1.0.tgz",
+          "integrity": "sha1-o0KLtwiLOmApL2aRkni3wpetTwc=",
+          "dev": true,
+          "requires": {
+            "p-limit": "^2.2.0"
+          }
+        },
+        "p-try": {
+          "version": "2.2.0",
+          "resolved": "https://registry.npm.taobao.org/p-try/download/p-try-2.2.0.tgz",
+          "integrity": "sha1-yyhoVA4xPWHeWPr741zpAE1VQOY=",
+          "dev": true
+        },
+        "path-exists": {
+          "version": "4.0.0",
+          "resolved": "https://registry.npm.taobao.org/path-exists/download/path-exists-4.0.0.tgz",
+          "integrity": "sha1-UTvb4tO5XXdi6METfvoZXGxhtbM=",
+          "dev": true
+        },
+        "resolve-from": {
+          "version": "5.0.0",
+          "resolved": "https://registry.npm.taobao.org/resolve-from/download/resolve-from-5.0.0.tgz",
+          "integrity": "sha1-w1IlhD3493bfIcV1V7wIfp39/Gk=",
+          "dev": true
+        }
+      }
+    },
+    "@istanbuljs/schema": {
+      "version": "0.1.2",
+      "resolved": "https://registry.npm.taobao.org/@istanbuljs/schema/download/@istanbuljs/schema-0.1.2.tgz",
+      "integrity": "sha1-JlIL8Jq+SlZEzVQU43ElqJVCQd0=",
+      "dev": true
+    },
+    "@jest/console": {
+      "version": "26.6.2",
+      "resolved": "https://registry.npm.taobao.org/@jest/console/download/@jest/console-26.6.2.tgz",
+      "integrity": "sha1-TgS8RkAUNYsDq0k3gF7jagrrmPI=",
+      "dev": true,
+      "requires": {
+        "@jest/types": "^26.6.2",
+        "@types/node": "*",
+        "chalk": "^4.0.0",
+        "jest-message-util": "^26.6.2",
+        "jest-util": "^26.6.2",
+        "slash": "^3.0.0"
+      },
+      "dependencies": {
+        "ansi-styles": {
+          "version": "4.3.0",
+          "resolved": "https://registry.npm.taobao.org/ansi-styles/download/ansi-styles-4.3.0.tgz?cache=0&sync_timestamp=1601839122515&other_urls=https%3A%2F%2Fregistry.npm.taobao.org%2Fansi-styles%2Fdownload%2Fansi-styles-4.3.0.tgz",
+          "integrity": "sha1-7dgDYornHATIWuegkG7a00tkiTc=",
+          "dev": true,
+          "requires": {
+            "color-convert": "^2.0.1"
+          }
+        },
+        "chalk": {
+          "version": "4.1.0",
+          "resolved": "https://registry.npm.taobao.org/chalk/download/chalk-4.1.0.tgz",
+          "integrity": "sha1-ThSHCmGNni7dl92DRf2dncMVZGo=",
+          "dev": true,
+          "requires": {
+            "ansi-styles": "^4.1.0",
+            "supports-color": "^7.1.0"
+          }
+        },
+        "color-convert": {
+          "version": "2.0.1",
+          "resolved": "https://registry.npm.taobao.org/color-convert/download/color-convert-2.0.1.tgz",
+          "integrity": "sha1-ctOmjVmMm9s68q0ehPIdiWq9TeM=",
+          "dev": true,
+          "requires": {
+            "color-name": "~1.1.4"
+          }
+        },
+        "color-name": {
+          "version": "1.1.4",
+          "resolved": "https://registry.npm.taobao.org/color-name/download/color-name-1.1.4.tgz",
+          "integrity": "sha1-wqCah6y95pVD3m9j+jmVyCbFNqI=",
+          "dev": true
+        },
+        "has-flag": {
+          "version": "4.0.0",
+          "resolved": "https://registry.npm.taobao.org/has-flag/download/has-flag-4.0.0.tgz?cache=0&sync_timestamp=1596294337050&other_urls=https%3A%2F%2Fregistry.npm.taobao.org%2Fhas-flag%2Fdownload%2Fhas-flag-4.0.0.tgz",
+          "integrity": "sha1-lEdx/ZyByBJlxNaUGGDaBrtZR5s=",
+          "dev": true
+        },
+        "slash": {
+          "version": "3.0.0",
+          "resolved": "https://registry.npm.taobao.org/slash/download/slash-3.0.0.tgz",
+          "integrity": "sha1-ZTm+hwwWWtvVJAIg2+Nh8bxNRjQ=",
+          "dev": true
+        },
+        "supports-color": {
+          "version": "7.2.0",
+          "resolved": "https://registry.npm.taobao.org/supports-color/download/supports-color-7.2.0.tgz?cache=0&sync_timestamp=1598611730985&other_urls=https%3A%2F%2Fregistry.npm.taobao.org%2Fsupports-color%2Fdownload%2Fsupports-color-7.2.0.tgz",
+          "integrity": "sha1-G33NyzK4E4gBs+R4umpRyqiWSNo=",
+          "dev": true,
+          "requires": {
+            "has-flag": "^4.0.0"
+          }
+        }
+      }
+    },
+    "@jest/core": {
+      "version": "26.6.3",
+      "resolved": "https://registry.npm.taobao.org/@jest/core/download/@jest/core-26.6.3.tgz?cache=0&sync_timestamp=1604468975323&other_urls=https%3A%2F%2Fregistry.npm.taobao.org%2F%40jest%2Fcore%2Fdownload%2F%40jest%2Fcore-26.6.3.tgz",
+      "integrity": "sha1-djn8s4M9dIpGVq2lS94ZMFHkX60=",
+      "dev": true,
+      "requires": {
+        "@jest/console": "^26.6.2",
+        "@jest/reporters": "^26.6.2",
+        "@jest/test-result": "^26.6.2",
+        "@jest/transform": "^26.6.2",
+        "@jest/types": "^26.6.2",
+        "@types/node": "*",
+        "ansi-escapes": "^4.2.1",
+        "chalk": "^4.0.0",
+        "exit": "^0.1.2",
+        "graceful-fs": "^4.2.4",
+        "jest-changed-files": "^26.6.2",
+        "jest-config": "^26.6.3",
+        "jest-haste-map": "^26.6.2",
+        "jest-message-util": "^26.6.2",
+        "jest-regex-util": "^26.0.0",
+        "jest-resolve": "^26.6.2",
+        "jest-resolve-dependencies": "^26.6.3",
+        "jest-runner": "^26.6.3",
+        "jest-runtime": "^26.6.3",
+        "jest-snapshot": "^26.6.2",
+        "jest-util": "^26.6.2",
+        "jest-validate": "^26.6.2",
+        "jest-watcher": "^26.6.2",
+        "micromatch": "^4.0.2",
+        "p-each-series": "^2.1.0",
+        "rimraf": "^3.0.0",
+        "slash": "^3.0.0",
+        "strip-ansi": "^6.0.0"
+      },
+      "dependencies": {
+        "ansi-regex": {
+          "version": "5.0.0",
+          "resolved": "https://registry.npm.taobao.org/ansi-regex/download/ansi-regex-5.0.0.tgz",
+          "integrity": "sha1-OIU59VF5vzkznIGvMKZU1p+Hy3U=",
+          "dev": true
+        },
+        "ansi-styles": {
+          "version": "4.3.0",
+          "resolved": "https://registry.npm.taobao.org/ansi-styles/download/ansi-styles-4.3.0.tgz?cache=0&sync_timestamp=1601839122515&other_urls=https%3A%2F%2Fregistry.npm.taobao.org%2Fansi-styles%2Fdownload%2Fansi-styles-4.3.0.tgz",
+          "integrity": "sha1-7dgDYornHATIWuegkG7a00tkiTc=",
+          "dev": true,
+          "requires": {
+            "color-convert": "^2.0.1"
+          }
+        },
+        "braces": {
+          "version": "3.0.2",
+          "resolved": "https://registry.npm.taobao.org/braces/download/braces-3.0.2.tgz",
+          "integrity": "sha1-NFThpGLujVmeI23zNs2epPiv4Qc=",
+          "dev": true,
+          "requires": {
+            "fill-range": "^7.0.1"
+          }
+        },
+        "chalk": {
+          "version": "4.1.0",
+          "resolved": "https://registry.npm.taobao.org/chalk/download/chalk-4.1.0.tgz",
+          "integrity": "sha1-ThSHCmGNni7dl92DRf2dncMVZGo=",
+          "dev": true,
+          "requires": {
+            "ansi-styles": "^4.1.0",
+            "supports-color": "^7.1.0"
+          }
+        },
+        "color-convert": {
+          "version": "2.0.1",
+          "resolved": "https://registry.npm.taobao.org/color-convert/download/color-convert-2.0.1.tgz",
+          "integrity": "sha1-ctOmjVmMm9s68q0ehPIdiWq9TeM=",
+          "dev": true,
+          "requires": {
+            "color-name": "~1.1.4"
+          }
+        },
+        "color-name": {
+          "version": "1.1.4",
+          "resolved": "https://registry.npm.taobao.org/color-name/download/color-name-1.1.4.tgz",
+          "integrity": "sha1-wqCah6y95pVD3m9j+jmVyCbFNqI=",
+          "dev": true
+        },
+        "fill-range": {
+          "version": "7.0.1",
+          "resolved": "https://registry.npm.taobao.org/fill-range/download/fill-range-7.0.1.tgz",
+          "integrity": "sha1-GRmmp8df44ssfHflGYU12prN2kA=",
+          "dev": true,
+          "requires": {
+            "to-regex-range": "^5.0.1"
+          }
+        },
+        "has-flag": {
+          "version": "4.0.0",
+          "resolved": "https://registry.npm.taobao.org/has-flag/download/has-flag-4.0.0.tgz?cache=0&sync_timestamp=1596294337050&other_urls=https%3A%2F%2Fregistry.npm.taobao.org%2Fhas-flag%2Fdownload%2Fhas-flag-4.0.0.tgz",
+          "integrity": "sha1-lEdx/ZyByBJlxNaUGGDaBrtZR5s=",
+          "dev": true
+        },
+        "is-number": {
+          "version": "7.0.0",
+          "resolved": "https://registry.npm.taobao.org/is-number/download/is-number-7.0.0.tgz",
+          "integrity": "sha1-dTU0W4lnNNX4DE0GxQlVUnoU8Ss=",
+          "dev": true
+        },
+        "micromatch": {
+          "version": "4.0.2",
+          "resolved": "https://registry.npm.taobao.org/micromatch/download/micromatch-4.0.2.tgz",
+          "integrity": "sha1-T8sJmb+fvC/L3SEvbWKbmlbDklk=",
+          "dev": true,
+          "requires": {
+            "braces": "^3.0.1",
+            "picomatch": "^2.0.5"
+          }
+        },
+        "rimraf": {
+          "version": "3.0.2",
+          "resolved": "https://registry.npm.taobao.org/rimraf/download/rimraf-3.0.2.tgz?cache=0&sync_timestamp=1587992602190&other_urls=https%3A%2F%2Fregistry.npm.taobao.org%2Frimraf%2Fdownload%2Frimraf-3.0.2.tgz",
+          "integrity": "sha1-8aVAK6YiCtUswSgrrBrjqkn9Bho=",
+          "dev": true,
+          "requires": {
+            "glob": "^7.1.3"
+          }
+        },
+        "slash": {
+          "version": "3.0.0",
+          "resolved": "https://registry.npm.taobao.org/slash/download/slash-3.0.0.tgz",
+          "integrity": "sha1-ZTm+hwwWWtvVJAIg2+Nh8bxNRjQ=",
+          "dev": true
+        },
+        "strip-ansi": {
+          "version": "6.0.0",
+          "resolved": "https://registry.npm.taobao.org/strip-ansi/download/strip-ansi-6.0.0.tgz",
+          "integrity": "sha1-CxVx3XZpzNTz4G4U7x7tJiJa5TI=",
+          "dev": true,
+          "requires": {
+            "ansi-regex": "^5.0.0"
+          }
+        },
+        "supports-color": {
+          "version": "7.2.0",
+          "resolved": "https://registry.npm.taobao.org/supports-color/download/supports-color-7.2.0.tgz?cache=0&sync_timestamp=1598611730985&other_urls=https%3A%2F%2Fregistry.npm.taobao.org%2Fsupports-color%2Fdownload%2Fsupports-color-7.2.0.tgz",
+          "integrity": "sha1-G33NyzK4E4gBs+R4umpRyqiWSNo=",
+          "dev": true,
+          "requires": {
+            "has-flag": "^4.0.0"
+          }
+        },
+        "to-regex-range": {
+          "version": "5.0.1",
+          "resolved": "https://registry.npm.taobao.org/to-regex-range/download/to-regex-range-5.0.1.tgz",
+          "integrity": "sha1-FkjESq58jZiKMmAY7XL1tN0DkuQ=",
+          "dev": true,
+          "requires": {
+            "is-number": "^7.0.0"
+          }
+        }
+      }
+    },
+    "@jest/environment": {
+      "version": "26.6.2",
+      "resolved": "https://registry.npm.taobao.org/@jest/environment/download/@jest/environment-26.6.2.tgz",
+      "integrity": "sha1-ujZMxy4iHnnMjwqZVVv111d8+Sw=",
+      "dev": true,
+      "requires": {
+        "@jest/fake-timers": "^26.6.2",
+        "@jest/types": "^26.6.2",
+        "@types/node": "*",
+        "jest-mock": "^26.6.2"
+      }
+    },
+    "@jest/fake-timers": {
+      "version": "26.6.2",
+      "resolved": "https://registry.npm.taobao.org/@jest/fake-timers/download/@jest/fake-timers-26.6.2.tgz",
+      "integrity": "sha1-RZwym89wzuSvTX4/PmeEgSNTWq0=",
+      "dev": true,
+      "requires": {
+        "@jest/types": "^26.6.2",
+        "@sinonjs/fake-timers": "^6.0.1",
+        "@types/node": "*",
+        "jest-message-util": "^26.6.2",
+        "jest-mock": "^26.6.2",
+        "jest-util": "^26.6.2"
+      }
+    },
+    "@jest/globals": {
+      "version": "26.6.2",
+      "resolved": "https://registry.npm.taobao.org/@jest/globals/download/@jest/globals-26.6.2.tgz?cache=0&sync_timestamp=1604321658564&other_urls=https%3A%2F%2Fregistry.npm.taobao.org%2F%40jest%2Fglobals%2Fdownload%2F%40jest%2Fglobals-26.6.2.tgz",
+      "integrity": "sha1-W2E7eKGqJlWukI66Y4zJaiDfcgo=",
+      "dev": true,
+      "requires": {
+        "@jest/environment": "^26.6.2",
+        "@jest/types": "^26.6.2",
+        "expect": "^26.6.2"
+      }
+    },
+    "@jest/reporters": {
+      "version": "26.6.2",
+      "resolved": "https://registry.npm.taobao.org/@jest/reporters/download/@jest/reporters-26.6.2.tgz",
+      "integrity": "sha1-H1GLmWN6Xxgwe9Ps+SdfaIKmZ/Y=",
+      "dev": true,
+      "requires": {
+        "@bcoe/v8-coverage": "^0.2.3",
+        "@jest/console": "^26.6.2",
+        "@jest/test-result": "^26.6.2",
+        "@jest/transform": "^26.6.2",
+        "@jest/types": "^26.6.2",
+        "chalk": "^4.0.0",
+        "collect-v8-coverage": "^1.0.0",
+        "exit": "^0.1.2",
+        "glob": "^7.1.2",
+        "graceful-fs": "^4.2.4",
+        "istanbul-lib-coverage": "^3.0.0",
+        "istanbul-lib-instrument": "^4.0.3",
+        "istanbul-lib-report": "^3.0.0",
+        "istanbul-lib-source-maps": "^4.0.0",
+        "istanbul-reports": "^3.0.2",
+        "jest-haste-map": "^26.6.2",
+        "jest-resolve": "^26.6.2",
+        "jest-util": "^26.6.2",
+        "jest-worker": "^26.6.2",
+        "node-notifier": "^8.0.0",
+        "slash": "^3.0.0",
+        "source-map": "^0.6.0",
+        "string-length": "^4.0.1",
+        "terminal-link": "^2.0.0",
+        "v8-to-istanbul": "^7.0.0"
+      },
+      "dependencies": {
+        "ansi-styles": {
+          "version": "4.3.0",
+          "resolved": "https://registry.npm.taobao.org/ansi-styles/download/ansi-styles-4.3.0.tgz?cache=0&sync_timestamp=1601839122515&other_urls=https%3A%2F%2Fregistry.npm.taobao.org%2Fansi-styles%2Fdownload%2Fansi-styles-4.3.0.tgz",
+          "integrity": "sha1-7dgDYornHATIWuegkG7a00tkiTc=",
+          "dev": true,
+          "requires": {
+            "color-convert": "^2.0.1"
+          }
+        },
+        "chalk": {
+          "version": "4.1.0",
+          "resolved": "https://registry.npm.taobao.org/chalk/download/chalk-4.1.0.tgz",
+          "integrity": "sha1-ThSHCmGNni7dl92DRf2dncMVZGo=",
+          "dev": true,
+          "requires": {
+            "ansi-styles": "^4.1.0",
+            "supports-color": "^7.1.0"
+          }
+        },
+        "color-convert": {
+          "version": "2.0.1",
+          "resolved": "https://registry.npm.taobao.org/color-convert/download/color-convert-2.0.1.tgz",
+          "integrity": "sha1-ctOmjVmMm9s68q0ehPIdiWq9TeM=",
+          "dev": true,
+          "requires": {
+            "color-name": "~1.1.4"
+          }
+        },
+        "color-name": {
+          "version": "1.1.4",
+          "resolved": "https://registry.npm.taobao.org/color-name/download/color-name-1.1.4.tgz",
+          "integrity": "sha1-wqCah6y95pVD3m9j+jmVyCbFNqI=",
+          "dev": true
+        },
+        "has-flag": {
+          "version": "4.0.0",
+          "resolved": "https://registry.npm.taobao.org/has-flag/download/has-flag-4.0.0.tgz?cache=0&sync_timestamp=1596294337050&other_urls=https%3A%2F%2Fregistry.npm.taobao.org%2Fhas-flag%2Fdownload%2Fhas-flag-4.0.0.tgz",
+          "integrity": "sha1-lEdx/ZyByBJlxNaUGGDaBrtZR5s=",
+          "dev": true
+        },
+        "slash": {
+          "version": "3.0.0",
+          "resolved": "https://registry.npm.taobao.org/slash/download/slash-3.0.0.tgz",
+          "integrity": "sha1-ZTm+hwwWWtvVJAIg2+Nh8bxNRjQ=",
+          "dev": true
+        },
+        "source-map": {
+          "version": "0.6.1",
+          "resolved": "https://registry.npm.taobao.org/source-map/download/source-map-0.6.1.tgz",
+          "integrity": "sha1-dHIq8y6WFOnCh6jQu95IteLxomM=",
+          "dev": true
+        },
+        "supports-color": {
+          "version": "7.2.0",
+          "resolved": "https://registry.npm.taobao.org/supports-color/download/supports-color-7.2.0.tgz?cache=0&sync_timestamp=1598611730985&other_urls=https%3A%2F%2Fregistry.npm.taobao.org%2Fsupports-color%2Fdownload%2Fsupports-color-7.2.0.tgz",
+          "integrity": "sha1-G33NyzK4E4gBs+R4umpRyqiWSNo=",
+          "dev": true,
+          "requires": {
+            "has-flag": "^4.0.0"
+          }
+        }
+      }
+    },
+    "@jest/source-map": {
+      "version": "26.6.2",
+      "resolved": "https://registry.npm.taobao.org/@jest/source-map/download/@jest/source-map-26.6.2.tgz?cache=0&sync_timestamp=1604319711726&other_urls=https%3A%2F%2Fregistry.npm.taobao.org%2F%40jest%2Fsource-map%2Fdownload%2F%40jest%2Fsource-map-26.6.2.tgz",
+      "integrity": "sha1-Ka9eHi4yTK/MyTbyGDCfVKtp1TU=",
+      "dev": true,
+      "requires": {
+        "callsites": "^3.0.0",
+        "graceful-fs": "^4.2.4",
+        "source-map": "^0.6.0"
+      },
+      "dependencies": {
+        "callsites": {
+          "version": "3.1.0",
+          "resolved": "https://registry.npm.taobao.org/callsites/download/callsites-3.1.0.tgz",
+          "integrity": "sha1-s2MKvYlDQy9Us/BRkjjjPNffL3M=",
+          "dev": true
+        },
+        "source-map": {
+          "version": "0.6.1",
+          "resolved": "https://registry.npm.taobao.org/source-map/download/source-map-0.6.1.tgz",
+          "integrity": "sha1-dHIq8y6WFOnCh6jQu95IteLxomM=",
+          "dev": true
+        }
+      }
+    },
+    "@jest/test-result": {
+      "version": "26.6.2",
+      "resolved": "https://registry.npm.taobao.org/@jest/test-result/download/@jest/test-result-26.6.2.tgz",
+      "integrity": "sha1-VdpYti3xNFdsyVR276X3lJ4/Xxg=",
+      "dev": true,
+      "requires": {
+        "@jest/console": "^26.6.2",
+        "@jest/types": "^26.6.2",
+        "@types/istanbul-lib-coverage": "^2.0.0",
+        "collect-v8-coverage": "^1.0.0"
+      }
+    },
+    "@jest/test-sequencer": {
+      "version": "26.6.3",
+      "resolved": "https://registry.npm.taobao.org/@jest/test-sequencer/download/@jest/test-sequencer-26.6.3.tgz?cache=0&sync_timestamp=1604469032027&other_urls=https%3A%2F%2Fregistry.npm.taobao.org%2F%40jest%2Ftest-sequencer%2Fdownload%2F%40jest%2Ftest-sequencer-26.6.3.tgz",
+      "integrity": "sha1-mOikUQCGOIbQdCBej/3Fp+tYKxc=",
+      "dev": true,
+      "requires": {
+        "@jest/test-result": "^26.6.2",
+        "graceful-fs": "^4.2.4",
+        "jest-haste-map": "^26.6.2",
+        "jest-runner": "^26.6.3",
+        "jest-runtime": "^26.6.3"
+      }
+    },
+    "@jest/transform": {
+      "version": "26.6.2",
+      "resolved": "https://registry.npm.taobao.org/@jest/transform/download/@jest/transform-26.6.2.tgz",
+      "integrity": "sha1-WsV8X6GtF7Kq6D5z5FgTiU3PLks=",
+      "dev": true,
+      "requires": {
+        "@babel/core": "^7.1.0",
+        "@jest/types": "^26.6.2",
+        "babel-plugin-istanbul": "^6.0.0",
+        "chalk": "^4.0.0",
+        "convert-source-map": "^1.4.0",
+        "fast-json-stable-stringify": "^2.0.0",
+        "graceful-fs": "^4.2.4",
+        "jest-haste-map": "^26.6.2",
+        "jest-regex-util": "^26.0.0",
+        "jest-util": "^26.6.2",
+        "micromatch": "^4.0.2",
+        "pirates": "^4.0.1",
+        "slash": "^3.0.0",
+        "source-map": "^0.6.1",
+        "write-file-atomic": "^3.0.0"
+      },
+      "dependencies": {
+        "ansi-styles": {
+          "version": "4.3.0",
+          "resolved": "https://registry.npm.taobao.org/ansi-styles/download/ansi-styles-4.3.0.tgz?cache=0&sync_timestamp=1601839122515&other_urls=https%3A%2F%2Fregistry.npm.taobao.org%2Fansi-styles%2Fdownload%2Fansi-styles-4.3.0.tgz",
+          "integrity": "sha1-7dgDYornHATIWuegkG7a00tkiTc=",
+          "dev": true,
+          "requires": {
+            "color-convert": "^2.0.1"
+          }
+        },
+        "braces": {
+          "version": "3.0.2",
+          "resolved": "https://registry.npm.taobao.org/braces/download/braces-3.0.2.tgz",
+          "integrity": "sha1-NFThpGLujVmeI23zNs2epPiv4Qc=",
+          "dev": true,
+          "requires": {
+            "fill-range": "^7.0.1"
+          }
+        },
+        "chalk": {
+          "version": "4.1.0",
+          "resolved": "https://registry.npm.taobao.org/chalk/download/chalk-4.1.0.tgz",
+          "integrity": "sha1-ThSHCmGNni7dl92DRf2dncMVZGo=",
+          "dev": true,
+          "requires": {
+            "ansi-styles": "^4.1.0",
+            "supports-color": "^7.1.0"
+          }
+        },
+        "color-convert": {
+          "version": "2.0.1",
+          "resolved": "https://registry.npm.taobao.org/color-convert/download/color-convert-2.0.1.tgz",
+          "integrity": "sha1-ctOmjVmMm9s68q0ehPIdiWq9TeM=",
+          "dev": true,
+          "requires": {
+            "color-name": "~1.1.4"
+          }
+        },
+        "color-name": {
+          "version": "1.1.4",
+          "resolved": "https://registry.npm.taobao.org/color-name/download/color-name-1.1.4.tgz",
+          "integrity": "sha1-wqCah6y95pVD3m9j+jmVyCbFNqI=",
+          "dev": true
+        },
+        "fill-range": {
+          "version": "7.0.1",
+          "resolved": "https://registry.npm.taobao.org/fill-range/download/fill-range-7.0.1.tgz",
+          "integrity": "sha1-GRmmp8df44ssfHflGYU12prN2kA=",
+          "dev": true,
+          "requires": {
+            "to-regex-range": "^5.0.1"
+          }
+        },
+        "has-flag": {
+          "version": "4.0.0",
+          "resolved": "https://registry.npm.taobao.org/has-flag/download/has-flag-4.0.0.tgz?cache=0&sync_timestamp=1596294337050&other_urls=https%3A%2F%2Fregistry.npm.taobao.org%2Fhas-flag%2Fdownload%2Fhas-flag-4.0.0.tgz",
+          "integrity": "sha1-lEdx/ZyByBJlxNaUGGDaBrtZR5s=",
+          "dev": true
+        },
+        "is-number": {
+          "version": "7.0.0",
+          "resolved": "https://registry.npm.taobao.org/is-number/download/is-number-7.0.0.tgz",
+          "integrity": "sha1-dTU0W4lnNNX4DE0GxQlVUnoU8Ss=",
+          "dev": true
+        },
+        "micromatch": {
+          "version": "4.0.2",
+          "resolved": "https://registry.npm.taobao.org/micromatch/download/micromatch-4.0.2.tgz",
+          "integrity": "sha1-T8sJmb+fvC/L3SEvbWKbmlbDklk=",
+          "dev": true,
+          "requires": {
+            "braces": "^3.0.1",
+            "picomatch": "^2.0.5"
+          }
+        },
+        "slash": {
+          "version": "3.0.0",
+          "resolved": "https://registry.npm.taobao.org/slash/download/slash-3.0.0.tgz",
+          "integrity": "sha1-ZTm+hwwWWtvVJAIg2+Nh8bxNRjQ=",
+          "dev": true
+        },
+        "source-map": {
+          "version": "0.6.1",
+          "resolved": "https://registry.npm.taobao.org/source-map/download/source-map-0.6.1.tgz",
+          "integrity": "sha1-dHIq8y6WFOnCh6jQu95IteLxomM=",
+          "dev": true
+        },
+        "supports-color": {
+          "version": "7.2.0",
+          "resolved": "https://registry.npm.taobao.org/supports-color/download/supports-color-7.2.0.tgz?cache=0&sync_timestamp=1598611730985&other_urls=https%3A%2F%2Fregistry.npm.taobao.org%2Fsupports-color%2Fdownload%2Fsupports-color-7.2.0.tgz",
+          "integrity": "sha1-G33NyzK4E4gBs+R4umpRyqiWSNo=",
+          "dev": true,
+          "requires": {
+            "has-flag": "^4.0.0"
+          }
+        },
+        "to-regex-range": {
+          "version": "5.0.1",
+          "resolved": "https://registry.npm.taobao.org/to-regex-range/download/to-regex-range-5.0.1.tgz",
+          "integrity": "sha1-FkjESq58jZiKMmAY7XL1tN0DkuQ=",
+          "dev": true,
+          "requires": {
+            "is-number": "^7.0.0"
+          }
+        }
+      }
+    },
+    "@jest/types": {
+      "version": "26.6.2",
+      "resolved": "https://registry.npm.taobao.org/@jest/types/download/@jest/types-26.6.2.tgz",
+      "integrity": "sha1-vvWlMgMOHYii9abZM/hOlyJu1I4=",
+      "dev": true,
+      "requires": {
+        "@types/istanbul-lib-coverage": "^2.0.0",
+        "@types/istanbul-reports": "^3.0.0",
+        "@types/node": "*",
+        "@types/yargs": "^15.0.0",
+        "chalk": "^4.0.0"
+      },
+      "dependencies": {
+        "ansi-styles": {
+          "version": "4.3.0",
+          "resolved": "https://registry.npm.taobao.org/ansi-styles/download/ansi-styles-4.3.0.tgz?cache=0&sync_timestamp=1601839122515&other_urls=https%3A%2F%2Fregistry.npm.taobao.org%2Fansi-styles%2Fdownload%2Fansi-styles-4.3.0.tgz",
+          "integrity": "sha1-7dgDYornHATIWuegkG7a00tkiTc=",
+          "dev": true,
+          "requires": {
+            "color-convert": "^2.0.1"
+          }
+        },
+        "chalk": {
+          "version": "4.1.0",
+          "resolved": "https://registry.npm.taobao.org/chalk/download/chalk-4.1.0.tgz",
+          "integrity": "sha1-ThSHCmGNni7dl92DRf2dncMVZGo=",
+          "dev": true,
+          "requires": {
+            "ansi-styles": "^4.1.0",
+            "supports-color": "^7.1.0"
+          }
+        },
+        "color-convert": {
+          "version": "2.0.1",
+          "resolved": "https://registry.npm.taobao.org/color-convert/download/color-convert-2.0.1.tgz",
+          "integrity": "sha1-ctOmjVmMm9s68q0ehPIdiWq9TeM=",
+          "dev": true,
+          "requires": {
+            "color-name": "~1.1.4"
+          }
+        },
+        "color-name": {
+          "version": "1.1.4",
+          "resolved": "https://registry.npm.taobao.org/color-name/download/color-name-1.1.4.tgz",
+          "integrity": "sha1-wqCah6y95pVD3m9j+jmVyCbFNqI=",
+          "dev": true
+        },
+        "has-flag": {
+          "version": "4.0.0",
+          "resolved": "https://registry.npm.taobao.org/has-flag/download/has-flag-4.0.0.tgz?cache=0&sync_timestamp=1596294337050&other_urls=https%3A%2F%2Fregistry.npm.taobao.org%2Fhas-flag%2Fdownload%2Fhas-flag-4.0.0.tgz",
+          "integrity": "sha1-lEdx/ZyByBJlxNaUGGDaBrtZR5s=",
+          "dev": true
+        },
+        "supports-color": {
+          "version": "7.2.0",
+          "resolved": "https://registry.npm.taobao.org/supports-color/download/supports-color-7.2.0.tgz?cache=0&sync_timestamp=1598611730985&other_urls=https%3A%2F%2Fregistry.npm.taobao.org%2Fsupports-color%2Fdownload%2Fsupports-color-7.2.0.tgz",
+          "integrity": "sha1-G33NyzK4E4gBs+R4umpRyqiWSNo=",
+          "dev": true,
+          "requires": {
+            "has-flag": "^4.0.0"
+          }
+        }
+      }
+    },
+    "@mrmlnc/readdir-enhanced": {
+      "version": "2.2.1",
+      "resolved": "https://registry.npm.taobao.org/@mrmlnc/readdir-enhanced/download/@mrmlnc/readdir-enhanced-2.2.1.tgz",
+      "integrity": "sha1-UkryQNGjYFJ7cwR17PoTRKpUDd4=",
+      "dev": true,
+      "requires": {
+        "call-me-maybe": "^1.0.1",
+        "glob-to-regexp": "^0.3.0"
+      }
+    },
+    "@nodelib/fs.scandir": {
+      "version": "2.1.3",
+      "resolved": "https://registry.npm.taobao.org/@nodelib/fs.scandir/download/@nodelib/fs.scandir-2.1.3.tgz",
+      "integrity": "sha1-Olgr21OATGum0UZXnEblITDPSjs=",
+      "dev": true,
+      "requires": {
+        "@nodelib/fs.stat": "2.0.3",
+        "run-parallel": "^1.1.9"
+      },
+      "dependencies": {
+        "@nodelib/fs.stat": {
+          "version": "2.0.3",
+          "resolved": "https://registry.npm.taobao.org/@nodelib/fs.stat/download/@nodelib/fs.stat-2.0.3.tgz",
+          "integrity": "sha1-NNxfTKu8cg9OYPdadH5+zWwXW9M=",
+          "dev": true
+        }
+      }
+    },
+    "@nodelib/fs.stat": {
+      "version": "1.1.3",
+      "resolved": "https://registry.npm.taobao.org/@nodelib/fs.stat/download/@nodelib/fs.stat-1.1.3.tgz",
+      "integrity": "sha1-K1o6s/kYzKSKjHVMCBaOPwPrphs=",
+      "dev": true
+    },
+    "@nodelib/fs.walk": {
+      "version": "1.2.4",
+      "resolved": "https://registry.npm.taobao.org/@nodelib/fs.walk/download/@nodelib/fs.walk-1.2.4.tgz",
+      "integrity": "sha1-ARuSAqcKY2bkNspcBlhEUoqwSXY=",
+      "dev": true,
+      "requires": {
+        "@nodelib/fs.scandir": "2.1.3",
+        "fastq": "^1.6.0"
+      }
+    },
+    "@npmcli/move-file": {
+      "version": "1.0.1",
+      "resolved": "https://registry.npm.taobao.org/@npmcli/move-file/download/@npmcli/move-file-1.0.1.tgz",
+      "integrity": "sha1-3hAwcNrA9IzknPZpPCOvWcD3BGQ=",
+      "dev": true,
+      "requires": {
+        "mkdirp": "^1.0.4"
+      },
+      "dependencies": {
+        "mkdirp": {
+          "version": "1.0.4",
+          "resolved": "https://registry.npm.taobao.org/mkdirp/download/mkdirp-1.0.4.tgz?cache=0&sync_timestamp=1587535418745&other_urls=https%3A%2F%2Fregistry.npm.taobao.org%2Fmkdirp%2Fdownload%2Fmkdirp-1.0.4.tgz",
+          "integrity": "sha1-PrXtYmInVteaXw4qIh3+utdcL34=",
+          "dev": true
+        }
+      }
+    },
+    "@sinonjs/commons": {
+      "version": "1.8.1",
+      "resolved": "https://registry.npm.taobao.org/@sinonjs/commons/download/@sinonjs/commons-1.8.1.tgz?cache=0&sync_timestamp=1594975802135&other_urls=https%3A%2F%2Fregistry.npm.taobao.org%2F%40sinonjs%2Fcommons%2Fdownload%2F%40sinonjs%2Fcommons-1.8.1.tgz",
+      "integrity": "sha1-598A+YogMyT23HzGBsrZ1KirIhc=",
+      "dev": true,
+      "requires": {
+        "type-detect": "4.0.8"
+      }
+    },
+    "@sinonjs/fake-timers": {
+      "version": "6.0.1",
+      "resolved": "https://registry.npm.taobao.org/@sinonjs/fake-timers/download/@sinonjs/fake-timers-6.0.1.tgz",
+      "integrity": "sha1-KTZ0/MsyYqx4LHqt/eyoaxDHXEA=",
+      "dev": true,
+      "requires": {
+        "@sinonjs/commons": "^1.7.0"
+      }
+    },
+    "@stylelint/postcss-css-in-js": {
+      "version": "0.37.2",
+      "resolved": "https://registry.npm.taobao.org/@stylelint/postcss-css-in-js/download/@stylelint/postcss-css-in-js-0.37.2.tgz",
+      "integrity": "sha1-flqErRgfQjSiSAgDQipHuHSa89I=",
+      "dev": true,
+      "requires": {
+        "@babel/core": ">=7.9.0"
+      }
+    },
+    "@stylelint/postcss-markdown": {
+      "version": "0.36.1",
+      "resolved": "https://registry.npm.taobao.org/@stylelint/postcss-markdown/download/@stylelint/postcss-markdown-0.36.1.tgz",
+      "integrity": "sha1-gpuH5sDxCAFFM9nXuYfcnvtmMug=",
+      "dev": true,
+      "requires": {
+        "remark": "^12.0.0",
+        "unist-util-find-all-after": "^3.0.1"
+      },
+      "dependencies": {
+        "is-buffer": {
+          "version": "2.0.5",
+          "resolved": "https://registry.npm.taobao.org/is-buffer/download/is-buffer-2.0.5.tgz?cache=0&sync_timestamp=1604429452232&other_urls=https%3A%2F%2Fregistry.npm.taobao.org%2Fis-buffer%2Fdownload%2Fis-buffer-2.0.5.tgz",
+          "integrity": "sha1-68JS5ADSL/jXf6CYiIIaJKZYwZE=",
+          "dev": true
+        },
+        "is-plain-obj": {
+          "version": "2.1.0",
+          "resolved": "https://registry.npm.taobao.org/is-plain-obj/download/is-plain-obj-2.1.0.tgz?cache=0&sync_timestamp=1602541991817&other_urls=https%3A%2F%2Fregistry.npm.taobao.org%2Fis-plain-obj%2Fdownload%2Fis-plain-obj-2.1.0.tgz",
+          "integrity": "sha1-ReQuN/zPH0Dajl927iFRWEDAkoc=",
+          "dev": true
+        },
+        "markdown-table": {
+          "version": "2.0.0",
+          "resolved": "https://registry.npm.taobao.org/markdown-table/download/markdown-table-2.0.0.tgz",
+          "integrity": "sha1-GUqQztJtMf51PYuUNEMCFMARhls=",
+          "dev": true,
+          "requires": {
+            "repeat-string": "^1.0.0"
+          }
+        },
+        "mdast-util-compact": {
+          "version": "2.0.1",
+          "resolved": "https://registry.npm.taobao.org/mdast-util-compact/download/mdast-util-compact-2.0.1.tgz",
+          "integrity": "sha1-yrxpovQxA2KDJvNbGs9zXVXJlJA=",
+          "dev": true,
+          "requires": {
+            "unist-util-visit": "^2.0.0"
+          }
+        },
+        "parse-entities": {
+          "version": "2.0.0",
+          "resolved": "https://registry.npm.taobao.org/parse-entities/download/parse-entities-2.0.0.tgz",
+          "integrity": "sha1-U8brW5MUofTsmfoP33zgHs2gy+g=",
+          "dev": true,
+          "requires": {
+            "character-entities": "^1.0.0",
+            "character-entities-legacy": "^1.0.0",
+            "character-reference-invalid": "^1.0.0",
+            "is-alphanumerical": "^1.0.0",
+            "is-decimal": "^1.0.0",
+            "is-hexadecimal": "^1.0.0"
+          }
+        },
+        "remark": {
+          "version": "12.0.1",
+          "resolved": "https://registry.npm.taobao.org/remark/download/remark-12.0.1.tgz?cache=0&sync_timestamp=1602663771669&other_urls=https%3A%2F%2Fregistry.npm.taobao.org%2Fremark%2Fdownload%2Fremark-12.0.1.tgz",
+          "integrity": "sha1-8d32jbe+ccorrQozzTZ4uGuccJ8=",
+          "dev": true,
+          "requires": {
+            "remark-parse": "^8.0.0",
+            "remark-stringify": "^8.0.0",
+            "unified": "^9.0.0"
+          }
+        },
+        "remark-parse": {
+          "version": "8.0.3",
+          "resolved": "https://registry.npm.taobao.org/remark-parse/download/remark-parse-8.0.3.tgz?cache=0&sync_timestamp=1602663568829&other_urls=https%3A%2F%2Fregistry.npm.taobao.org%2Fremark-parse%2Fdownload%2Fremark-parse-8.0.3.tgz",
+          "integrity": "sha1-nGKqOzW3mkhkVMaQRykGB19Ax+E=",
+          "dev": true,
+          "requires": {
+            "ccount": "^1.0.0",
+            "collapse-white-space": "^1.0.2",
+            "is-alphabetical": "^1.0.0",
+            "is-decimal": "^1.0.0",
+            "is-whitespace-character": "^1.0.0",
+            "is-word-character": "^1.0.0",
+            "markdown-escapes": "^1.0.0",
+            "parse-entities": "^2.0.0",
+            "repeat-string": "^1.5.4",
+            "state-toggle": "^1.0.0",
+            "trim": "0.0.1",
+            "trim-trailing-lines": "^1.0.0",
+            "unherit": "^1.0.4",
+            "unist-util-remove-position": "^2.0.0",
+            "vfile-location": "^3.0.0",
+            "xtend": "^4.0.1"
+          }
+        },
+        "remark-stringify": {
+          "version": "8.1.1",
+          "resolved": "https://registry.npm.taobao.org/remark-stringify/download/remark-stringify-8.1.1.tgz?cache=0&sync_timestamp=1602663716084&other_urls=https%3A%2F%2Fregistry.npm.taobao.org%2Fremark-stringify%2Fdownload%2Fremark-stringify-8.1.1.tgz",
+          "integrity": "sha1-4qncenv0TkahVex4mW24lngNjOU=",
+          "dev": true,
+          "requires": {
+            "ccount": "^1.0.0",
+            "is-alphanumeric": "^1.0.0",
+            "is-decimal": "^1.0.0",
+            "is-whitespace-character": "^1.0.0",
+            "longest-streak": "^2.0.1",
+            "markdown-escapes": "^1.0.0",
+            "markdown-table": "^2.0.0",
+            "mdast-util-compact": "^2.0.0",
+            "parse-entities": "^2.0.0",
+            "repeat-string": "^1.5.4",
+            "state-toggle": "^1.0.0",
+            "stringify-entities": "^3.0.0",
+            "unherit": "^1.0.4",
+            "xtend": "^4.0.1"
+          }
+        },
+        "stringify-entities": {
+          "version": "3.1.0",
+          "resolved": "https://registry.npm.taobao.org/stringify-entities/download/stringify-entities-3.1.0.tgz?cache=0&sync_timestamp=1603096784534&other_urls=https%3A%2F%2Fregistry.npm.taobao.org%2Fstringify-entities%2Fdownload%2Fstringify-entities-3.1.0.tgz",
+          "integrity": "sha1-uNP+rCVtn/zJ+h/v3PPKcFdu6QM=",
+          "dev": true,
+          "requires": {
+            "character-entities-html4": "^1.0.0",
+            "character-entities-legacy": "^1.0.0",
+            "xtend": "^4.0.0"
+          }
+        },
+        "unified": {
+          "version": "9.2.0",
+          "resolved": "https://registry.npm.taobao.org/unified/download/unified-9.2.0.tgz?cache=0&sync_timestamp=1598031761770&other_urls=https%3A%2F%2Fregistry.npm.taobao.org%2Funified%2Fdownload%2Funified-9.2.0.tgz",
+          "integrity": "sha1-Z6YsYnxAWJ7eu/YPU+39TYIgJ/g=",
+          "dev": true,
+          "requires": {
+            "bail": "^1.0.0",
+            "extend": "^3.0.0",
+            "is-buffer": "^2.0.0",
+            "is-plain-obj": "^2.0.0",
+            "trough": "^1.0.0",
+            "vfile": "^4.0.0"
+          }
+        },
+        "unist-util-find-all-after": {
+          "version": "3.0.2",
+          "resolved": "https://registry.npm.taobao.org/unist-util-find-all-after/download/unist-util-find-all-after-3.0.2.tgz",
+          "integrity": "sha1-/f7NFMW3rqXp7zjV4NX3dO61YfY=",
+          "dev": true,
+          "requires": {
+            "unist-util-is": "^4.0.0"
+          }
+        },
+        "unist-util-is": {
+          "version": "4.0.3",
+          "resolved": "https://registry.npm.taobao.org/unist-util-is/download/unist-util-is-4.0.3.tgz?cache=0&sync_timestamp=1604050976793&other_urls=https%3A%2F%2Fregistry.npm.taobao.org%2Funist-util-is%2Fdownload%2Funist-util-is-4.0.3.tgz",
+          "integrity": "sha1-6LRNtV/CDEN1KzNGwRY0TUXXyR0=",
+          "dev": true
+        },
+        "unist-util-remove-position": {
+          "version": "2.0.1",
+          "resolved": "https://registry.npm.taobao.org/unist-util-remove-position/download/unist-util-remove-position-2.0.1.tgz",
+          "integrity": "sha1-XRnKef26cSMBmZsrc1U8qPOzUsw=",
+          "dev": true,
+          "requires": {
+            "unist-util-visit": "^2.0.0"
+          }
+        },
+        "unist-util-visit": {
+          "version": "2.0.3",
+          "resolved": "https://registry.npm.taobao.org/unist-util-visit/download/unist-util-visit-2.0.3.tgz?cache=0&sync_timestamp=1594459284890&other_urls=https%3A%2F%2Fregistry.npm.taobao.org%2Funist-util-visit%2Fdownload%2Funist-util-visit-2.0.3.tgz",
+          "integrity": "sha1-w3A4kxRt9HIDu4qXla9H17lxIIw=",
+          "dev": true,
+          "requires": {
+            "@types/unist": "^2.0.0",
+            "unist-util-is": "^4.0.0",
+            "unist-util-visit-parents": "^3.0.0"
+          }
+        },
+        "unist-util-visit-parents": {
+          "version": "3.1.1",
+          "resolved": "https://registry.npm.taobao.org/unist-util-visit-parents/download/unist-util-visit-parents-3.1.1.tgz?cache=0&sync_timestamp=1603108482643&other_urls=https%3A%2F%2Fregistry.npm.taobao.org%2Funist-util-visit-parents%2Fdownload%2Funist-util-visit-parents-3.1.1.tgz",
+          "integrity": "sha1-ZabOaY94prD1aqDojxOAGIbNrvY=",
+          "dev": true,
+          "requires": {
+            "@types/unist": "^2.0.0",
+            "unist-util-is": "^4.0.0"
+          }
+        },
+        "vfile": {
+          "version": "4.2.0",
+          "resolved": "https://registry.npm.taobao.org/vfile/download/vfile-4.2.0.tgz?cache=0&sync_timestamp=1596111341065&other_urls=https%3A%2F%2Fregistry.npm.taobao.org%2Fvfile%2Fdownload%2Fvfile-4.2.0.tgz",
+          "integrity": "sha1-JseKyS63CBawHUVl4AO35loqDgE=",
+          "dev": true,
+          "requires": {
+            "@types/unist": "^2.0.0",
+            "is-buffer": "^2.0.0",
+            "replace-ext": "1.0.0",
+            "unist-util-stringify-position": "^2.0.0",
+            "vfile-message": "^2.0.0"
+          }
+        },
+        "vfile-location": {
+          "version": "3.2.0",
+          "resolved": "https://registry.npm.taobao.org/vfile-location/download/vfile-location-3.2.0.tgz?cache=0&sync_timestamp=1604225085911&other_urls=https%3A%2F%2Fregistry.npm.taobao.org%2Fvfile-location%2Fdownload%2Fvfile-location-3.2.0.tgz",
+          "integrity": "sha1-2OQfvL1AYGNmnr9sM9Vq6HIdDzw=",
+          "dev": true
+        }
+      }
+    },
+    "@types/babel__core": {
+      "version": "7.1.12",
+      "resolved": "https://registry.npm.taobao.org/@types/babel__core/download/@types/babel__core-7.1.12.tgz",
+      "integrity": "sha1-TY6eUesmVVKn5PH/IhmrYTO9+y0=",
+      "dev": true,
+      "requires": {
+        "@babel/parser": "^7.1.0",
+        "@babel/types": "^7.0.0",
+        "@types/babel__generator": "*",
+        "@types/babel__template": "*",
+        "@types/babel__traverse": "*"
+      }
+    },
+    "@types/babel__generator": {
+      "version": "7.6.2",
+      "resolved": "https://registry.npm.taobao.org/@types/babel__generator/download/@types/babel__generator-7.6.2.tgz?cache=0&other_urls=https%3A%2F%2Fregistry.npm.taobao.org%2F%40types%2Fbabel__generator%2Fdownload%2F%40types%2Fbabel__generator-7.6.2.tgz",
+      "integrity": "sha1-89cReOGHhY98ReMDgPjxt0FaEtg=",
+      "dev": true,
+      "requires": {
+        "@babel/types": "^7.0.0"
+      }
+    },
+    "@types/babel__template": {
+      "version": "7.4.0",
+      "resolved": "https://registry.npm.taobao.org/@types/babel__template/download/@types/babel__template-7.4.0.tgz",
+      "integrity": "sha1-DIiN1ws+6e67bk8gDoCdoAdiYr4=",
+      "dev": true,
+      "requires": {
+        "@babel/parser": "^7.1.0",
+        "@babel/types": "^7.0.0"
+      }
+    },
+    "@types/babel__traverse": {
+      "version": "7.0.15",
+      "resolved": "https://registry.npm.taobao.org/@types/babel__traverse/download/@types/babel__traverse-7.0.15.tgz",
+      "integrity": "sha1-255COJMetp74qrCtZSPU1MqjnQM=",
+      "dev": true,
+      "requires": {
+        "@babel/types": "^7.3.0"
+      }
+    },
+    "@types/cookie": {
+      "version": "0.3.3",
+      "resolved": "https://registry.npm.taobao.org/@types/cookie/download/@types/cookie-0.3.3.tgz?cache=0&sync_timestamp=1605053525369&other_urls=https%3A%2F%2Fregistry.npm.taobao.org%2F%40types%2Fcookie%2Fdownload%2F%40types%2Fcookie-0.3.3.tgz",
+      "integrity": "sha1-hbx0ungvt6o6UU0RdngysOO8aAM=",
+      "dev": true
+    },
+    "@types/eslint-visitor-keys": {
+      "version": "1.0.0",
+      "resolved": "https://registry.npm.taobao.org/@types/eslint-visitor-keys/download/@types/eslint-visitor-keys-1.0.0.tgz",
+      "integrity": "sha1-HuMNeVRMqE1o1LPNsK9PIFZj3S0=",
+      "dev": true
+    },
+    "@types/glob": {
+      "version": "7.1.3",
+      "resolved": "https://registry.npm.taobao.org/@types/glob/download/@types/glob-7.1.3.tgz?cache=0&sync_timestamp=1605053412496&other_urls=https%3A%2F%2Fregistry.npm.taobao.org%2F%40types%2Fglob%2Fdownload%2F%40types%2Fglob-7.1.3.tgz",
+      "integrity": "sha1-5rqA82t9qtLGhazZJmOC5omFwYM=",
+      "dev": true,
+      "requires": {
+        "@types/minimatch": "*",
+        "@types/node": "*"
+      }
+    },
+    "@types/graceful-fs": {
+      "version": "4.1.4",
+      "resolved": "https://registry.npm.taobao.org/@types/graceful-fs/download/@types/graceful-fs-4.1.4.tgz?cache=0&sync_timestamp=1605053615976&other_urls=https%3A%2F%2Fregistry.npm.taobao.org%2F%40types%2Fgraceful-fs%2Fdownload%2F%40types%2Fgraceful-fs-4.1.4.tgz",
+      "integrity": "sha1-T/n2QafG0aNQj/iLwxQbFSdy51M=",
+      "dev": true,
+      "requires": {
+        "@types/node": "*"
+      }
+    },
+    "@types/istanbul-lib-coverage": {
+      "version": "2.0.3",
+      "resolved": "https://registry.npm.taobao.org/@types/istanbul-lib-coverage/download/@types/istanbul-lib-coverage-2.0.3.tgz?cache=0&sync_timestamp=1605054056155&other_urls=https%3A%2F%2Fregistry.npm.taobao.org%2F%40types%2Fistanbul-lib-coverage%2Fdownload%2F%40types%2Fistanbul-lib-coverage-2.0.3.tgz",
+      "integrity": "sha1-S6jdtyAiH0MuRDvV+RF/0iz9R2I=",
+      "dev": true
+    },
+    "@types/istanbul-lib-report": {
+      "version": "3.0.0",
+      "resolved": "https://registry.npm.taobao.org/@types/istanbul-lib-report/download/@types/istanbul-lib-report-3.0.0.tgz?cache=0&sync_timestamp=1605054055971&other_urls=https%3A%2F%2Fregistry.npm.taobao.org%2F%40types%2Fistanbul-lib-report%2Fdownload%2F%40types%2Fistanbul-lib-report-3.0.0.tgz",
+      "integrity": "sha1-wUwk8Y6oGQwRjudWK3/5mjZVJoY=",
+      "dev": true,
+      "requires": {
+        "@types/istanbul-lib-coverage": "*"
+      }
+    },
+    "@types/istanbul-reports": {
+      "version": "3.0.0",
+      "resolved": "https://registry.npm.taobao.org/@types/istanbul-reports/download/@types/istanbul-reports-3.0.0.tgz?cache=0&sync_timestamp=1605054056153&other_urls=https%3A%2F%2Fregistry.npm.taobao.org%2F%40types%2Fistanbul-reports%2Fdownload%2F%40types%2Fistanbul-reports-3.0.0.tgz",
+      "integrity": "sha1-UIsTqjRPpJdiNOdd3cw0klc32CE=",
+      "dev": true,
+      "requires": {
+        "@types/istanbul-lib-report": "*"
+      }
+    },
+    "@types/json-schema": {
+      "version": "7.0.6",
+      "resolved": "https://registry.npm.taobao.org/@types/json-schema/download/@types/json-schema-7.0.6.tgz?cache=0&sync_timestamp=1605053861867&other_urls=https%3A%2F%2Fregistry.npm.taobao.org%2F%40types%2Fjson-schema%2Fdownload%2F%40types%2Fjson-schema-7.0.6.tgz",
+      "integrity": "sha1-9MfsQ+gbMZqYFRFQMXCfJph4kfA=",
+      "dev": true
+    },
+    "@types/json5": {
+      "version": "0.0.29",
+      "resolved": "https://registry.npm.taobao.org/@types/json5/download/@types/json5-0.0.29.tgz?cache=0&sync_timestamp=1605054241417&other_urls=https%3A%2F%2Fregistry.npm.taobao.org%2F%40types%2Fjson5%2Fdownload%2F%40types%2Fjson5-0.0.29.tgz",
+      "integrity": "sha1-7ihweulOEdK4J7y+UnC86n8+ce4=",
+      "dev": true
+    },
+    "@types/minimatch": {
+      "version": "3.0.3",
+      "resolved": "https://registry.npm.taobao.org/@types/minimatch/download/@types/minimatch-3.0.3.tgz",
+      "integrity": "sha1-PcoOPzOyAPx9ETnAzZbBJoyt/Z0=",
+      "dev": true
+    },
+    "@types/minimist": {
+      "version": "1.2.1",
+      "resolved": "https://registry.npm.taobao.org/@types/minimist/download/@types/minimist-1.2.1.tgz",
+      "integrity": "sha1-KD9mn/dte4Jg34q3pCYsyD2YglY=",
+      "dev": true
+    },
+    "@types/node": {
+      "version": "14.14.7",
+      "resolved": "https://registry.npm.taobao.org/@types/node/download/@types/node-14.14.7.tgz",
+      "integrity": "sha1-jqHo+OriQwz0QFZLmMbfzh7FlF0=",
+      "dev": true
+    },
+    "@types/normalize-package-data": {
+      "version": "2.4.0",
+      "resolved": "https://registry.npm.taobao.org/@types/normalize-package-data/download/@types/normalize-package-data-2.4.0.tgz?cache=0&sync_timestamp=1605054933259&other_urls=https%3A%2F%2Fregistry.npm.taobao.org%2F%40types%2Fnormalize-package-data%2Fdownload%2F%40types%2Fnormalize-package-data-2.4.0.tgz",
+      "integrity": "sha1-5IbQ2XOW15vu3QpuM/RTT/a0lz4=",
+      "dev": true
+    },
+    "@types/npmlog": {
+      "version": "4.1.2",
+      "resolved": "https://registry.npm.taobao.org/@types/npmlog/download/@types/npmlog-4.1.2.tgz?cache=0&sync_timestamp=1605055837348&other_urls=https%3A%2F%2Fregistry.npm.taobao.org%2F%40types%2Fnpmlog%2Fdownload%2F%40types%2Fnpmlog-4.1.2.tgz",
+      "integrity": "sha1-0HD+amt4dV0QkqPcSS00w9j4ccQ=",
+      "dev": true
+    },
+    "@types/parse-json": {
+      "version": "4.0.0",
+      "resolved": "https://registry.npm.taobao.org/@types/parse-json/download/@types/parse-json-4.0.0.tgz?cache=0&sync_timestamp=1605054934191&other_urls=https%3A%2F%2Fregistry.npm.taobao.org%2F%40types%2Fparse-json%2Fdownload%2F%40types%2Fparse-json-4.0.0.tgz",
+      "integrity": "sha1-L4u0QUNNFjs1+4/9zNcTiSf/uMA=",
+      "dev": true
+    },
+    "@types/prettier": {
+      "version": "2.1.5",
+      "resolved": "https://registry.npm.taobao.org/@types/prettier/download/@types/prettier-2.1.5.tgz",
+      "integrity": "sha1-tqs7uinha4IdhOCez63tRiuBawA=",
+      "dev": true
+    },
+    "@types/prop-types": {
+      "version": "15.7.3",
+      "resolved": "https://registry.npm.taobao.org/@types/prop-types/download/@types/prop-types-15.7.3.tgz?cache=0&sync_timestamp=1605055388480&other_urls=https%3A%2F%2Fregistry.npm.taobao.org%2F%40types%2Fprop-types%2Fdownload%2F%40types%2Fprop-types-15.7.3.tgz",
+      "integrity": "sha1-KrDV2i5YFflLC51LldHl8kOrLKc="
+    },
+    "@types/q": {
+      "version": "1.5.4",
+      "resolved": "https://registry.npm.taobao.org/@types/q/download/@types/q-1.5.4.tgz?cache=0&sync_timestamp=1605055096527&other_urls=https%3A%2F%2Fregistry.npm.taobao.org%2F%40types%2Fq%2Fdownload%2F%40types%2Fq-1.5.4.tgz",
+      "integrity": "sha1-FZJUFOCtLNdlv+9YhC9+JqesyyQ=",
+      "dev": true
+    },
+    "@types/react": {
+      "version": "16.9.56",
+      "resolved": "https://registry.npm.taobao.org/@types/react/download/@types/react-16.9.56.tgz?cache=0&sync_timestamp=1604651654114&other_urls=https%3A%2F%2Fregistry.npm.taobao.org%2F%40types%2Freact%2Fdownload%2F%40types%2Freact-16.9.56.tgz",
+      "integrity": "sha1-6iWEe1PFvsBkkzCV/DZrFGLirfA=",
+      "requires": {
+        "@types/prop-types": "*",
+        "csstype": "^3.0.2"
+      }
+    },
+    "@types/react-dom": {
+      "version": "16.9.9",
+      "resolved": "https://registry.npm.taobao.org/@types/react-dom/download/@types/react-dom-16.9.9.tgz?cache=0&sync_timestamp=1605055329509&other_urls=https%3A%2F%2Fregistry.npm.taobao.org%2F%40types%2Freact-dom%2Fdownload%2F%40types%2Freact-dom-16.9.9.tgz",
+      "integrity": "sha1-0tCm9yCgIGNpzL7/91K6N7lYMTY=",
+      "requires": {
+        "@types/react": "*"
+      }
+    },
+    "@types/stack-utils": {
+      "version": "2.0.0",
+      "resolved": "https://registry.npm.taobao.org/@types/stack-utils/download/@types/stack-utils-2.0.0.tgz",
+      "integrity": "sha1-cDZkC04hzC8lmugmzoQ9J32tjP8=",
+      "dev": true
+    },
+    "@types/unist": {
+      "version": "2.0.3",
+      "resolved": "https://registry.npm.taobao.org/@types/unist/download/@types/unist-2.0.3.tgz",
+      "integrity": "sha1-nAiGeYdvN061mD8VDUeHqm+zLX4=",
+      "dev": true
+    },
+    "@types/url-parse": {
+      "version": "1.4.3",
+      "resolved": "https://registry.npm.taobao.org/@types/url-parse/download/@types/url-parse-1.4.3.tgz?cache=0&sync_timestamp=1605057382227&other_urls=https%3A%2F%2Fregistry.npm.taobao.org%2F%40types%2Furl-parse%2Fdownload%2F%40types%2Furl-parse-1.4.3.tgz",
+      "integrity": "sha1-+6SdkPg0lRywAKZ07+49byCWgyk=",
+      "dev": true
+    },
+    "@types/vfile": {
+      "version": "3.0.2",
+      "resolved": "https://registry.npm.taobao.org/@types/vfile/download/@types/vfile-3.0.2.tgz",
+      "integrity": "sha1-GcGM0jLfEc5vpq2AJZvIbDZrCbk=",
+      "dev": true,
+      "requires": {
+        "@types/node": "*",
+        "@types/unist": "*",
+        "@types/vfile-message": "*"
+      }
+    },
+    "@types/vfile-message": {
+      "version": "2.0.0",
+      "resolved": "https://registry.npm.taobao.org/@types/vfile-message/download/@types/vfile-message-2.0.0.tgz",
+      "integrity": "sha1-aQ5Grw/fwfn6rgDNBJzIiJV5J9U=",
+      "dev": true,
+      "requires": {
+        "vfile-message": "*"
+      }
+    },
+    "@types/yargs": {
+      "version": "15.0.9",
+      "resolved": "https://registry.npm.taobao.org/@types/yargs/download/@types/yargs-15.0.9.tgz?cache=0&sync_timestamp=1605057458388&other_urls=https%3A%2F%2Fregistry.npm.taobao.org%2F%40types%2Fyargs%2Fdownload%2F%40types%2Fyargs-15.0.9.tgz",
+      "integrity": "sha1-UkzXmY/oEM2wLyYQG2mczNFW/xk=",
+      "dev": true,
+      "requires": {
+        "@types/yargs-parser": "*"
+      }
+    },
+    "@types/yargs-parser": {
+      "version": "15.0.0",
+      "resolved": "https://registry.npm.taobao.org/@types/yargs-parser/download/@types/yargs-parser-15.0.0.tgz?cache=0&sync_timestamp=1605057457263&other_urls=https%3A%2F%2Fregistry.npm.taobao.org%2F%40types%2Fyargs-parser%2Fdownload%2F%40types%2Fyargs-parser-15.0.0.tgz",
+      "integrity": "sha1-yz+fdBhp4gzOMw/765JxWQSDiC0=",
+      "dev": true
+    },
+    "@typescript-eslint/eslint-plugin": {
+      "version": "2.34.0",
+      "resolved": "https://registry.npm.taobao.org/@typescript-eslint/eslint-plugin/download/@typescript-eslint/eslint-plugin-2.34.0.tgz",
+      "integrity": "sha1-b4zopGx96kpvHRcdK7j7rm2sK+k=",
+      "dev": true,
+      "requires": {
+        "@typescript-eslint/experimental-utils": "2.34.0",
+        "functional-red-black-tree": "^1.0.1",
+        "regexpp": "^3.0.0",
+        "tsutils": "^3.17.1"
+      }
+    },
+    "@typescript-eslint/experimental-utils": {
+      "version": "2.34.0",
+      "resolved": "https://registry.npm.taobao.org/@typescript-eslint/experimental-utils/download/@typescript-eslint/experimental-utils-2.34.0.tgz?cache=0&sync_timestamp=1605227301184&other_urls=https%3A%2F%2Fregistry.npm.taobao.org%2F%40typescript-eslint%2Fexperimental-utils%2Fdownload%2F%40typescript-eslint%2Fexperimental-utils-2.34.0.tgz",
+      "integrity": "sha1-01JLZEzbQO687KZ/jPPkzJyPmA8=",
+      "dev": true,
+      "requires": {
+        "@types/json-schema": "^7.0.3",
+        "@typescript-eslint/typescript-estree": "2.34.0",
+        "eslint-scope": "^5.0.0",
+        "eslint-utils": "^2.0.0"
+      }
+    },
+    "@typescript-eslint/parser": {
+      "version": "2.34.0",
+      "resolved": "https://registry.npm.taobao.org/@typescript-eslint/parser/download/@typescript-eslint/parser-2.34.0.tgz",
+      "integrity": "sha1-UCUmMMoxloVCDpo5ygX+GFola8g=",
+      "dev": true,
+      "requires": {
+        "@types/eslint-visitor-keys": "^1.0.0",
+        "@typescript-eslint/experimental-utils": "2.34.0",
+        "@typescript-eslint/typescript-estree": "2.34.0",
+        "eslint-visitor-keys": "^1.1.0"
+      }
+    },
+    "@typescript-eslint/typescript-estree": {
+      "version": "2.34.0",
+      "resolved": "https://registry.npm.taobao.org/@typescript-eslint/typescript-estree/download/@typescript-eslint/typescript-estree-2.34.0.tgz?cache=0&sync_timestamp=1605227303561&other_urls=https%3A%2F%2Fregistry.npm.taobao.org%2F%40typescript-eslint%2Ftypescript-estree%2Fdownload%2F%40typescript-eslint%2Ftypescript-estree-2.34.0.tgz",
+      "integrity": "sha1-FK62NTs57wcyzH8bgoUpSTfPN9U=",
+      "dev": true,
+      "requires": {
+        "debug": "^4.1.1",
+        "eslint-visitor-keys": "^1.1.0",
+        "glob": "^7.1.6",
+        "is-glob": "^4.0.1",
+        "lodash": "^4.17.15",
+        "semver": "^7.3.2",
+        "tsutils": "^3.17.1"
+      }
+    },
+    "@webassemblyjs/ast": {
+      "version": "1.9.0",
+      "resolved": "https://registry.npm.taobao.org/@webassemblyjs/ast/download/@webassemblyjs/ast-1.9.0.tgz?cache=0&sync_timestamp=1601756233286&other_urls=https%3A%2F%2Fregistry.npm.taobao.org%2F%40webassemblyjs%2Fast%2Fdownload%2F%40webassemblyjs%2Fast-1.9.0.tgz",
+      "integrity": "sha1-vYUGBLQEJFmlpBzX0zjL7Wle2WQ=",
+      "dev": true,
+      "requires": {
+        "@webassemblyjs/helper-module-context": "1.9.0",
+        "@webassemblyjs/helper-wasm-bytecode": "1.9.0",
+        "@webassemblyjs/wast-parser": "1.9.0"
+      }
+    },
+    "@webassemblyjs/floating-point-hex-parser": {
+      "version": "1.9.0",
+      "resolved": "https://registry.npm.taobao.org/@webassemblyjs/floating-point-hex-parser/download/@webassemblyjs/floating-point-hex-parser-1.9.0.tgz?cache=0&sync_timestamp=1601756232132&other_urls=https%3A%2F%2Fregistry.npm.taobao.org%2F%40webassemblyjs%2Ffloating-point-hex-parser%2Fdownload%2F%40webassemblyjs%2Ffloating-point-hex-parser-1.9.0.tgz",
+      "integrity": "sha1-PD07Jxvd/ITesA9xNEQ4MR1S/7Q=",
+      "dev": true
+    },
+    "@webassemblyjs/helper-api-error": {
+      "version": "1.9.0",
+      "resolved": "https://registry.npm.taobao.org/@webassemblyjs/helper-api-error/download/@webassemblyjs/helper-api-error-1.9.0.tgz?cache=0&sync_timestamp=1601756232631&other_urls=https%3A%2F%2Fregistry.npm.taobao.org%2F%40webassemblyjs%2Fhelper-api-error%2Fdownload%2F%40webassemblyjs%2Fhelper-api-error-1.9.0.tgz",
+      "integrity": "sha1-ID9nbjM7lsnaLuqzzO8zxFkotqI=",
+      "dev": true
+    },
+    "@webassemblyjs/helper-buffer": {
+      "version": "1.9.0",
+      "resolved": "https://registry.npm.taobao.org/@webassemblyjs/helper-buffer/download/@webassemblyjs/helper-buffer-1.9.0.tgz?cache=0&sync_timestamp=1601756248143&other_urls=https%3A%2F%2Fregistry.npm.taobao.org%2F%40webassemblyjs%2Fhelper-buffer%2Fdownload%2F%40webassemblyjs%2Fhelper-buffer-1.9.0.tgz",
+      "integrity": "sha1-oUQtJpxf6yP8vJ73WdrDVH8p3gA=",
+      "dev": true
+    },
+    "@webassemblyjs/helper-code-frame": {
+      "version": "1.9.0",
+      "resolved": "https://registry.npm.taobao.org/@webassemblyjs/helper-code-frame/download/@webassemblyjs/helper-code-frame-1.9.0.tgz?cache=0&sync_timestamp=1601756233909&other_urls=https%3A%2F%2Fregistry.npm.taobao.org%2F%40webassemblyjs%2Fhelper-code-frame%2Fdownload%2F%40webassemblyjs%2Fhelper-code-frame-1.9.0.tgz",
+      "integrity": "sha1-ZH+Iks0gQ6gqwMjF51w28dkVnyc=",
+      "dev": true,
+      "requires": {
+        "@webassemblyjs/wast-printer": "1.9.0"
+      }
+    },
+    "@webassemblyjs/helper-fsm": {
+      "version": "1.9.0",
+      "resolved": "https://registry.npm.taobao.org/@webassemblyjs/helper-fsm/download/@webassemblyjs/helper-fsm-1.9.0.tgz?cache=0&sync_timestamp=1601756231939&other_urls=https%3A%2F%2Fregistry.npm.taobao.org%2F%40webassemblyjs%2Fhelper-fsm%2Fdownload%2F%40webassemblyjs%2Fhelper-fsm-1.9.0.tgz",
+      "integrity": "sha1-wFJWtxJEIUZx9LCOwQitY7cO3bg=",
+      "dev": true
+    },
+    "@webassemblyjs/helper-module-context": {
+      "version": "1.9.0",
+      "resolved": "https://registry.npm.taobao.org/@webassemblyjs/helper-module-context/download/@webassemblyjs/helper-module-context-1.9.0.tgz?cache=0&sync_timestamp=1601756234776&other_urls=https%3A%2F%2Fregistry.npm.taobao.org%2F%40webassemblyjs%2Fhelper-module-context%2Fdownload%2F%40webassemblyjs%2Fhelper-module-context-1.9.0.tgz",
+      "integrity": "sha1-JdiIS3aDmHGgimxvgGw5ee9xLwc=",
+      "dev": true,
+      "requires": {
+        "@webassemblyjs/ast": "1.9.0"
+      }
+    },
+    "@webassemblyjs/helper-wasm-bytecode": {
+      "version": "1.9.0",
+      "resolved": "https://registry.npm.taobao.org/@webassemblyjs/helper-wasm-bytecode/download/@webassemblyjs/helper-wasm-bytecode-1.9.0.tgz?cache=0&sync_timestamp=1601756232301&other_urls=https%3A%2F%2Fregistry.npm.taobao.org%2F%40webassemblyjs%2Fhelper-wasm-bytecode%2Fdownload%2F%40webassemblyjs%2Fhelper-wasm-bytecode-1.9.0.tgz",
+      "integrity": "sha1-T+2L6sm4wU+MWLcNEk1UndH+V5A=",
+      "dev": true
+    },
+    "@webassemblyjs/helper-wasm-section": {
+      "version": "1.9.0",
+      "resolved": "https://registry.npm.taobao.org/@webassemblyjs/helper-wasm-section/download/@webassemblyjs/helper-wasm-section-1.9.0.tgz?cache=0&sync_timestamp=1601756234204&other_urls=https%3A%2F%2Fregistry.npm.taobao.org%2F%40webassemblyjs%2Fhelper-wasm-section%2Fdownload%2F%40webassemblyjs%2Fhelper-wasm-section-1.9.0.tgz",
+      "integrity": "sha1-WkE41aYpK6GLBMWuSXF+QWeWU0Y=",
+      "dev": true,
+      "requires": {
+        "@webassemblyjs/ast": "1.9.0",
+        "@webassemblyjs/helper-buffer": "1.9.0",
+        "@webassemblyjs/helper-wasm-bytecode": "1.9.0",
+        "@webassemblyjs/wasm-gen": "1.9.0"
+      }
+    },
+    "@webassemblyjs/ieee754": {
+      "version": "1.9.0",
+      "resolved": "https://registry.npm.taobao.org/@webassemblyjs/ieee754/download/@webassemblyjs/ieee754-1.9.0.tgz?cache=0&sync_timestamp=1601756232741&other_urls=https%3A%2F%2Fregistry.npm.taobao.org%2F%40webassemblyjs%2Fieee754%2Fdownload%2F%40webassemblyjs%2Fieee754-1.9.0.tgz",
+      "integrity": "sha1-Fceg+6roP7JhQ7us9tbfFwKtOeQ=",
+      "dev": true,
+      "requires": {
+        "@xtuc/ieee754": "^1.2.0"
+      }
+    },
+    "@webassemblyjs/leb128": {
+      "version": "1.9.0",
+      "resolved": "https://registry.npm.taobao.org/@webassemblyjs/leb128/download/@webassemblyjs/leb128-1.9.0.tgz?cache=0&sync_timestamp=1601756232514&other_urls=https%3A%2F%2Fregistry.npm.taobao.org%2F%40webassemblyjs%2Fleb128%2Fdownload%2F%40webassemblyjs%2Fleb128-1.9.0.tgz",
+      "integrity": "sha1-8Zygt2ptxVYjoJz/p2noOPoeHJU=",
+      "dev": true,
+      "requires": {
+        "@xtuc/long": "4.2.2"
+      }
+    },
+    "@webassemblyjs/utf8": {
+      "version": "1.9.0",
+      "resolved": "https://registry.npm.taobao.org/@webassemblyjs/utf8/download/@webassemblyjs/utf8-1.9.0.tgz?cache=0&sync_timestamp=1601756233013&other_urls=https%3A%2F%2Fregistry.npm.taobao.org%2F%40webassemblyjs%2Futf8%2Fdownload%2F%40webassemblyjs%2Futf8-1.9.0.tgz",
+      "integrity": "sha1-BNM7Y2945qaBMifoJAL3Y3tiKas=",
+      "dev": true
+    },
+    "@webassemblyjs/wasm-edit": {
+      "version": "1.9.0",
+      "resolved": "https://registry.npm.taobao.org/@webassemblyjs/wasm-edit/download/@webassemblyjs/wasm-edit-1.9.0.tgz?cache=0&sync_timestamp=1601756233442&other_urls=https%3A%2F%2Fregistry.npm.taobao.org%2F%40webassemblyjs%2Fwasm-edit%2Fdownload%2F%40webassemblyjs%2Fwasm-edit-1.9.0.tgz",
+      "integrity": "sha1-P+bXnT8PkiGDqoYALELdJWz+6c8=",
+      "dev": true,
+      "requires": {
+        "@webassemblyjs/ast": "1.9.0",
+        "@webassemblyjs/helper-buffer": "1.9.0",
+        "@webassemblyjs/helper-wasm-bytecode": "1.9.0",
+        "@webassemblyjs/helper-wasm-section": "1.9.0",
+        "@webassemblyjs/wasm-gen": "1.9.0",
+        "@webassemblyjs/wasm-opt": "1.9.0",
+        "@webassemblyjs/wasm-parser": "1.9.0",
+        "@webassemblyjs/wast-printer": "1.9.0"
+      }
+    },
+    "@webassemblyjs/wasm-gen": {
+      "version": "1.9.0",
+      "resolved": "https://registry.npm.taobao.org/@webassemblyjs/wasm-gen/download/@webassemblyjs/wasm-gen-1.9.0.tgz?cache=0&sync_timestamp=1601756234341&other_urls=https%3A%2F%2Fregistry.npm.taobao.org%2F%40webassemblyjs%2Fwasm-gen%2Fdownload%2F%40webassemblyjs%2Fwasm-gen-1.9.0.tgz",
+      "integrity": "sha1-ULxw7Gje2OJ2OwGhQYv0NJGnpJw=",
+      "dev": true,
+      "requires": {
+        "@webassemblyjs/ast": "1.9.0",
+        "@webassemblyjs/helper-wasm-bytecode": "1.9.0",
+        "@webassemblyjs/ieee754": "1.9.0",
+        "@webassemblyjs/leb128": "1.9.0",
+        "@webassemblyjs/utf8": "1.9.0"
+      }
+    },
+    "@webassemblyjs/wasm-opt": {
+      "version": "1.9.0",
+      "resolved": "https://registry.npm.taobao.org/@webassemblyjs/wasm-opt/download/@webassemblyjs/wasm-opt-1.9.0.tgz?cache=0&sync_timestamp=1601756233142&other_urls=https%3A%2F%2Fregistry.npm.taobao.org%2F%40webassemblyjs%2Fwasm-opt%2Fdownload%2F%40webassemblyjs%2Fwasm-opt-1.9.0.tgz",
+      "integrity": "sha1-IhEYHlsxMmRDzIES658LkChyGmE=",
+      "dev": true,
+      "requires": {
+        "@webassemblyjs/ast": "1.9.0",
+        "@webassemblyjs/helper-buffer": "1.9.0",
+        "@webassemblyjs/wasm-gen": "1.9.0",
+        "@webassemblyjs/wasm-parser": "1.9.0"
+      }
+    },
+    "@webassemblyjs/wasm-parser": {
+      "version": "1.9.0",
+      "resolved": "https://registry.npm.taobao.org/@webassemblyjs/wasm-parser/download/@webassemblyjs/wasm-parser-1.9.0.tgz?cache=0&sync_timestamp=1601756233776&other_urls=https%3A%2F%2Fregistry.npm.taobao.org%2F%40webassemblyjs%2Fwasm-parser%2Fdownload%2F%40webassemblyjs%2Fwasm-parser-1.9.0.tgz",
+      "integrity": "sha1-nUjkSCbfSmWYKUqmyHRp1kL/9l4=",
+      "dev": true,
+      "requires": {
+        "@webassemblyjs/ast": "1.9.0",
+        "@webassemblyjs/helper-api-error": "1.9.0",
+        "@webassemblyjs/helper-wasm-bytecode": "1.9.0",
+        "@webassemblyjs/ieee754": "1.9.0",
+        "@webassemblyjs/leb128": "1.9.0",
+        "@webassemblyjs/utf8": "1.9.0"
+      }
+    },
+    "@webassemblyjs/wast-parser": {
+      "version": "1.9.0",
+      "resolved": "https://registry.npm.taobao.org/@webassemblyjs/wast-parser/download/@webassemblyjs/wast-parser-1.9.0.tgz?cache=0&sync_timestamp=1601756234653&other_urls=https%3A%2F%2Fregistry.npm.taobao.org%2F%40webassemblyjs%2Fwast-parser%2Fdownload%2F%40webassemblyjs%2Fwast-parser-1.9.0.tgz",
+      "integrity": "sha1-MDERXXmsW9JhVWzsw/qQo+9FGRQ=",
+      "dev": true,
+      "requires": {
+        "@webassemblyjs/ast": "1.9.0",
+        "@webassemblyjs/floating-point-hex-parser": "1.9.0",
+        "@webassemblyjs/helper-api-error": "1.9.0",
+        "@webassemblyjs/helper-code-frame": "1.9.0",
+        "@webassemblyjs/helper-fsm": "1.9.0",
+        "@xtuc/long": "4.2.2"
+      }
+    },
+    "@webassemblyjs/wast-printer": {
+      "version": "1.9.0",
+      "resolved": "https://registry.npm.taobao.org/@webassemblyjs/wast-printer/download/@webassemblyjs/wast-printer-1.9.0.tgz?cache=0&sync_timestamp=1601756233564&other_urls=https%3A%2F%2Fregistry.npm.taobao.org%2F%40webassemblyjs%2Fwast-printer%2Fdownload%2F%40webassemblyjs%2Fwast-printer-1.9.0.tgz",
+      "integrity": "sha1-STXVTIX+9jewDOn1I3dFHQDUeJk=",
+      "dev": true,
+      "requires": {
+        "@webassemblyjs/ast": "1.9.0",
+        "@webassemblyjs/wast-parser": "1.9.0",
+        "@xtuc/long": "4.2.2"
+      }
+    },
+    "@xtuc/ieee754": {
+      "version": "1.2.0",
+      "resolved": "https://registry.npm.taobao.org/@xtuc/ieee754/download/@xtuc/ieee754-1.2.0.tgz",
+      "integrity": "sha1-7vAUoxRa5Hehy8AM0eVSM23Ot5A=",
+      "dev": true
+    },
+    "@xtuc/long": {
+      "version": "4.2.2",
+      "resolved": "https://registry.npm.taobao.org/@xtuc/long/download/@xtuc/long-4.2.2.tgz",
+      "integrity": "sha1-0pHGpOl5ibXGHZrPOWrk/hM6cY0=",
+      "dev": true
+    },
+    "abab": {
+      "version": "2.0.5",
+      "resolved": "https://registry.npm.taobao.org/abab/download/abab-2.0.5.tgz?cache=0&sync_timestamp=1599850200902&other_urls=https%3A%2F%2Fregistry.npm.taobao.org%2Fabab%2Fdownload%2Fabab-2.0.5.tgz",
+      "integrity": "sha1-wLZ4+zLWD8EhnHhNaoJv44Wut5o=",
+      "dev": true
+    },
+    "abbrev": {
+      "version": "1.1.1",
+      "resolved": "https://registry.npm.taobao.org/abbrev/download/abbrev-1.1.1.tgz",
+      "integrity": "sha1-+PLIh60Qv2f2NPAFtph/7TF5qsg=",
+      "dev": true
+    },
+    "accepts": {
+      "version": "1.3.7",
+      "resolved": "https://registry.npm.taobao.org/accepts/download/accepts-1.3.7.tgz",
+      "integrity": "sha1-UxvHJlF6OytB+FACHGzBXqq1B80=",
+      "dev": true,
+      "requires": {
+        "mime-types": "~2.1.24",
+        "negotiator": "0.6.2"
+      }
+    },
+    "acorn": {
+      "version": "7.4.1",
+      "resolved": "https://registry.npm.taobao.org/acorn/download/acorn-7.4.1.tgz",
+      "integrity": "sha1-/q7SVZc9LndVW4PbwIhRpsY1IPo=",
+      "dev": true
+    },
+    "acorn-globals": {
+      "version": "6.0.0",
+      "resolved": "https://registry.npm.taobao.org/acorn-globals/download/acorn-globals-6.0.0.tgz",
+      "integrity": "sha1-Rs3Tnw+P8IqHZhm1X1rIptx3C0U=",
+      "dev": true,
+      "requires": {
+        "acorn": "^7.1.1",
+        "acorn-walk": "^7.1.1"
+      }
+    },
+    "acorn-jsx": {
+      "version": "5.3.1",
+      "resolved": "https://registry.npm.taobao.org/acorn-jsx/download/acorn-jsx-5.3.1.tgz",
+      "integrity": "sha1-/IZh4Rt6wVOcR9v+oucrOvNNJns=",
+      "dev": true
+    },
+    "acorn-walk": {
+      "version": "7.2.0",
+      "resolved": "https://registry.npm.taobao.org/acorn-walk/download/acorn-walk-7.2.0.tgz?cache=0&sync_timestamp=1597235826369&other_urls=https%3A%2F%2Fregistry.npm.taobao.org%2Facorn-walk%2Fdownload%2Facorn-walk-7.2.0.tgz",
+      "integrity": "sha1-DeiJpgEgOQmw++B7iTjcIdLpZ7w=",
+      "dev": true
+    },
+    "add-asset-html-webpack-plugin": {
+      "version": "3.1.3",
+      "resolved": "https://registry.npm.taobao.org/add-asset-html-webpack-plugin/download/add-asset-html-webpack-plugin-3.1.3.tgz",
+      "integrity": "sha1-vsd9yBgmRKWKDuvK59H56xYtr98=",
+      "dev": true,
+      "requires": {
+        "globby": "^9.0.0",
+        "micromatch": "^3.1.3",
+        "p-each-series": "^1.0.0"
+      },
+      "dependencies": {
+        "p-each-series": {
+          "version": "1.0.0",
+          "resolved": "https://registry.npm.taobao.org/p-each-series/download/p-each-series-1.0.0.tgz",
+          "integrity": "sha1-kw89Et0fUOdDRFeiLNbwSsatf3E=",
+          "dev": true,
+          "requires": {
+            "p-reduce": "^1.0.0"
+          }
+        }
+      }
+    },
+    "address": {
+      "version": "1.1.2",
+      "resolved": "https://registry.npm.taobao.org/address/download/address-1.1.2.tgz",
+      "integrity": "sha1-vxEWycdYxRt6kz0pa3LCIe2UKLY=",
+      "dev": true
+    },
+    "aggregate-error": {
+      "version": "3.1.0",
+      "resolved": "https://registry.npm.taobao.org/aggregate-error/download/aggregate-error-3.1.0.tgz?cache=0&sync_timestamp=1598049934879&other_urls=https%3A%2F%2Fregistry.npm.taobao.org%2Faggregate-error%2Fdownload%2Faggregate-error-3.1.0.tgz",
+      "integrity": "sha1-kmcP9Q9TWb23o+DUDQ7DDFc3aHo=",
+      "dev": true,
+      "requires": {
+        "clean-stack": "^2.0.0",
+        "indent-string": "^4.0.0"
+      },
+      "dependencies": {
+        "indent-string": {
+          "version": "4.0.0",
+          "resolved": "https://registry.npm.taobao.org/indent-string/download/indent-string-4.0.0.tgz",
+          "integrity": "sha1-Yk+PRJfWGbLZdoUx1Y9BIoVNclE=",
+          "dev": true
+        }
+      }
+    },
+    "ajv": {
+      "version": "6.12.6",
+      "resolved": "https://registry.npm.taobao.org/ajv/download/ajv-6.12.6.tgz?cache=0&sync_timestamp=1604996837320&other_urls=https%3A%2F%2Fregistry.npm.taobao.org%2Fajv%2Fdownload%2Fajv-6.12.6.tgz",
+      "integrity": "sha1-uvWmLoArB9l3A0WG+MO69a3ybfQ=",
+      "dev": true,
+      "requires": {
+        "fast-deep-equal": "^3.1.1",
+        "fast-json-stable-stringify": "^2.0.0",
+        "json-schema-traverse": "^0.4.1",
+        "uri-js": "^4.2.2"
+      }
+    },
+    "ajv-errors": {
+      "version": "1.0.1",
+      "resolved": "https://registry.npm.taobao.org/ajv-errors/download/ajv-errors-1.0.1.tgz",
+      "integrity": "sha1-81mGrOuRr63sQQL72FAUlQzvpk0=",
+      "dev": true
+    },
+    "ajv-keywords": {
+      "version": "3.5.2",
+      "resolved": "https://registry.npm.taobao.org/ajv-keywords/download/ajv-keywords-3.5.2.tgz?cache=0&sync_timestamp=1604565104795&other_urls=https%3A%2F%2Fregistry.npm.taobao.org%2Fajv-keywords%2Fdownload%2Fajv-keywords-3.5.2.tgz",
+      "integrity": "sha1-MfKdpatuANHC0yms97WSlhTVAU0=",
+      "dev": true
+    },
+    "alphanum-sort": {
+      "version": "1.0.2",
+      "resolved": "https://registry.npm.taobao.org/alphanum-sort/download/alphanum-sort-1.0.2.tgz",
+      "integrity": "sha1-l6ERlkmyEa0zaR2fn0hqjsn74KM=",
+      "dev": true
+    },
+    "amdefine": {
+      "version": "1.0.1",
+      "resolved": "https://registry.npm.taobao.org/amdefine/download/amdefine-1.0.1.tgz",
+      "integrity": "sha1-SlKCrBZHKek2Gbz9OtFR+BfOkfU=",
+      "dev": true
+    },
+    "ansi-colors": {
+      "version": "3.2.4",
+      "resolved": "https://registry.npm.taobao.org/ansi-colors/download/ansi-colors-3.2.4.tgz",
+      "integrity": "sha1-46PaS/uubIapwoViXeEkojQCb78=",
+      "dev": true
+    },
+    "ansi-escapes": {
+      "version": "4.3.1",
+      "resolved": "https://registry.npm.taobao.org/ansi-escapes/download/ansi-escapes-4.3.1.tgz",
+      "integrity": "sha1-pcR8xDGB8fOP/XB2g3cA05VSKmE=",
+      "dev": true,
+      "requires": {
+        "type-fest": "^0.11.0"
+      },
+      "dependencies": {
+        "type-fest": {
+          "version": "0.11.0",
+          "resolved": "https://registry.npm.taobao.org/type-fest/download/type-fest-0.11.0.tgz?cache=0&sync_timestamp=1605191548126&other_urls=https%3A%2F%2Fregistry.npm.taobao.org%2Ftype-fest%2Fdownload%2Ftype-fest-0.11.0.tgz",
+          "integrity": "sha1-l6vwhyMQ/tiKXEZrJWgVdhReM/E=",
+          "dev": true
+        }
+      }
+    },
+    "ansi-html": {
+      "version": "0.0.7",
+      "resolved": "https://registry.npm.taobao.org/ansi-html/download/ansi-html-0.0.7.tgz",
+      "integrity": "sha1-gTWEAhliqenm/QOflA0S9WynhZ4=",
+      "dev": true
+    },
+    "ansi-regex": {
+      "version": "4.1.0",
+      "resolved": "https://registry.npm.taobao.org/ansi-regex/download/ansi-regex-4.1.0.tgz",
+      "integrity": "sha1-i5+PCM8ay4Q3Vqg5yox+MWjFGZc=",
+      "dev": true
+    },
+    "ansi-styles": {
+      "version": "3.2.1",
+      "resolved": "https://registry.npm.taobao.org/ansi-styles/download/ansi-styles-3.2.1.tgz?cache=0&sync_timestamp=1601839122515&other_urls=https%3A%2F%2Fregistry.npm.taobao.org%2Fansi-styles%2Fdownload%2Fansi-styles-3.2.1.tgz",
+      "integrity": "sha1-QfuyAkPlCxK+DwS43tvwdSDOhB0=",
+      "dev": true,
+      "requires": {
+        "color-convert": "^1.9.0"
+      }
+    },
+    "anymatch": {
+      "version": "3.1.1",
+      "resolved": "https://registry.npm.taobao.org/anymatch/download/anymatch-3.1.1.tgz",
+      "integrity": "sha1-xV7PAhheJGklk5kxDBc84xIzsUI=",
+      "dev": true,
+      "requires": {
+        "normalize-path": "^3.0.0",
+        "picomatch": "^2.0.4"
+      }
+    },
+    "append-field": {
+      "version": "1.0.0",
+      "resolved": "https://registry.npm.taobao.org/append-field/download/append-field-1.0.0.tgz",
+      "integrity": "sha1-HjRA6RXwsSA9I3SOeO3XubW0PlY=",
+      "dev": true
+    },
+    "aproba": {
+      "version": "1.2.0",
+      "resolved": "https://registry.npm.taobao.org/aproba/download/aproba-1.2.0.tgz",
+      "integrity": "sha1-aALmJk79GMeQobDVF/DyYnvyyUo=",
+      "dev": true
+    },
+    "are-we-there-yet": {
+      "version": "1.1.5",
+      "resolved": "https://registry.npm.taobao.org/are-we-there-yet/download/are-we-there-yet-1.1.5.tgz",
+      "integrity": "sha1-SzXClE8GKov82mZBB2A1D+nd/CE=",
+      "dev": true,
+      "requires": {
+        "delegates": "^1.0.0",
+        "readable-stream": "^2.0.6"
+      },
+      "dependencies": {
+        "readable-stream": {
+          "version": "2.3.7",
+          "resolved": "https://registry.npm.taobao.org/readable-stream/download/readable-stream-2.3.7.tgz",
+          "integrity": "sha1-Hsoc9xGu+BTAT2IlKjamL2yyO1c=",
+          "dev": true,
+          "requires": {
+            "core-util-is": "~1.0.0",
+            "inherits": "~2.0.3",
+            "isarray": "~1.0.0",
+            "process-nextick-args": "~2.0.0",
+            "safe-buffer": "~5.1.1",
+            "string_decoder": "~1.1.1",
+            "util-deprecate": "~1.0.1"
+          }
+        },
+        "safe-buffer": {
+          "version": "5.1.2",
+          "resolved": "https://registry.npm.taobao.org/safe-buffer/download/safe-buffer-5.1.2.tgz",
+          "integrity": "sha1-mR7GnSluAxN0fVm9/St0XDX4go0=",
+          "dev": true
+        },
+        "string_decoder": {
+          "version": "1.1.1",
+          "resolved": "https://registry.npm.taobao.org/string_decoder/download/string_decoder-1.1.1.tgz",
+          "integrity": "sha1-nPFhG6YmhdcDCunkujQUnDrwP8g=",
+          "dev": true,
+          "requires": {
+            "safe-buffer": "~5.1.0"
+          }
+        }
+      }
+    },
+    "argparse": {
+      "version": "1.0.10",
+      "resolved": "https://registry.npm.taobao.org/argparse/download/argparse-1.0.10.tgz",
+      "integrity": "sha1-vNZ5HqWuCXJeF+WtmIE0zUCz2RE=",
+      "dev": true,
+      "requires": {
+        "sprintf-js": "~1.0.2"
+      }
+    },
+    "aria-query": {
+      "version": "4.2.2",
+      "resolved": "https://registry.npm.taobao.org/aria-query/download/aria-query-4.2.2.tgz?cache=0&other_urls=https%3A%2F%2Fregistry.npm.taobao.org%2Faria-query%2Fdownload%2Faria-query-4.2.2.tgz",
+      "integrity": "sha1-DSymyazrVriXfp/tau1+FbvS+Ds=",
+      "dev": true,
+      "requires": {
+        "@babel/runtime": "^7.10.2",
+        "@babel/runtime-corejs3": "^7.10.2"
+      }
+    },
+    "arr-diff": {
+      "version": "4.0.0",
+      "resolved": "https://registry.npm.taobao.org/arr-diff/download/arr-diff-4.0.0.tgz",
+      "integrity": "sha1-1kYQdP6/7HHn4VI1dhoyml3HxSA=",
+      "dev": true
+    },
+    "arr-flatten": {
+      "version": "1.1.0",
+      "resolved": "https://registry.npm.taobao.org/arr-flatten/download/arr-flatten-1.1.0.tgz",
+      "integrity": "sha1-NgSLv/TntH4TZkQxbJlmnqWukfE=",
+      "dev": true
+    },
+    "arr-union": {
+      "version": "3.1.0",
+      "resolved": "https://registry.npm.taobao.org/arr-union/download/arr-union-3.1.0.tgz",
+      "integrity": "sha1-45sJrqne+Gao8gbiiK9jkZuuOcQ=",
+      "dev": true
+    },
+    "array-find-index": {
+      "version": "1.0.2",
+      "resolved": "https://registry.npm.taobao.org/array-find-index/download/array-find-index-1.0.2.tgz",
+      "integrity": "sha1-3wEKoSh+Fku9pvlyOwqWoexBh6E=",
+      "dev": true
+    },
+    "array-flatten": {
+      "version": "2.1.2",
+      "resolved": "https://registry.npm.taobao.org/array-flatten/download/array-flatten-2.1.2.tgz",
+      "integrity": "sha1-JO+AoowaiTYX4hSbDG0NeIKTsJk=",
+      "dev": true
+    },
+    "array-ify": {
+      "version": "1.0.0",
+      "resolved": "https://registry.npm.taobao.org/array-ify/download/array-ify-1.0.0.tgz",
+      "integrity": "sha1-nlKHYrSpBmrRY6aWKjZEGOlibs4=",
+      "dev": true
+    },
+    "array-includes": {
+      "version": "3.1.1",
+      "resolved": "https://registry.npm.taobao.org/array-includes/download/array-includes-3.1.1.tgz",
+      "integrity": "sha1-zdZ+aFK9+cEhVGB4ZzIlXtJFk0g=",
+      "dev": true,
+      "requires": {
+        "define-properties": "^1.1.3",
+        "es-abstract": "^1.17.0",
+        "is-string": "^1.0.5"
+      }
+    },
+    "array-union": {
+      "version": "1.0.2",
+      "resolved": "https://registry.npm.taobao.org/array-union/download/array-union-1.0.2.tgz",
+      "integrity": "sha1-mjRBDk9OPaI96jdb5b5w8kd47Dk=",
+      "dev": true,
+      "requires": {
+        "array-uniq": "^1.0.1"
+      }
+    },
+    "array-uniq": {
+      "version": "1.0.3",
+      "resolved": "https://registry.npm.taobao.org/array-uniq/download/array-uniq-1.0.3.tgz",
+      "integrity": "sha1-r2rId6Jcx/dOBYiUdThY39sk/bY=",
+      "dev": true
+    },
+    "array-unique": {
+      "version": "0.3.2",
+      "resolved": "https://registry.npm.taobao.org/array-unique/download/array-unique-0.3.2.tgz",
+      "integrity": "sha1-qJS3XUvE9s1nnvMkSp/Y9Gri1Cg=",
+      "dev": true
+    },
+    "array.prototype.flat": {
+      "version": "1.2.3",
+      "resolved": "https://registry.npm.taobao.org/array.prototype.flat/download/array.prototype.flat-1.2.3.tgz",
+      "integrity": "sha1-DegrQmsDGNv9uUAInjiwQ9N/bHs=",
+      "dev": true,
+      "requires": {
+        "define-properties": "^1.1.3",
+        "es-abstract": "^1.17.0-next.1"
+      }
+    },
+    "array.prototype.flatmap": {
+      "version": "1.2.3",
+      "resolved": "https://registry.npm.taobao.org/array.prototype.flatmap/download/array.prototype.flatmap-1.2.3.tgz",
+      "integrity": "sha1-HBP4SheFZgQt1j3kQURA25Ii5EM=",
+      "dev": true,
+      "requires": {
+        "define-properties": "^1.1.3",
+        "es-abstract": "^1.17.0-next.1",
+        "function-bind": "^1.1.1"
+      }
+    },
+    "arrify": {
+      "version": "1.0.1",
+      "resolved": "https://registry.npm.taobao.org/arrify/download/arrify-1.0.1.tgz",
+      "integrity": "sha1-iYUI2iIm84DfkEcoRWhJwVAaSw0=",
+      "dev": true
+    },
+    "asap": {
+      "version": "2.0.6",
+      "resolved": "https://registry.npm.taobao.org/asap/download/asap-2.0.6.tgz",
+      "integrity": "sha1-5QNHYR1+aQlDIIu9r+vLwvuGbUY="
+    },
+    "asn1": {
+      "version": "0.2.4",
+      "resolved": "https://registry.npm.taobao.org/asn1/download/asn1-0.2.4.tgz",
+      "integrity": "sha1-jSR136tVO7M+d7VOWeiAu4ziMTY=",
+      "dev": true,
+      "requires": {
+        "safer-buffer": "~2.1.0"
+      }
+    },
+    "asn1.js": {
+      "version": "5.4.1",
+      "resolved": "https://registry.npm.taobao.org/asn1.js/download/asn1.js-5.4.1.tgz",
+      "integrity": "sha1-EamAuE67kXgc41sP3C7ilON4Pwc=",
+      "dev": true,
+      "requires": {
+        "bn.js": "^4.0.0",
+        "inherits": "^2.0.1",
+        "minimalistic-assert": "^1.0.0",
+        "safer-buffer": "^2.1.0"
+      },
+      "dependencies": {
+        "bn.js": {
+          "version": "4.11.9",
+          "resolved": "https://registry.npm.taobao.org/bn.js/download/bn.js-4.11.9.tgz",
+          "integrity": "sha1-JtVWgpRY+dHoH8SJUkk9C6NQeCg=",
+          "dev": true
+        }
+      }
+    },
+    "assert": {
+      "version": "1.5.0",
+      "resolved": "https://registry.npm.taobao.org/assert/download/assert-1.5.0.tgz?cache=0&sync_timestamp=1586265311434&other_urls=https%3A%2F%2Fregistry.npm.taobao.org%2Fassert%2Fdownload%2Fassert-1.5.0.tgz",
+      "integrity": "sha1-VcEJqvbgrv2z3EtxJAxwv1dLGOs=",
+      "dev": true,
+      "requires": {
+        "object-assign": "^4.1.1",
+        "util": "0.10.3"
+      },
+      "dependencies": {
+        "inherits": {
+          "version": "2.0.1",
+          "resolved": "https://registry.npm.taobao.org/inherits/download/inherits-2.0.1.tgz",
+          "integrity": "sha1-sX0I0ya0Qj5Wjv9xn5GwscvfafE=",
+          "dev": true
+        },
+        "util": {
+          "version": "0.10.3",
+          "resolved": "https://registry.npm.taobao.org/util/download/util-0.10.3.tgz",
+          "integrity": "sha1-evsa/lCAUkZInj23/g7TeTNqwPk=",
+          "dev": true,
+          "requires": {
+            "inherits": "2.0.1"
+          }
+        }
+      }
+    },
+    "assert-plus": {
+      "version": "1.0.0",
+      "resolved": "https://registry.npm.taobao.org/assert-plus/download/assert-plus-1.0.0.tgz",
+      "integrity": "sha1-8S4PPF13sLHN2RRpQuTpbB5N1SU=",
+      "dev": true
+    },
+    "assign-symbols": {
+      "version": "1.0.0",
+      "resolved": "https://registry.npm.taobao.org/assign-symbols/download/assign-symbols-1.0.0.tgz",
+      "integrity": "sha1-WWZ/QfrdTyDMvCu5a41Pf3jsA2c=",
+      "dev": true
+    },
+    "ast-types-flow": {
+      "version": "0.0.7",
+      "resolved": "https://registry.npm.taobao.org/ast-types-flow/download/ast-types-flow-0.0.7.tgz",
+      "integrity": "sha1-9wtzXGvKGlycItmCw+Oef+ujva0=",
+      "dev": true
+    },
+    "astral-regex": {
+      "version": "1.0.0",
+      "resolved": "https://registry.npm.taobao.org/astral-regex/download/astral-regex-1.0.0.tgz",
+      "integrity": "sha1-bIw/uCfdQ+45GPJ7gngqt2WKb9k=",
+      "dev": true
+    },
+    "async": {
+      "version": "2.6.3",
+      "resolved": "https://registry.npm.taobao.org/async/download/async-2.6.3.tgz",
+      "integrity": "sha1-1yYl4jRKNlbjo61Pp0n6gymdgv8=",
+      "dev": true,
+      "requires": {
+        "lodash": "^4.17.14"
+      }
+    },
+    "async-each": {
+      "version": "1.0.3",
+      "resolved": "https://registry.npm.taobao.org/async-each/download/async-each-1.0.3.tgz",
+      "integrity": "sha1-tyfb+H12UWAvBvTUrDh/R9kbDL8=",
+      "dev": true
+    },
+    "async-foreach": {
+      "version": "0.1.3",
+      "resolved": "https://registry.npm.taobao.org/async-foreach/download/async-foreach-0.1.3.tgz",
+      "integrity": "sha1-NhIfhFwFeBct5Bmpfb6x0W7DRUI=",
+      "dev": true
+    },
+    "async-limiter": {
+      "version": "1.0.1",
+      "resolved": "https://registry.npm.taobao.org/async-limiter/download/async-limiter-1.0.1.tgz",
+      "integrity": "sha1-3TeelPDbgxCwgpH51kwyCXZmF/0=",
+      "dev": true
+    },
+    "asynckit": {
+      "version": "0.4.0",
+      "resolved": "https://registry.npm.taobao.org/asynckit/download/asynckit-0.4.0.tgz",
+      "integrity": "sha1-x57Zf380y48robyXkLzDZkdLS3k=",
+      "dev": true
+    },
+    "at-least-node": {
+      "version": "1.0.0",
+      "resolved": "https://registry.npm.taobao.org/at-least-node/download/at-least-node-1.0.0.tgz",
+      "integrity": "sha1-YCzUtG6EStTv/JKoARo8RuAjjcI=",
+      "dev": true
+    },
+    "atob": {
+      "version": "2.1.2",
+      "resolved": "https://registry.npm.taobao.org/atob/download/atob-2.1.2.tgz",
+      "integrity": "sha1-bZUX654DDSQ2ZmZR6GvZ9vE1M8k=",
+      "dev": true
+    },
+    "autoprefixer": {
+      "version": "9.8.6",
+      "resolved": "https://registry.npm.taobao.org/autoprefixer/download/autoprefixer-9.8.6.tgz",
+      "integrity": "sha1-O3NZTKG/kmYyDFrPFYjXTep0IQ8=",
+      "dev": true,
+      "requires": {
+        "browserslist": "^4.12.0",
+        "caniuse-lite": "^1.0.30001109",
+        "colorette": "^1.2.1",
+        "normalize-range": "^0.1.2",
+        "num2fraction": "^1.2.2",
+        "postcss": "^7.0.32",
+        "postcss-value-parser": "^4.1.0"
+      },
+      "dependencies": {
+        "postcss-value-parser": {
+          "version": "4.1.0",
+          "resolved": "https://registry.npm.taobao.org/postcss-value-parser/download/postcss-value-parser-4.1.0.tgz",
+          "integrity": "sha1-RD9qIM7WSBor2k+oUypuVdeJoss=",
+          "dev": true
+        }
+      }
+    },
+    "aws-sign2": {
+      "version": "0.7.0",
+      "resolved": "https://registry.npm.taobao.org/aws-sign2/download/aws-sign2-0.7.0.tgz",
+      "integrity": "sha1-tG6JCTSpWR8tL2+G1+ap8bP+dqg=",
+      "dev": true
+    },
+    "aws4": {
+      "version": "1.11.0",
+      "resolved": "https://registry.npm.taobao.org/aws4/download/aws4-1.11.0.tgz?cache=0&sync_timestamp=1604101210422&other_urls=https%3A%2F%2Fregistry.npm.taobao.org%2Faws4%2Fdownload%2Faws4-1.11.0.tgz",
+      "integrity": "sha1-1h9G2DslGSUOJ4Ta9bCUeai0HFk=",
+      "dev": true
+    },
+    "axe-core": {
+      "version": "4.0.2",
+      "resolved": "https://registry.npm.taobao.org/axe-core/download/axe-core-4.0.2.tgz",
+      "integrity": "sha1-x89zeDeKUfzSctPAlmgAKkmQscs=",
+      "dev": true
+    },
+    "axios": {
+      "version": "0.19.2",
+      "resolved": "https://registry.npm.taobao.org/axios/download/axios-0.19.2.tgz?cache=0&sync_timestamp=1603468716105&other_urls=https%3A%2F%2Fregistry.npm.taobao.org%2Faxios%2Fdownload%2Faxios-0.19.2.tgz",
+      "integrity": "sha1-PqNsXYgY0NX4qKl6bTa4bNwAyyc=",
+      "dev": true,
+      "requires": {
+        "follow-redirects": "1.5.10"
+      },
+      "dependencies": {
+        "debug": {
+          "version": "3.1.0",
+          "resolved": "https://registry.npm.taobao.org/debug/download/debug-3.1.0.tgz?cache=0&sync_timestamp=1600502871403&other_urls=https%3A%2F%2Fregistry.npm.taobao.org%2Fdebug%2Fdownload%2Fdebug-3.1.0.tgz",
+          "integrity": "sha1-W7WgZyYotkFJVmuhaBnmFRjGcmE=",
+          "dev": true,
+          "requires": {
+            "ms": "2.0.0"
+          }
+        },
+        "follow-redirects": {
+          "version": "1.5.10",
+          "resolved": "https://registry.npm.taobao.org/follow-redirects/download/follow-redirects-1.5.10.tgz?cache=0&sync_timestamp=1597057988030&other_urls=https%3A%2F%2Fregistry.npm.taobao.org%2Ffollow-redirects%2Fdownload%2Ffollow-redirects-1.5.10.tgz",
+          "integrity": "sha1-e3qfmuov3/NnhqlP9kPtB/T/Xio=",
+          "dev": true,
+          "requires": {
+            "debug": "=3.1.0"
+          }
+        },
+        "ms": {
+          "version": "2.0.0",
+          "resolved": "https://registry.npm.taobao.org/ms/download/ms-2.0.0.tgz",
+          "integrity": "sha1-VgiurfwAvmwpAd9fmGF4jeDVl8g=",
+          "dev": true
+        }
+      }
+    },
+    "axobject-query": {
+      "version": "2.2.0",
+      "resolved": "https://registry.npm.taobao.org/axobject-query/download/axobject-query-2.2.0.tgz?cache=0&sync_timestamp=1592784810338&other_urls=https%3A%2F%2Fregistry.npm.taobao.org%2Faxobject-query%2Fdownload%2Faxobject-query-2.2.0.tgz",
+      "integrity": "sha1-lD1H4QwLcEqkInXiDt83ImSJib4=",
+      "dev": true
+    },
+    "babel-code-frame": {
+      "version": "6.26.0",
+      "resolved": "https://registry.npm.taobao.org/babel-code-frame/download/babel-code-frame-6.26.0.tgz",
+      "integrity": "sha1-Y/1D99weO7fONZR9uP42mj9Yx0s=",
+      "dev": true,
+      "requires": {
+        "chalk": "^1.1.3",
+        "esutils": "^2.0.2",
+        "js-tokens": "^3.0.2"
+      },
+      "dependencies": {
+        "ansi-regex": {
+          "version": "2.1.1",
+          "resolved": "https://registry.npm.taobao.org/ansi-regex/download/ansi-regex-2.1.1.tgz",
+          "integrity": "sha1-w7M6te42DYbg5ijwRorn7yfWVN8=",
+          "dev": true
+        },
+        "ansi-styles": {
+          "version": "2.2.1",
+          "resolved": "https://registry.npm.taobao.org/ansi-styles/download/ansi-styles-2.2.1.tgz?cache=0&sync_timestamp=1601839122515&other_urls=https%3A%2F%2Fregistry.npm.taobao.org%2Fansi-styles%2Fdownload%2Fansi-styles-2.2.1.tgz",
+          "integrity": "sha1-tDLdM1i2NM914eRmQ2gkBTPB3b4=",
+          "dev": true
+        },
+        "chalk": {
+          "version": "1.1.3",
+          "resolved": "https://registry.npm.taobao.org/chalk/download/chalk-1.1.3.tgz",
+          "integrity": "sha1-qBFcVeSnAv5NFQq9OHKCKn4J/Jg=",
+          "dev": true,
+          "requires": {
+            "ansi-styles": "^2.2.1",
+            "escape-string-regexp": "^1.0.2",
+            "has-ansi": "^2.0.0",
+            "strip-ansi": "^3.0.0",
+            "supports-color": "^2.0.0"
+          }
+        },
+        "js-tokens": {
+          "version": "3.0.2",
+          "resolved": "https://registry.npm.taobao.org/js-tokens/download/js-tokens-3.0.2.tgz",
+          "integrity": "sha1-mGbfOVECEw449/mWvOtlRDIJwls=",
+          "dev": true
+        },
+        "strip-ansi": {
+          "version": "3.0.1",
+          "resolved": "https://registry.npm.taobao.org/strip-ansi/download/strip-ansi-3.0.1.tgz",
+          "integrity": "sha1-ajhfuIU9lS1f8F0Oiq+UJ43GPc8=",
+          "dev": true,
+          "requires": {
+            "ansi-regex": "^2.0.0"
+          }
+        },
+        "supports-color": {
+          "version": "2.0.0",
+          "resolved": "https://registry.npm.taobao.org/supports-color/download/supports-color-2.0.0.tgz?cache=0&sync_timestamp=1598611730985&other_urls=https%3A%2F%2Fregistry.npm.taobao.org%2Fsupports-color%2Fdownload%2Fsupports-color-2.0.0.tgz",
+          "integrity": "sha1-U10EXOa2Nj+kARcIRimZXp3zJMc=",
+          "dev": true
+        }
+      }
+    },
+    "babel-eslint": {
+      "version": "10.1.0",
+      "resolved": "https://registry.npm.taobao.org/babel-eslint/download/babel-eslint-10.1.0.tgz",
+      "integrity": "sha1-aWjlaKkQt4+zd5zdi2rC9HmUMjI=",
+      "dev": true,
+      "requires": {
+        "@babel/code-frame": "^7.0.0",
+        "@babel/parser": "^7.7.0",
+        "@babel/traverse": "^7.7.0",
+        "@babel/types": "^7.7.0",
+        "eslint-visitor-keys": "^1.0.0",
+        "resolve": "^1.12.0"
+      }
+    },
+    "babel-jest": {
+      "version": "26.6.3",
+      "resolved": "https://registry.npm.taobao.org/babel-jest/download/babel-jest-26.6.3.tgz",
+      "integrity": "sha1-2H0lywA3V3oMifguV1XF0pPAEFY=",
+      "dev": true,
+      "requires": {
+        "@jest/transform": "^26.6.2",
+        "@jest/types": "^26.6.2",
+        "@types/babel__core": "^7.1.7",
+        "babel-plugin-istanbul": "^6.0.0",
+        "babel-preset-jest": "^26.6.2",
+        "chalk": "^4.0.0",
+        "graceful-fs": "^4.2.4",
+        "slash": "^3.0.0"
+      },
+      "dependencies": {
+        "ansi-styles": {
+          "version": "4.3.0",
+          "resolved": "https://registry.npm.taobao.org/ansi-styles/download/ansi-styles-4.3.0.tgz?cache=0&sync_timestamp=1601839122515&other_urls=https%3A%2F%2Fregistry.npm.taobao.org%2Fansi-styles%2Fdownload%2Fansi-styles-4.3.0.tgz",
+          "integrity": "sha1-7dgDYornHATIWuegkG7a00tkiTc=",
+          "dev": true,
+          "requires": {
+            "color-convert": "^2.0.1"
+          }
+        },
+        "chalk": {
+          "version": "4.1.0",
+          "resolved": "https://registry.npm.taobao.org/chalk/download/chalk-4.1.0.tgz",
+          "integrity": "sha1-ThSHCmGNni7dl92DRf2dncMVZGo=",
+          "dev": true,
+          "requires": {
+            "ansi-styles": "^4.1.0",
+            "supports-color": "^7.1.0"
+          }
+        },
+        "color-convert": {
+          "version": "2.0.1",
+          "resolved": "https://registry.npm.taobao.org/color-convert/download/color-convert-2.0.1.tgz",
+          "integrity": "sha1-ctOmjVmMm9s68q0ehPIdiWq9TeM=",
+          "dev": true,
+          "requires": {
+            "color-name": "~1.1.4"
+          }
+        },
+        "color-name": {
+          "version": "1.1.4",
+          "resolved": "https://registry.npm.taobao.org/color-name/download/color-name-1.1.4.tgz",
+          "integrity": "sha1-wqCah6y95pVD3m9j+jmVyCbFNqI=",
+          "dev": true
+        },
+        "has-flag": {
+          "version": "4.0.0",
+          "resolved": "https://registry.npm.taobao.org/has-flag/download/has-flag-4.0.0.tgz?cache=0&sync_timestamp=1596294337050&other_urls=https%3A%2F%2Fregistry.npm.taobao.org%2Fhas-flag%2Fdownload%2Fhas-flag-4.0.0.tgz",
+          "integrity": "sha1-lEdx/ZyByBJlxNaUGGDaBrtZR5s=",
+          "dev": true
+        },
+        "slash": {
+          "version": "3.0.0",
+          "resolved": "https://registry.npm.taobao.org/slash/download/slash-3.0.0.tgz",
+          "integrity": "sha1-ZTm+hwwWWtvVJAIg2+Nh8bxNRjQ=",
+          "dev": true
+        },
+        "supports-color": {
+          "version": "7.2.0",
+          "resolved": "https://registry.npm.taobao.org/supports-color/download/supports-color-7.2.0.tgz?cache=0&sync_timestamp=1598611730985&other_urls=https%3A%2F%2Fregistry.npm.taobao.org%2Fsupports-color%2Fdownload%2Fsupports-color-7.2.0.tgz",
+          "integrity": "sha1-G33NyzK4E4gBs+R4umpRyqiWSNo=",
+          "dev": true,
+          "requires": {
+            "has-flag": "^4.0.0"
+          }
+        }
+      }
+    },
+    "babel-loader": {
+      "version": "8.2.1",
+      "resolved": "https://registry.npm.taobao.org/babel-loader/download/babel-loader-8.2.1.tgz?cache=0&sync_timestamp=1605043056908&other_urls=https%3A%2F%2Fregistry.npm.taobao.org%2Fbabel-loader%2Fdownload%2Fbabel-loader-8.2.1.tgz",
+      "integrity": "sha1-5TMTJUZ36G8nU29QcdgH4B0k7AA=",
+      "dev": true,
+      "requires": {
+        "find-cache-dir": "^2.1.0",
+        "loader-utils": "^1.4.0",
+        "make-dir": "^2.1.0",
+        "pify": "^4.0.1",
+        "schema-utils": "^2.6.5"
+      },
+      "dependencies": {
+        "make-dir": {
+          "version": "2.1.0",
+          "resolved": "https://registry.npm.taobao.org/make-dir/download/make-dir-2.1.0.tgz",
+          "integrity": "sha1-XwMQ4YuL6JjMBwCSlaMK5B6R5vU=",
+          "dev": true,
+          "requires": {
+            "pify": "^4.0.1",
+            "semver": "^5.6.0"
+          }
+        },
+        "pify": {
+          "version": "4.0.1",
+          "resolved": "https://registry.npm.taobao.org/pify/download/pify-4.0.1.tgz",
+          "integrity": "sha1-SyzSXFDVmHNcUCkiJP2MbfQeMjE=",
+          "dev": true
+        },
+        "schema-utils": {
+          "version": "2.7.1",
+          "resolved": "https://registry.npm.taobao.org/schema-utils/download/schema-utils-2.7.1.tgz",
+          "integrity": "sha1-HKTzLRskxZDCA7jnpQvw6kzTlNc=",
+          "dev": true,
+          "requires": {
+            "@types/json-schema": "^7.0.5",
+            "ajv": "^6.12.4",
+            "ajv-keywords": "^3.5.2"
+          }
+        },
+        "semver": {
+          "version": "5.7.1",
+          "resolved": "https://registry.npm.taobao.org/semver/download/semver-5.7.1.tgz",
+          "integrity": "sha1-qVT5Ma66UI0we78Gnv8MAclhFvc=",
+          "dev": true
+        }
+      }
+    },
+    "babel-plugin-dynamic-import-node": {
+      "version": "2.3.3",
+      "resolved": "https://registry.npm.taobao.org/babel-plugin-dynamic-import-node/download/babel-plugin-dynamic-import-node-2.3.3.tgz",
+      "integrity": "sha1-hP2hnJduxcbe/vV/lCez3vZuF6M=",
+      "dev": true,
+      "requires": {
+        "object.assign": "^4.1.0"
+      }
+    },
+    "babel-plugin-import": {
+      "version": "1.13.1",
+      "resolved": "https://registry.npm.taobao.org/babel-plugin-import/download/babel-plugin-import-1.13.1.tgz",
+      "integrity": "sha1-9s8ay3bFzjZrriZjrRK9iUMW2Ns=",
+      "dev": true,
+      "requires": {
+        "@babel/helper-module-imports": "^7.0.0",
+        "@babel/runtime": "^7.0.0"
+      }
+    },
+    "babel-plugin-istanbul": {
+      "version": "6.0.0",
+      "resolved": "https://registry.npm.taobao.org/babel-plugin-istanbul/download/babel-plugin-istanbul-6.0.0.tgz",
+      "integrity": "sha1-4VnM3Jr5XgtXDHW0Vzt8NNZx12U=",
+      "dev": true,
+      "requires": {
+        "@babel/helper-plugin-utils": "^7.0.0",
+        "@istanbuljs/load-nyc-config": "^1.0.0",
+        "@istanbuljs/schema": "^0.1.2",
+        "istanbul-lib-instrument": "^4.0.0",
+        "test-exclude": "^6.0.0"
+      }
+    },
+    "babel-plugin-jest-hoist": {
+      "version": "26.6.2",
+      "resolved": "https://registry.npm.taobao.org/babel-plugin-jest-hoist/download/babel-plugin-jest-hoist-26.6.2.tgz?cache=0&sync_timestamp=1604319713233&other_urls=https%3A%2F%2Fregistry.npm.taobao.org%2Fbabel-plugin-jest-hoist%2Fdownload%2Fbabel-plugin-jest-hoist-26.6.2.tgz",
+      "integrity": "sha1-gYW9AwNI0lTG192XQ1Xmoosh5i0=",
+      "dev": true,
+      "requires": {
+        "@babel/template": "^7.3.3",
+        "@babel/types": "^7.3.3",
+        "@types/babel__core": "^7.0.0",
+        "@types/babel__traverse": "^7.0.6"
+      }
+    },
+    "babel-plugin-module-resolver": {
+      "version": "4.0.0",
+      "resolved": "https://registry.npm.taobao.org/babel-plugin-module-resolver/download/babel-plugin-module-resolver-4.0.0.tgz",
+      "integrity": "sha1-jzo9nUgofcHTsNVZUROtq9NqhH8=",
+      "dev": true,
+      "requires": {
+        "find-babel-config": "^1.2.0",
+        "glob": "^7.1.6",
+        "pkg-up": "^3.1.0",
+        "reselect": "^4.0.0",
+        "resolve": "^1.13.1"
+      }
+    },
+    "babel-preset-current-node-syntax": {
+      "version": "1.0.0",
+      "resolved": "https://registry.npm.taobao.org/babel-preset-current-node-syntax/download/babel-preset-current-node-syntax-1.0.0.tgz?cache=0&sync_timestamp=1604147849036&other_urls=https%3A%2F%2Fregistry.npm.taobao.org%2Fbabel-preset-current-node-syntax%2Fdownload%2Fbabel-preset-current-node-syntax-1.0.0.tgz",
+      "integrity": "sha1-z1/u8pVRJTRxz6gvyOD1Bj3wenc=",
+      "dev": true,
+      "requires": {
+        "@babel/plugin-syntax-async-generators": "^7.8.4",
+        "@babel/plugin-syntax-bigint": "^7.8.3",
+        "@babel/plugin-syntax-class-properties": "^7.8.3",
+        "@babel/plugin-syntax-import-meta": "^7.8.3",
+        "@babel/plugin-syntax-json-strings": "^7.8.3",
+        "@babel/plugin-syntax-logical-assignment-operators": "^7.8.3",
+        "@babel/plugin-syntax-nullish-coalescing-operator": "^7.8.3",
+        "@babel/plugin-syntax-numeric-separator": "^7.8.3",
+        "@babel/plugin-syntax-object-rest-spread": "^7.8.3",
+        "@babel/plugin-syntax-optional-catch-binding": "^7.8.3",
+        "@babel/plugin-syntax-optional-chaining": "^7.8.3",
+        "@babel/plugin-syntax-top-level-await": "^7.8.3"
+      }
+    },
+    "babel-preset-jest": {
+      "version": "26.6.2",
+      "resolved": "https://registry.npm.taobao.org/babel-preset-jest/download/babel-preset-jest-26.6.2.tgz?cache=0&sync_timestamp=1604319712402&other_urls=https%3A%2F%2Fregistry.npm.taobao.org%2Fbabel-preset-jest%2Fdownload%2Fbabel-preset-jest-26.6.2.tgz",
+      "integrity": "sha1-dHhysRcd8DIlJCZYaIHWLTF5j+4=",
+      "dev": true,
+      "requires": {
+        "babel-plugin-jest-hoist": "^26.6.2",
+        "babel-preset-current-node-syntax": "^1.0.0"
+      }
+    },
+    "babel-runtime": {
+      "version": "6.26.0",
+      "resolved": "https://registry.npm.taobao.org/babel-runtime/download/babel-runtime-6.26.0.tgz",
+      "integrity": "sha1-llxwWGaOgrVde/4E/yM3vItWR/4=",
+      "requires": {
+        "core-js": "^2.4.0",
+        "regenerator-runtime": "^0.11.0"
+      }
+    },
+    "bail": {
+      "version": "1.0.5",
+      "resolved": "https://registry.npm.taobao.org/bail/download/bail-1.0.5.tgz",
+      "integrity": "sha1-tvoTNASjksvB+MS/Y/WVM1Hnp3Y=",
+      "dev": true
+    },
+    "balanced-match": {
+      "version": "1.0.0",
+      "resolved": "https://registry.npm.taobao.org/balanced-match/download/balanced-match-1.0.0.tgz",
+      "integrity": "sha1-ibTRmasr7kneFk6gK4nORi1xt2c=",
+      "dev": true
+    },
+    "base": {
+      "version": "0.11.2",
+      "resolved": "https://registry.npm.taobao.org/base/download/base-0.11.2.tgz",
+      "integrity": "sha1-e95c7RRbbVUakNuH+DxVi060io8=",
+      "dev": true,
+      "requires": {
+        "cache-base": "^1.0.1",
+        "class-utils": "^0.3.5",
+        "component-emitter": "^1.2.1",
+        "define-property": "^1.0.0",
+        "isobject": "^3.0.1",
+        "mixin-deep": "^1.2.0",
+        "pascalcase": "^0.1.1"
+      },
+      "dependencies": {
+        "define-property": {
+          "version": "1.0.0",
+          "resolved": "https://registry.npm.taobao.org/define-property/download/define-property-1.0.0.tgz",
+          "integrity": "sha1-dp66rz9KY6rTr56NMEybvnm/sOY=",
+          "dev": true,
+          "requires": {
+            "is-descriptor": "^1.0.0"
+          }
+        },
+        "is-accessor-descriptor": {
+          "version": "1.0.0",
+          "resolved": "https://registry.npm.taobao.org/is-accessor-descriptor/download/is-accessor-descriptor-1.0.0.tgz",
+          "integrity": "sha1-FpwvbT3x+ZJhgHI2XJsOofaHhlY=",
+          "dev": true,
+          "requires": {
+            "kind-of": "^6.0.0"
+          }
+        },
+        "is-data-descriptor": {
+          "version": "1.0.0",
+          "resolved": "https://registry.npm.taobao.org/is-data-descriptor/download/is-data-descriptor-1.0.0.tgz",
+          "integrity": "sha1-2Eh2Mh0Oet0DmQQGq7u9NrqSaMc=",
+          "dev": true,
+          "requires": {
+            "kind-of": "^6.0.0"
+          }
+        },
+        "is-descriptor": {
+          "version": "1.0.2",
+          "resolved": "https://registry.npm.taobao.org/is-descriptor/download/is-descriptor-1.0.2.tgz",
+          "integrity": "sha1-OxWXRqZmBLBPjIFSS6NlxfFNhuw=",
+          "dev": true,
+          "requires": {
+            "is-accessor-descriptor": "^1.0.0",
+            "is-data-descriptor": "^1.0.0",
+            "kind-of": "^6.0.2"
+          }
+        }
+      }
+    },
+    "base16": {
+      "version": "1.0.0",
+      "resolved": "https://registry.npm.taobao.org/base16/download/base16-1.0.0.tgz",
+      "integrity": "sha1-4pf2DX7BAUp6lxo568ipjAtoHnA="
+    },
+    "base64-js": {
+      "version": "1.5.1",
+      "resolved": "https://registry.npm.taobao.org/base64-js/download/base64-js-1.5.1.tgz?cache=0&other_urls=https%3A%2F%2Fregistry.npm.taobao.org%2Fbase64-js%2Fdownload%2Fbase64-js-1.5.1.tgz",
+      "integrity": "sha1-GxtEAWClv3rUC2UPCVljSBkDkwo=",
+      "dev": true
+    },
+    "batch": {
+      "version": "0.6.1",
+      "resolved": "https://registry.npm.taobao.org/batch/download/batch-0.6.1.tgz",
+      "integrity": "sha1-3DQxT05nkxgJP8dgJyUl+UvyXBY=",
+      "dev": true
+    },
+    "bcrypt-pbkdf": {
+      "version": "1.0.2",
+      "resolved": "https://registry.npm.taobao.org/bcrypt-pbkdf/download/bcrypt-pbkdf-1.0.2.tgz",
+      "integrity": "sha1-pDAdOJtqQ/m2f/PKEaP2Y342Dp4=",
+      "dev": true,
+      "requires": {
+        "tweetnacl": "^0.14.3"
+      }
+    },
+    "bfj": {
+      "version": "6.1.2",
+      "resolved": "https://registry.npm.taobao.org/bfj/download/bfj-6.1.2.tgz",
+      "integrity": "sha1-MlyGGoIryzWKQceKM7jm4ght3n8=",
+      "dev": true,
+      "requires": {
+        "bluebird": "^3.5.5",
+        "check-types": "^8.0.3",
+        "hoopy": "^0.1.4",
+        "tryer": "^1.0.1"
+      }
+    },
+    "big.js": {
+      "version": "5.2.2",
+      "resolved": "https://registry.npm.taobao.org/big.js/download/big.js-5.2.2.tgz",
+      "integrity": "sha1-ZfCvOC9Xi83HQr2cKB6cstd2gyg=",
+      "dev": true
+    },
+    "binary-extensions": {
+      "version": "2.1.0",
+      "resolved": "https://registry.npm.taobao.org/binary-extensions/download/binary-extensions-2.1.0.tgz?cache=0&sync_timestamp=1593261309792&other_urls=https%3A%2F%2Fregistry.npm.taobao.org%2Fbinary-extensions%2Fdownload%2Fbinary-extensions-2.1.0.tgz",
+      "integrity": "sha1-MPpAyef+B9vIlWeM0ocCTeokHdk=",
+      "dev": true
+    },
+    "bindings": {
+      "version": "1.5.0",
+      "resolved": "https://registry.npm.taobao.org/bindings/download/bindings-1.5.0.tgz",
+      "integrity": "sha1-EDU8npRTNLwFEabZCzj7x8nFBN8=",
+      "dev": true,
+      "optional": true,
+      "requires": {
+        "file-uri-to-path": "1.0.0"
+      }
+    },
+    "block-stream": {
+      "version": "0.0.9",
+      "resolved": "https://registry.npm.taobao.org/block-stream/download/block-stream-0.0.9.tgz",
+      "integrity": "sha1-E+v+d4oDIFz+A3UUgeu0szAMEmo=",
+      "dev": true,
+      "requires": {
+        "inherits": "~2.0.0"
+      }
+    },
+    "bluebird": {
+      "version": "3.7.2",
+      "resolved": "https://registry.npm.taobao.org/bluebird/download/bluebird-3.7.2.tgz?cache=0&sync_timestamp=1586263933818&other_urls=https%3A%2F%2Fregistry.npm.taobao.org%2Fbluebird%2Fdownload%2Fbluebird-3.7.2.tgz",
+      "integrity": "sha1-nyKcFb4nJFT/qXOs4NvueaGww28=",
+      "dev": true
+    },
+    "bn.js": {
+      "version": "5.1.3",
+      "resolved": "https://registry.npm.taobao.org/bn.js/download/bn.js-5.1.3.tgz",
+      "integrity": "sha1-vsoAVAj2Quvr6oCwQrTRjSrA7ms=",
+      "dev": true
+    },
+    "body-parser": {
+      "version": "1.19.0",
+      "resolved": "https://registry.npm.taobao.org/body-parser/download/body-parser-1.19.0.tgz",
+      "integrity": "sha1-lrJwnlfJxOCab9Zqj9l5hE9p8Io=",
+      "dev": true,
+      "requires": {
+        "bytes": "3.1.0",
+        "content-type": "~1.0.4",
+        "debug": "2.6.9",
+        "depd": "~1.1.2",
+        "http-errors": "1.7.2",
+        "iconv-lite": "0.4.24",
+        "on-finished": "~2.3.0",
+        "qs": "6.7.0",
+        "raw-body": "2.4.0",
+        "type-is": "~1.6.17"
+      },
+      "dependencies": {
+        "bytes": {
+          "version": "3.1.0",
+          "resolved": "https://registry.npm.taobao.org/bytes/download/bytes-3.1.0.tgz",
+          "integrity": "sha1-9s95M6Ng4FiPqf3oVlHNx/gF0fY=",
+          "dev": true
+        },
+        "debug": {
+          "version": "2.6.9",
+          "resolved": "https://registry.npm.taobao.org/debug/download/debug-2.6.9.tgz?cache=0&sync_timestamp=1600502871403&other_urls=https%3A%2F%2Fregistry.npm.taobao.org%2Fdebug%2Fdownload%2Fdebug-2.6.9.tgz",
+          "integrity": "sha1-XRKFFd8TT/Mn6QpMk/Tgd6U2NB8=",
+          "dev": true,
+          "requires": {
+            "ms": "2.0.0"
+          }
+        },
+        "iconv-lite": {
+          "version": "0.4.24",
+          "resolved": "https://registry.npm.taobao.org/iconv-lite/download/iconv-lite-0.4.24.tgz",
+          "integrity": "sha1-ICK0sl+93CHS9SSXSkdKr+czkIs=",
+          "dev": true,
+          "requires": {
+            "safer-buffer": ">= 2.1.2 < 3"
+          }
+        },
+        "ms": {
+          "version": "2.0.0",
+          "resolved": "https://registry.npm.taobao.org/ms/download/ms-2.0.0.tgz",
+          "integrity": "sha1-VgiurfwAvmwpAd9fmGF4jeDVl8g=",
+          "dev": true
+        },
+        "qs": {
+          "version": "6.7.0",
+          "resolved": "https://registry.npm.taobao.org/qs/download/qs-6.7.0.tgz",
+          "integrity": "sha1-QdwaAV49WB8WIXdr4xr7KHapsbw=",
+          "dev": true
+        }
+      }
+    },
+    "bonjour": {
+      "version": "3.5.0",
+      "resolved": "https://registry.npm.taobao.org/bonjour/download/bonjour-3.5.0.tgz",
+      "integrity": "sha1-jokKGD2O6aI5OzhExpGkK897yfU=",
+      "dev": true,
+      "requires": {
+        "array-flatten": "^2.1.0",
+        "deep-equal": "^1.0.1",
+        "dns-equal": "^1.0.0",
+        "dns-txt": "^2.0.2",
+        "multicast-dns": "^6.0.1",
+        "multicast-dns-service-types": "^1.1.0"
+      }
+    },
+    "boolbase": {
+      "version": "1.0.0",
+      "resolved": "https://registry.npm.taobao.org/boolbase/download/boolbase-1.0.0.tgz",
+      "integrity": "sha1-aN/1++YMUes3cl6p4+0xDcwed24=",
+      "dev": true
+    },
+    "brace-expansion": {
+      "version": "1.1.11",
+      "resolved": "https://registry.npm.taobao.org/brace-expansion/download/brace-expansion-1.1.11.tgz?cache=0&sync_timestamp=1601898189928&other_urls=https%3A%2F%2Fregistry.npm.taobao.org%2Fbrace-expansion%2Fdownload%2Fbrace-expansion-1.1.11.tgz",
+      "integrity": "sha1-PH/L9SnYcibz0vUrlm/1Jx60Qd0=",
+      "dev": true,
+      "requires": {
+        "balanced-match": "^1.0.0",
+        "concat-map": "0.0.1"
+      }
+    },
+    "braces": {
+      "version": "2.3.2",
+      "resolved": "https://registry.npm.taobao.org/braces/download/braces-2.3.2.tgz",
+      "integrity": "sha1-WXn9PxTNUxVl5fot8av/8d+u5yk=",
+      "dev": true,
+      "requires": {
+        "arr-flatten": "^1.1.0",
+        "array-unique": "^0.3.2",
+        "extend-shallow": "^2.0.1",
+        "fill-range": "^4.0.0",
+        "isobject": "^3.0.1",
+        "repeat-element": "^1.1.2",
+        "snapdragon": "^0.8.1",
+        "snapdragon-node": "^2.0.1",
+        "split-string": "^3.0.2",
+        "to-regex": "^3.0.1"
+      },
+      "dependencies": {
+        "extend-shallow": {
+          "version": "2.0.1",
+          "resolved": "https://registry.npm.taobao.org/extend-shallow/download/extend-shallow-2.0.1.tgz",
+          "integrity": "sha1-Ua99YUrZqfYQ6huvu5idaxxWiQ8=",
+          "dev": true,
+          "requires": {
+            "is-extendable": "^0.1.0"
+          }
+        }
+      }
+    },
+    "brorand": {
+      "version": "1.1.0",
+      "resolved": "https://registry.npm.taobao.org/brorand/download/brorand-1.1.0.tgz",
+      "integrity": "sha1-EsJe/kCkXjwyPrhnWgoM5XsiNx8=",
+      "dev": true
+    },
+    "browser-process-hrtime": {
+      "version": "1.0.0",
+      "resolved": "https://registry.npm.taobao.org/browser-process-hrtime/download/browser-process-hrtime-1.0.0.tgz",
+      "integrity": "sha1-PJtLfXgsgSHlbxAQbYTA0P/JRiY=",
+      "dev": true
+    },
+    "browserify-aes": {
+      "version": "1.2.0",
+      "resolved": "https://registry.npm.taobao.org/browserify-aes/download/browserify-aes-1.2.0.tgz",
+      "integrity": "sha1-Mmc0ZC9APavDADIJhTu3CtQo70g=",
+      "dev": true,
+      "requires": {
+        "buffer-xor": "^1.0.3",
+        "cipher-base": "^1.0.0",
+        "create-hash": "^1.1.0",
+        "evp_bytestokey": "^1.0.3",
+        "inherits": "^2.0.1",
+        "safe-buffer": "^5.0.1"
+      }
+    },
+    "browserify-cipher": {
+      "version": "1.0.1",
+      "resolved": "https://registry.npm.taobao.org/browserify-cipher/download/browserify-cipher-1.0.1.tgz",
+      "integrity": "sha1-jWR0wbhwv9q807z8wZNKEOlPFfA=",
+      "dev": true,
+      "requires": {
+        "browserify-aes": "^1.0.4",
+        "browserify-des": "^1.0.0",
+        "evp_bytestokey": "^1.0.0"
+      }
+    },
+    "browserify-des": {
+      "version": "1.0.2",
+      "resolved": "https://registry.npm.taobao.org/browserify-des/download/browserify-des-1.0.2.tgz",
+      "integrity": "sha1-OvTx9Zg5QDVy8cZiBDdfen9wPpw=",
+      "dev": true,
+      "requires": {
+        "cipher-base": "^1.0.1",
+        "des.js": "^1.0.0",
+        "inherits": "^2.0.1",
+        "safe-buffer": "^5.1.2"
+      }
+    },
+    "browserify-rsa": {
+      "version": "4.1.0",
+      "resolved": "https://registry.npm.taobao.org/browserify-rsa/download/browserify-rsa-4.1.0.tgz",
+      "integrity": "sha1-sv0Gtbda4pf3zi3GUfkY9b4VjI0=",
+      "dev": true,
+      "requires": {
+        "bn.js": "^5.0.0",
+        "randombytes": "^2.0.1"
+      }
+    },
+    "browserify-sign": {
+      "version": "4.2.1",
+      "resolved": "https://registry.npm.taobao.org/browserify-sign/download/browserify-sign-4.2.1.tgz",
+      "integrity": "sha1-6vSt1G3VS+O7OzbAzxWrvrp5VsM=",
+      "dev": true,
+      "requires": {
+        "bn.js": "^5.1.1",
+        "browserify-rsa": "^4.0.1",
+        "create-hash": "^1.2.0",
+        "create-hmac": "^1.1.7",
+        "elliptic": "^6.5.3",
+        "inherits": "^2.0.4",
+        "parse-asn1": "^5.1.5",
+        "readable-stream": "^3.6.0",
+        "safe-buffer": "^5.2.0"
+      }
+    },
+    "browserify-zlib": {
+      "version": "0.2.0",
+      "resolved": "https://registry.npm.taobao.org/browserify-zlib/download/browserify-zlib-0.2.0.tgz",
+      "integrity": "sha1-KGlFnZqjviRf6P4sofRuLn9U1z8=",
+      "dev": true,
+      "requires": {
+        "pako": "~1.0.5"
+      }
+    },
+    "browserslist": {
+      "version": "4.14.7",
+      "resolved": "https://registry.npm.taobao.org/browserslist/download/browserslist-4.14.7.tgz?cache=0&sync_timestamp=1604944989360&other_urls=https%3A%2F%2Fregistry.npm.taobao.org%2Fbrowserslist%2Fdownload%2Fbrowserslist-4.14.7.tgz",
+      "integrity": "sha1-wHHBs2IsHC55B5mje7CUc6Q1HLY=",
+      "dev": true,
+      "requires": {
+        "caniuse-lite": "^1.0.30001157",
+        "colorette": "^1.2.1",
+        "electron-to-chromium": "^1.3.591",
+        "escalade": "^3.1.1",
+        "node-releases": "^1.1.66"
+      }
+    },
+    "bser": {
+      "version": "2.1.1",
+      "resolved": "https://registry.npm.taobao.org/bser/download/bser-2.1.1.tgz",
+      "integrity": "sha1-5nh9og7OnQeZhTPP2d5vXDj0vAU=",
+      "dev": true,
+      "requires": {
+        "node-int64": "^0.4.0"
+      }
+    },
+    "buffer": {
+      "version": "4.9.2",
+      "resolved": "https://registry.npm.taobao.org/buffer/download/buffer-4.9.2.tgz?cache=0&sync_timestamp=1604959484032&other_urls=https%3A%2F%2Fregistry.npm.taobao.org%2Fbuffer%2Fdownload%2Fbuffer-4.9.2.tgz",
+      "integrity": "sha1-Iw6tNEACmIZEhBqwJEr4xEu+Pvg=",
+      "dev": true,
+      "requires": {
+        "base64-js": "^1.0.2",
+        "ieee754": "^1.1.4",
+        "isarray": "^1.0.0"
+      }
+    },
+    "buffer-from": {
+      "version": "1.1.1",
+      "resolved": "https://registry.npm.taobao.org/buffer-from/download/buffer-from-1.1.1.tgz",
+      "integrity": "sha1-MnE7wCj3XAL9txDXx7zsHyxgcO8=",
+      "dev": true
+    },
+    "buffer-indexof": {
+      "version": "1.1.1",
+      "resolved": "https://registry.npm.taobao.org/buffer-indexof/download/buffer-indexof-1.1.1.tgz",
+      "integrity": "sha1-Uvq8xqYG0aADAoAmSO9o9jnaJow=",
+      "dev": true
+    },
+    "buffer-xor": {
+      "version": "1.0.3",
+      "resolved": "https://registry.npm.taobao.org/buffer-xor/download/buffer-xor-1.0.3.tgz",
+      "integrity": "sha1-JuYe0UIvtw3ULm42cp7VHYVf6Nk=",
+      "dev": true
+    },
+    "build-plugin-app-core": {
+      "version": "0.1.23",
+      "resolved": "https://registry.npm.taobao.org/build-plugin-app-core/download/build-plugin-app-core-0.1.23.tgz",
+      "integrity": "sha1-cbiqu2MYpdi9gqnpMuKaupusfa0=",
+      "dev": true,
+      "requires": {
+        "chalk": "^4.0.0",
+        "chokidar": "^3.4.1",
+        "create-app-shared": "^0.1.14",
+        "ejs": "^3.0.1",
+        "fs-extra": "^8.1.0",
+        "globby": "^11.0.0",
+        "history": "^4.9.0",
+        "miniapp-history": "^0.1.0",
+        "miniapp-renderer": "^0.1.4",
+        "prettier": "^2.0.2",
+        "query-string": "^6.13.1",
+        "rax-app-renderer": "^0.1.4",
+        "rax-use-router": "^3.0.0",
+        "react-app-renderer": "0.1.10",
+        "universal-env": "^3.0.0"
+      },
+      "dependencies": {
+        "@nodelib/fs.stat": {
+          "version": "2.0.3",
+          "resolved": "https://registry.npm.taobao.org/@nodelib/fs.stat/download/@nodelib/fs.stat-2.0.3.tgz",
+          "integrity": "sha1-NNxfTKu8cg9OYPdadH5+zWwXW9M=",
+          "dev": true
+        },
+        "ansi-styles": {
+          "version": "4.3.0",
+          "resolved": "https://registry.npm.taobao.org/ansi-styles/download/ansi-styles-4.3.0.tgz?cache=0&sync_timestamp=1601839122515&other_urls=https%3A%2F%2Fregistry.npm.taobao.org%2Fansi-styles%2Fdownload%2Fansi-styles-4.3.0.tgz",
+          "integrity": "sha1-7dgDYornHATIWuegkG7a00tkiTc=",
+          "dev": true,
+          "requires": {
+            "color-convert": "^2.0.1"
+          }
+        },
+        "array-union": {
+          "version": "2.1.0",
+          "resolved": "https://registry.npm.taobao.org/array-union/download/array-union-2.1.0.tgz",
+          "integrity": "sha1-t5hCCtvrHego2ErNii4j0+/oXo0=",
+          "dev": true
+        },
+        "braces": {
+          "version": "3.0.2",
+          "resolved": "https://registry.npm.taobao.org/braces/download/braces-3.0.2.tgz",
+          "integrity": "sha1-NFThpGLujVmeI23zNs2epPiv4Qc=",
+          "dev": true,
+          "requires": {
+            "fill-range": "^7.0.1"
+          }
+        },
+        "chalk": {
+          "version": "4.1.0",
+          "resolved": "https://registry.npm.taobao.org/chalk/download/chalk-4.1.0.tgz",
+          "integrity": "sha1-ThSHCmGNni7dl92DRf2dncMVZGo=",
+          "dev": true,
+          "requires": {
+            "ansi-styles": "^4.1.0",
+            "supports-color": "^7.1.0"
+          }
+        },
+        "color-convert": {
+          "version": "2.0.1",
+          "resolved": "https://registry.npm.taobao.org/color-convert/download/color-convert-2.0.1.tgz",
+          "integrity": "sha1-ctOmjVmMm9s68q0ehPIdiWq9TeM=",
+          "dev": true,
+          "requires": {
+            "color-name": "~1.1.4"
+          }
+        },
+        "color-name": {
+          "version": "1.1.4",
+          "resolved": "https://registry.npm.taobao.org/color-name/download/color-name-1.1.4.tgz",
+          "integrity": "sha1-wqCah6y95pVD3m9j+jmVyCbFNqI=",
+          "dev": true
+        },
+        "dir-glob": {
+          "version": "3.0.1",
+          "resolved": "https://registry.npm.taobao.org/dir-glob/download/dir-glob-3.0.1.tgz",
+          "integrity": "sha1-Vtv3PZkqSpO6FYT0U0Bj/S5BcX8=",
+          "dev": true,
+          "requires": {
+            "path-type": "^4.0.0"
+          }
+        },
+        "fast-glob": {
+          "version": "3.2.4",
+          "resolved": "https://registry.npm.taobao.org/fast-glob/download/fast-glob-3.2.4.tgz?cache=0&sync_timestamp=1592290372789&other_urls=https%3A%2F%2Fregistry.npm.taobao.org%2Ffast-glob%2Fdownload%2Ffast-glob-3.2.4.tgz",
+          "integrity": "sha1-0grvv5lXk4Pn88xmUpFYybmFVNM=",
+          "dev": true,
+          "requires": {
+            "@nodelib/fs.stat": "^2.0.2",
+            "@nodelib/fs.walk": "^1.2.3",
+            "glob-parent": "^5.1.0",
+            "merge2": "^1.3.0",
+            "micromatch": "^4.0.2",
+            "picomatch": "^2.2.1"
+          }
+        },
+        "fill-range": {
+          "version": "7.0.1",
+          "resolved": "https://registry.npm.taobao.org/fill-range/download/fill-range-7.0.1.tgz",
+          "integrity": "sha1-GRmmp8df44ssfHflGYU12prN2kA=",
+          "dev": true,
+          "requires": {
+            "to-regex-range": "^5.0.1"
+          }
+        },
+        "glob-parent": {
+          "version": "5.1.1",
+          "resolved": "https://registry.npm.taobao.org/glob-parent/download/glob-parent-5.1.1.tgz",
+          "integrity": "sha1-tsHvQXxOVmPqSY8cRa+saRa7wik=",
+          "dev": true,
+          "requires": {
+            "is-glob": "^4.0.1"
+          }
+        },
+        "globby": {
+          "version": "11.0.1",
+          "resolved": "https://registry.npm.taobao.org/globby/download/globby-11.0.1.tgz",
+          "integrity": "sha1-mivxB6Bo8//qvEmtcCx57ejP01c=",
+          "dev": true,
+          "requires": {
+            "array-union": "^2.1.0",
+            "dir-glob": "^3.0.1",
+            "fast-glob": "^3.1.1",
+            "ignore": "^5.1.4",
+            "merge2": "^1.3.0",
+            "slash": "^3.0.0"
+          }
+        },
+        "has-flag": {
+          "version": "4.0.0",
+          "resolved": "https://registry.npm.taobao.org/has-flag/download/has-flag-4.0.0.tgz?cache=0&sync_timestamp=1596294337050&other_urls=https%3A%2F%2Fregistry.npm.taobao.org%2Fhas-flag%2Fdownload%2Fhas-flag-4.0.0.tgz",
+          "integrity": "sha1-lEdx/ZyByBJlxNaUGGDaBrtZR5s=",
+          "dev": true
+        },
+        "is-number": {
+          "version": "7.0.0",
+          "resolved": "https://registry.npm.taobao.org/is-number/download/is-number-7.0.0.tgz",
+          "integrity": "sha1-dTU0W4lnNNX4DE0GxQlVUnoU8Ss=",
+          "dev": true
+        },
+        "micromatch": {
+          "version": "4.0.2",
+          "resolved": "https://registry.npm.taobao.org/micromatch/download/micromatch-4.0.2.tgz",
+          "integrity": "sha1-T8sJmb+fvC/L3SEvbWKbmlbDklk=",
+          "dev": true,
+          "requires": {
+            "braces": "^3.0.1",
+            "picomatch": "^2.0.5"
+          }
+        },
+        "path-type": {
+          "version": "4.0.0",
+          "resolved": "https://registry.npm.taobao.org/path-type/download/path-type-4.0.0.tgz",
+          "integrity": "sha1-hO0BwKe6OAr+CdkKjBgNzZ0DBDs=",
+          "dev": true
+        },
+        "slash": {
+          "version": "3.0.0",
+          "resolved": "https://registry.npm.taobao.org/slash/download/slash-3.0.0.tgz",
+          "integrity": "sha1-ZTm+hwwWWtvVJAIg2+Nh8bxNRjQ=",
+          "dev": true
+        },
+        "supports-color": {
+          "version": "7.2.0",
+          "resolved": "https://registry.npm.taobao.org/supports-color/download/supports-color-7.2.0.tgz?cache=0&sync_timestamp=1598611730985&other_urls=https%3A%2F%2Fregistry.npm.taobao.org%2Fsupports-color%2Fdownload%2Fsupports-color-7.2.0.tgz",
+          "integrity": "sha1-G33NyzK4E4gBs+R4umpRyqiWSNo=",
+          "dev": true,
+          "requires": {
+            "has-flag": "^4.0.0"
+          }
+        },
+        "to-regex-range": {
+          "version": "5.0.1",
+          "resolved": "https://registry.npm.taobao.org/to-regex-range/download/to-regex-range-5.0.1.tgz",
+          "integrity": "sha1-FkjESq58jZiKMmAY7XL1tN0DkuQ=",
+          "dev": true,
+          "requires": {
+            "is-number": "^7.0.0"
+          }
+        }
+      }
+    },
+    "build-plugin-fusion": {
+      "version": "0.1.8",
+      "resolved": "https://registry.npm.taobao.org/build-plugin-fusion/download/build-plugin-fusion-0.1.8.tgz",
+      "integrity": "sha1-JVUBeV5/tHp/y1YVPalLBGihwyw=",
+      "dev": true,
+      "requires": {
+        "babel-plugin-import": "^1.11.2",
+        "babel-plugin-module-resolver": "^4.0.0",
+        "find-root": "^1.1.0",
+        "ice-skin-loader": "^0.3.0-0",
+        "lodash": "^4.17.15",
+        "postcss": "^7.0.32",
+        "postcss-plugin-rpx2vw": "^0.0.2",
+        "resolve-sass-import": "^0.1.0",
+        "semver": "^6.1.0",
+        "webpack-plugin-import": "^0.2.5",
+        "webpack-sources": "^1.3.0"
+      },
+      "dependencies": {
+        "semver": {
+          "version": "6.3.0",
+          "resolved": "https://registry.npm.taobao.org/semver/download/semver-6.3.0.tgz",
+          "integrity": "sha1-7gpkyK9ejO6mdoexM3YeG+y9HT0=",
+          "dev": true
+        }
+      }
+    },
+    "build-plugin-ice-config": {
+      "version": "1.7.1",
+      "resolved": "https://registry.npm.taobao.org/build-plugin-ice-config/download/build-plugin-ice-config-1.7.1.tgz",
+      "integrity": "sha1-vLMLxnV19KUDh9Bl9NTDc2wwoWM=",
+      "dev": true,
+      "requires": {
+        "fs-extra": "^8.1.0"
+      }
+    },
+    "build-plugin-ice-helpers": {
+      "version": "1.7.1",
+      "resolved": "https://registry.npm.taobao.org/build-plugin-ice-helpers/download/build-plugin-ice-helpers-1.7.1.tgz",
+      "integrity": "sha1-i4cpu3bE1IziChXNGEtI+8+30fs=",
+      "dev": true,
+      "requires": {
+        "@types/cookie": "^0.3.3",
+        "@types/url-parse": "^1.4.3",
+        "cookie": "^0.4.0",
+        "fs-extra": "^8.1.0",
+        "url-parse": "^1.4.7"
+      },
+      "dependencies": {
+        "cookie": {
+          "version": "0.4.1",
+          "resolved": "https://registry.npm.taobao.org/cookie/download/cookie-0.4.1.tgz?cache=0&sync_timestamp=1587525998658&other_urls=https%3A%2F%2Fregistry.npm.taobao.org%2Fcookie%2Fdownload%2Fcookie-0.4.1.tgz",
+          "integrity": "sha1-r9cT/ibr0hupXOth+agRblClN9E=",
+          "dev": true
+        }
+      }
+    },
+    "build-plugin-ice-logger": {
+      "version": "1.7.2",
+      "resolved": "https://registry.npm.taobao.org/build-plugin-ice-logger/download/build-plugin-ice-logger-1.7.2.tgz",
+      "integrity": "sha1-wdgmoHBhAqdI5OSh+bfAckJ3GGY=",
+      "dev": true,
+      "requires": {
+        "fs-extra": "^8.1.0",
+        "loglevel": "^1.6.6"
+      }
+    },
+    "build-plugin-ice-mpa": {
+      "version": "1.7.1",
+      "resolved": "https://registry.npm.taobao.org/build-plugin-ice-mpa/download/build-plugin-ice-mpa-1.7.1.tgz",
+      "integrity": "sha1-TEmVlIgmfOgVtMjG8Bazg+HgazM=",
+      "dev": true,
+      "requires": {
+        "fs-extra": "^8.1.0"
+      }
+    },
+    "build-plugin-ice-request": {
+      "version": "1.7.2",
+      "resolved": "https://registry.npm.taobao.org/build-plugin-ice-request/download/build-plugin-ice-request-1.7.2.tgz",
+      "integrity": "sha1-gNEERdIKc64+/sgkRLw9lfGEdT0=",
+      "dev": true,
+      "requires": {
+        "@ahooksjs/use-request": "^2.0.0",
+        "axios": "^0.19.2",
+        "fs-extra": "^8.1.0"
+      }
+    },
+    "build-plugin-ice-router": {
+      "version": "1.7.5",
+      "resolved": "https://registry.npm.taobao.org/build-plugin-ice-router/download/build-plugin-ice-router-1.7.5.tgz",
+      "integrity": "sha1-ff0ekvUyGe4X+VUAUwD/E5TKB8k=",
+      "dev": true,
+      "requires": {
+        "fs-extra": "^8.1.0",
+        "glob": "^7.1.6",
+        "history": "^4.10.1",
+        "query-string": "^6.12.1",
+        "react": "^16.12.0",
+        "react-dom": "^16.12.0",
+        "react-router-dom": "^5.1.2"
+      }
+    },
+    "build-plugin-ice-ssr": {
+      "version": "1.7.6",
+      "resolved": "https://registry.npm.taobao.org/build-plugin-ice-ssr/download/build-plugin-ice-ssr-1.7.6.tgz",
+      "integrity": "sha1-e9TYbHFvH2BeImfNbCB+hdOMYQ0=",
+      "dev": true,
+      "requires": {
+        "build-scripts-config": "^0.1.6",
+        "chalk": "^4.0.0",
+        "cheerio": "^1.0.0-rc.3",
+        "ejs": "^3.0.1",
+        "fs-extra": "^8.1.0",
+        "html-minifier": "^4.0.0",
+        "parseurl": "^1.3.3"
+      },
+      "dependencies": {
+        "ansi-styles": {
+          "version": "4.3.0",
+          "resolved": "https://registry.npm.taobao.org/ansi-styles/download/ansi-styles-4.3.0.tgz?cache=0&sync_timestamp=1601839122515&other_urls=https%3A%2F%2Fregistry.npm.taobao.org%2Fansi-styles%2Fdownload%2Fansi-styles-4.3.0.tgz",
+          "integrity": "sha1-7dgDYornHATIWuegkG7a00tkiTc=",
+          "dev": true,
+          "requires": {
+            "color-convert": "^2.0.1"
+          }
+        },
+        "chalk": {
+          "version": "4.1.0",
+          "resolved": "https://registry.npm.taobao.org/chalk/download/chalk-4.1.0.tgz",
+          "integrity": "sha1-ThSHCmGNni7dl92DRf2dncMVZGo=",
+          "dev": true,
+          "requires": {
+            "ansi-styles": "^4.1.0",
+            "supports-color": "^7.1.0"
+          }
+        },
+        "color-convert": {
+          "version": "2.0.1",
+          "resolved": "https://registry.npm.taobao.org/color-convert/download/color-convert-2.0.1.tgz",
+          "integrity": "sha1-ctOmjVmMm9s68q0ehPIdiWq9TeM=",
+          "dev": true,
+          "requires": {
+            "color-name": "~1.1.4"
+          }
+        },
+        "color-name": {
+          "version": "1.1.4",
+          "resolved": "https://registry.npm.taobao.org/color-name/download/color-name-1.1.4.tgz",
+          "integrity": "sha1-wqCah6y95pVD3m9j+jmVyCbFNqI=",
+          "dev": true
+        },
+        "has-flag": {
+          "version": "4.0.0",
+          "resolved": "https://registry.npm.taobao.org/has-flag/download/has-flag-4.0.0.tgz?cache=0&sync_timestamp=1596294337050&other_urls=https%3A%2F%2Fregistry.npm.taobao.org%2Fhas-flag%2Fdownload%2Fhas-flag-4.0.0.tgz",
+          "integrity": "sha1-lEdx/ZyByBJlxNaUGGDaBrtZR5s=",
+          "dev": true
+        },
+        "supports-color": {
+          "version": "7.2.0",
+          "resolved": "https://registry.npm.taobao.org/supports-color/download/supports-color-7.2.0.tgz?cache=0&sync_timestamp=1598611730985&other_urls=https%3A%2F%2Fregistry.npm.taobao.org%2Fsupports-color%2Fdownload%2Fsupports-color-7.2.0.tgz",
+          "integrity": "sha1-G33NyzK4E4gBs+R4umpRyqiWSNo=",
+          "dev": true,
+          "requires": {
+            "has-flag": "^4.0.0"
+          }
+        }
+      }
+    },
+    "build-plugin-ice-store": {
+      "version": "1.7.8",
+      "resolved": "https://registry.npm.taobao.org/build-plugin-ice-store/download/build-plugin-ice-store-1.7.8.tgz",
+      "integrity": "sha1-XXk7lFvgWu+fA2ZmuVi1ffod3LM=",
+      "dev": true,
+      "requires": {
+        "@ice/store": "^1.3.1",
+        "ejs": "^3.0.2",
+        "enhanced-resolve": "^4.3.0",
+        "fs-extra": "^8.1.0",
+        "fs-readdir-recursive": "^1.1.0",
+        "loader-utils": "^2.0.0",
+        "prettier": "^2.0.4",
+        "rax-redux": "^1.0.0"
+      },
+      "dependencies": {
+        "json5": {
+          "version": "2.1.3",
+          "resolved": "https://registry.npm.taobao.org/json5/download/json5-2.1.3.tgz",
+          "integrity": "sha1-ybD3+pIzv+WAf+ZvzzpWF+1ZfUM=",
+          "dev": true,
+          "requires": {
+            "minimist": "^1.2.5"
+          }
+        },
+        "loader-utils": {
+          "version": "2.0.0",
+          "resolved": "https://registry.npm.taobao.org/loader-utils/download/loader-utils-2.0.0.tgz",
+          "integrity": "sha1-5MrOW4FtQloWa18JfhDNErNgZLA=",
+          "dev": true,
+          "requires": {
+            "big.js": "^5.2.2",
+            "emojis-list": "^3.0.0",
+            "json5": "^2.1.2"
+          }
+        }
+      }
+    },
+    "build-plugin-icestark": {
+      "version": "1.7.2",
+      "resolved": "https://registry.npm.taobao.org/build-plugin-icestark/download/build-plugin-icestark-1.7.2.tgz",
+      "integrity": "sha1-34oaL95xR8eQsxup2H8p6uuKNGY=",
+      "dev": true,
+      "requires": {
+        "@ice/stark": "^1.3.1",
+        "@ice/stark-app": "^1.2.0",
+        "fs-extra": "^8.1.0",
+        "glob": "^7.1.6"
+      }
+    },
+    "build-plugin-miniapp": {
+      "version": "0.1.7",
+      "resolved": "https://registry.npm.taobao.org/build-plugin-miniapp/download/build-plugin-miniapp-0.1.7.tgz",
+      "integrity": "sha1-9gtn1tDUgKf5OWHH8pwv5yS98y0=",
+      "dev": true,
+      "requires": {
+        "miniapp-builder-shared": "^0.1.1",
+        "miniapp-runtime-config": "^0.1.1"
+      }
+    },
+    "build-plugin-moment-locales": {
+      "version": "0.1.0",
+      "resolved": "https://registry.npm.taobao.org/build-plugin-moment-locales/download/build-plugin-moment-locales-0.1.0.tgz",
+      "integrity": "sha1-ipy7+DMBt5J6IatHHRru3/+rZ2Q=",
+      "dev": true
+    },
+    "build-plugin-react-app": {
+      "version": "1.7.10",
+      "resolved": "https://registry.npm.taobao.org/build-plugin-react-app/download/build-plugin-react-app-1.7.10.tgz",
+      "integrity": "sha1-9dG0NCuAGfQCooxZF3Dzn/6QZFM=",
+      "dev": true,
+      "requires": {
+        "@builder/app-helpers": "^1.0.0",
+        "@builder/user-config": "^0.1.0",
+        "build-scripts-config": "^0.1.0",
+        "chalk": "^4.0.0",
+        "copy-webpack-plugin": "^5.0.4",
+        "core-js": "^3.7.0",
+        "debug": "^4.1.1",
+        "fs-extra": "^8.1.0",
+        "html-webpack-plugin": "^3.2.0",
+        "lodash": "^4.17.15",
+        "mkcert": "^1.2.0",
+        "path-exists": "^4.0.0",
+        "postcss-plugin-rpx2vw": "^0.0.2",
+        "react-dev-utils": "^10.2.1",
+        "webpack-plugin-import": "^0.2.6"
+      },
+      "dependencies": {
+        "@babel/code-frame": {
+          "version": "7.8.3",
+          "resolved": "https://registry.npm.taobao.org/@babel/code-frame/download/@babel/code-frame-7.8.3.tgz",
+          "integrity": "sha1-M+JZA9dIEYFTThLsCiXxa2/PQZ4=",
+          "dev": true,
+          "requires": {
+            "@babel/highlight": "^7.8.3"
+          }
+        },
+        "ansi-regex": {
+          "version": "5.0.0",
+          "resolved": "https://registry.npm.taobao.org/ansi-regex/download/ansi-regex-5.0.0.tgz",
+          "integrity": "sha1-OIU59VF5vzkznIGvMKZU1p+Hy3U=",
+          "dev": true
+        },
+        "ansi-styles": {
+          "version": "4.3.0",
+          "resolved": "https://registry.npm.taobao.org/ansi-styles/download/ansi-styles-4.3.0.tgz?cache=0&sync_timestamp=1601839122515&other_urls=https%3A%2F%2Fregistry.npm.taobao.org%2Fansi-styles%2Fdownload%2Fansi-styles-4.3.0.tgz",
+          "integrity": "sha1-7dgDYornHATIWuegkG7a00tkiTc=",
+          "dev": true,
+          "requires": {
+            "color-convert": "^2.0.1"
+          }
+        },
+        "browserslist": {
+          "version": "4.10.0",
+          "resolved": "https://registry.npm.taobao.org/browserslist/download/browserslist-4.10.0.tgz?cache=0&sync_timestamp=1604944989360&other_urls=https%3A%2F%2Fregistry.npm.taobao.org%2Fbrowserslist%2Fdownload%2Fbrowserslist-4.10.0.tgz",
+          "integrity": "sha1-8XlzeRPq8NK5jkkmrBymoVy8xqk=",
+          "dev": true,
+          "requires": {
+            "caniuse-lite": "^1.0.30001035",
+            "electron-to-chromium": "^1.3.378",
+            "node-releases": "^1.1.52",
+            "pkg-up": "^3.1.0"
+          }
+        },
+        "chalk": {
+          "version": "4.1.0",
+          "resolved": "https://registry.npm.taobao.org/chalk/download/chalk-4.1.0.tgz",
+          "integrity": "sha1-ThSHCmGNni7dl92DRf2dncMVZGo=",
+          "dev": true,
+          "requires": {
+            "ansi-styles": "^4.1.0",
+            "supports-color": "^7.1.0"
+          }
+        },
+        "cli-width": {
+          "version": "2.2.1",
+          "resolved": "https://registry.npm.taobao.org/cli-width/download/cli-width-2.2.1.tgz",
+          "integrity": "sha1-sEM9C06chH7xiGik7xb9X8gnHEg=",
+          "dev": true
+        },
+        "color-convert": {
+          "version": "2.0.1",
+          "resolved": "https://registry.npm.taobao.org/color-convert/download/color-convert-2.0.1.tgz",
+          "integrity": "sha1-ctOmjVmMm9s68q0ehPIdiWq9TeM=",
+          "dev": true,
+          "requires": {
+            "color-name": "~1.1.4"
+          }
+        },
+        "color-name": {
+          "version": "1.1.4",
+          "resolved": "https://registry.npm.taobao.org/color-name/download/color-name-1.1.4.tgz",
+          "integrity": "sha1-wqCah6y95pVD3m9j+jmVyCbFNqI=",
+          "dev": true
+        },
+        "copy-webpack-plugin": {
+          "version": "5.1.2",
+          "resolved": "https://registry.npm.taobao.org/copy-webpack-plugin/download/copy-webpack-plugin-5.1.2.tgz?cache=0&other_urls=https%3A%2F%2Fregistry.npm.taobao.org%2Fcopy-webpack-plugin%2Fdownload%2Fcopy-webpack-plugin-5.1.2.tgz",
+          "integrity": "sha1-ioieHcr6bJHGzUvhrRWPHTgjuuI=",
+          "dev": true,
+          "requires": {
+            "cacache": "^12.0.3",
+            "find-cache-dir": "^2.1.0",
+            "glob-parent": "^3.1.0",
+            "globby": "^7.1.1",
+            "is-glob": "^4.0.1",
+            "loader-utils": "^1.2.3",
+            "minimatch": "^3.0.4",
+            "normalize-path": "^3.0.0",
+            "p-limit": "^2.2.1",
+            "schema-utils": "^1.0.0",
+            "serialize-javascript": "^4.0.0",
+            "webpack-log": "^2.0.0"
+          }
+        },
+        "core-js": {
+          "version": "3.7.0",
+          "resolved": "https://registry.npm.taobao.org/core-js/download/core-js-3.7.0.tgz?cache=0&sync_timestamp=1604675498528&other_urls=https%3A%2F%2Fregistry.npm.taobao.org%2Fcore-js%2Fdownload%2Fcore-js-3.7.0.tgz",
+          "integrity": "sha1-sKdhoCSIV3r7+XF55Ggb9JVoUg8=",
+          "dev": true
+        },
+        "cross-spawn": {
+          "version": "7.0.1",
+          "resolved": "https://registry.npm.taobao.org/cross-spawn/download/cross-spawn-7.0.1.tgz",
+          "integrity": "sha1-CrVihuD3wk4VPQTMKqAn5DqaXRQ=",
+          "dev": true,
+          "requires": {
+            "path-key": "^3.1.0",
+            "shebang-command": "^2.0.0",
+            "which": "^2.0.1"
+          }
+        },
+        "detect-port-alt": {
+          "version": "1.1.6",
+          "resolved": "https://registry.npm.taobao.org/detect-port-alt/download/detect-port-alt-1.1.6.tgz",
+          "integrity": "sha1-JHB96r6TLUo89iEwICfCsmZWgnU=",
+          "dev": true,
+          "requires": {
+            "address": "^1.0.1",
+            "debug": "^2.6.0"
+          },
+          "dependencies": {
+            "debug": {
+              "version": "2.6.9",
+              "resolved": "https://registry.npm.taobao.org/debug/download/debug-2.6.9.tgz?cache=0&sync_timestamp=1600502871403&other_urls=https%3A%2F%2Fregistry.npm.taobao.org%2Fdebug%2Fdownload%2Fdebug-2.6.9.tgz",
+              "integrity": "sha1-XRKFFd8TT/Mn6QpMk/Tgd6U2NB8=",
+              "dev": true,
+              "requires": {
+                "ms": "2.0.0"
+              }
+            }
+          }
+        },
+        "emoji-regex": {
+          "version": "8.0.0",
+          "resolved": "https://registry.npm.taobao.org/emoji-regex/download/emoji-regex-8.0.0.tgz?cache=0&sync_timestamp=1603212263242&other_urls=https%3A%2F%2Fregistry.npm.taobao.org%2Femoji-regex%2Fdownload%2Femoji-regex-8.0.0.tgz",
+          "integrity": "sha1-6Bj9ac5cz8tARZT4QpY79TFkzDc=",
+          "dev": true
+        },
+        "emojis-list": {
+          "version": "2.1.0",
+          "resolved": "https://registry.npm.taobao.org/emojis-list/download/emojis-list-2.1.0.tgz",
+          "integrity": "sha1-TapNnbAPmBmIDHn6RXrlsJof04k=",
+          "dev": true
+        },
+        "escape-string-regexp": {
+          "version": "2.0.0",
+          "resolved": "https://registry.npm.taobao.org/escape-string-regexp/download/escape-string-regexp-2.0.0.tgz?cache=0&sync_timestamp=1587627107924&other_urls=https%3A%2F%2Fregistry.npm.taobao.org%2Fescape-string-regexp%2Fdownload%2Fescape-string-regexp-2.0.0.tgz",
+          "integrity": "sha1-owME6Z2qMuI7L9IPUbq9B8/8o0Q=",
+          "dev": true
+        },
+        "filesize": {
+          "version": "6.0.1",
+          "resolved": "https://registry.npm.taobao.org/filesize/download/filesize-6.0.1.tgz",
+          "integrity": "sha1-+FC1CZCcfIb35FDqGQBsMcLtPS8=",
+          "dev": true
+        },
+        "find-up": {
+          "version": "4.1.0",
+          "resolved": "https://registry.npm.taobao.org/find-up/download/find-up-4.1.0.tgz?cache=0&sync_timestamp=1597169862146&other_urls=https%3A%2F%2Fregistry.npm.taobao.org%2Ffind-up%2Fdownload%2Ffind-up-4.1.0.tgz",
+          "integrity": "sha1-l6/n1s3AvFkoWEt8jXsW6KmqXRk=",
+          "dev": true,
+          "requires": {
+            "locate-path": "^5.0.0",
+            "path-exists": "^4.0.0"
+          }
+        },
+        "fork-ts-checker-webpack-plugin": {
+          "version": "3.1.1",
+          "resolved": "https://registry.npm.taobao.org/fork-ts-checker-webpack-plugin/download/fork-ts-checker-webpack-plugin-3.1.1.tgz",
+          "integrity": "sha1-oWQsDT5l9QwswXQunAqA9EH4axk=",
+          "dev": true,
+          "requires": {
+            "babel-code-frame": "^6.22.0",
+            "chalk": "^2.4.1",
+            "chokidar": "^3.3.0",
+            "micromatch": "^3.1.10",
+            "minimatch": "^3.0.4",
+            "semver": "^5.6.0",
+            "tapable": "^1.0.0",
+            "worker-rpc": "^0.1.0"
+          },
+          "dependencies": {
+            "ansi-styles": {
+              "version": "3.2.1",
+              "resolved": "https://registry.npm.taobao.org/ansi-styles/download/ansi-styles-3.2.1.tgz?cache=0&sync_timestamp=1601839122515&other_urls=https%3A%2F%2Fregistry.npm.taobao.org%2Fansi-styles%2Fdownload%2Fansi-styles-3.2.1.tgz",
+              "integrity": "sha1-QfuyAkPlCxK+DwS43tvwdSDOhB0=",
+              "dev": true,
+              "requires": {
+                "color-convert": "^1.9.0"
+              }
+            },
+            "chalk": {
+              "version": "2.4.2",
+              "resolved": "https://registry.npm.taobao.org/chalk/download/chalk-2.4.2.tgz",
+              "integrity": "sha1-zUJUFnelQzPPVBpJEIwUMrRMlCQ=",
+              "dev": true,
+              "requires": {
+                "ansi-styles": "^3.2.1",
+                "escape-string-regexp": "^1.0.5",
+                "supports-color": "^5.3.0"
+              }
+            },
+            "color-convert": {
+              "version": "1.9.3",
+              "resolved": "https://registry.npm.taobao.org/color-convert/download/color-convert-1.9.3.tgz",
+              "integrity": "sha1-u3GFBpDh8TZWfeYp0tVHHe2kweg=",
+              "dev": true,
+              "requires": {
+                "color-name": "1.1.3"
+              }
+            },
+            "color-name": {
+              "version": "1.1.3",
+              "resolved": "https://registry.npm.taobao.org/color-name/download/color-name-1.1.3.tgz",
+              "integrity": "sha1-p9BVi9icQveV3UIyj3QIMcpTvCU=",
+              "dev": true
+            },
+            "escape-string-regexp": {
+              "version": "1.0.5",
+              "resolved": "https://registry.npm.taobao.org/escape-string-regexp/download/escape-string-regexp-1.0.5.tgz?cache=0&sync_timestamp=1587627107924&other_urls=https%3A%2F%2Fregistry.npm.taobao.org%2Fescape-string-regexp%2Fdownload%2Fescape-string-regexp-1.0.5.tgz",
+              "integrity": "sha1-G2HAViGQqN/2rjuyzwIAyhMLhtQ=",
+              "dev": true
+            },
+            "has-flag": {
+              "version": "3.0.0",
+              "resolved": "https://registry.npm.taobao.org/has-flag/download/has-flag-3.0.0.tgz?cache=0&sync_timestamp=1596294337050&other_urls=https%3A%2F%2Fregistry.npm.taobao.org%2Fhas-flag%2Fdownload%2Fhas-flag-3.0.0.tgz",
+              "integrity": "sha1-tdRU3CGZriJWmfNGfloH87lVuv0=",
+              "dev": true
+            },
+            "supports-color": {
+              "version": "5.5.0",
+              "resolved": "https://registry.npm.taobao.org/supports-color/download/supports-color-5.5.0.tgz?cache=0&sync_timestamp=1598611730985&other_urls=https%3A%2F%2Fregistry.npm.taobao.org%2Fsupports-color%2Fdownload%2Fsupports-color-5.5.0.tgz",
+              "integrity": "sha1-4uaaRKyHcveKHsCzW2id9lMO/I8=",
+              "dev": true,
+              "requires": {
+                "has-flag": "^3.0.0"
+              }
+            }
+          }
+        },
+        "globby": {
+          "version": "7.1.1",
+          "resolved": "https://registry.npm.taobao.org/globby/download/globby-7.1.1.tgz",
+          "integrity": "sha1-+yzP+UAfhgCUXfral0QMypcrhoA=",
+          "dev": true,
+          "requires": {
+            "array-union": "^1.0.1",
+            "dir-glob": "^2.0.0",
+            "glob": "^7.1.2",
+            "ignore": "^3.3.5",
+            "pify": "^3.0.0",
+            "slash": "^1.0.0"
+          }
+        },
+        "has-flag": {
+          "version": "4.0.0",
+          "resolved": "https://registry.npm.taobao.org/has-flag/download/has-flag-4.0.0.tgz?cache=0&sync_timestamp=1596294337050&other_urls=https%3A%2F%2Fregistry.npm.taobao.org%2Fhas-flag%2Fdownload%2Fhas-flag-4.0.0.tgz",
+          "integrity": "sha1-lEdx/ZyByBJlxNaUGGDaBrtZR5s=",
+          "dev": true
+        },
+        "ignore": {
+          "version": "3.3.10",
+          "resolved": "https://registry.npm.taobao.org/ignore/download/ignore-3.3.10.tgz",
+          "integrity": "sha1-Cpf7h2mG6AgcYxFg+PnziRV/AEM=",
+          "dev": true
+        },
+        "inquirer": {
+          "version": "7.0.4",
+          "resolved": "https://registry.npm.taobao.org/inquirer/download/inquirer-7.0.4.tgz",
+          "integrity": "sha1-ma9b3kcVOryiP1x/ww2yR/OdpwM=",
+          "dev": true,
+          "requires": {
+            "ansi-escapes": "^4.2.1",
+            "chalk": "^2.4.2",
+            "cli-cursor": "^3.1.0",
+            "cli-width": "^2.0.0",
+            "external-editor": "^3.0.3",
+            "figures": "^3.0.0",
+            "lodash": "^4.17.15",
+            "mute-stream": "0.0.8",
+            "run-async": "^2.2.0",
+            "rxjs": "^6.5.3",
+            "string-width": "^4.1.0",
+            "strip-ansi": "^5.1.0",
+            "through": "^2.3.6"
+          },
+          "dependencies": {
+            "ansi-regex": {
+              "version": "4.1.0",
+              "resolved": "https://registry.npm.taobao.org/ansi-regex/download/ansi-regex-4.1.0.tgz",
+              "integrity": "sha1-i5+PCM8ay4Q3Vqg5yox+MWjFGZc=",
+              "dev": true
+            },
+            "ansi-styles": {
+              "version": "3.2.1",
+              "resolved": "https://registry.npm.taobao.org/ansi-styles/download/ansi-styles-3.2.1.tgz?cache=0&sync_timestamp=1601839122515&other_urls=https%3A%2F%2Fregistry.npm.taobao.org%2Fansi-styles%2Fdownload%2Fansi-styles-3.2.1.tgz",
+              "integrity": "sha1-QfuyAkPlCxK+DwS43tvwdSDOhB0=",
+              "dev": true,
+              "requires": {
+                "color-convert": "^1.9.0"
+              }
+            },
+            "chalk": {
+              "version": "2.4.2",
+              "resolved": "https://registry.npm.taobao.org/chalk/download/chalk-2.4.2.tgz",
+              "integrity": "sha1-zUJUFnelQzPPVBpJEIwUMrRMlCQ=",
+              "dev": true,
+              "requires": {
+                "ansi-styles": "^3.2.1",
+                "escape-string-regexp": "^1.0.5",
+                "supports-color": "^5.3.0"
+              }
+            },
+            "color-convert": {
+              "version": "1.9.3",
+              "resolved": "https://registry.npm.taobao.org/color-convert/download/color-convert-1.9.3.tgz",
+              "integrity": "sha1-u3GFBpDh8TZWfeYp0tVHHe2kweg=",
+              "dev": true,
+              "requires": {
+                "color-name": "1.1.3"
+              }
+            },
+            "color-name": {
+              "version": "1.1.3",
+              "resolved": "https://registry.npm.taobao.org/color-name/download/color-name-1.1.3.tgz",
+              "integrity": "sha1-p9BVi9icQveV3UIyj3QIMcpTvCU=",
+              "dev": true
+            },
+            "escape-string-regexp": {
+              "version": "1.0.5",
+              "resolved": "https://registry.npm.taobao.org/escape-string-regexp/download/escape-string-regexp-1.0.5.tgz?cache=0&sync_timestamp=1587627107924&other_urls=https%3A%2F%2Fregistry.npm.taobao.org%2Fescape-string-regexp%2Fdownload%2Fescape-string-regexp-1.0.5.tgz",
+              "integrity": "sha1-G2HAViGQqN/2rjuyzwIAyhMLhtQ=",
+              "dev": true
+            },
+            "has-flag": {
+              "version": "3.0.0",
+              "resolved": "https://registry.npm.taobao.org/has-flag/download/has-flag-3.0.0.tgz?cache=0&sync_timestamp=1596294337050&other_urls=https%3A%2F%2Fregistry.npm.taobao.org%2Fhas-flag%2Fdownload%2Fhas-flag-3.0.0.tgz",
+              "integrity": "sha1-tdRU3CGZriJWmfNGfloH87lVuv0=",
+              "dev": true
+            },
+            "strip-ansi": {
+              "version": "5.2.0",
+              "resolved": "https://registry.npm.taobao.org/strip-ansi/download/strip-ansi-5.2.0.tgz",
+              "integrity": "sha1-jJpTb+tq/JYr36WxBKUJHBrZwK4=",
+              "dev": true,
+              "requires": {
+                "ansi-regex": "^4.1.0"
+              }
+            },
+            "supports-color": {
+              "version": "5.5.0",
+              "resolved": "https://registry.npm.taobao.org/supports-color/download/supports-color-5.5.0.tgz?cache=0&sync_timestamp=1598611730985&other_urls=https%3A%2F%2Fregistry.npm.taobao.org%2Fsupports-color%2Fdownload%2Fsupports-color-5.5.0.tgz",
+              "integrity": "sha1-4uaaRKyHcveKHsCzW2id9lMO/I8=",
+              "dev": true,
+              "requires": {
+                "has-flag": "^3.0.0"
+              }
+            }
+          }
+        },
+        "is-fullwidth-code-point": {
+          "version": "3.0.0",
+          "resolved": "https://registry.npm.taobao.org/is-fullwidth-code-point/download/is-fullwidth-code-point-3.0.0.tgz",
+          "integrity": "sha1-8Rb4Bk/pCz94RKOJl8C3UFEmnx0=",
+          "dev": true
+        },
+        "locate-path": {
+          "version": "5.0.0",
+          "resolved": "https://registry.npm.taobao.org/locate-path/download/locate-path-5.0.0.tgz",
+          "integrity": "sha1-Gvujlq/WdqbUJQTQpno6frn2KqA=",
+          "dev": true,
+          "requires": {
+            "p-locate": "^4.1.0"
+          }
+        },
+        "ms": {
+          "version": "2.0.0",
+          "resolved": "https://registry.npm.taobao.org/ms/download/ms-2.0.0.tgz",
+          "integrity": "sha1-VgiurfwAvmwpAd9fmGF4jeDVl8g=",
+          "dev": true
+        },
+        "open": {
+          "version": "7.3.0",
+          "resolved": "https://registry.npm.taobao.org/open/download/open-7.3.0.tgz?cache=0&sync_timestamp=1601376312546&other_urls=https%3A%2F%2Fregistry.npm.taobao.org%2Fopen%2Fdownload%2Fopen-7.3.0.tgz",
+          "integrity": "sha1-RUYf3uRkRPNkW24U6zypS4Lhvmk=",
+          "dev": true,
+          "requires": {
+            "is-docker": "^2.0.0",
+            "is-wsl": "^2.1.1"
+          }
+        },
+        "p-limit": {
+          "version": "2.3.0",
+          "resolved": "https://registry.npm.taobao.org/p-limit/download/p-limit-2.3.0.tgz",
+          "integrity": "sha1-PdM8ZHohT9//2DWTPrCG2g3CHbE=",
+          "dev": true,
+          "requires": {
+            "p-try": "^2.0.0"
+          }
+        },
+        "p-locate": {
+          "version": "4.1.0",
+          "resolved": "https://registry.npm.taobao.org/p-locate/download/p-locate-4.1.0.tgz?cache=0&sync_timestamp=1597081508945&other_urls=https%3A%2F%2Fregistry.npm.taobao.org%2Fp-locate%2Fdownload%2Fp-locate-4.1.0.tgz",
+          "integrity": "sha1-o0KLtwiLOmApL2aRkni3wpetTwc=",
+          "dev": true,
+          "requires": {
+            "p-limit": "^2.2.0"
+          }
+        },
+        "p-try": {
+          "version": "2.2.0",
+          "resolved": "https://registry.npm.taobao.org/p-try/download/p-try-2.2.0.tgz",
+          "integrity": "sha1-yyhoVA4xPWHeWPr741zpAE1VQOY=",
+          "dev": true
+        },
+        "path-exists": {
+          "version": "4.0.0",
+          "resolved": "https://registry.npm.taobao.org/path-exists/download/path-exists-4.0.0.tgz",
+          "integrity": "sha1-UTvb4tO5XXdi6METfvoZXGxhtbM=",
+          "dev": true
+        },
+        "path-key": {
+          "version": "3.1.1",
+          "resolved": "https://registry.npm.taobao.org/path-key/download/path-key-3.1.1.tgz",
+          "integrity": "sha1-WB9q3mWMu6ZaDTOA3ndTKVBU83U=",
+          "dev": true
+        },
+        "path-type": {
+          "version": "3.0.0",
+          "resolved": "https://registry.npm.taobao.org/path-type/download/path-type-3.0.0.tgz",
+          "integrity": "sha1-zvMdyOCho7sNEFwM2Xzzv0f0428=",
+          "dev": true,
+          "requires": {
+            "pify": "^3.0.0"
+          }
+        },
+        "pify": {
+          "version": "3.0.0",
+          "resolved": "https://registry.npm.taobao.org/pify/download/pify-3.0.0.tgz",
+          "integrity": "sha1-5aSs0sEB/fPZpNB/DbxNtJ3SgXY=",
+          "dev": true
+        },
+        "react-dev-utils": {
+          "version": "10.2.1",
+          "resolved": "https://registry.npm.taobao.org/react-dev-utils/download/react-dev-utils-10.2.1.tgz?cache=0&sync_timestamp=1603462727689&other_urls=https%3A%2F%2Fregistry.npm.taobao.org%2Freact-dev-utils%2Fdownload%2Freact-dev-utils-10.2.1.tgz",
+          "integrity": "sha1-9t4yWuJfpNVG0J30uxvv3G3RnBk=",
+          "dev": true,
+          "requires": {
+            "@babel/code-frame": "7.8.3",
+            "address": "1.1.2",
+            "browserslist": "4.10.0",
+            "chalk": "2.4.2",
+            "cross-spawn": "7.0.1",
+            "detect-port-alt": "1.1.6",
+            "escape-string-regexp": "2.0.0",
+            "filesize": "6.0.1",
+            "find-up": "4.1.0",
+            "fork-ts-checker-webpack-plugin": "3.1.1",
+            "global-modules": "2.0.0",
+            "globby": "8.0.2",
+            "gzip-size": "5.1.1",
+            "immer": "1.10.0",
+            "inquirer": "7.0.4",
+            "is-root": "2.1.0",
+            "loader-utils": "1.2.3",
+            "open": "^7.0.2",
+            "pkg-up": "3.1.0",
+            "react-error-overlay": "^6.0.7",
+            "recursive-readdir": "2.2.2",
+            "shell-quote": "1.7.2",
+            "strip-ansi": "6.0.0",
+            "text-table": "0.2.0"
+          },
+          "dependencies": {
+            "ansi-styles": {
+              "version": "3.2.1",
+              "resolved": "https://registry.npm.taobao.org/ansi-styles/download/ansi-styles-3.2.1.tgz?cache=0&sync_timestamp=1601839122515&other_urls=https%3A%2F%2Fregistry.npm.taobao.org%2Fansi-styles%2Fdownload%2Fansi-styles-3.2.1.tgz",
+              "integrity": "sha1-QfuyAkPlCxK+DwS43tvwdSDOhB0=",
+              "dev": true,
+              "requires": {
+                "color-convert": "^1.9.0"
+              }
+            },
+            "chalk": {
+              "version": "2.4.2",
+              "resolved": "https://registry.npm.taobao.org/chalk/download/chalk-2.4.2.tgz",
+              "integrity": "sha1-zUJUFnelQzPPVBpJEIwUMrRMlCQ=",
+              "dev": true,
+              "requires": {
+                "ansi-styles": "^3.2.1",
+                "escape-string-regexp": "^1.0.5",
+                "supports-color": "^5.3.0"
+              },
+              "dependencies": {
+                "escape-string-regexp": {
+                  "version": "1.0.5",
+                  "resolved": "https://registry.npm.taobao.org/escape-string-regexp/download/escape-string-regexp-1.0.5.tgz?cache=0&sync_timestamp=1587627107924&other_urls=https%3A%2F%2Fregistry.npm.taobao.org%2Fescape-string-regexp%2Fdownload%2Fescape-string-regexp-1.0.5.tgz",
+                  "integrity": "sha1-G2HAViGQqN/2rjuyzwIAyhMLhtQ=",
+                  "dev": true
+                }
+              }
+            },
+            "color-convert": {
+              "version": "1.9.3",
+              "resolved": "https://registry.npm.taobao.org/color-convert/download/color-convert-1.9.3.tgz",
+              "integrity": "sha1-u3GFBpDh8TZWfeYp0tVHHe2kweg=",
+              "dev": true,
+              "requires": {
+                "color-name": "1.1.3"
+              }
+            },
+            "color-name": {
+              "version": "1.1.3",
+              "resolved": "https://registry.npm.taobao.org/color-name/download/color-name-1.1.3.tgz",
+              "integrity": "sha1-p9BVi9icQveV3UIyj3QIMcpTvCU=",
+              "dev": true
+            },
+            "dir-glob": {
+              "version": "2.0.0",
+              "resolved": "https://registry.npm.taobao.org/dir-glob/download/dir-glob-2.0.0.tgz",
+              "integrity": "sha1-CyBdK2rvmCOMooZZioIE0p0KADQ=",
+              "dev": true,
+              "requires": {
+                "arrify": "^1.0.1",
+                "path-type": "^3.0.0"
+              }
+            },
+            "globby": {
+              "version": "8.0.2",
+              "resolved": "https://registry.npm.taobao.org/globby/download/globby-8.0.2.tgz",
+              "integrity": "sha1-VpdhnM2VxSdduy1vqkIIfBqUHY0=",
+              "dev": true,
+              "requires": {
+                "array-union": "^1.0.1",
+                "dir-glob": "2.0.0",
+                "fast-glob": "^2.0.2",
+                "glob": "^7.1.2",
+                "ignore": "^3.3.5",
+                "pify": "^3.0.0",
+                "slash": "^1.0.0"
+              }
+            },
+            "has-flag": {
+              "version": "3.0.0",
+              "resolved": "https://registry.npm.taobao.org/has-flag/download/has-flag-3.0.0.tgz?cache=0&sync_timestamp=1596294337050&other_urls=https%3A%2F%2Fregistry.npm.taobao.org%2Fhas-flag%2Fdownload%2Fhas-flag-3.0.0.tgz",
+              "integrity": "sha1-tdRU3CGZriJWmfNGfloH87lVuv0=",
+              "dev": true
+            },
+            "loader-utils": {
+              "version": "1.2.3",
+              "resolved": "https://registry.npm.taobao.org/loader-utils/download/loader-utils-1.2.3.tgz",
+              "integrity": "sha1-H/XcaRHJ8KBiUxpMBLYJQGEIwsc=",
+              "dev": true,
+              "requires": {
+                "big.js": "^5.2.2",
+                "emojis-list": "^2.0.0",
+                "json5": "^1.0.1"
+              }
+            },
+            "supports-color": {
+              "version": "5.5.0",
+              "resolved": "https://registry.npm.taobao.org/supports-color/download/supports-color-5.5.0.tgz?cache=0&sync_timestamp=1598611730985&other_urls=https%3A%2F%2Fregistry.npm.taobao.org%2Fsupports-color%2Fdownload%2Fsupports-color-5.5.0.tgz",
+              "integrity": "sha1-4uaaRKyHcveKHsCzW2id9lMO/I8=",
+              "dev": true,
+              "requires": {
+                "has-flag": "^3.0.0"
+              }
+            }
+          }
+        },
+        "semver": {
+          "version": "5.7.1",
+          "resolved": "https://registry.npm.taobao.org/semver/download/semver-5.7.1.tgz",
+          "integrity": "sha1-qVT5Ma66UI0we78Gnv8MAclhFvc=",
+          "dev": true
+        },
+        "shebang-command": {
+          "version": "2.0.0",
+          "resolved": "https://registry.npm.taobao.org/shebang-command/download/shebang-command-2.0.0.tgz",
+          "integrity": "sha1-zNCvT4g1+9wmW4JGGq8MNmY/NOo=",
+          "dev": true,
+          "requires": {
+            "shebang-regex": "^3.0.0"
+          }
+        },
+        "shebang-regex": {
+          "version": "3.0.0",
+          "resolved": "https://registry.npm.taobao.org/shebang-regex/download/shebang-regex-3.0.0.tgz",
+          "integrity": "sha1-rhbxZE2HPsrYQ7AwexQzYtTEIXI=",
+          "dev": true
+        },
+        "slash": {
+          "version": "1.0.0",
+          "resolved": "https://registry.npm.taobao.org/slash/download/slash-1.0.0.tgz",
+          "integrity": "sha1-xB8vbDn8FtHNF61LXYlhFK5HDVU=",
+          "dev": true
+        },
+        "string-width": {
+          "version": "4.2.0",
+          "resolved": "https://registry.npm.taobao.org/string-width/download/string-width-4.2.0.tgz",
+          "integrity": "sha1-lSGCxGzHssMT0VluYjmSvRY7crU=",
+          "dev": true,
+          "requires": {
+            "emoji-regex": "^8.0.0",
+            "is-fullwidth-code-point": "^3.0.0",
+            "strip-ansi": "^6.0.0"
+          }
+        },
+        "strip-ansi": {
+          "version": "6.0.0",
+          "resolved": "https://registry.npm.taobao.org/strip-ansi/download/strip-ansi-6.0.0.tgz",
+          "integrity": "sha1-CxVx3XZpzNTz4G4U7x7tJiJa5TI=",
+          "dev": true,
+          "requires": {
+            "ansi-regex": "^5.0.0"
+          }
+        },
+        "supports-color": {
+          "version": "7.2.0",
+          "resolved": "https://registry.npm.taobao.org/supports-color/download/supports-color-7.2.0.tgz?cache=0&sync_timestamp=1598611730985&other_urls=https%3A%2F%2Fregistry.npm.taobao.org%2Fsupports-color%2Fdownload%2Fsupports-color-7.2.0.tgz",
+          "integrity": "sha1-G33NyzK4E4gBs+R4umpRyqiWSNo=",
+          "dev": true,
+          "requires": {
+            "has-flag": "^4.0.0"
+          }
+        },
+        "which": {
+          "version": "2.0.2",
+          "resolved": "https://registry.npm.taobao.org/which/download/which-2.0.2.tgz",
+          "integrity": "sha1-fGqN0KY2oDJ+ELWckobu6T8/UbE=",
+          "dev": true,
+          "requires": {
+            "isexe": "^2.0.0"
+          }
+        }
+      }
+    },
+    "build-scripts-config": {
+      "version": "0.1.8",
+      "resolved": "https://registry.npm.taobao.org/build-scripts-config/download/build-scripts-config-0.1.8.tgz",
+      "integrity": "sha1-xazuJ/wVfD/bMTTmOMBXy4RRDsg=",
+      "dev": true,
+      "requires": {
+        "@babel/plugin-proposal-class-properties": "^7.1.0",
+        "@babel/plugin-proposal-decorators": "^7.1.2",
+        "@babel/plugin-proposal-do-expressions": "^7.0.0",
+        "@babel/plugin-proposal-export-default-from": "^7.0.0",
+        "@babel/plugin-proposal-export-namespace-from": "^7.0.0",
+        "@babel/plugin-proposal-function-bind": "^7.0.0",
+        "@babel/plugin-proposal-function-sent": "^7.1.0",
+        "@babel/plugin-proposal-json-strings": "^7.0.0",
+        "@babel/plugin-proposal-logical-assignment-operators": "^7.0.0",
+        "@babel/plugin-proposal-nullish-coalescing-operator": "^7.0.0",
+        "@babel/plugin-proposal-numeric-separator": "^7.0.0",
+        "@babel/plugin-proposal-optional-chaining": "^7.0.0",
+        "@babel/plugin-proposal-pipeline-operator": "^7.0.0",
+        "@babel/plugin-proposal-throw-expressions": "^7.0.0",
+        "@babel/plugin-syntax-dynamic-import": "^7.0.0",
+        "@babel/plugin-syntax-import-meta": "^7.0.0",
+        "@babel/plugin-transform-runtime": "^7.1.0",
+        "@babel/preset-env": "^7.4.0",
+        "@babel/preset-flow": "^7.0.0",
+        "@babel/preset-react": "^7.0.0",
+        "@babel/preset-typescript": "^7.3.3",
+        "autoprefixer": "^9.6.1",
+        "babel-jest": "^24.9.0",
+        "babel-loader": "^8.0.6",
+        "camelcase": "^5.3.1",
+        "case-sensitive-paths-webpack-plugin": "^2.2.0",
+        "core-js": "^3.3.1",
+        "css-hot-loader": "^1.4.4",
+        "css-loader": "^3.2.0",
+        "file-loader": "^5.0.2",
+        "identity-obj-proxy": "^3.0.0",
+        "less": "^3.10.3",
+        "less-loader": "^5.0.0",
+        "loader-utils": "^1.2.3",
+        "lodash.clonedeep": "^4.5.0",
+        "mini-css-extract-plugin": "^0.8.0",
+        "node-sass": "^4.12.0",
+        "optimize-css-assets-webpack-plugin": "^5.0.3",
+        "postcss-loader": "^3.0.0",
+        "postcss-safe-parser": "^4.0.1",
+        "regenerator-runtime": "^0.13.3",
+        "sass-loader": "^8.0.0",
+        "terser-webpack-plugin": "^2.3.1",
+        "time-fix-plugin": "^2.0.6",
+        "ts-loader": "^6.1.2",
+        "typescript": "^3.6.3",
+        "url-loader": "^2.1.0",
+        "webpack-chain": "^6.0.0",
+        "webpack-filter-warnings-plugin": "^1.2.1",
+        "webpack-simple-progress-plugin": "0.0.4"
+      },
+      "dependencies": {
+        "@jest/console": {
+          "version": "24.9.0",
+          "resolved": "https://registry.npm.taobao.org/@jest/console/download/@jest/console-24.9.0.tgz",
+          "integrity": "sha1-ebG8Bvt0qM+wHL3t+UVYSxuXB/A=",
+          "dev": true,
+          "requires": {
+            "@jest/source-map": "^24.9.0",
+            "chalk": "^2.0.1",
+            "slash": "^2.0.0"
+          }
+        },
+        "@jest/fake-timers": {
+          "version": "24.9.0",
+          "resolved": "https://registry.npm.taobao.org/@jest/fake-timers/download/@jest/fake-timers-24.9.0.tgz",
+          "integrity": "sha1-uj5r8O7NCaY2BJiWQ00wZjZUDJM=",
+          "dev": true,
+          "requires": {
+            "@jest/types": "^24.9.0",
+            "jest-message-util": "^24.9.0",
+            "jest-mock": "^24.9.0"
+          }
+        },
+        "@jest/source-map": {
+          "version": "24.9.0",
+          "resolved": "https://registry.npm.taobao.org/@jest/source-map/download/@jest/source-map-24.9.0.tgz?cache=0&sync_timestamp=1604319711726&other_urls=https%3A%2F%2Fregistry.npm.taobao.org%2F%40jest%2Fsource-map%2Fdownload%2F%40jest%2Fsource-map-24.9.0.tgz",
+          "integrity": "sha1-DiY6lEML5LQdpoPMwea//ioZFxQ=",
+          "dev": true,
+          "requires": {
+            "callsites": "^3.0.0",
+            "graceful-fs": "^4.1.15",
+            "source-map": "^0.6.0"
+          }
+        },
+        "@jest/test-result": {
+          "version": "24.9.0",
+          "resolved": "https://registry.npm.taobao.org/@jest/test-result/download/@jest/test-result-24.9.0.tgz",
+          "integrity": "sha1-EXluiqnb+I6gJXV7MVJZWtBroMo=",
+          "dev": true,
+          "requires": {
+            "@jest/console": "^24.9.0",
+            "@jest/types": "^24.9.0",
+            "@types/istanbul-lib-coverage": "^2.0.0"
+          }
+        },
+        "@jest/transform": {
+          "version": "24.9.0",
+          "resolved": "https://registry.npm.taobao.org/@jest/transform/download/@jest/transform-24.9.0.tgz",
+          "integrity": "sha1-SuJ2iyllU/rasJ6ewRlUPJCxbFY=",
+          "dev": true,
+          "requires": {
+            "@babel/core": "^7.1.0",
+            "@jest/types": "^24.9.0",
+            "babel-plugin-istanbul": "^5.1.0",
+            "chalk": "^2.0.1",
+            "convert-source-map": "^1.4.0",
+            "fast-json-stable-stringify": "^2.0.0",
+            "graceful-fs": "^4.1.15",
+            "jest-haste-map": "^24.9.0",
+            "jest-regex-util": "^24.9.0",
+            "jest-util": "^24.9.0",
+            "micromatch": "^3.1.10",
+            "pirates": "^4.0.1",
+            "realpath-native": "^1.1.0",
+            "slash": "^2.0.0",
+            "source-map": "^0.6.1",
+            "write-file-atomic": "2.4.1"
+          }
+        },
+        "@jest/types": {
+          "version": "24.9.0",
+          "resolved": "https://registry.npm.taobao.org/@jest/types/download/@jest/types-24.9.0.tgz",
+          "integrity": "sha1-Y8smy3UA0Gnlo4lEGnxqtekJ/Fk=",
+          "dev": true,
+          "requires": {
+            "@types/istanbul-lib-coverage": "^2.0.0",
+            "@types/istanbul-reports": "^1.1.1",
+            "@types/yargs": "^13.0.0"
+          }
+        },
+        "@types/istanbul-reports": {
+          "version": "1.1.2",
+          "resolved": "https://registry.npm.taobao.org/@types/istanbul-reports/download/@types/istanbul-reports-1.1.2.tgz?cache=0&sync_timestamp=1605054056153&other_urls=https%3A%2F%2Fregistry.npm.taobao.org%2F%40types%2Fistanbul-reports%2Fdownload%2F%40types%2Fistanbul-reports-1.1.2.tgz",
+          "integrity": "sha1-6HXMaJ5HvOVJ7IHz315vbxHPrrI=",
+          "dev": true,
+          "requires": {
+            "@types/istanbul-lib-coverage": "*",
+            "@types/istanbul-lib-report": "*"
+          }
+        },
+        "@types/stack-utils": {
+          "version": "1.0.1",
+          "resolved": "https://registry.npm.taobao.org/@types/stack-utils/download/@types/stack-utils-1.0.1.tgz",
+          "integrity": "sha1-CoUdO9lkmPolwzq3J47TvWXwbD4=",
+          "dev": true
+        },
+        "@types/yargs": {
+          "version": "13.0.11",
+          "resolved": "https://registry.npm.taobao.org/@types/yargs/download/@types/yargs-13.0.11.tgz?cache=0&sync_timestamp=1605057458388&other_urls=https%3A%2F%2Fregistry.npm.taobao.org%2F%40types%2Fyargs%2Fdownload%2F%40types%2Fyargs-13.0.11.tgz",
+          "integrity": "sha1-3vLwyT5L3yxh1+NImbF+NL4o07E=",
+          "dev": true,
+          "requires": {
+            "@types/yargs-parser": "*"
+          }
+        },
+        "anymatch": {
+          "version": "2.0.0",
+          "resolved": "https://registry.npm.taobao.org/anymatch/download/anymatch-2.0.0.tgz",
+          "integrity": "sha1-vLJLTzeTTZqnrBe0ra+J58du8us=",
+          "dev": true,
+          "requires": {
+            "micromatch": "^3.1.4",
+            "normalize-path": "^2.1.1"
+          }
+        },
+        "babel-jest": {
+          "version": "24.9.0",
+          "resolved": "https://registry.npm.taobao.org/babel-jest/download/babel-jest-24.9.0.tgz",
+          "integrity": "sha1-P8Mny4RnuJ0U17xw4xUQSng8zVQ=",
+          "dev": true,
+          "requires": {
+            "@jest/transform": "^24.9.0",
+            "@jest/types": "^24.9.0",
+            "@types/babel__core": "^7.1.0",
+            "babel-plugin-istanbul": "^5.1.0",
+            "babel-preset-jest": "^24.9.0",
+            "chalk": "^2.4.2",
+            "slash": "^2.0.0"
+          }
+        },
+        "babel-plugin-istanbul": {
+          "version": "5.2.0",
+          "resolved": "https://registry.npm.taobao.org/babel-plugin-istanbul/download/babel-plugin-istanbul-5.2.0.tgz",
+          "integrity": "sha1-30reg9iXqS3wacTZolzyZxKTyFQ=",
+          "dev": true,
+          "requires": {
+            "@babel/helper-plugin-utils": "^7.0.0",
+            "find-up": "^3.0.0",
+            "istanbul-lib-instrument": "^3.3.0",
+            "test-exclude": "^5.2.3"
+          }
+        },
+        "babel-plugin-jest-hoist": {
+          "version": "24.9.0",
+          "resolved": "https://registry.npm.taobao.org/babel-plugin-jest-hoist/download/babel-plugin-jest-hoist-24.9.0.tgz?cache=0&sync_timestamp=1604319713233&other_urls=https%3A%2F%2Fregistry.npm.taobao.org%2Fbabel-plugin-jest-hoist%2Fdownload%2Fbabel-plugin-jest-hoist-24.9.0.tgz",
+          "integrity": "sha1-T4NwketAfgFEfIhDy+xUbQAC11Y=",
+          "dev": true,
+          "requires": {
+            "@types/babel__traverse": "^7.0.6"
+          }
+        },
+        "babel-preset-jest": {
+          "version": "24.9.0",
+          "resolved": "https://registry.npm.taobao.org/babel-preset-jest/download/babel-preset-jest-24.9.0.tgz?cache=0&sync_timestamp=1604319712402&other_urls=https%3A%2F%2Fregistry.npm.taobao.org%2Fbabel-preset-jest%2Fdownload%2Fbabel-preset-jest-24.9.0.tgz",
+          "integrity": "sha1-GStSHiIX+x0fZ89z9wwzZlCtPNw=",
+          "dev": true,
+          "requires": {
+            "@babel/plugin-syntax-object-rest-spread": "^7.0.0",
+            "babel-plugin-jest-hoist": "^24.9.0"
+          }
+        },
+        "cacache": {
+          "version": "13.0.1",
+          "resolved": "https://registry.npm.taobao.org/cacache/download/cacache-13.0.1.tgz?cache=0&sync_timestamp=1594428010987&other_urls=https%3A%2F%2Fregistry.npm.taobao.org%2Fcacache%2Fdownload%2Fcacache-13.0.1.tgz",
+          "integrity": "sha1-qAAMIWlwiQgvhSh6GuxuOCAkpxw=",
+          "dev": true,
+          "requires": {
+            "chownr": "^1.1.2",
+            "figgy-pudding": "^3.5.1",
+            "fs-minipass": "^2.0.0",
+            "glob": "^7.1.4",
+            "graceful-fs": "^4.2.2",
+            "infer-owner": "^1.0.4",
+            "lru-cache": "^5.1.1",
+            "minipass": "^3.0.0",
+            "minipass-collect": "^1.0.2",
+            "minipass-flush": "^1.0.5",
+            "minipass-pipeline": "^1.2.2",
+            "mkdirp": "^0.5.1",
+            "move-concurrently": "^1.0.1",
+            "p-map": "^3.0.0",
+            "promise-inflight": "^1.0.1",
+            "rimraf": "^2.7.1",
+            "ssri": "^7.0.0",
+            "unique-filename": "^1.1.1"
+          }
+        },
+        "callsites": {
+          "version": "3.1.0",
+          "resolved": "https://registry.npm.taobao.org/callsites/download/callsites-3.1.0.tgz",
+          "integrity": "sha1-s2MKvYlDQy9Us/BRkjjjPNffL3M=",
+          "dev": true
+        },
+        "camelcase": {
+          "version": "5.3.1",
+          "resolved": "https://registry.npm.taobao.org/camelcase/download/camelcase-5.3.1.tgz?cache=0&sync_timestamp=1603921882890&other_urls=https%3A%2F%2Fregistry.npm.taobao.org%2Fcamelcase%2Fdownload%2Fcamelcase-5.3.1.tgz",
+          "integrity": "sha1-48mzFWnhBoEd8kL3FXJaH0xJQyA=",
+          "dev": true
+        },
+        "core-js": {
+          "version": "3.7.0",
+          "resolved": "https://registry.npm.taobao.org/core-js/download/core-js-3.7.0.tgz?cache=0&sync_timestamp=1604675498528&other_urls=https%3A%2F%2Fregistry.npm.taobao.org%2Fcore-js%2Fdownload%2Fcore-js-3.7.0.tgz",
+          "integrity": "sha1-sKdhoCSIV3r7+XF55Ggb9JVoUg8=",
+          "dev": true
+        },
+        "escape-string-regexp": {
+          "version": "2.0.0",
+          "resolved": "https://registry.npm.taobao.org/escape-string-regexp/download/escape-string-regexp-2.0.0.tgz?cache=0&sync_timestamp=1587627107924&other_urls=https%3A%2F%2Fregistry.npm.taobao.org%2Fescape-string-regexp%2Fdownload%2Fescape-string-regexp-2.0.0.tgz",
+          "integrity": "sha1-owME6Z2qMuI7L9IPUbq9B8/8o0Q=",
+          "dev": true
+        },
+        "find-cache-dir": {
+          "version": "3.3.1",
+          "resolved": "https://registry.npm.taobao.org/find-cache-dir/download/find-cache-dir-3.3.1.tgz",
+          "integrity": "sha1-ibM/rUpGcNqpT4Vff74x1thP6IA=",
+          "dev": true,
+          "requires": {
+            "commondir": "^1.0.1",
+            "make-dir": "^3.0.2",
+            "pkg-dir": "^4.1.0"
+          }
+        },
+        "find-up": {
+          "version": "3.0.0",
+          "resolved": "https://registry.npm.taobao.org/find-up/download/find-up-3.0.0.tgz?cache=0&sync_timestamp=1597169862146&other_urls=https%3A%2F%2Fregistry.npm.taobao.org%2Ffind-up%2Fdownload%2Ffind-up-3.0.0.tgz",
+          "integrity": "sha1-SRafHXmTQwZG2mHsxa41XCHJe3M=",
+          "dev": true,
+          "requires": {
+            "locate-path": "^3.0.0"
+          }
+        },
+        "fsevents": {
+          "version": "1.2.13",
+          "resolved": "https://registry.npm.taobao.org/fsevents/download/fsevents-1.2.13.tgz?cache=0&sync_timestamp=1604593283990&other_urls=https%3A%2F%2Fregistry.npm.taobao.org%2Ffsevents%2Fdownload%2Ffsevents-1.2.13.tgz",
+          "integrity": "sha1-8yXLBFVZJCi88Rs4M3DvcOO/zDg=",
+          "dev": true,
+          "optional": true,
+          "requires": {
+            "bindings": "^1.5.0",
+            "nan": "^2.12.1"
+          }
+        },
+        "istanbul-lib-coverage": {
+          "version": "2.0.5",
+          "resolved": "https://registry.npm.taobao.org/istanbul-lib-coverage/download/istanbul-lib-coverage-2.0.5.tgz",
+          "integrity": "sha1-Z18KtpUD+tSx2En3NrqsqAM0T0k=",
+          "dev": true
+        },
+        "istanbul-lib-instrument": {
+          "version": "3.3.0",
+          "resolved": "https://registry.npm.taobao.org/istanbul-lib-instrument/download/istanbul-lib-instrument-3.3.0.tgz",
+          "integrity": "sha1-pfY9kfC7wMPkee9MXeAnM17G1jA=",
+          "dev": true,
+          "requires": {
+            "@babel/generator": "^7.4.0",
+            "@babel/parser": "^7.4.3",
+            "@babel/template": "^7.4.0",
+            "@babel/traverse": "^7.4.3",
+            "@babel/types": "^7.4.0",
+            "istanbul-lib-coverage": "^2.0.5",
+            "semver": "^6.0.0"
+          }
+        },
+        "jest-haste-map": {
+          "version": "24.9.0",
+          "resolved": "https://registry.npm.taobao.org/jest-haste-map/download/jest-haste-map-24.9.0.tgz",
+          "integrity": "sha1-s4pdZCdJNOIfpBeump++t3zqrH0=",
+          "dev": true,
+          "requires": {
+            "@jest/types": "^24.9.0",
+            "anymatch": "^2.0.0",
+            "fb-watchman": "^2.0.0",
+            "fsevents": "^1.2.7",
+            "graceful-fs": "^4.1.15",
+            "invariant": "^2.2.4",
+            "jest-serializer": "^24.9.0",
+            "jest-util": "^24.9.0",
+            "jest-worker": "^24.9.0",
+            "micromatch": "^3.1.10",
+            "sane": "^4.0.3",
+            "walker": "^1.0.7"
+          }
+        },
+        "jest-message-util": {
+          "version": "24.9.0",
+          "resolved": "https://registry.npm.taobao.org/jest-message-util/download/jest-message-util-24.9.0.tgz?cache=0&sync_timestamp=1604319716333&other_urls=https%3A%2F%2Fregistry.npm.taobao.org%2Fjest-message-util%2Fdownload%2Fjest-message-util-24.9.0.tgz",
+          "integrity": "sha1-Un9UoeOA9eICqNEUmw7IcvQxGeM=",
+          "dev": true,
+          "requires": {
+            "@babel/code-frame": "^7.0.0",
+            "@jest/test-result": "^24.9.0",
+            "@jest/types": "^24.9.0",
+            "@types/stack-utils": "^1.0.1",
+            "chalk": "^2.0.1",
+            "micromatch": "^3.1.10",
+            "slash": "^2.0.0",
+            "stack-utils": "^1.0.1"
+          }
+        },
+        "jest-mock": {
+          "version": "24.9.0",
+          "resolved": "https://registry.npm.taobao.org/jest-mock/download/jest-mock-24.9.0.tgz?cache=0&sync_timestamp=1604319657931&other_urls=https%3A%2F%2Fregistry.npm.taobao.org%2Fjest-mock%2Fdownload%2Fjest-mock-24.9.0.tgz",
+          "integrity": "sha1-wig1VB7jebkIZzrVEIeiGFwT8cY=",
+          "dev": true,
+          "requires": {
+            "@jest/types": "^24.9.0"
+          }
+        },
+        "jest-regex-util": {
+          "version": "24.9.0",
+          "resolved": "https://registry.npm.taobao.org/jest-regex-util/download/jest-regex-util-24.9.0.tgz",
+          "integrity": "sha1-wT+zOAveIr9ldUMsST6o/jeWVjY=",
+          "dev": true
+        },
+        "jest-serializer": {
+          "version": "24.9.0",
+          "resolved": "https://registry.npm.taobao.org/jest-serializer/download/jest-serializer-24.9.0.tgz",
+          "integrity": "sha1-5tfX75bTHouQeacUdUxdXFgojnM=",
+          "dev": true
+        },
+        "jest-util": {
+          "version": "24.9.0",
+          "resolved": "https://registry.npm.taobao.org/jest-util/download/jest-util-24.9.0.tgz?cache=0&sync_timestamp=1604321502822&other_urls=https%3A%2F%2Fregistry.npm.taobao.org%2Fjest-util%2Fdownload%2Fjest-util-24.9.0.tgz",
+          "integrity": "sha1-c5aBTkhTbS6Fo33j5MQx18sUAWI=",
+          "dev": true,
+          "requires": {
+            "@jest/console": "^24.9.0",
+            "@jest/fake-timers": "^24.9.0",
+            "@jest/source-map": "^24.9.0",
+            "@jest/test-result": "^24.9.0",
+            "@jest/types": "^24.9.0",
+            "callsites": "^3.0.0",
+            "chalk": "^2.0.1",
+            "graceful-fs": "^4.1.15",
+            "is-ci": "^2.0.0",
+            "mkdirp": "^0.5.1",
+            "slash": "^2.0.0",
+            "source-map": "^0.6.0"
+          }
+        },
+        "jest-worker": {
+          "version": "24.9.0",
+          "resolved": "https://registry.npm.taobao.org/jest-worker/download/jest-worker-24.9.0.tgz?cache=0&sync_timestamp=1604319657366&other_urls=https%3A%2F%2Fregistry.npm.taobao.org%2Fjest-worker%2Fdownload%2Fjest-worker-24.9.0.tgz",
+          "integrity": "sha1-Xb/bWy0yLphWeJgjipaXvM5ns+U=",
+          "dev": true,
+          "requires": {
+            "merge-stream": "^2.0.0",
+            "supports-color": "^6.1.0"
+          }
+        },
+        "load-json-file": {
+          "version": "4.0.0",
+          "resolved": "https://registry.npm.taobao.org/load-json-file/download/load-json-file-4.0.0.tgz",
+          "integrity": "sha1-L19Fq5HjMhYjT9U62rZo607AmTs=",
+          "dev": true,
+          "requires": {
+            "graceful-fs": "^4.1.2",
+            "parse-json": "^4.0.0",
+            "pify": "^3.0.0",
+            "strip-bom": "^3.0.0"
+          }
+        },
+        "locate-path": {
+          "version": "3.0.0",
+          "resolved": "https://registry.npm.taobao.org/locate-path/download/locate-path-3.0.0.tgz",
+          "integrity": "sha1-2+w7OrdZdYBxtY/ln8QYca8hQA4=",
+          "dev": true,
+          "requires": {
+            "p-locate": "^3.0.0",
+            "path-exists": "^3.0.0"
+          }
+        },
+        "normalize-path": {
+          "version": "2.1.1",
+          "resolved": "https://registry.npm.taobao.org/normalize-path/download/normalize-path-2.1.1.tgz",
+          "integrity": "sha1-GrKLVW4Zg2Oowab35vogE3/mrtk=",
+          "dev": true,
+          "requires": {
+            "remove-trailing-separator": "^1.0.1"
+          }
+        },
+        "p-limit": {
+          "version": "2.3.0",
+          "resolved": "https://registry.npm.taobao.org/p-limit/download/p-limit-2.3.0.tgz",
+          "integrity": "sha1-PdM8ZHohT9//2DWTPrCG2g3CHbE=",
+          "dev": true,
+          "requires": {
+            "p-try": "^2.0.0"
+          }
+        },
+        "p-locate": {
+          "version": "3.0.0",
+          "resolved": "https://registry.npm.taobao.org/p-locate/download/p-locate-3.0.0.tgz?cache=0&sync_timestamp=1597081508945&other_urls=https%3A%2F%2Fregistry.npm.taobao.org%2Fp-locate%2Fdownload%2Fp-locate-3.0.0.tgz",
+          "integrity": "sha1-Mi1poFwCZLJZl9n0DNiokasAZKQ=",
+          "dev": true,
+          "requires": {
+            "p-limit": "^2.0.0"
+          }
+        },
+        "p-map": {
+          "version": "3.0.0",
+          "resolved": "https://registry.npm.taobao.org/p-map/download/p-map-3.0.0.tgz",
+          "integrity": "sha1-1wTZr4orpoTiYA2aIVmD1BQal50=",
+          "dev": true,
+          "requires": {
+            "aggregate-error": "^3.0.0"
+          }
+        },
+        "p-try": {
+          "version": "2.2.0",
+          "resolved": "https://registry.npm.taobao.org/p-try/download/p-try-2.2.0.tgz",
+          "integrity": "sha1-yyhoVA4xPWHeWPr741zpAE1VQOY=",
+          "dev": true
+        },
+        "parse-json": {
+          "version": "4.0.0",
+          "resolved": "https://registry.npm.taobao.org/parse-json/download/parse-json-4.0.0.tgz?cache=0&sync_timestamp=1598129247474&other_urls=https%3A%2F%2Fregistry.npm.taobao.org%2Fparse-json%2Fdownload%2Fparse-json-4.0.0.tgz",
+          "integrity": "sha1-vjX1Qlvh9/bHRxhPmKeIy5lHfuA=",
+          "dev": true,
+          "requires": {
+            "error-ex": "^1.3.1",
+            "json-parse-better-errors": "^1.0.1"
+          }
+        },
+        "path-type": {
+          "version": "3.0.0",
+          "resolved": "https://registry.npm.taobao.org/path-type/download/path-type-3.0.0.tgz",
+          "integrity": "sha1-zvMdyOCho7sNEFwM2Xzzv0f0428=",
+          "dev": true,
+          "requires": {
+            "pify": "^3.0.0"
+          }
+        },
+        "pify": {
+          "version": "3.0.0",
+          "resolved": "https://registry.npm.taobao.org/pify/download/pify-3.0.0.tgz",
+          "integrity": "sha1-5aSs0sEB/fPZpNB/DbxNtJ3SgXY=",
+          "dev": true
+        },
+        "pkg-dir": {
+          "version": "4.2.0",
+          "resolved": "https://registry.npm.taobao.org/pkg-dir/download/pkg-dir-4.2.0.tgz?cache=0&sync_timestamp=1602859008602&other_urls=https%3A%2F%2Fregistry.npm.taobao.org%2Fpkg-dir%2Fdownload%2Fpkg-dir-4.2.0.tgz",
+          "integrity": "sha1-8JkTPfft5CLoHR2ESCcO6z5CYfM=",
+          "dev": true,
+          "requires": {
+            "find-up": "^4.0.0"
+          },
+          "dependencies": {
+            "find-up": {
+              "version": "4.1.0",
+              "resolved": "https://registry.npm.taobao.org/find-up/download/find-up-4.1.0.tgz?cache=0&sync_timestamp=1597169862146&other_urls=https%3A%2F%2Fregistry.npm.taobao.org%2Ffind-up%2Fdownload%2Ffind-up-4.1.0.tgz",
+              "integrity": "sha1-l6/n1s3AvFkoWEt8jXsW6KmqXRk=",
+              "dev": true,
+              "requires": {
+                "locate-path": "^5.0.0",
+                "path-exists": "^4.0.0"
+              }
+            },
+            "locate-path": {
+              "version": "5.0.0",
+              "resolved": "https://registry.npm.taobao.org/locate-path/download/locate-path-5.0.0.tgz",
+              "integrity": "sha1-Gvujlq/WdqbUJQTQpno6frn2KqA=",
+              "dev": true,
+              "requires": {
+                "p-locate": "^4.1.0"
+              }
+            },
+            "p-locate": {
+              "version": "4.1.0",
+              "resolved": "https://registry.npm.taobao.org/p-locate/download/p-locate-4.1.0.tgz?cache=0&sync_timestamp=1597081508945&other_urls=https%3A%2F%2Fregistry.npm.taobao.org%2Fp-locate%2Fdownload%2Fp-locate-4.1.0.tgz",
+              "integrity": "sha1-o0KLtwiLOmApL2aRkni3wpetTwc=",
+              "dev": true,
+              "requires": {
+                "p-limit": "^2.2.0"
+              }
+            },
+            "path-exists": {
+              "version": "4.0.0",
+              "resolved": "https://registry.npm.taobao.org/path-exists/download/path-exists-4.0.0.tgz",
+              "integrity": "sha1-UTvb4tO5XXdi6METfvoZXGxhtbM=",
+              "dev": true
+            }
+          }
+        },
+        "read-pkg": {
+          "version": "3.0.0",
+          "resolved": "https://registry.npm.taobao.org/read-pkg/download/read-pkg-3.0.0.tgz",
+          "integrity": "sha1-nLxoaXj+5l0WwA4rGcI3/Pbjg4k=",
+          "dev": true,
+          "requires": {
+            "load-json-file": "^4.0.0",
+            "normalize-package-data": "^2.3.2",
+            "path-type": "^3.0.0"
+          }
+        },
+        "read-pkg-up": {
+          "version": "4.0.0",
+          "resolved": "https://registry.npm.taobao.org/read-pkg-up/download/read-pkg-up-4.0.0.tgz",
+          "integrity": "sha1-GyIcYIi6d5lgHICPkRYcZuWPiXg=",
+          "dev": true,
+          "requires": {
+            "find-up": "^3.0.0",
+            "read-pkg": "^3.0.0"
+          }
+        },
+        "regenerator-runtime": {
+          "version": "0.13.7",
+          "resolved": "https://registry.npm.taobao.org/regenerator-runtime/download/regenerator-runtime-0.13.7.tgz?cache=0&other_urls=https%3A%2F%2Fregistry.npm.taobao.org%2Fregenerator-runtime%2Fdownload%2Fregenerator-runtime-0.13.7.tgz",
+          "integrity": "sha1-ysLazIoepnX+qrrriugziYrkb1U=",
+          "dev": true
+        },
+        "rimraf": {
+          "version": "2.7.1",
+          "resolved": "https://registry.npm.taobao.org/rimraf/download/rimraf-2.7.1.tgz?cache=0&sync_timestamp=1587992602190&other_urls=https%3A%2F%2Fregistry.npm.taobao.org%2Frimraf%2Fdownload%2Frimraf-2.7.1.tgz",
+          "integrity": "sha1-NXl/E6f9rcVmFCwp1PB8ytSD4+w=",
+          "dev": true,
+          "requires": {
+            "glob": "^7.1.3"
+          }
+        },
+        "schema-utils": {
+          "version": "2.7.1",
+          "resolved": "https://registry.npm.taobao.org/schema-utils/download/schema-utils-2.7.1.tgz",
+          "integrity": "sha1-HKTzLRskxZDCA7jnpQvw6kzTlNc=",
+          "dev": true,
+          "requires": {
+            "@types/json-schema": "^7.0.5",
+            "ajv": "^6.12.4",
+            "ajv-keywords": "^3.5.2"
+          }
+        },
+        "semver": {
+          "version": "6.3.0",
+          "resolved": "https://registry.npm.taobao.org/semver/download/semver-6.3.0.tgz",
+          "integrity": "sha1-7gpkyK9ejO6mdoexM3YeG+y9HT0=",
+          "dev": true
+        },
+        "source-map": {
+          "version": "0.6.1",
+          "resolved": "https://registry.npm.taobao.org/source-map/download/source-map-0.6.1.tgz",
+          "integrity": "sha1-dHIq8y6WFOnCh6jQu95IteLxomM=",
+          "dev": true
+        },
+        "ssri": {
+          "version": "7.1.0",
+          "resolved": "https://registry.npm.taobao.org/ssri/download/ssri-7.1.0.tgz",
+          "integrity": "sha1-ksJBv23oI2W1x/tL126XVSLhKU0=",
+          "dev": true,
+          "requires": {
+            "figgy-pudding": "^3.5.1",
+            "minipass": "^3.1.1"
+          }
+        },
+        "stack-utils": {
+          "version": "1.0.3",
+          "resolved": "https://registry.npm.taobao.org/stack-utils/download/stack-utils-1.0.3.tgz?cache=0&sync_timestamp=1605310634130&other_urls=https%3A%2F%2Fregistry.npm.taobao.org%2Fstack-utils%2Fdownload%2Fstack-utils-1.0.3.tgz",
+          "integrity": "sha1-23pHVzO1uL9lIZB7GIkdKQBvd1E=",
+          "dev": true,
+          "requires": {
+            "escape-string-regexp": "^2.0.0"
+          }
+        },
+        "supports-color": {
+          "version": "6.1.0",
+          "resolved": "https://registry.npm.taobao.org/supports-color/download/supports-color-6.1.0.tgz?cache=0&sync_timestamp=1598611730985&other_urls=https%3A%2F%2Fregistry.npm.taobao.org%2Fsupports-color%2Fdownload%2Fsupports-color-6.1.0.tgz",
+          "integrity": "sha1-B2Srxpxj1ayELdSGfo0CXogN+PM=",
+          "dev": true,
+          "requires": {
+            "has-flag": "^3.0.0"
+          }
+        },
+        "terser-webpack-plugin": {
+          "version": "2.3.8",
+          "resolved": "https://registry.npm.taobao.org/terser-webpack-plugin/download/terser-webpack-plugin-2.3.8.tgz?cache=0&sync_timestamp=1603881757308&other_urls=https%3A%2F%2Fregistry.npm.taobao.org%2Fterser-webpack-plugin%2Fdownload%2Fterser-webpack-plugin-2.3.8.tgz",
+          "integrity": "sha1-iUdkoZsHQ/L3BOfCqEjFKDppZyQ=",
+          "dev": true,
+          "requires": {
+            "cacache": "^13.0.1",
+            "find-cache-dir": "^3.3.1",
+            "jest-worker": "^25.4.0",
+            "p-limit": "^2.3.0",
+            "schema-utils": "^2.6.6",
+            "serialize-javascript": "^4.0.0",
+            "source-map": "^0.6.1",
+            "terser": "^4.6.12",
+            "webpack-sources": "^1.4.3"
+          },
+          "dependencies": {
+            "has-flag": {
+              "version": "4.0.0",
+              "resolved": "https://registry.npm.taobao.org/has-flag/download/has-flag-4.0.0.tgz?cache=0&sync_timestamp=1596294337050&other_urls=https%3A%2F%2Fregistry.npm.taobao.org%2Fhas-flag%2Fdownload%2Fhas-flag-4.0.0.tgz",
+              "integrity": "sha1-lEdx/ZyByBJlxNaUGGDaBrtZR5s=",
+              "dev": true
+            },
+            "jest-worker": {
+              "version": "25.5.0",
+              "resolved": "https://registry.npm.taobao.org/jest-worker/download/jest-worker-25.5.0.tgz?cache=0&sync_timestamp=1604319657366&other_urls=https%3A%2F%2Fregistry.npm.taobao.org%2Fjest-worker%2Fdownload%2Fjest-worker-25.5.0.tgz",
+              "integrity": "sha1-JhHQcbec6g9D7lej0RhZOsFUfbE=",
+              "dev": true,
+              "requires": {
+                "merge-stream": "^2.0.0",
+                "supports-color": "^7.0.0"
+              }
+            },
+            "supports-color": {
+              "version": "7.2.0",
+              "resolved": "https://registry.npm.taobao.org/supports-color/download/supports-color-7.2.0.tgz?cache=0&sync_timestamp=1598611730985&other_urls=https%3A%2F%2Fregistry.npm.taobao.org%2Fsupports-color%2Fdownload%2Fsupports-color-7.2.0.tgz",
+              "integrity": "sha1-G33NyzK4E4gBs+R4umpRyqiWSNo=",
+              "dev": true,
+              "requires": {
+                "has-flag": "^4.0.0"
+              }
+            }
+          }
+        },
+        "test-exclude": {
+          "version": "5.2.3",
+          "resolved": "https://registry.npm.taobao.org/test-exclude/download/test-exclude-5.2.3.tgz",
+          "integrity": "sha1-w9Ph4xHrfuQF4JLawQrv0JCR6sA=",
+          "dev": true,
+          "requires": {
+            "glob": "^7.1.3",
+            "minimatch": "^3.0.4",
+            "read-pkg-up": "^4.0.0",
+            "require-main-filename": "^2.0.0"
+          }
+        },
+        "write-file-atomic": {
+          "version": "2.4.1",
+          "resolved": "https://registry.npm.taobao.org/write-file-atomic/download/write-file-atomic-2.4.1.tgz",
+          "integrity": "sha1-0LBUY8GIroBDlv1asqNwBir4dSk=",
+          "dev": true,
+          "requires": {
+            "graceful-fs": "^4.1.11",
+            "imurmurhash": "^0.1.4",
+            "signal-exit": "^3.0.2"
+          }
+        }
+      }
+    },
+    "builtin-status-codes": {
+      "version": "3.0.0",
+      "resolved": "https://registry.npm.taobao.org/builtin-status-codes/download/builtin-status-codes-3.0.0.tgz",
+      "integrity": "sha1-hZgoeOIbmOHGZCXgPQF0eI9Wnug=",
+      "dev": true
+    },
+    "busboy": {
+      "version": "0.2.14",
+      "resolved": "https://registry.npm.taobao.org/busboy/download/busboy-0.2.14.tgz",
+      "integrity": "sha1-bCpiLvz0fFe7vh4qnDetNseSVFM=",
... 18835 lines suppressed ...


[dubbo-spi-extensions] 20/39: 修改类注释

Posted by li...@apache.org.
This is an automated email from the ASF dual-hosted git repository.

liujun pushed a commit to branch 2.7.x
in repository https://gitbox.apache.org/repos/asf/dubbo-spi-extensions.git

commit 46d56dc4112a61d1b9bb1181972e6fed710f5ccb
Author: qq213539 <21...@qq.com>
AuthorDate: Mon Dec 7 16:20:46 2020 +0800

    修改类注释
---
 .../src/main/java/org/apache/dubbo/apidocs/annotations/ApiDoc.java    | 2 --
 .../src/main/java/org/apache/dubbo/apidocs/annotations/ApiModule.java | 2 --
 .../main/java/org/apache/dubbo/apidocs/annotations/RequestParam.java  | 2 --
 .../java/org/apache/dubbo/apidocs/annotations/ResponseProperty.java   | 2 --
 .../src/main/java/org/apache/dubbo/apidocs/EnableDubboApiDocs.java    | 2 --
 .../org/apache/dubbo/apidocs/core/DubboApiDocsAnnotationScanner.java  | 3 ---
 .../main/java/org/apache/dubbo/apidocs/core/DubboApiDocsCache.java    | 3 ---
 .../main/java/org/apache/dubbo/apidocs/core/beans/ApiCacheItem.java   | 3 ---
 .../java/org/apache/dubbo/apidocs/core/beans/ApiParamsCacheItem.java  | 3 ---
 .../main/java/org/apache/dubbo/apidocs/core/beans/HtmlTypeEnum.java   | 2 --
 .../java/org/apache/dubbo/apidocs/core/beans/ModuleCacheItem.java     | 3 ---
 .../src/main/java/org/apache/dubbo/apidocs/core/beans/ParamBean.java  | 2 --
 .../org/apache/dubbo/apidocs/core/providers/DubboDocProviderImpl.java | 2 --
 .../org/apache/dubbo/apidocs/core/providers/IDubboDocProvider.java    | 2 --
 .../src/main/java/org/apache/dubbo/apidocs/utils/ClassTypeUtil.java   | 3 ---
 .../src/main/java/org/apache/dubbo/apidocs/utils/SimpleTypeImpl.java  | 2 --
 .../main/java/org/apache/dubbo/apidocs/examples/api/IAsyncDemo.java   | 2 --
 .../main/java/org/apache/dubbo/apidocs/examples/api/ISyncDemo.java    | 2 --
 .../java/org/apache/dubbo/apidocs/examples/params/DemoParamBean1.java | 2 --
 .../apache/dubbo/apidocs/examples/params/DemoParamBean1SubBean1.java  | 2 --
 .../java/org/apache/dubbo/apidocs/examples/params/DemoParamBean2.java | 2 --
 .../java/org/apache/dubbo/apidocs/examples/params/DemoParamBean3.java | 3 ---
 .../java/org/apache/dubbo/apidocs/examples/params/DemoParamBean4.java | 3 ---
 .../main/java/org/apache/dubbo/apidocs/examples/params/TestBean.java  | 2 --
 .../main/java/org/apache/dubbo/apidocs/examples/params/TestEnum.java  | 2 --
 .../org/apache/dubbo/apidocs/examples/responses/BaseResponse.java     | 2 --
 .../org/apache/dubbo/apidocs/examples/responses/DemoRespBean1.java    | 2 --
 .../java/org/apache/dubbo/apidocs/examples/ExampleScaApplication.java | 2 --
 .../org/apache/dubbo/apidocs/examples/api/impl/AsyncDemoImpl.java     | 2 --
 .../java/org/apache/dubbo/apidocs/examples/api/impl/SyncDemoImpl.java | 2 --
 .../java/org/apache/dubbo/apidocs/examples/cfg/DubboDocConfig.java    | 2 --
 .../java/org/apache/dubbo/apidocs/examples/ExampleApplication.java    | 2 --
 .../org/apache/dubbo/apidocs/examples/api/impl/AsyncDemoImpl.java     | 3 ---
 .../java/org/apache/dubbo/apidocs/examples/api/impl/SyncDemoImpl.java | 2 --
 .../java/org/apache/dubbo/apidocs/examples/cfg/DubboDocConfig.java    | 2 --
 .../org/apache/dubbo/apidocs/DubboApiDocsUiServerApplication.java     | 2 --
 .../src/main/java/org/apache/dubbo/apidocs/cfg/SwaggerConfig.java     | 2 --
 .../src/main/java/org/apache/dubbo/apidocs/cfg/WebConfig.java         | 2 --
 .../org/apache/dubbo/apidocs/controller/DubboApiDocsController.java   | 4 +---
 .../java/org/apache/dubbo/apidocs/controller/vo/ApiInfoRequest.java   | 2 --
 .../apache/dubbo/apidocs/controller/vo/CallDubboServiceRequest.java   | 2 --
 .../apidocs/controller/vo/CallDubboServiceRequestInterfaceParam.java  | 2 --
 .../main/java/org/apache/dubbo/apidocs/editor/CustomDateEditor.java   | 2 --
 .../java/org/apache/dubbo/apidocs/editor/CustomLocalDateEditor.java   | 2 --
 .../org/apache/dubbo/apidocs/editor/CustomLocalDateTimeEditor.java    | 2 --
 .../main/java/org/apache/dubbo/apidocs/utils/DubboGenericUtil.java    | 4 +---
 .../main/java/org/apache/dubbo/apidocs/utils/LocalDateTimeUtil.java   | 2 --
 47 files changed, 2 insertions(+), 105 deletions(-)

diff --git a/dubbo-api-docs/dubbo-api-docs-annotations/src/main/java/org/apache/dubbo/apidocs/annotations/ApiDoc.java b/dubbo-api-docs/dubbo-api-docs-annotations/src/main/java/org/apache/dubbo/apidocs/annotations/ApiDoc.java
index f55c4c9..6417f4d 100644
--- a/dubbo-api-docs/dubbo-api-docs-annotations/src/main/java/org/apache/dubbo/apidocs/annotations/ApiDoc.java
+++ b/dubbo-api-docs/dubbo-api-docs-annotations/src/main/java/org/apache/dubbo/apidocs/annotations/ApiDoc.java
@@ -24,8 +24,6 @@ import java.lang.annotation.Target;
 
 /**
  * dubbo api docs annotation,use to label of api.
- * @author klw(213539@qq.com)
- * 2020/10/29 14:46
  */
 @Retention(RetentionPolicy.RUNTIME)
 @Target({ElementType.METHOD})
diff --git a/dubbo-api-docs/dubbo-api-docs-annotations/src/main/java/org/apache/dubbo/apidocs/annotations/ApiModule.java b/dubbo-api-docs/dubbo-api-docs-annotations/src/main/java/org/apache/dubbo/apidocs/annotations/ApiModule.java
index 27d2bdc..0f97eaa 100644
--- a/dubbo-api-docs/dubbo-api-docs-annotations/src/main/java/org/apache/dubbo/apidocs/annotations/ApiModule.java
+++ b/dubbo-api-docs/dubbo-api-docs-annotations/src/main/java/org/apache/dubbo/apidocs/annotations/ApiModule.java
@@ -24,8 +24,6 @@ import java.lang.annotation.Target;
 
 /**
  * api module, used to mark the purpose of an interface class module.
- * @author klw(213539@qq.com)
- * 2020/10/29 14:51
  */
 @Retention(RetentionPolicy.RUNTIME)
 @Target({ElementType.TYPE})
diff --git a/dubbo-api-docs/dubbo-api-docs-annotations/src/main/java/org/apache/dubbo/apidocs/annotations/RequestParam.java b/dubbo-api-docs/dubbo-api-docs-annotations/src/main/java/org/apache/dubbo/apidocs/annotations/RequestParam.java
index a42f765..13a8fd0 100644
--- a/dubbo-api-docs/dubbo-api-docs-annotations/src/main/java/org/apache/dubbo/apidocs/annotations/RequestParam.java
+++ b/dubbo-api-docs/dubbo-api-docs-annotations/src/main/java/org/apache/dubbo/apidocs/annotations/RequestParam.java
@@ -25,8 +25,6 @@ import java.lang.annotation.Target;
 
 /**
  * Dimension request parameter.
- * @author klw(213539@qq.com)
- * 2020/10/29 14:48
  */
 @Retention(RetentionPolicy.RUNTIME)
 @Target({ElementType.FIELD, ElementType.PARAMETER})
diff --git a/dubbo-api-docs/dubbo-api-docs-annotations/src/main/java/org/apache/dubbo/apidocs/annotations/ResponseProperty.java b/dubbo-api-docs/dubbo-api-docs-annotations/src/main/java/org/apache/dubbo/apidocs/annotations/ResponseProperty.java
index f18c184..23641b2 100644
--- a/dubbo-api-docs/dubbo-api-docs-annotations/src/main/java/org/apache/dubbo/apidocs/annotations/ResponseProperty.java
+++ b/dubbo-api-docs/dubbo-api-docs-annotations/src/main/java/org/apache/dubbo/apidocs/annotations/ResponseProperty.java
@@ -25,8 +25,6 @@ import java.lang.annotation.Target;
 
 /**
  * Dimension response property.
- * @author klw(213539@qq.com)
- * 2020/10/29 14:50
  */
 @Retention(RetentionPolicy.RUNTIME)
 @Target({ElementType.FIELD})
diff --git a/dubbo-api-docs/dubbo-api-docs-core/src/main/java/org/apache/dubbo/apidocs/EnableDubboApiDocs.java b/dubbo-api-docs/dubbo-api-docs-core/src/main/java/org/apache/dubbo/apidocs/EnableDubboApiDocs.java
index 435a056..667c649 100644
--- a/dubbo-api-docs/dubbo-api-docs-core/src/main/java/org/apache/dubbo/apidocs/EnableDubboApiDocs.java
+++ b/dubbo-api-docs/dubbo-api-docs-core/src/main/java/org/apache/dubbo/apidocs/EnableDubboApiDocs.java
@@ -28,8 +28,6 @@ import java.lang.annotation.Target;
 
 /**
  * Enable dubbo api doc.
- * @author klw(213539@qq.com)
- * 2020/10/29 17:48
  */
 @Retention(RetentionPolicy.RUNTIME)
 @Target({ElementType.TYPE})
diff --git a/dubbo-api-docs/dubbo-api-docs-core/src/main/java/org/apache/dubbo/apidocs/core/DubboApiDocsAnnotationScanner.java b/dubbo-api-docs/dubbo-api-docs-core/src/main/java/org/apache/dubbo/apidocs/core/DubboApiDocsAnnotationScanner.java
index 94c2e88..b357068 100644
--- a/dubbo-api-docs/dubbo-api-docs-core/src/main/java/org/apache/dubbo/apidocs/core/DubboApiDocsAnnotationScanner.java
+++ b/dubbo-api-docs/dubbo-api-docs-core/src/main/java/org/apache/dubbo/apidocs/core/DubboApiDocsAnnotationScanner.java
@@ -52,9 +52,6 @@ import java.util.Map;
 
 /**
  * Scan and process dubbo doc annotations.
- *
- * @author klw(213539 @ qq.com)
- * 2020/10/29 17:55
  */
 @Slf4j
 @Import({DubboDocProviderImpl.class})
diff --git a/dubbo-api-docs/dubbo-api-docs-core/src/main/java/org/apache/dubbo/apidocs/core/DubboApiDocsCache.java b/dubbo-api-docs/dubbo-api-docs-core/src/main/java/org/apache/dubbo/apidocs/core/DubboApiDocsCache.java
index 36304f2..3aede0e 100644
--- a/dubbo-api-docs/dubbo-api-docs-core/src/main/java/org/apache/dubbo/apidocs/core/DubboApiDocsCache.java
+++ b/dubbo-api-docs/dubbo-api-docs-core/src/main/java/org/apache/dubbo/apidocs/core/DubboApiDocsCache.java
@@ -29,9 +29,6 @@ import java.util.concurrent.ConcurrentHashMap;
 
 /**
  * dubbo doc cache.
- *
- * @author klw(213539 @ qq.com)
- * 2020/10/29 17:40
  */
 public class DubboApiDocsCache {
 
diff --git a/dubbo-api-docs/dubbo-api-docs-core/src/main/java/org/apache/dubbo/apidocs/core/beans/ApiCacheItem.java b/dubbo-api-docs/dubbo-api-docs-core/src/main/java/org/apache/dubbo/apidocs/core/beans/ApiCacheItem.java
index 4732cef..853c89d 100644
--- a/dubbo-api-docs/dubbo-api-docs-core/src/main/java/org/apache/dubbo/apidocs/core/beans/ApiCacheItem.java
+++ b/dubbo-api-docs/dubbo-api-docs-core/src/main/java/org/apache/dubbo/apidocs/core/beans/ApiCacheItem.java
@@ -8,9 +8,6 @@ import java.util.Map;
 
 /**
  * api cache item.
- *
- * @author klw(213539 @ qq.com)
- * @date 2020/11/20 16:22
  */
 @Getter
 @Setter
diff --git a/dubbo-api-docs/dubbo-api-docs-core/src/main/java/org/apache/dubbo/apidocs/core/beans/ApiParamsCacheItem.java b/dubbo-api-docs/dubbo-api-docs-core/src/main/java/org/apache/dubbo/apidocs/core/beans/ApiParamsCacheItem.java
index 89880fe..8f0149f 100644
--- a/dubbo-api-docs/dubbo-api-docs-core/src/main/java/org/apache/dubbo/apidocs/core/beans/ApiParamsCacheItem.java
+++ b/dubbo-api-docs/dubbo-api-docs-core/src/main/java/org/apache/dubbo/apidocs/core/beans/ApiParamsCacheItem.java
@@ -7,9 +7,6 @@ import java.util.List;
 
 /**
  * api params cache item.
- *
- * @author klw(213539 @ qq.com)
- * @date 2020/11/20 16:46
  */
 @Getter
 @Setter
diff --git a/dubbo-api-docs/dubbo-api-docs-core/src/main/java/org/apache/dubbo/apidocs/core/beans/HtmlTypeEnum.java b/dubbo-api-docs/dubbo-api-docs-core/src/main/java/org/apache/dubbo/apidocs/core/beans/HtmlTypeEnum.java
index 37303d6..e5339f1 100644
--- a/dubbo-api-docs/dubbo-api-docs-core/src/main/java/org/apache/dubbo/apidocs/core/beans/HtmlTypeEnum.java
+++ b/dubbo-api-docs/dubbo-api-docs-core/src/main/java/org/apache/dubbo/apidocs/core/beans/HtmlTypeEnum.java
@@ -18,8 +18,6 @@ package org.apache.dubbo.apidocs.core.beans;
 
 /**
  * html type enum.
- * @author klw(213539@qq.com)
- * 2020/10/29 16:56
  */
 public enum HtmlTypeEnum {
 
diff --git a/dubbo-api-docs/dubbo-api-docs-core/src/main/java/org/apache/dubbo/apidocs/core/beans/ModuleCacheItem.java b/dubbo-api-docs/dubbo-api-docs-core/src/main/java/org/apache/dubbo/apidocs/core/beans/ModuleCacheItem.java
index cdf8b61..10a5133 100644
--- a/dubbo-api-docs/dubbo-api-docs-core/src/main/java/org/apache/dubbo/apidocs/core/beans/ModuleCacheItem.java
+++ b/dubbo-api-docs/dubbo-api-docs-core/src/main/java/org/apache/dubbo/apidocs/core/beans/ModuleCacheItem.java
@@ -7,9 +7,6 @@ import java.util.List;
 
 /**
  * api module cache item.
- *
- * @author klw(213539 @ qq.com)
- * @date 2020/11/20 15:21
  */
 @Getter
 @Setter
diff --git a/dubbo-api-docs/dubbo-api-docs-core/src/main/java/org/apache/dubbo/apidocs/core/beans/ParamBean.java b/dubbo-api-docs/dubbo-api-docs-core/src/main/java/org/apache/dubbo/apidocs/core/beans/ParamBean.java
index 02206ec..b3d1875 100644
--- a/dubbo-api-docs/dubbo-api-docs-core/src/main/java/org/apache/dubbo/apidocs/core/beans/ParamBean.java
+++ b/dubbo-api-docs/dubbo-api-docs-core/src/main/java/org/apache/dubbo/apidocs/core/beans/ParamBean.java
@@ -24,8 +24,6 @@ import java.util.List;
 
 /**
  * Parameter bean corresponding to {@link org.apache.dubbo.apidocs.annotations.RequestParam}, for caching.
- * @author klw(213539@qq.com)
- * 2020/10/29 17:32
  */
 @Getter
 @Setter
diff --git a/dubbo-api-docs/dubbo-api-docs-core/src/main/java/org/apache/dubbo/apidocs/core/providers/DubboDocProviderImpl.java b/dubbo-api-docs/dubbo-api-docs-core/src/main/java/org/apache/dubbo/apidocs/core/providers/DubboDocProviderImpl.java
index 92b24ca..5f93bef 100644
--- a/dubbo-api-docs/dubbo-api-docs-core/src/main/java/org/apache/dubbo/apidocs/core/providers/DubboDocProviderImpl.java
+++ b/dubbo-api-docs/dubbo-api-docs-core/src/main/java/org/apache/dubbo/apidocs/core/providers/DubboDocProviderImpl.java
@@ -26,8 +26,6 @@ import java.util.List;
 
 /**
  * The api implementation of Dubbo doc.
- * @author klw(213539@qq.com)
- * 2020/10/29 17:38
  */
 @Slf4j
 @DubboService
diff --git a/dubbo-api-docs/dubbo-api-docs-core/src/main/java/org/apache/dubbo/apidocs/core/providers/IDubboDocProvider.java b/dubbo-api-docs/dubbo-api-docs-core/src/main/java/org/apache/dubbo/apidocs/core/providers/IDubboDocProvider.java
index 92bb416..050f698 100644
--- a/dubbo-api-docs/dubbo-api-docs-core/src/main/java/org/apache/dubbo/apidocs/core/providers/IDubboDocProvider.java
+++ b/dubbo-api-docs/dubbo-api-docs-core/src/main/java/org/apache/dubbo/apidocs/core/providers/IDubboDocProvider.java
@@ -22,8 +22,6 @@ import java.util.List;
 
 /**
  * The api used by Dubbo doc, get the parsed API information.
- * @author klw(213539@qq.com)
- * 2020/10/29 16:57
  */
 public interface IDubboDocProvider {
 
diff --git a/dubbo-api-docs/dubbo-api-docs-core/src/main/java/org/apache/dubbo/apidocs/utils/ClassTypeUtil.java b/dubbo-api-docs/dubbo-api-docs-core/src/main/java/org/apache/dubbo/apidocs/utils/ClassTypeUtil.java
index 137b908..199b742 100644
--- a/dubbo-api-docs/dubbo-api-docs-core/src/main/java/org/apache/dubbo/apidocs/utils/ClassTypeUtil.java
+++ b/dubbo-api-docs/dubbo-api-docs-core/src/main/java/org/apache/dubbo/apidocs/utils/ClassTypeUtil.java
@@ -32,9 +32,6 @@ import org.apache.dubbo.apidocs.annotations.*;
 
 /**
  * Java class tool class, special for Dubbo doc.
- *
- * @author klw(213539 @ qq.com)
- * 2020/10/29 18:08
  */
 @Slf4j
 public class ClassTypeUtil {
diff --git a/dubbo-api-docs/dubbo-api-docs-core/src/main/java/org/apache/dubbo/apidocs/utils/SimpleTypeImpl.java b/dubbo-api-docs/dubbo-api-docs-core/src/main/java/org/apache/dubbo/apidocs/utils/SimpleTypeImpl.java
index a71a468..d48fa74 100644
--- a/dubbo-api-docs/dubbo-api-docs-core/src/main/java/org/apache/dubbo/apidocs/utils/SimpleTypeImpl.java
+++ b/dubbo-api-docs/dubbo-api-docs-core/src/main/java/org/apache/dubbo/apidocs/utils/SimpleTypeImpl.java
@@ -4,8 +4,6 @@ import java.lang.reflect.Type;
 
 /**
  * Simple implementation of {@link Type}.
- * @author klw(213539@qq.com)
- * 2020/10/29 14:55
  */
 public class SimpleTypeImpl implements Type {
 
diff --git a/dubbo-api-docs/dubbo-api-docs-examples/examples-api/src/main/java/org/apache/dubbo/apidocs/examples/api/IAsyncDemo.java b/dubbo-api-docs/dubbo-api-docs-examples/examples-api/src/main/java/org/apache/dubbo/apidocs/examples/api/IAsyncDemo.java
index 50426ce..31a6294 100644
--- a/dubbo-api-docs/dubbo-api-docs-examples/examples-api/src/main/java/org/apache/dubbo/apidocs/examples/api/IAsyncDemo.java
+++ b/dubbo-api-docs/dubbo-api-docs-examples/examples-api/src/main/java/org/apache/dubbo/apidocs/examples/api/IAsyncDemo.java
@@ -28,8 +28,6 @@ import java.util.concurrent.CompletableFuture;
 
 /**
  * asynchronous demo.
- * @author klw(213539@qq.com)
- * 2020/10/30 10:13
  */
 public interface IAsyncDemo {
 
diff --git a/dubbo-api-docs/dubbo-api-docs-examples/examples-api/src/main/java/org/apache/dubbo/apidocs/examples/api/ISyncDemo.java b/dubbo-api-docs/dubbo-api-docs-examples/examples-api/src/main/java/org/apache/dubbo/apidocs/examples/api/ISyncDemo.java
index 9cf5255..e1e8b40 100644
--- a/dubbo-api-docs/dubbo-api-docs-examples/examples-api/src/main/java/org/apache/dubbo/apidocs/examples/api/ISyncDemo.java
+++ b/dubbo-api-docs/dubbo-api-docs-examples/examples-api/src/main/java/org/apache/dubbo/apidocs/examples/api/ISyncDemo.java
@@ -28,8 +28,6 @@ import java.util.Map;
 
 /**
  * synchronization demo.
- * @author klw(213539@qq.com)
- * 2020/10/30 10:13
  */
 public interface ISyncDemo {
 
diff --git a/dubbo-api-docs/dubbo-api-docs-examples/examples-api/src/main/java/org/apache/dubbo/apidocs/examples/params/DemoParamBean1.java b/dubbo-api-docs/dubbo-api-docs-examples/examples-api/src/main/java/org/apache/dubbo/apidocs/examples/params/DemoParamBean1.java
index b1025ea..f2b0c97 100644
--- a/dubbo-api-docs/dubbo-api-docs-examples/examples-api/src/main/java/org/apache/dubbo/apidocs/examples/params/DemoParamBean1.java
+++ b/dubbo-api-docs/dubbo-api-docs-examples/examples-api/src/main/java/org/apache/dubbo/apidocs/examples/params/DemoParamBean1.java
@@ -26,8 +26,6 @@ import java.util.Map;
 
 /**
  * demo request bean.
- * @author klw(213539@qq.com)
- * 2020/10/30 9:58
  */
 @Getter
 @Setter
diff --git a/dubbo-api-docs/dubbo-api-docs-examples/examples-api/src/main/java/org/apache/dubbo/apidocs/examples/params/DemoParamBean1SubBean1.java b/dubbo-api-docs/dubbo-api-docs-examples/examples-api/src/main/java/org/apache/dubbo/apidocs/examples/params/DemoParamBean1SubBean1.java
index d12f73f..2ce694a 100644
--- a/dubbo-api-docs/dubbo-api-docs-examples/examples-api/src/main/java/org/apache/dubbo/apidocs/examples/params/DemoParamBean1SubBean1.java
+++ b/dubbo-api-docs/dubbo-api-docs-examples/examples-api/src/main/java/org/apache/dubbo/apidocs/examples/params/DemoParamBean1SubBean1.java
@@ -23,8 +23,6 @@ import lombok.Setter;
 
 /**
  * Attribute bean in DemoParamBean1.
- * @author klw(213539@qq.com)
- * 2020/10/30 9:49
  */
 @Getter
 @Setter
diff --git a/dubbo-api-docs/dubbo-api-docs-examples/examples-api/src/main/java/org/apache/dubbo/apidocs/examples/params/DemoParamBean2.java b/dubbo-api-docs/dubbo-api-docs-examples/examples-api/src/main/java/org/apache/dubbo/apidocs/examples/params/DemoParamBean2.java
index 52a64ba..81a3312 100644
--- a/dubbo-api-docs/dubbo-api-docs-examples/examples-api/src/main/java/org/apache/dubbo/apidocs/examples/params/DemoParamBean2.java
+++ b/dubbo-api-docs/dubbo-api-docs-examples/examples-api/src/main/java/org/apache/dubbo/apidocs/examples/params/DemoParamBean2.java
@@ -23,8 +23,6 @@ import lombok.Setter;
 
 /**
  * demo request bean 2.
- * @author klw(213539@qq.com)
- * 2020/10/30 9:57
  */
 @Getter
 @Setter
diff --git a/dubbo-api-docs/dubbo-api-docs-examples/examples-api/src/main/java/org/apache/dubbo/apidocs/examples/params/DemoParamBean3.java b/dubbo-api-docs/dubbo-api-docs-examples/examples-api/src/main/java/org/apache/dubbo/apidocs/examples/params/DemoParamBean3.java
index 9139197..5a5cf63 100644
--- a/dubbo-api-docs/dubbo-api-docs-examples/examples-api/src/main/java/org/apache/dubbo/apidocs/examples/params/DemoParamBean3.java
+++ b/dubbo-api-docs/dubbo-api-docs-examples/examples-api/src/main/java/org/apache/dubbo/apidocs/examples/params/DemoParamBean3.java
@@ -24,9 +24,6 @@ import lombok.Setter;
 
 /**
  * DemoParamBean3.
- *
- * @author klw(213539 @ qq.com)
- * @date 2020/11/13 9:56
  */
 @Getter
 @Setter
diff --git a/dubbo-api-docs/dubbo-api-docs-examples/examples-api/src/main/java/org/apache/dubbo/apidocs/examples/params/DemoParamBean4.java b/dubbo-api-docs/dubbo-api-docs-examples/examples-api/src/main/java/org/apache/dubbo/apidocs/examples/params/DemoParamBean4.java
index 6b5f716..0cc6ea9 100644
--- a/dubbo-api-docs/dubbo-api-docs-examples/examples-api/src/main/java/org/apache/dubbo/apidocs/examples/params/DemoParamBean4.java
+++ b/dubbo-api-docs/dubbo-api-docs-examples/examples-api/src/main/java/org/apache/dubbo/apidocs/examples/params/DemoParamBean4.java
@@ -24,9 +24,6 @@ import lombok.Setter;
 
 /**
  * DemoParamBean4.
- *
- * @author klw(213539 @ qq.com)
- * @date 2020/11/13 9:56
  */
 @Getter
 @Setter
diff --git a/dubbo-api-docs/dubbo-api-docs-examples/examples-api/src/main/java/org/apache/dubbo/apidocs/examples/params/TestBean.java b/dubbo-api-docs/dubbo-api-docs-examples/examples-api/src/main/java/org/apache/dubbo/apidocs/examples/params/TestBean.java
index 267ff7f..a655459 100644
--- a/dubbo-api-docs/dubbo-api-docs-examples/examples-api/src/main/java/org/apache/dubbo/apidocs/examples/params/TestBean.java
+++ b/dubbo-api-docs/dubbo-api-docs-examples/examples-api/src/main/java/org/apache/dubbo/apidocs/examples/params/TestBean.java
@@ -21,8 +21,6 @@ import lombok.Setter;
 
 /**
  * test.
- * @author klw(213539@qq.com)
- * 2020/10/30 9:57
  */
 @Getter
 @Setter
diff --git a/dubbo-api-docs/dubbo-api-docs-examples/examples-api/src/main/java/org/apache/dubbo/apidocs/examples/params/TestEnum.java b/dubbo-api-docs/dubbo-api-docs-examples/examples-api/src/main/java/org/apache/dubbo/apidocs/examples/params/TestEnum.java
index 38bb180..c21f137 100644
--- a/dubbo-api-docs/dubbo-api-docs-examples/examples-api/src/main/java/org/apache/dubbo/apidocs/examples/params/TestEnum.java
+++ b/dubbo-api-docs/dubbo-api-docs-examples/examples-api/src/main/java/org/apache/dubbo/apidocs/examples/params/TestEnum.java
@@ -18,8 +18,6 @@ package org.apache.dubbo.apidocs.examples.params;
 
 /**
  * Enumeration for test.
- * @author klw(213539@qq.com)
- * 2020/10/30 9:48
  */
 public enum TestEnum {
 
diff --git a/dubbo-api-docs/dubbo-api-docs-examples/examples-api/src/main/java/org/apache/dubbo/apidocs/examples/responses/BaseResponse.java b/dubbo-api-docs/dubbo-api-docs-examples/examples-api/src/main/java/org/apache/dubbo/apidocs/examples/responses/BaseResponse.java
index 59ef44b..e262827 100644
--- a/dubbo-api-docs/dubbo-api-docs-examples/examples-api/src/main/java/org/apache/dubbo/apidocs/examples/responses/BaseResponse.java
+++ b/dubbo-api-docs/dubbo-api-docs-examples/examples-api/src/main/java/org/apache/dubbo/apidocs/examples/responses/BaseResponse.java
@@ -22,8 +22,6 @@ import lombok.ToString;
 
 /**
  * BaseResponse.
- * @author klw(213539@qq.com)
- * 2020/10/30 9:46
  */
 @Getter
 @Setter
diff --git a/dubbo-api-docs/dubbo-api-docs-examples/examples-api/src/main/java/org/apache/dubbo/apidocs/examples/responses/DemoRespBean1.java b/dubbo-api-docs/dubbo-api-docs-examples/examples-api/src/main/java/org/apache/dubbo/apidocs/examples/responses/DemoRespBean1.java
index e8aec9c..657b4b7 100644
--- a/dubbo-api-docs/dubbo-api-docs-examples/examples-api/src/main/java/org/apache/dubbo/apidocs/examples/responses/DemoRespBean1.java
+++ b/dubbo-api-docs/dubbo-api-docs-examples/examples-api/src/main/java/org/apache/dubbo/apidocs/examples/responses/DemoRespBean1.java
@@ -26,8 +26,6 @@ import java.util.Map;
 
 /**
  * demo response bean 1.
- * @author klw(213539@qq.com)
- * 2020/10/30 9:56
  */
 @Getter
 @Setter
diff --git a/dubbo-api-docs/dubbo-api-docs-examples/examples-provider-sca/src/main/java/org/apache/dubbo/apidocs/examples/ExampleScaApplication.java b/dubbo-api-docs/dubbo-api-docs-examples/examples-provider-sca/src/main/java/org/apache/dubbo/apidocs/examples/ExampleScaApplication.java
index a6f600f..49e1888 100644
--- a/dubbo-api-docs/dubbo-api-docs-examples/examples-provider-sca/src/main/java/org/apache/dubbo/apidocs/examples/ExampleScaApplication.java
+++ b/dubbo-api-docs/dubbo-api-docs-examples/examples-provider-sca/src/main/java/org/apache/dubbo/apidocs/examples/ExampleScaApplication.java
@@ -25,8 +25,6 @@ import org.springframework.cloud.client.discovery.EnableDiscoveryClient;
 
 /**
  * example dubbo provider service using spring-cloud-starter-dubbo.
- * @author klw(213539@qq.com)
- * `2020/12/4` 17:48
  */
 @SpringBootApplication
 @EnableDiscoveryClient
diff --git a/dubbo-api-docs/dubbo-api-docs-examples/examples-provider-sca/src/main/java/org/apache/dubbo/apidocs/examples/api/impl/AsyncDemoImpl.java b/dubbo-api-docs/dubbo-api-docs-examples/examples-provider-sca/src/main/java/org/apache/dubbo/apidocs/examples/api/impl/AsyncDemoImpl.java
index b4f14fb..049e20b 100644
--- a/dubbo-api-docs/dubbo-api-docs-examples/examples-provider-sca/src/main/java/org/apache/dubbo/apidocs/examples/api/impl/AsyncDemoImpl.java
+++ b/dubbo-api-docs/dubbo-api-docs-examples/examples-provider-sca/src/main/java/org/apache/dubbo/apidocs/examples/api/impl/AsyncDemoImpl.java
@@ -33,8 +33,6 @@ import java.util.concurrent.Executors;
 
 /**
  * Asynchronous demo implementation.
- * @author klw(213539@qq.com)
- * 2020/12/4 17:53
  */
 @DubboService(async = true)
 @ApiModule(value = "Asynchronous demo", apiInterface = IAsyncDemo.class)
diff --git a/dubbo-api-docs/dubbo-api-docs-examples/examples-provider-sca/src/main/java/org/apache/dubbo/apidocs/examples/api/impl/SyncDemoImpl.java b/dubbo-api-docs/dubbo-api-docs-examples/examples-provider-sca/src/main/java/org/apache/dubbo/apidocs/examples/api/impl/SyncDemoImpl.java
index 60b6827..877c57b 100644
--- a/dubbo-api-docs/dubbo-api-docs-examples/examples-provider-sca/src/main/java/org/apache/dubbo/apidocs/examples/api/impl/SyncDemoImpl.java
+++ b/dubbo-api-docs/dubbo-api-docs-examples/examples-provider-sca/src/main/java/org/apache/dubbo/apidocs/examples/api/impl/SyncDemoImpl.java
@@ -35,8 +35,6 @@ import java.util.Map;
 
 /**
  * Synchronous demo implementation.
- * @author klw(213539@qq.com)
- * 2020/12/4 17:53
  */
 @Slf4j
 @DubboService
diff --git a/dubbo-api-docs/dubbo-api-docs-examples/examples-provider-sca/src/main/java/org/apache/dubbo/apidocs/examples/cfg/DubboDocConfig.java b/dubbo-api-docs/dubbo-api-docs-examples/examples-provider-sca/src/main/java/org/apache/dubbo/apidocs/examples/cfg/DubboDocConfig.java
index d832f7d..8db249d 100644
--- a/dubbo-api-docs/dubbo-api-docs-examples/examples-provider-sca/src/main/java/org/apache/dubbo/apidocs/examples/cfg/DubboDocConfig.java
+++ b/dubbo-api-docs/dubbo-api-docs-examples/examples-provider-sca/src/main/java/org/apache/dubbo/apidocs/examples/cfg/DubboDocConfig.java
@@ -23,8 +23,6 @@ import org.springframework.context.annotation.Profile;
 
 /**
  * dubbo doc config.
- * @author klw(213539@qq.com)
- * 2020/12/4 17:52
  */
 @Configuration
 // Enable dubbo api doc
diff --git a/dubbo-api-docs/dubbo-api-docs-examples/examples-provider/src/main/java/org/apache/dubbo/apidocs/examples/ExampleApplication.java b/dubbo-api-docs/dubbo-api-docs-examples/examples-provider/src/main/java/org/apache/dubbo/apidocs/examples/ExampleApplication.java
index 6d4039f..b893bbb 100644
--- a/dubbo-api-docs/dubbo-api-docs-examples/examples-provider/src/main/java/org/apache/dubbo/apidocs/examples/ExampleApplication.java
+++ b/dubbo-api-docs/dubbo-api-docs-examples/examples-provider/src/main/java/org/apache/dubbo/apidocs/examples/ExampleApplication.java
@@ -24,8 +24,6 @@ import org.springframework.boot.builder.SpringApplicationBuilder;
 
 /**
  * example dubbo provider service application.
- * @author klw(213539@qq.com)
- * 2020/10/30 14:54
  */
 @SpringBootApplication
 @EnableDubbo(scanBasePackages = {"org.apache.dubbo.apidocs.examples.api"})
diff --git a/dubbo-api-docs/dubbo-api-docs-examples/examples-provider/src/main/java/org/apache/dubbo/apidocs/examples/api/impl/AsyncDemoImpl.java b/dubbo-api-docs/dubbo-api-docs-examples/examples-provider/src/main/java/org/apache/dubbo/apidocs/examples/api/impl/AsyncDemoImpl.java
index bde2bf8..9a4b4c7 100644
--- a/dubbo-api-docs/dubbo-api-docs-examples/examples-provider/src/main/java/org/apache/dubbo/apidocs/examples/api/impl/AsyncDemoImpl.java
+++ b/dubbo-api-docs/dubbo-api-docs-examples/examples-provider/src/main/java/org/apache/dubbo/apidocs/examples/api/impl/AsyncDemoImpl.java
@@ -36,9 +36,6 @@ import java.util.concurrent.ScheduledThreadPoolExecutor;
 
 /**
  * Asynchronous demo implementation.
- *
- * @author klw(213539 @ qq.com)
- * 2020/10/30 14:54
  */
 @DubboService(async = true)
 @ApiModule(value = "Asynchronous demo", apiInterface = IAsyncDemo.class)
diff --git a/dubbo-api-docs/dubbo-api-docs-examples/examples-provider/src/main/java/org/apache/dubbo/apidocs/examples/api/impl/SyncDemoImpl.java b/dubbo-api-docs/dubbo-api-docs-examples/examples-provider/src/main/java/org/apache/dubbo/apidocs/examples/api/impl/SyncDemoImpl.java
index fd21ef4..0449688 100644
--- a/dubbo-api-docs/dubbo-api-docs-examples/examples-provider/src/main/java/org/apache/dubbo/apidocs/examples/api/impl/SyncDemoImpl.java
+++ b/dubbo-api-docs/dubbo-api-docs-examples/examples-provider/src/main/java/org/apache/dubbo/apidocs/examples/api/impl/SyncDemoImpl.java
@@ -35,8 +35,6 @@ import java.util.Map;
 
 /**
  * Synchronous demo implementation.
- * @author klw(213539@qq.com)
- * 2020/10/30 14:57
  */
 @Slf4j
 @DubboService
diff --git a/dubbo-api-docs/dubbo-api-docs-examples/examples-provider/src/main/java/org/apache/dubbo/apidocs/examples/cfg/DubboDocConfig.java b/dubbo-api-docs/dubbo-api-docs-examples/examples-provider/src/main/java/org/apache/dubbo/apidocs/examples/cfg/DubboDocConfig.java
index 29c0401..de479b7 100644
--- a/dubbo-api-docs/dubbo-api-docs-examples/examples-provider/src/main/java/org/apache/dubbo/apidocs/examples/cfg/DubboDocConfig.java
+++ b/dubbo-api-docs/dubbo-api-docs-examples/examples-provider/src/main/java/org/apache/dubbo/apidocs/examples/cfg/DubboDocConfig.java
@@ -23,8 +23,6 @@ import org.springframework.context.annotation.Profile;
 
 /**
  * dubbo doc config.
- * @author klw(213539@qq.com)
- * 2020/10/30 14:58
  */
 @Configuration
 @EnableDubboApiDocs
diff --git a/dubbo-api-docs/dubbo-api-docs-ui-server/src/main/java/org/apache/dubbo/apidocs/DubboApiDocsUiServerApplication.java b/dubbo-api-docs/dubbo-api-docs-ui-server/src/main/java/org/apache/dubbo/apidocs/DubboApiDocsUiServerApplication.java
index a8a7c65..8186ec1 100644
--- a/dubbo-api-docs/dubbo-api-docs-ui-server/src/main/java/org/apache/dubbo/apidocs/DubboApiDocsUiServerApplication.java
+++ b/dubbo-api-docs/dubbo-api-docs-ui-server/src/main/java/org/apache/dubbo/apidocs/DubboApiDocsUiServerApplication.java
@@ -23,8 +23,6 @@ import org.springframework.context.ConfigurableApplicationContext;
 
 /**
  * Start Dubbo doc ui server.
- * @author klw(213539@qq.com)
- * 2020/11/14 20:41
  */
 @SpringBootApplication
 public class DubboApiDocsUiServerApplication {
diff --git a/dubbo-api-docs/dubbo-api-docs-ui-server/src/main/java/org/apache/dubbo/apidocs/cfg/SwaggerConfig.java b/dubbo-api-docs/dubbo-api-docs-ui-server/src/main/java/org/apache/dubbo/apidocs/cfg/SwaggerConfig.java
index 5a1dbe9..1b3e15b 100644
--- a/dubbo-api-docs/dubbo-api-docs-ui-server/src/main/java/org/apache/dubbo/apidocs/cfg/SwaggerConfig.java
+++ b/dubbo-api-docs/dubbo-api-docs-ui-server/src/main/java/org/apache/dubbo/apidocs/cfg/SwaggerConfig.java
@@ -31,8 +31,6 @@ import springfox.documentation.swagger2.annotations.EnableSwagger2WebFlux;
 
 /**
  * swagger config.
- * @author klw(213539@qq.com)
- * 2020/11/14 20:42
  */
 @Configuration
 @EnableSwagger2
diff --git a/dubbo-api-docs/dubbo-api-docs-ui-server/src/main/java/org/apache/dubbo/apidocs/cfg/WebConfig.java b/dubbo-api-docs/dubbo-api-docs-ui-server/src/main/java/org/apache/dubbo/apidocs/cfg/WebConfig.java
index 87b4062..6cbb26f 100644
--- a/dubbo-api-docs/dubbo-api-docs-ui-server/src/main/java/org/apache/dubbo/apidocs/cfg/WebConfig.java
+++ b/dubbo-api-docs/dubbo-api-docs-ui-server/src/main/java/org/apache/dubbo/apidocs/cfg/WebConfig.java
@@ -24,8 +24,6 @@ import reactor.core.publisher.Mono;
 
 /**
  * web config.
- * @author klw(213539@qq.com)
- * 2020/11/14 20:44
  */
 @Component
 public class WebConfig implements WebFilter {
diff --git a/dubbo-api-docs/dubbo-api-docs-ui-server/src/main/java/org/apache/dubbo/apidocs/controller/DubboApiDocsController.java b/dubbo-api-docs/dubbo-api-docs-ui-server/src/main/java/org/apache/dubbo/apidocs/controller/DubboApiDocsController.java
index 0e84797..838cf8e 100644
--- a/dubbo-api-docs/dubbo-api-docs-ui-server/src/main/java/org/apache/dubbo/apidocs/controller/DubboApiDocsController.java
+++ b/dubbo-api-docs/dubbo-api-docs-ui-server/src/main/java/org/apache/dubbo/apidocs/controller/DubboApiDocsController.java
@@ -45,10 +45,8 @@ import java.util.concurrent.CompletableFuture;
 
 /**
  * dubbo doc ui server api.
- * @author klw(213539@qq.com)
- * 2020/11/14 20:23
  */
-@Api(tags = {"alita-restful-API--demoAPI"})
+@Api(tags = {"dubbo doc ui server api"})
 @RestController
 @Slf4j
 @RequestMapping("/api")
diff --git a/dubbo-api-docs/dubbo-api-docs-ui-server/src/main/java/org/apache/dubbo/apidocs/controller/vo/ApiInfoRequest.java b/dubbo-api-docs/dubbo-api-docs-ui-server/src/main/java/org/apache/dubbo/apidocs/controller/vo/ApiInfoRequest.java
index 5896de5..5f37b4d 100644
--- a/dubbo-api-docs/dubbo-api-docs-ui-server/src/main/java/org/apache/dubbo/apidocs/controller/vo/ApiInfoRequest.java
+++ b/dubbo-api-docs/dubbo-api-docs-ui-server/src/main/java/org/apache/dubbo/apidocs/controller/vo/ApiInfoRequest.java
@@ -22,8 +22,6 @@ import lombok.Setter;
 
 /**
  * Obtain the API module list and the request parameters of the API parameter information interface.
- * @author klw(213539@qq.com)
- * 2020/11/14 20:45
  */
 @Getter
 @Setter
diff --git a/dubbo-api-docs/dubbo-api-docs-ui-server/src/main/java/org/apache/dubbo/apidocs/controller/vo/CallDubboServiceRequest.java b/dubbo-api-docs/dubbo-api-docs-ui-server/src/main/java/org/apache/dubbo/apidocs/controller/vo/CallDubboServiceRequest.java
index f81653c..741fdde 100644
--- a/dubbo-api-docs/dubbo-api-docs-ui-server/src/main/java/org/apache/dubbo/apidocs/controller/vo/CallDubboServiceRequest.java
+++ b/dubbo-api-docs/dubbo-api-docs-ui-server/src/main/java/org/apache/dubbo/apidocs/controller/vo/CallDubboServiceRequest.java
@@ -23,8 +23,6 @@ import lombok.Setter;
 
 /**
  * Call Dubbo api to request parameters.
- * @author klw(213539@qq.com)
- * 2020/11/14 20:46
  */
 @Getter
 @Setter
diff --git a/dubbo-api-docs/dubbo-api-docs-ui-server/src/main/java/org/apache/dubbo/apidocs/controller/vo/CallDubboServiceRequestInterfaceParam.java b/dubbo-api-docs/dubbo-api-docs-ui-server/src/main/java/org/apache/dubbo/apidocs/controller/vo/CallDubboServiceRequestInterfaceParam.java
index 44f3bce..7b318ae 100644
--- a/dubbo-api-docs/dubbo-api-docs-ui-server/src/main/java/org/apache/dubbo/apidocs/controller/vo/CallDubboServiceRequestInterfaceParam.java
+++ b/dubbo-api-docs/dubbo-api-docs-ui-server/src/main/java/org/apache/dubbo/apidocs/controller/vo/CallDubboServiceRequestInterfaceParam.java
@@ -22,8 +22,6 @@ import lombok.Setter;
 
 /**
  * Parameters passed to duboo service api.
- * @author klw(213539@qq.com)
- * 2020/11/14 20:46
  */
 @Getter
 @Setter
diff --git a/dubbo-api-docs/dubbo-api-docs-ui-server/src/main/java/org/apache/dubbo/apidocs/editor/CustomDateEditor.java b/dubbo-api-docs/dubbo-api-docs-ui-server/src/main/java/org/apache/dubbo/apidocs/editor/CustomDateEditor.java
index f29bced..c11efd1 100644
--- a/dubbo-api-docs/dubbo-api-docs-ui-server/src/main/java/org/apache/dubbo/apidocs/editor/CustomDateEditor.java
+++ b/dubbo-api-docs/dubbo-api-docs-ui-server/src/main/java/org/apache/dubbo/apidocs/editor/CustomDateEditor.java
@@ -28,8 +28,6 @@ import java.util.regex.Pattern;
 
 /**
  * Date editor for controller.
- * @author klw(213539@qq.com)
- * 2020/11/14 20:47
  */
 public class CustomDateEditor extends PropertyEditorSupport {
 
diff --git a/dubbo-api-docs/dubbo-api-docs-ui-server/src/main/java/org/apache/dubbo/apidocs/editor/CustomLocalDateEditor.java b/dubbo-api-docs/dubbo-api-docs-ui-server/src/main/java/org/apache/dubbo/apidocs/editor/CustomLocalDateEditor.java
index 08fb508..291e98b 100644
--- a/dubbo-api-docs/dubbo-api-docs-ui-server/src/main/java/org/apache/dubbo/apidocs/editor/CustomLocalDateEditor.java
+++ b/dubbo-api-docs/dubbo-api-docs-ui-server/src/main/java/org/apache/dubbo/apidocs/editor/CustomLocalDateEditor.java
@@ -25,8 +25,6 @@ import java.time.format.DateTimeFormatter;
 
 /**
  * Localdate editor for controller.
- * @author klw(213539@qq.com)
- * 2020/11/14 20:59
  */
 public class CustomLocalDateEditor extends PropertyEditorSupport {
 
diff --git a/dubbo-api-docs/dubbo-api-docs-ui-server/src/main/java/org/apache/dubbo/apidocs/editor/CustomLocalDateTimeEditor.java b/dubbo-api-docs/dubbo-api-docs-ui-server/src/main/java/org/apache/dubbo/apidocs/editor/CustomLocalDateTimeEditor.java
index 6f87a54..5d5c84a 100644
--- a/dubbo-api-docs/dubbo-api-docs-ui-server/src/main/java/org/apache/dubbo/apidocs/editor/CustomLocalDateTimeEditor.java
+++ b/dubbo-api-docs/dubbo-api-docs-ui-server/src/main/java/org/apache/dubbo/apidocs/editor/CustomLocalDateTimeEditor.java
@@ -25,8 +25,6 @@ import java.time.format.DateTimeFormatter;
 
 /**
  * LocalDateTime editor for controller.
- * @author klw(213539@qq.com)
- * 2020/11/14 20:59
  */
 public class CustomLocalDateTimeEditor extends PropertyEditorSupport {
 
diff --git a/dubbo-api-docs/dubbo-api-docs-ui-server/src/main/java/org/apache/dubbo/apidocs/utils/DubboGenericUtil.java b/dubbo-api-docs/dubbo-api-docs-ui-server/src/main/java/org/apache/dubbo/apidocs/utils/DubboGenericUtil.java
index 6d98388..fac8fce 100644
--- a/dubbo-api-docs/dubbo-api-docs-ui-server/src/main/java/org/apache/dubbo/apidocs/utils/DubboGenericUtil.java
+++ b/dubbo-api-docs/dubbo-api-docs-ui-server/src/main/java/org/apache/dubbo/apidocs/utils/DubboGenericUtil.java
@@ -31,8 +31,6 @@ import java.util.concurrent.Executors;
 
 /**
  * Dubbo operation related tool class.
- * @author klw(213539@qq.com)
- * 2020/11/14 21:00
  */
 public class DubboGenericUtil {
 
@@ -67,7 +65,7 @@ public class DubboGenericUtil {
         // T (number of threads) = N (number of server cores) * u (expected CPU utilization) * (1 + E (waiting time) / C (calculation time))
         executor = Executors.newFixedThreadPool(Runtime.getRuntime().availableProcessors() * 40 * (1 + 5 / 2));
         application = new ApplicationConfig();
-        application.setName("alita-dubbo-debug-tool");
+        application.setName("dubbo-api-docs");
         registryConfigCache = new ConcurrentHashMap<>();
         referenceCache = new ConcurrentHashMap<>();
     }
diff --git a/dubbo-api-docs/dubbo-api-docs-ui-server/src/main/java/org/apache/dubbo/apidocs/utils/LocalDateTimeUtil.java b/dubbo-api-docs/dubbo-api-docs-ui-server/src/main/java/org/apache/dubbo/apidocs/utils/LocalDateTimeUtil.java
index 0fd69e8..2568ac7 100644
--- a/dubbo-api-docs/dubbo-api-docs-ui-server/src/main/java/org/apache/dubbo/apidocs/utils/LocalDateTimeUtil.java
+++ b/dubbo-api-docs/dubbo-api-docs-ui-server/src/main/java/org/apache/dubbo/apidocs/utils/LocalDateTimeUtil.java
@@ -25,8 +25,6 @@ import java.util.Date;
 
 /**
  * Date time tool class of LocalDateTime.
- * @author klw(213539@qq.com)
- * 2020/11/14 21:02
  */
 public class LocalDateTimeUtil {
 


[dubbo-spi-extensions] 34/39: fix #10 中的问题 fix #7 增加BigDecimal, BigInteger的支持

Posted by li...@apache.org.
This is an automated email from the ASF dual-hosted git repository.

liujun pushed a commit to branch 2.7.x
in repository https://gitbox.apache.org/repos/asf/dubbo-spi-extensions.git

commit 9efb793dd333143a93f437a49ab9cc581de21052
Author: qq213539 <21...@qq.com>
AuthorDate: Fri Jan 29 18:19:22 2021 +0800

    fix #10 中的问题
    fix #7 增加BigDecimal, BigInteger的支持
---
 .../apache/dubbo/apidocs/annotations/ApiDoc.java   |   1 +
 .../dubbo/apidocs/annotations/ApiModule.java       |   1 +
 .../core/DubboApiDocsAnnotationScanner.java        | 111 +++++++++++++--------
 .../core/providers/DubboDocProviderImpl.java       |   4 -
 .../apache/dubbo/apidocs/utils/ClassTypeUtil.java  |  41 +++++---
 .../apidocs/examples/api/IQuickStartDemo.java      |  21 +++-
 .../examples/params/QuickStartRequestBase.java     |   4 +-
 .../examples/params/QuickStartRequestBean.java     |   4 +-
 ...equestBean.java => QuickStartRequestBean2.java} |  39 ++++----
 .../examples/params/QuickStartRespBean.java        |   4 +-
 .../examples/api/impl/QuickStartDemoImpl.java      |  32 ++++--
 .../src/main/resources/application.yml             |   5 +-
 12 files changed, 172 insertions(+), 95 deletions(-)

diff --git a/dubbo-api-docs/dubbo-api-docs-annotations/src/main/java/org/apache/dubbo/apidocs/annotations/ApiDoc.java b/dubbo-api-docs/dubbo-api-docs-annotations/src/main/java/org/apache/dubbo/apidocs/annotations/ApiDoc.java
index 6417f4d..7f0aafb 100644
--- a/dubbo-api-docs/dubbo-api-docs-annotations/src/main/java/org/apache/dubbo/apidocs/annotations/ApiDoc.java
+++ b/dubbo-api-docs/dubbo-api-docs-annotations/src/main/java/org/apache/dubbo/apidocs/annotations/ApiDoc.java
@@ -43,6 +43,7 @@ public @interface ApiDoc {
     /**
      * api version.
      */
+    @Deprecated
     String version() default "";
 
     /**
diff --git a/dubbo-api-docs/dubbo-api-docs-annotations/src/main/java/org/apache/dubbo/apidocs/annotations/ApiModule.java b/dubbo-api-docs/dubbo-api-docs-annotations/src/main/java/org/apache/dubbo/apidocs/annotations/ApiModule.java
index 0f97eaa..d3f6f29 100644
--- a/dubbo-api-docs/dubbo-api-docs-annotations/src/main/java/org/apache/dubbo/apidocs/annotations/ApiModule.java
+++ b/dubbo-api-docs/dubbo-api-docs-annotations/src/main/java/org/apache/dubbo/apidocs/annotations/ApiModule.java
@@ -43,6 +43,7 @@ public @interface ApiModule {
     /**
      * module version
      */
+    @Deprecated
     String version() default "";
 
 }
diff --git a/dubbo-api-docs/dubbo-api-docs-core/src/main/java/org/apache/dubbo/apidocs/core/DubboApiDocsAnnotationScanner.java b/dubbo-api-docs/dubbo-api-docs-core/src/main/java/org/apache/dubbo/apidocs/core/DubboApiDocsAnnotationScanner.java
index e8a8565..5878d3c 100644
--- a/dubbo-api-docs/dubbo-api-docs-core/src/main/java/org/apache/dubbo/apidocs/core/DubboApiDocsAnnotationScanner.java
+++ b/dubbo-api-docs/dubbo-api-docs-core/src/main/java/org/apache/dubbo/apidocs/core/DubboApiDocsAnnotationScanner.java
@@ -51,6 +51,8 @@ import java.lang.reflect.Method;
 import java.lang.reflect.Parameter;
 import java.lang.reflect.Type;
 import java.lang.reflect.TypeVariable;
+import java.math.BigDecimal;
+import java.math.BigInteger;
 import java.util.ArrayList;
 import java.util.HashMap;
 import java.util.List;
@@ -100,13 +102,17 @@ public class DubboApiDocsAnnotationScanner implements ApplicationListener<Applic
                 return;
             }
             boolean async;
+            String apiVersion;
             if (apiModuleClass.isAnnotationPresent(Service.class)) {
                 Service dubboService = apiModuleClass.getAnnotation(Service.class);
                 async = dubboService.async();
+                apiVersion = dubboService.version();
             } else {
                 DubboService dubboService = apiModuleClass.getAnnotation(DubboService.class);
                 async = dubboService.async();
+                apiVersion = dubboService.version();
             }
+            apiVersion = applicationContext.getEnvironment().resolvePlaceholders(apiVersion);
             ModuleCacheItem moduleCacheItem = new ModuleCacheItem();
             DubboApiDocsCache.addApiModule(moduleAnn.apiInterface().getCanonicalName(), moduleCacheItem);
             //module name
@@ -114,7 +120,7 @@ public class DubboApiDocsAnnotationScanner implements ApplicationListener<Applic
             //interface name containing package path
             moduleCacheItem.setModuleClassName(moduleAnn.apiInterface().getCanonicalName());
             //module version
-            moduleCacheItem.setModuleVersion(moduleAnn.version());
+            moduleCacheItem.setModuleVersion(apiVersion);
 
             Method[] apiModuleMethods = apiModuleClass.getMethods();
             // API basic information list in module cache
@@ -122,7 +128,7 @@ public class DubboApiDocsAnnotationScanner implements ApplicationListener<Applic
             moduleCacheItem.setModuleApiList(moduleApiList);
             for (Method method : apiModuleMethods) {
                 if (method.isAnnotationPresent(ApiDoc.class)) {
-                    processApiDocAnnotation(method, moduleApiList, moduleAnn, async, moduleCacheItem);
+                    processApiDocAnnotation(method, moduleApiList, moduleAnn, async, moduleCacheItem, apiVersion);
                 }
             }
         });
@@ -130,7 +136,7 @@ public class DubboApiDocsAnnotationScanner implements ApplicationListener<Applic
     }
 
     private void processApiDocAnnotation(Method method, List<ApiCacheItem> moduleApiList, ApiModule moduleAnn,
-                                         boolean async, ModuleCacheItem moduleCacheItem) {
+                                         boolean async, ModuleCacheItem moduleCacheItem, String apiVersion) {
 
         ApiDoc dubboApi = method.getAnnotation(ApiDoc.class);
 
@@ -144,7 +150,7 @@ public class DubboApiDocsAnnotationScanner implements ApplicationListener<Applic
         // API description
         apiListItem.setDescription(dubboApi.description());
         //API version
-        apiListItem.setApiVersion(dubboApi.version());
+        apiListItem.setApiVersion(apiVersion);
         //Description of API return data
         apiListItem.setApiRespDec(dubboApi.responseClassDescription());
 
@@ -161,7 +167,7 @@ public class DubboApiDocsAnnotationScanner implements ApplicationListener<Applic
         apiParamsAndResp.setAsync(async);
         apiParamsAndResp.setApiName(method.getName());
         apiParamsAndResp.setApiDocName(dubboApi.value());
-        apiParamsAndResp.setApiVersion(dubboApi.version());
+        apiParamsAndResp.setApiVersion(apiVersion);
         apiParamsAndResp.setApiRespDec(dubboApi.responseClassDescription());
         apiParamsAndResp.setDescription(dubboApi.description());
         apiParamsAndResp.setApiModelClass(moduleCacheItem.getModuleClassName());
@@ -188,15 +194,15 @@ public class DubboApiDocsAnnotationScanner implements ApplicationListener<Applic
                 }
             }
             ParamBean paramBean = this.processHtmlType(argClass, requestParam, null);
+            Parameter methodParameter = parameters[i];
             if (paramBean == null) {
                 // Not a basic type, handling properties in method parameters
-                List<ParamBean> apiParamsList = processField(argClass, parameterType);
+                List<ParamBean> apiParamsList = processField(argClass, parameterType, methodParameter);
                 if (apiParamsList != null && !apiParamsList.isEmpty()) {
                     paramListItem.setParamInfo(apiParamsList);
                 }
             } else {
                 // Is the basic type
-                Parameter methodParameter = parameters[i];
                 paramListItem.setName(methodParameter.getName());
                 paramListItem.setHtmlType(paramBean.getHtmlType().name());
                 paramListItem.setAllowableValues(paramBean.getAllowableValues());
@@ -219,7 +225,7 @@ public class DubboApiDocsAnnotationScanner implements ApplicationListener<Applic
      * For the attributes in the method parameters, only one layer is processed.
      * The deeper layer is directly converted to JSON, and the deeper layer is up to 5 layers
      */
-    private List<ParamBean> processField(Class<?> argClass, Type parameterType) {
+    private List<ParamBean> processField(Class<?> argClass, Type parameterType, Parameter parameter) {
         Map<String, String> genericTypeAndNamesMap;
         if (parameterType instanceof ParameterizedTypeImpl) {
             ParameterizedTypeImpl parameterTypeImpl = (ParameterizedTypeImpl) parameterType;
@@ -227,8 +233,7 @@ public class DubboApiDocsAnnotationScanner implements ApplicationListener<Applic
             Type[] actualTypeArguments = parameterTypeImpl.getActualTypeArguments();
             genericTypeAndNamesMap =  new HashMap<>(typeVariables.length);
             for (int i = 0; i < typeVariables.length; i++) {
-                TypeVariable<? extends Class<?>> typeVariable = typeVariables[i];
-                genericTypeAndNamesMap.put(typeVariable.getTypeName(), actualTypeArguments[i].getTypeName());
+                genericTypeAndNamesMap.put(typeVariables[i].getTypeName(), actualTypeArguments[i].getTypeName());
             }
         } else {
             genericTypeAndNamesMap =  new HashMap<>(0);
@@ -237,25 +242,59 @@ public class DubboApiDocsAnnotationScanner implements ApplicationListener<Applic
         List<ParamBean> apiParamsList = new ArrayList(16);
         // get all fields
         List<Field> allFields = ClassTypeUtil.getAllFields(null, argClass);
-        for (Field field : allFields) {
-            ParamBean paramBean = new ParamBean();
-            paramBean.setName(field.getName());
-            String genericTypeName = genericTypeAndNamesMap.get(field.getGenericType().getTypeName());
-            Class<?> genericType = null;
-            if (StringUtils.isBlank(genericTypeName)) {
-                paramBean.setJavaType(field.getType().getCanonicalName());
-            } else {
-                paramBean.setJavaType(genericTypeName);
-                try {
-                    genericType = Class.forName(genericTypeName);
-                } catch (ClassNotFoundException e) {
-                    e.printStackTrace();
+        if (allFields.size() > 0) {
+            for (Field field : allFields) {
+                if ("serialVersionUID".equals(field.getName())) {
+                    continue;
+                }
+                ParamBean paramBean = new ParamBean();
+                paramBean.setName(field.getName());
+                String genericTypeName = genericTypeAndNamesMap.get(field.getGenericType().getTypeName());
+                Class<?> genericType = null;
+                if (StringUtils.isBlank(genericTypeName)) {
+                    paramBean.setJavaType(field.getType().getCanonicalName());
+                } else {
+                    paramBean.setJavaType(genericTypeName);
+                    genericType =ClassTypeUtil.makeClass(genericTypeName);
+                }
+                RequestParam requestParam = null;
+                if (field.isAnnotationPresent(RequestParam.class)) {
+                    // Handling @RequestParam annotations on properties
+                    requestParam = field.getAnnotation(RequestParam.class);
+                    paramBean.setDocName(requestParam.value());
+                    paramBean.setRequired(requestParam.required());
+                    paramBean.setDescription(requestParam.description());
+                    paramBean.setExample(requestParam.example());
+                    paramBean.setDefaultValue(requestParam.defaultValue());
+                } else {
+                    paramBean.setRequired(false);
+                }
+
+                if (this.processHtmlType(null == genericType ? field.getType() : genericType, requestParam, paramBean) == null) {
+                    // Not a basic type, handle as JSON
+                    Object objResult;
+                    if (null == genericType) {
+                        objResult = ClassTypeUtil.initClassTypeWithDefaultValue(
+                                field.getGenericType(), field.getType(), 0);
+                    } else {
+                        objResult = ClassTypeUtil.initClassTypeWithDefaultValue(
+                                null, genericType, 0, true);
+                    }
+                    if (!ClassTypeUtil.isBaseType(objResult)) {
+                        paramBean.setHtmlType(HtmlTypeEnum.TEXT_AREA);
+                        paramBean.setSubParamsJson(JSON.toJSONString(objResult, ClassTypeUtil.FAST_JSON_FEATURES));
+                    }
                 }
+                apiParamsList.add(paramBean);
             }
+        } else {
+            ParamBean paramBean = new ParamBean();
+            paramBean.setName(parameter.getName());
+            paramBean.setJavaType(argClass.getCanonicalName());
             RequestParam requestParam = null;
-            if (field.isAnnotationPresent(RequestParam.class)) {
+            if (parameter.isAnnotationPresent(RequestParam.class)) {
                 // Handling @RequestParam annotations on properties
-                requestParam = field.getAnnotation(RequestParam.class);
+                requestParam = parameter.getAnnotation(RequestParam.class);
                 paramBean.setDocName(requestParam.value());
                 paramBean.setRequired(requestParam.required());
                 paramBean.setDescription(requestParam.description());
@@ -265,20 +304,11 @@ public class DubboApiDocsAnnotationScanner implements ApplicationListener<Applic
                 paramBean.setRequired(false);
             }
 
-            if (this.processHtmlType(null == genericType ? field.getType() : genericType, requestParam, paramBean) == null) {
-                // Not a basic type, handle as JSON
-                Object objResult;
-                if (null == genericType) {
-                    objResult =ClassTypeUtil.initClassTypeWithDefaultValue(
-                            field.getGenericType(), field.getType(), 0);
-                } else {
-                    objResult =ClassTypeUtil.initClassTypeWithDefaultValue(
-                            null, genericType, 0, true);
-                }
-                if (!ClassTypeUtil.isBaseType(objResult)) {
-                    paramBean.setHtmlType(HtmlTypeEnum.TEXT_AREA);
-                    paramBean.setSubParamsJson(JSON.toJSONString(objResult, ClassTypeUtil.FAST_JSON_FEATURES));
-                }
+            Object objResult = ClassTypeUtil.initClassTypeWithDefaultValue(
+                    parameterType, argClass, 0);
+            if (!ClassTypeUtil.isBaseType(objResult)) {
+                paramBean.setHtmlType(HtmlTypeEnum.TEXT_AREA);
+                paramBean.setSubParamsJson(JSON.toJSONString(objResult, ClassTypeUtil.FAST_JSON_FEATURES));
             }
             apiParamsList.add(paramBean);
         }
@@ -310,7 +340,8 @@ public class DubboApiDocsAnnotationScanner implements ApplicationListener<Applic
         } else if (Byte.class.isAssignableFrom(classType) || byte.class.isAssignableFrom(classType)) {
             param.setHtmlType(HtmlTypeEnum.TEXT_BYTE);
             processed = true;
-        } else if (Long.class.isAssignableFrom(classType) || long.class.isAssignableFrom(classType)) {
+        } else if (Long.class.isAssignableFrom(classType) || long.class.isAssignableFrom(classType) ||
+                BigDecimal.class.isAssignableFrom(classType) || BigInteger.class.isAssignableFrom(classType)) {
             param.setHtmlType(HtmlTypeEnum.NUMBER_INTEGER);
             processed = true;
         } else if (Double.class.isAssignableFrom(classType) || double.class.isAssignableFrom(classType)) {
diff --git a/dubbo-api-docs/dubbo-api-docs-core/src/main/java/org/apache/dubbo/apidocs/core/providers/DubboDocProviderImpl.java b/dubbo-api-docs/dubbo-api-docs-core/src/main/java/org/apache/dubbo/apidocs/core/providers/DubboDocProviderImpl.java
index 0bddd1c..a77bc91 100644
--- a/dubbo-api-docs/dubbo-api-docs-core/src/main/java/org/apache/dubbo/apidocs/core/providers/DubboDocProviderImpl.java
+++ b/dubbo-api-docs/dubbo-api-docs-core/src/main/java/org/apache/dubbo/apidocs/core/providers/DubboDocProviderImpl.java
@@ -18,16 +18,12 @@ package org.apache.dubbo.apidocs.core.providers;
 
 import org.apache.dubbo.apidocs.core.DubboApiDocsCache;
 import org.apache.dubbo.apidocs.core.beans.ModuleCacheItem;
-import org.apache.dubbo.common.logger.Logger;
-import org.apache.dubbo.common.logger.LoggerFactory;
-import org.apache.dubbo.config.annotation.DubboService;
 
 import java.util.List;
 
 /**
  * The api implementation of Dubbo doc.
  */
-@DubboService
 public class DubboDocProviderImpl implements IDubboDocProvider {
 
     @Override
diff --git a/dubbo-api-docs/dubbo-api-docs-core/src/main/java/org/apache/dubbo/apidocs/utils/ClassTypeUtil.java b/dubbo-api-docs/dubbo-api-docs-core/src/main/java/org/apache/dubbo/apidocs/utils/ClassTypeUtil.java
index 559f288..2efacd5 100644
--- a/dubbo-api-docs/dubbo-api-docs-core/src/main/java/org/apache/dubbo/apidocs/utils/ClassTypeUtil.java
+++ b/dubbo-api-docs/dubbo-api-docs-core/src/main/java/org/apache/dubbo/apidocs/utils/ClassTypeUtil.java
@@ -22,6 +22,8 @@ import org.apache.commons.lang3.StringUtils;
 import sun.reflect.generics.reflectiveObjects.ParameterizedTypeImpl;
 
 import java.lang.reflect.*;
+import java.math.BigDecimal;
+import java.math.BigInteger;
 import java.time.LocalDate;
 import java.time.LocalDateTime;
 import java.util.*;
@@ -103,6 +105,19 @@ public class ClassTypeUtil {
             return initResult;
         }
 
+        Map<String, String> genericTypeAndNamesMap;
+        if (genericType instanceof ParameterizedTypeImpl) {
+            ParameterizedTypeImpl parameterTypeImpl = (ParameterizedTypeImpl) genericType;
+            TypeVariable<? extends Class<?>>[] typeVariables = parameterTypeImpl.getRawType().getTypeParameters();
+            Type[] actualTypeArguments = parameterTypeImpl.getActualTypeArguments();
+            genericTypeAndNamesMap =  new HashMap<>(typeVariables.length);
+            for (int i = 0; i < typeVariables.length; i++) {
+                genericTypeAndNamesMap.put(typeVariables[i].getTypeName(), actualTypeArguments[i].getTypeName());
+            }
+        } else {
+            genericTypeAndNamesMap =  new HashMap<>(0);
+        }
+
         Map<String, Object> result = new HashMap<>(16);
         if (isBuildClassAttribute) {
             result.put("class", classType.getCanonicalName());
@@ -130,23 +145,11 @@ public class ClassTypeUtil {
                 }
             } else {
                 // Check if the type of the property is generic
-                if ("T".equals(field2.getGenericType().getTypeName())) {
+                String genericTypeName = genericTypeAndNamesMap.get(field2.getGenericType().getTypeName());
+                if (StringUtils.isNotBlank(genericTypeName)) {
                     // The type of the attribute is generic. Find the generic from the definition of
                     // the class in which the attribute is located
-                    ParameterizedType pt = (ParameterizedType) genericType;
-                    Type[] actualTypeArguments = pt.getActualTypeArguments();
-                    if (actualTypeArguments.length > 0) {
-                        if (actualTypeArguments.length == 1) {
-                            result.put(field2.getName(), initClassTypeWithDefaultValue(
-                                    makeParameterizedType(actualTypeArguments[0].getTypeName()),
-                                    makeClass(pt.getActualTypeArguments()[0].getTypeName()), processCount));
-                        } else {
-                            LOG.warn(classType.getName() + "#" + field2.getName() + " generics are not supported temporarily. " +
-                                    "This property will be ignored");
-                        }
-                    } else {
-                        result.put(field2.getName(), initClassTypeWithDefaultValue(field2.getGenericType(), field2.getType(), processCount));
-                    }
+                    result.put(field2.getName(), initClassTypeWithDefaultValue(null, makeClass(genericTypeName), processCount, true));
                 } else {
                     // Not generic
                     result.put(field2.getName(), initClassTypeWithDefaultValue(field2.getGenericType(), field2.getType(), processCount));
@@ -232,6 +235,10 @@ public class ClassTypeUtil {
             ParameterizedType pt = (ParameterizedType) genericType;
             String typeName = pt.getActualTypeArguments()[0].getTypeName();
             return initClassTypeWithDefaultValue(makeParameterizedType(typeName), makeClass(typeName), processCount);
+        } else if (BigDecimal.class.isAssignableFrom(classType)) {
+            return 0;
+        } else if (BigInteger.class.isAssignableFrom(classType)) {
+            return 0;
         }
         return null;
     }
@@ -251,7 +258,9 @@ public class ClassTypeUtil {
                 o instanceof Character ||
                 o instanceof Short ||
                 o instanceof Boolean ||
-                o instanceof String) {
+                o instanceof String ||
+                o instanceof BigDecimal ||
+                o instanceof BigInteger) {
             return true;
         }
         return false;
diff --git a/dubbo-api-docs/dubbo-api-docs-examples/examples-api/src/main/java/org/apache/dubbo/apidocs/examples/api/IQuickStartDemo.java b/dubbo-api-docs/dubbo-api-docs-examples/examples-api/src/main/java/org/apache/dubbo/apidocs/examples/api/IQuickStartDemo.java
index aa5251e..c3bca6f 100644
--- a/dubbo-api-docs/dubbo-api-docs-examples/examples-api/src/main/java/org/apache/dubbo/apidocs/examples/api/IQuickStartDemo.java
+++ b/dubbo-api-docs/dubbo-api-docs-examples/examples-api/src/main/java/org/apache/dubbo/apidocs/examples/api/IQuickStartDemo.java
@@ -19,9 +19,12 @@ package org.apache.dubbo.apidocs.examples.api;
 import org.apache.dubbo.apidocs.examples.params.DemoParamBean4;
 import org.apache.dubbo.apidocs.examples.params.QuickStartRequestBase;
 import org.apache.dubbo.apidocs.examples.params.QuickStartRequestBean;
+import org.apache.dubbo.apidocs.examples.params.QuickStartRequestBean2;
 import org.apache.dubbo.apidocs.examples.params.QuickStartRespBean;
 
+import java.math.BigDecimal;
 import java.util.List;
+import java.util.Map;
 
 /**
  * quick start demo.
@@ -35,14 +38,26 @@ public interface IQuickStartDemo {
      * @param beanParam
      * @return org.apache.dubbo.apidocs.examples.params.QuickStartRespBean
      */
-//    QuickStartRespBean quickStart(String strParam, QuickStartRequestBean beanParam);
+//    QuickStartRespBean quickStart(List<DemoParamBean4> strParam, QuickStartRequestBean beanParam);
 
     /**
-     * quick start demo, request use generic.
+     * quick start demo2, request use generic.
      * @param beanList
      * @param beanParam
      * @return org.apache.dubbo.apidocs.examples.params.QuickStartRespBean
      */
-    QuickStartRespBean quickStart2(List<String> beanList, QuickStartRequestBase<QuickStartRequestBean, DemoParamBean4> beanParam);
+//    QuickStartRespBean quickStart2(Map<String, DemoParamBean4> beanList, QuickStartRequestBase<QuickStartRequestBean, DemoParamBean4> beanParam);
 
+    /**
+     * quick start demo3, request use multiple generic.
+     * @return org.apache.dubbo.apidocs.examples.params.QuickStartRespBean
+     */
+//    QuickStartRespBean quickStart3(QuickStartRequestBean2 beanParam);
+
+    /**
+     * quick start demo4, response use multiple generic bean, but not set generic.
+     * @param beanParam
+     * @return org.apache.dubbo.apidocs.examples.params.QuickStartRequestBase
+     */
+    QuickStartRequestBase quickStart4(BigDecimal number, QuickStartRequestBean2 beanParam);
 }
diff --git a/dubbo-api-docs/dubbo-api-docs-examples/examples-api/src/main/java/org/apache/dubbo/apidocs/examples/params/QuickStartRequestBase.java b/dubbo-api-docs/dubbo-api-docs-examples/examples-api/src/main/java/org/apache/dubbo/apidocs/examples/params/QuickStartRequestBase.java
index 94cbd0f..5453ca9 100644
--- a/dubbo-api-docs/dubbo-api-docs-examples/examples-api/src/main/java/org/apache/dubbo/apidocs/examples/params/QuickStartRequestBase.java
+++ b/dubbo-api-docs/dubbo-api-docs-examples/examples-api/src/main/java/org/apache/dubbo/apidocs/examples/params/QuickStartRequestBase.java
@@ -7,7 +7,9 @@ import org.apache.dubbo.apidocs.annotations.RequestParam;
  *
  * @date 2021/1/26 15:24
  */
-public class QuickStartRequestBase<E, T> {
+public class QuickStartRequestBase<E, T> implements java.io.Serializable {
+
+    private static final long serialVersionUID = 373497393757790262L;
 
     @RequestParam(value = "Request method", required = true)
     private String method;
diff --git a/dubbo-api-docs/dubbo-api-docs-examples/examples-api/src/main/java/org/apache/dubbo/apidocs/examples/params/QuickStartRequestBean.java b/dubbo-api-docs/dubbo-api-docs-examples/examples-api/src/main/java/org/apache/dubbo/apidocs/examples/params/QuickStartRequestBean.java
index 30e9ef3..1388efd 100644
--- a/dubbo-api-docs/dubbo-api-docs-examples/examples-api/src/main/java/org/apache/dubbo/apidocs/examples/params/QuickStartRequestBean.java
+++ b/dubbo-api-docs/dubbo-api-docs-examples/examples-api/src/main/java/org/apache/dubbo/apidocs/examples/params/QuickStartRequestBean.java
@@ -21,7 +21,9 @@ import org.apache.dubbo.apidocs.annotations.RequestParam;
 /**
  * quick start demo request parameter bean.
  */
-public class QuickStartRequestBean {
+public class QuickStartRequestBean implements java.io.Serializable {
+
+    private static final long serialVersionUID = -7214413446084107294L;
 
     @RequestParam(value = "You name", required = true, description = "please enter your full name", example = "Zhang San")
     private String name;
diff --git a/dubbo-api-docs/dubbo-api-docs-examples/examples-api/src/main/java/org/apache/dubbo/apidocs/examples/params/QuickStartRequestBean.java b/dubbo-api-docs/dubbo-api-docs-examples/examples-api/src/main/java/org/apache/dubbo/apidocs/examples/params/QuickStartRequestBean2.java
similarity index 59%
copy from dubbo-api-docs/dubbo-api-docs-examples/examples-api/src/main/java/org/apache/dubbo/apidocs/examples/params/QuickStartRequestBean.java
copy to dubbo-api-docs/dubbo-api-docs-examples/examples-api/src/main/java/org/apache/dubbo/apidocs/examples/params/QuickStartRequestBean2.java
index 30e9ef3..815cd10 100644
--- a/dubbo-api-docs/dubbo-api-docs-examples/examples-api/src/main/java/org/apache/dubbo/apidocs/examples/params/QuickStartRequestBean.java
+++ b/dubbo-api-docs/dubbo-api-docs-examples/examples-api/src/main/java/org/apache/dubbo/apidocs/examples/params/QuickStartRequestBean2.java
@@ -18,19 +18,23 @@ package org.apache.dubbo.apidocs.examples.params;
 
 import org.apache.dubbo.apidocs.annotations.RequestParam;
 
+import java.math.BigDecimal;
+
 /**
  * quick start demo request parameter bean.
  */
-public class QuickStartRequestBean {
+public class QuickStartRequestBean2 implements java.io.Serializable {
+
+    private static final long serialVersionUID = -7214413446084107294L;
 
     @RequestParam(value = "You name", required = true, description = "please enter your full name", example = "Zhang San")
     private String name;
 
-    @RequestParam(value = "You age", defaultValue = "18")
-    private int age;
+    @RequestParam(value = "multiple generic")
+    private QuickStartRequestBase<QuickStartRequestBean, DemoParamBean4> requestBase;
 
-    @RequestParam("Are you a main?")
-    private boolean man;
+    @RequestParam(value = "BigDecimal number")
+    private BigDecimal bigDecimalNumber;
 
     public String getName() {
         return name;
@@ -40,28 +44,19 @@ public class QuickStartRequestBean {
         this.name = name;
     }
 
-    public int getAge() {
-        return age;
-    }
-
-    public void setAge(int age) {
-        this.age = age;
+    public QuickStartRequestBase<QuickStartRequestBean, DemoParamBean4> getRequestBase() {
+        return requestBase;
     }
 
-    public boolean getMan() {
-        return man;
+    public void setRequestBase(QuickStartRequestBase<QuickStartRequestBean, DemoParamBean4> requestBase) {
+        this.requestBase = requestBase;
     }
 
-    public void setMan(boolean man) {
-        this.man = man;
+    public BigDecimal getBigDecimalNumber() {
+        return bigDecimalNumber;
     }
 
-    @Override
-    public String toString() {
-        return "QuickStartRequestBean{" +
-                "name='" + name + '\'' +
-                ", age=" + age +
-                ", man=" + man +
-                '}';
+    public void setBigDecimalNumber(BigDecimal bigDecimalNumber) {
+        this.bigDecimalNumber = bigDecimalNumber;
     }
 }
diff --git a/dubbo-api-docs/dubbo-api-docs-examples/examples-api/src/main/java/org/apache/dubbo/apidocs/examples/params/QuickStartRespBean.java b/dubbo-api-docs/dubbo-api-docs-examples/examples-api/src/main/java/org/apache/dubbo/apidocs/examples/params/QuickStartRespBean.java
index ccb84c7..660a6a6 100644
--- a/dubbo-api-docs/dubbo-api-docs-examples/examples-api/src/main/java/org/apache/dubbo/apidocs/examples/params/QuickStartRespBean.java
+++ b/dubbo-api-docs/dubbo-api-docs-examples/examples-api/src/main/java/org/apache/dubbo/apidocs/examples/params/QuickStartRespBean.java
@@ -21,7 +21,9 @@ import org.apache.dubbo.apidocs.annotations.ResponseProperty;
 /**
  * quick star demo response bean.
  */
-public class QuickStartRespBean {
+public class QuickStartRespBean implements java.io.Serializable {
+
+    private static final long serialVersionUID = 7598240511561924368L;
 
     @ResponseProperty(value = "Response code", example = "500")
     private int code;
diff --git a/dubbo-api-docs/dubbo-api-docs-examples/examples-provider/src/main/java/org/apache/dubbo/apidocs/examples/api/impl/QuickStartDemoImpl.java b/dubbo-api-docs/dubbo-api-docs-examples/examples-provider/src/main/java/org/apache/dubbo/apidocs/examples/api/impl/QuickStartDemoImpl.java
index c2c9d17..f246c96 100644
--- a/dubbo-api-docs/dubbo-api-docs-examples/examples-provider/src/main/java/org/apache/dubbo/apidocs/examples/api/impl/QuickStartDemoImpl.java
+++ b/dubbo-api-docs/dubbo-api-docs-examples/examples-provider/src/main/java/org/apache/dubbo/apidocs/examples/api/impl/QuickStartDemoImpl.java
@@ -18,33 +18,53 @@ package org.apache.dubbo.apidocs.examples.api.impl;
 
 import org.apache.dubbo.apidocs.annotations.ApiDoc;
 import org.apache.dubbo.apidocs.annotations.ApiModule;
+import org.apache.dubbo.apidocs.annotations.RequestParam;
 import org.apache.dubbo.apidocs.examples.api.IQuickStartDemo;
 import org.apache.dubbo.apidocs.examples.params.DemoParamBean4;
 import org.apache.dubbo.apidocs.examples.params.QuickStartRequestBase;
 import org.apache.dubbo.apidocs.examples.params.QuickStartRequestBean;
+import org.apache.dubbo.apidocs.examples.params.QuickStartRequestBean2;
 import org.apache.dubbo.apidocs.examples.params.QuickStartRespBean;
 import org.apache.dubbo.config.annotation.DubboService;
 
+import java.math.BigDecimal;
 import java.util.List;
+import java.util.Map;
 
 /**
  * quick start demo implement.
  *
  * @date 2020/12/23 17:21
  */
-@DubboService(version = "v0.1")
-@ApiModule(value = "quick start demo", apiInterface = IQuickStartDemo.class, version = "v0.1")
+@DubboService(version = "${demo.apiversion.quickstart}")
+@ApiModule(value = "quick start demo", apiInterface = IQuickStartDemo.class)
 public class QuickStartDemoImpl implements IQuickStartDemo {
 
 //    @ApiDoc(value = "quick start demo", version = "v0.1", description = "this api is a quick start demo", responseClassDescription="A quick star response bean")
 //    @Override
-//    public QuickStartRespBean quickStart(@RequestParam(value = "strParam", required = true) String strParam, QuickStartRequestBean beanParam) {
+//    public QuickStartRespBean quickStart(@RequestParam(value = "strParamxxx", required = true) List<DemoParamBean4> strParam, QuickStartRequestBean beanParam) {
 //        return new QuickStartRespBean(200, "hello " + beanParam.getName() + ", " + beanParam.toString());
 //    }
+//
+//    @ApiDoc(value = "quick start demo, request use generic.", version = "v0.1", description = "quick start demo, request use generic.", responseClassDescription="A quick star response bean")
+//    @Override
+//    public QuickStartRespBean quickStart2(Map<String, DemoParamBean4> beanList, QuickStartRequestBase<QuickStartRequestBean, DemoParamBean4> beanParam) {
+//        return new QuickStartRespBean(200, "【" + beanParam.getMethod() + "】hello " + beanParam.getBody3() + ", " + beanParam.toString());
+//    }
+//
+//    @ApiDoc(value = "multiple generic demo", version = "v0.1", description = "multiple generic demo.", responseClassDescription="A quick star response bean")
+//    @Override
+//    public QuickStartRespBean quickStart3(QuickStartRequestBean2 beanParam) {
+//        return new QuickStartRespBean(200,"quickStart3, multiple generic demo");
+//    }
 
-    @ApiDoc(value = "quick start demo, request use generic.", version = "v0.1", description = "quick start demo, request use generic.", responseClassDescription="A quick star response bean")
+    @ApiDoc(value = "response use multiple generic bean", description = "response use multiple generic bean, but not set generic.", responseClassDescription="A quick star response bean")
     @Override
-    public QuickStartRespBean quickStart2(List<String> beanList, QuickStartRequestBase<QuickStartRequestBean, DemoParamBean4> beanParam) {
-        return new QuickStartRespBean(200, "【" + beanParam.getMethod() + "】hello " + beanParam.getBody3().getName() + ", " + beanParam.toString());
+    public QuickStartRequestBase quickStart4(BigDecimal number, QuickStartRequestBean2 beanParam) {
+        QuickStartRequestBase response = new QuickStartRequestBase();
+        response.setBody("body");
+        response.setBody3("body3");
+        response.setMethod("test");
+        return response;
     }
 }
diff --git a/dubbo-api-docs/dubbo-api-docs-examples/examples-provider/src/main/resources/application.yml b/dubbo-api-docs/dubbo-api-docs-examples/examples-provider/src/main/resources/application.yml
index ae4c2fa..2e8048a 100644
--- a/dubbo-api-docs/dubbo-api-docs-examples/examples-provider/src/main/resources/application.yml
+++ b/dubbo-api-docs/dubbo-api-docs-examples/examples-provider/src/main/resources/application.yml
@@ -14,4 +14,7 @@ dubbo:
   application:
     name: dubbo-api-docs-example-provider
   metadata-report:
-    address: nacos://127.0.0.1:8848
\ No newline at end of file
+    address: nacos://127.0.0.1:8848
+demo:
+  apiversion:
+    quickstart: v0.1
\ No newline at end of file


[dubbo-spi-extensions] 25/39: Merge pull request #1, introduce api docs feature

Posted by li...@apache.org.
This is an automated email from the ASF dual-hosted git repository.

liujun pushed a commit to branch 2.7.x
in repository https://gitbox.apache.org/repos/asf/dubbo-spi-extensions.git

commit a00ee8984b4a9571dfed1055a438d9757947f443
Merge: a463413 5f057c7
Author: ken.lj <ke...@gmail.com>
AuthorDate: Mon Dec 21 16:13:32 2020 +0800

    Merge pull request #1, introduce api docs feature

 dubbo-api-docs/README.md                           |  83 +++++
 dubbo-api-docs/README_ch.md                        |  85 +++++
 dubbo-api-docs/dubbo-api-docs-annotations/pom.xml  |  31 ++
 .../apache/dubbo/apidocs/annotations/ApiDoc.java   |  53 ++++
 .../dubbo/apidocs/annotations/ApiModule.java       |  48 +++
 .../dubbo/apidocs/annotations/RequestParam.java    |  68 ++++
 .../apidocs/annotations/ResponseProperty.java      |  45 +++
 dubbo-api-docs/dubbo-api-docs-core/pom.xml         |  71 +++++
 .../apache/dubbo/apidocs/EnableDubboApiDocs.java   |  38 +++
 .../core/DubboApiDocsAnnotationScanner.java        | 351 +++++++++++++++++++++
 .../dubbo/apidocs/core/DubboApiDocsCache.java      | 118 +++++++
 .../dubbo/apidocs/core/beans/ApiCacheItem.java     | 109 +++++++
 .../apidocs/core/beans/ApiParamsCacheItem.java     | 119 +++++++
 .../dubbo/apidocs/core/beans/HtmlTypeEnum.java     |  60 ++++
 .../dubbo/apidocs/core/beans/ModuleCacheItem.java  |  49 +++
 .../apache/dubbo/apidocs/core/beans/ParamBean.java | 174 ++++++++++
 .../core/providers/DubboDocProviderImpl.java       |  52 +++
 .../apidocs/core/providers/IDubboDocProvider.java  |  54 ++++
 .../apache/dubbo/apidocs/utils/ClassTypeUtil.java  | 308 ++++++++++++++++++
 .../apache/dubbo/apidocs/utils/SimpleTypeImpl.java |  21 ++
 .../dubbo-api-docs-examples/examples-api/pom.xml   |  40 +++
 .../dubbo/apidocs/examples/api/IAsyncDemo.java     |  88 ++++++
 .../dubbo/apidocs/examples/api/ISyncDemo.java      | 102 ++++++
 .../apidocs/examples/params/DemoParamBean1.java    | 187 +++++++++++
 .../examples/params/DemoParamBean1SubBean1.java    |  62 ++++
 .../apidocs/examples/params/DemoParamBean2.java    |  47 +++
 .../apidocs/examples/params/DemoParamBean3.java    |  50 +++
 .../apidocs/examples/params/DemoParamBean4.java    |  38 +++
 .../dubbo/apidocs/examples/params/TestBean.java    |  34 ++
 .../dubbo/apidocs/examples/params/TestEnum.java    |  28 ++
 .../apidocs/examples/responses/BaseResponse.java   |  72 +++++
 .../apidocs/examples/responses/DemoRespBean1.java  | 116 +++++++
 .../examples-provider-sca/pom.xml                  |  62 ++++
 .../apidocs/examples/ExampleScaApplication.java    |  41 +++
 .../apidocs/examples/api/impl/AsyncDemoImpl.java   | 102 ++++++
 .../apidocs/examples/api/impl/SyncDemoImpl.java    | 125 ++++++++
 .../dubbo/apidocs/examples/cfg/DubboDocConfig.java |  32 ++
 .../src/main/resources/application.yml             |  12 +
 .../src/main/resources/bootstrap.yml               |   9 +
 .../src/main/resources/dubbo.properties            |   1 +
 .../examples-provider/pom.xml                      |  80 +++++
 .../dubbo/apidocs/examples/ExampleApplication.java |  39 +++
 .../apidocs/examples/api/impl/AsyncDemoImpl.java   | 107 +++++++
 .../apidocs/examples/api/impl/SyncDemoImpl.java    | 126 ++++++++
 .../dubbo/apidocs/examples/cfg/DubboDocConfig.java |  31 ++
 .../src/main/resources/application.yml             |  17 +
 dubbo-api-docs/dubbo-api-docs-examples/pom.xml     |  70 ++++
 dubbo-api-docs/pom.xml                             | 250 +++++++++++++++
 dubbo-api-docs/readmeImgs/dubbo_docs_en.png        | Bin 0 -> 600733 bytes
 dubbo-api-docs/readmeImgs/dubbo_docs_zh.png        | Bin 0 -> 538526 bytes
 50 files changed, 3905 insertions(+)


[dubbo-spi-extensions] 22/39: 修改注释

Posted by li...@apache.org.
This is an automated email from the ASF dual-hosted git repository.

liujun pushed a commit to branch 2.7.x
in repository https://gitbox.apache.org/repos/asf/dubbo-spi-extensions.git

commit f5b363eb4d26685b7b0fa7f3696aafa93d68809d
Author: qq213539 <21...@qq.com>
AuthorDate: Fri Dec 18 15:51:03 2020 +0800

    修改注释
---
 .../apache/dubbo/apidocs/core/DubboApiDocsAnnotationScanner.java    | 1 -
 .../org/apache/dubbo/apidocs/core/providers/IDubboDocProvider.java  | 6 ------
 .../src/main/java/org/apache/dubbo/apidocs/utils/ClassTypeUtil.java | 3 ---
 .../main/java/org/apache/dubbo/apidocs/examples/api/IAsyncDemo.java | 2 --
 .../main/java/org/apache/dubbo/apidocs/examples/api/ISyncDemo.java  | 2 --
 5 files changed, 14 deletions(-)

diff --git a/dubbo-api-docs/dubbo-api-docs-core/src/main/java/org/apache/dubbo/apidocs/core/DubboApiDocsAnnotationScanner.java b/dubbo-api-docs/dubbo-api-docs-core/src/main/java/org/apache/dubbo/apidocs/core/DubboApiDocsAnnotationScanner.java
index 3780c6e..f43cb40 100644
--- a/dubbo-api-docs/dubbo-api-docs-core/src/main/java/org/apache/dubbo/apidocs/core/DubboApiDocsAnnotationScanner.java
+++ b/dubbo-api-docs/dubbo-api-docs-core/src/main/java/org/apache/dubbo/apidocs/core/DubboApiDocsAnnotationScanner.java
@@ -248,7 +248,6 @@ public class DubboApiDocsAnnotationScanner implements ApplicationListener<Applic
 
     /**
      * Determine what HTML form elements to use.
-     * 2020/10/29 18:24
      *
      * @param classType  classType
      * @param annotation annotation
diff --git a/dubbo-api-docs/dubbo-api-docs-core/src/main/java/org/apache/dubbo/apidocs/core/providers/IDubboDocProvider.java b/dubbo-api-docs/dubbo-api-docs-core/src/main/java/org/apache/dubbo/apidocs/core/providers/IDubboDocProvider.java
index 050f698..b08156b 100644
--- a/dubbo-api-docs/dubbo-api-docs-core/src/main/java/org/apache/dubbo/apidocs/core/providers/IDubboDocProvider.java
+++ b/dubbo-api-docs/dubbo-api-docs-core/src/main/java/org/apache/dubbo/apidocs/core/providers/IDubboDocProvider.java
@@ -27,23 +27,18 @@ public interface IDubboDocProvider {
 
     /**
      * Get basic information of all modules, excluding API parameter information.
-     * 2020/10/30 16:38
-     * @param
      * @return java.lang.String
      */
     String apiModuleList();
 
     /**
      * Get all information of all modules , including API parameter information.
-     * 2020/11/9 9:53
-     * @param
      * @return java.lang.String
      */
     List<ModuleCacheItem> apiModuleListAndApiInfo();
 
     /**
      * Get module information according to the complete class name of Dubbo provider interface.
-     * 2020/10/30 16:38
      * @param apiInterfaceClassName
      * @return java.lang.String
      */
@@ -51,7 +46,6 @@ public interface IDubboDocProvider {
 
     /**
      * Get method parameters and return information according to the complete class name and method name of Dubbo provider interface.
-     * 2020/10/30 16:38
      * @param apiInterfaceClassNameMethodName
      * @return java.lang.String
      */
diff --git a/dubbo-api-docs/dubbo-api-docs-core/src/main/java/org/apache/dubbo/apidocs/utils/ClassTypeUtil.java b/dubbo-api-docs/dubbo-api-docs-core/src/main/java/org/apache/dubbo/apidocs/utils/ClassTypeUtil.java
index e9bc5d5..a7e9179 100644
--- a/dubbo-api-docs/dubbo-api-docs-core/src/main/java/org/apache/dubbo/apidocs/utils/ClassTypeUtil.java
+++ b/dubbo-api-docs/dubbo-api-docs-core/src/main/java/org/apache/dubbo/apidocs/utils/ClassTypeUtil.java
@@ -70,7 +70,6 @@ public class ClassTypeUtil {
 
     /**
      * Instantiate class and its fields.
-     * 2020/10/29 18:08
      *
      * @param genericType  genericType
      * @param classType    classType
@@ -222,7 +221,6 @@ public class ClassTypeUtil {
 
     /**
      * Check if it is a basic data type.
-     * 2020/10/29 18:09
      *
      * @param o
      * @return boolean
@@ -244,7 +242,6 @@ public class ClassTypeUtil {
 
     /**
      * Get all fields in the class.
-     * 2020/10/29 18:10
      *
      * @param fieldList fieldList
      * @param classz    classz
diff --git a/dubbo-api-docs/dubbo-api-docs-examples/examples-api/src/main/java/org/apache/dubbo/apidocs/examples/api/IAsyncDemo.java b/dubbo-api-docs/dubbo-api-docs-examples/examples-api/src/main/java/org/apache/dubbo/apidocs/examples/api/IAsyncDemo.java
index 31a6294..d178e9e 100644
--- a/dubbo-api-docs/dubbo-api-docs-examples/examples-api/src/main/java/org/apache/dubbo/apidocs/examples/api/IAsyncDemo.java
+++ b/dubbo-api-docs/dubbo-api-docs-examples/examples-api/src/main/java/org/apache/dubbo/apidocs/examples/api/IAsyncDemo.java
@@ -33,7 +33,6 @@ public interface IAsyncDemo {
 
     /**
      * request and response parameters are beans.
-     * 2020/11/14 22:21
      * @param param1
      * @param param2
      * @return java.util.concurrent.CompletableFuture<org.apache.dubbo.apidocs.examples.responses.DemoRespBean1>
@@ -80,7 +79,6 @@ public interface IAsyncDemo {
 
     /**
      * Simple test.
-     * 2020/11/13 10:11
      * @param param1
      * @param param2
      * @return java.util.concurrent.CompletableFuture<org.apache.dubbo.apidocs.examples.params.DemoParamBean3>
diff --git a/dubbo-api-docs/dubbo-api-docs-examples/examples-api/src/main/java/org/apache/dubbo/apidocs/examples/api/ISyncDemo.java b/dubbo-api-docs/dubbo-api-docs-examples/examples-api/src/main/java/org/apache/dubbo/apidocs/examples/api/ISyncDemo.java
index 64237dd..c88084a 100644
--- a/dubbo-api-docs/dubbo-api-docs-examples/examples-api/src/main/java/org/apache/dubbo/apidocs/examples/api/ISyncDemo.java
+++ b/dubbo-api-docs/dubbo-api-docs-examples/examples-api/src/main/java/org/apache/dubbo/apidocs/examples/api/ISyncDemo.java
@@ -33,7 +33,6 @@ public interface ISyncDemo {
 
     /**
      * request and response parameters are beans.
-     * 2020/11/14 22:21
      * @param param1
      * @param param2
      * @return org.apache.dubbo.apidocs.examples.responses.DemoRespBean1
@@ -94,7 +93,6 @@ public interface ISyncDemo {
 
     /**
      * Simple test.
-     * 2020/11/13 10:11
      * @param param1
      * @param param2
      * @return org.apache.dubbo.apidocs.examples.params.DemoParamBean3


[dubbo-spi-extensions] 07/39: update version to 3.0.0-SNAPSHOT

Posted by li...@apache.org.
This is an automated email from the ASF dual-hosted git repository.

liujun pushed a commit to branch 2.7.x
in repository https://gitbox.apache.org/repos/asf/dubbo-spi-extensions.git

commit c1b0fd9c5350005e52c98d5405166237223a041a
Author: ken.lj <ke...@gmail.com>
AuthorDate: Thu Aug 27 15:11:55 2020 +0800

    update version to 3.0.0-SNAPSHOT
---
 dubbo-all/pom.xml                                                  | 2 +-
 dubbo-spi-configcenter/dubbo-configcenter-consul/pom.xml           | 2 +-
 dubbo-spi-configcenter/dubbo-configcenter-etcd/pom.xml             | 2 +-
 dubbo-spi-container/dubbo-container-log4j/pom.xml                  | 2 +-
 dubbo-spi-container/dubbo-container-logback/pom.xml                | 2 +-
 dubbo-spi-metadata/dubbo-metadata-report-consul/pom.xml            | 2 +-
 dubbo-spi-metadata/dubbo-metadata-report-etcd/pom.xml              | 2 +-
 dubbo-spi-registry/dubbo-registry-consul/pom.xml                   | 2 +-
 dubbo-spi-registry/dubbo-registry-default/pom.xml                  | 2 +-
 dubbo-spi-registry/dubbo-registry-etcd3/pom.xml                    | 2 +-
 dubbo-spi-registry/dubbo-registry-eureka/pom.xml                   | 2 +-
 dubbo-spi-registry/dubbo-registry-redis/pom.xml                    | 2 +-
 dubbo-spi-registry/dubbo-registry-sofa/pom.xml                     | 2 +-
 dubbo-spi-remoting/dubbo-remoting-etcd3/pom.xml                    | 2 +-
 dubbo-spi-remoting/dubbo-remoting-grizzly/pom.xml                  | 2 +-
 dubbo-spi-remoting/dubbo-remoting-http/pom.xml                     | 2 +-
 dubbo-spi-remoting/dubbo-remoting-mina/pom.xml                     | 2 +-
 dubbo-spi-remoting/dubbo-remoting-p2p/pom.xml                      | 2 +-
 dubbo-spi-rpc/dubbo-rpc-hessian/pom.xml                            | 2 +-
 dubbo-spi-rpc/dubbo-rpc-http/pom.xml                               | 2 +-
 dubbo-spi-rpc/dubbo-rpc-memcached/pom.xml                          | 2 +-
 dubbo-spi-rpc/dubbo-rpc-native-thrift/pom.xml                      | 4 ++--
 dubbo-spi-rpc/dubbo-rpc-redis/pom.xml                              | 2 +-
 dubbo-spi-rpc/dubbo-rpc-rmi/pom.xml                                | 2 +-
 dubbo-spi-rpc/dubbo-rpc-thrift/pom.xml                             | 2 +-
 dubbo-spi-rpc/dubbo-rpc-webservice/pom.xml                         | 2 +-
 dubbo-spi-rpc/dubbo-rpc-xml/pom.xml                                | 2 +-
 dubbo-spi-serialization/dubbo-serialization-avro/pom.xml           | 2 +-
 dubbo-spi-serialization/dubbo-serialization-fastjson/pom.xml       | 2 +-
 dubbo-spi-serialization/dubbo-serialization-fst/pom.xml            | 2 +-
 dubbo-spi-serialization/dubbo-serialization-gson/pom.xml           | 2 +-
 dubbo-spi-serialization/dubbo-serialization-kryo/pom.xml           | 2 +-
 dubbo-spi-serialization/dubbo-serialization-native-hession/pom.xml | 2 +-
 dubbo-spi-serialization/dubbo-serialization-protobuf/pom.xml       | 2 +-
 dubbo-spi-serialization/dubbo-serialization-protostuff/pom.xml     | 2 +-
 dubbo-spi-serialization/dubbo-serialization-test/pom.xml           | 2 +-
 36 files changed, 37 insertions(+), 37 deletions(-)

diff --git a/dubbo-all/pom.xml b/dubbo-all/pom.xml
index 495ef55..93898ca 100644
--- a/dubbo-all/pom.xml
+++ b/dubbo-all/pom.xml
@@ -20,7 +20,7 @@
     <parent>
         <groupId>org.apache.dubbo</groupId>
         <artifactId>dubbo-parent</artifactId>
-        <version>${revision}</version>
+        <version>3.0.0-SNAPSHOT</version>
     </parent>
     <artifactId>dubbo-all</artifactId>
     <packaging>jar</packaging>
diff --git a/dubbo-spi-configcenter/dubbo-configcenter-consul/pom.xml b/dubbo-spi-configcenter/dubbo-configcenter-consul/pom.xml
index 674728c..3349bff 100644
--- a/dubbo-spi-configcenter/dubbo-configcenter-consul/pom.xml
+++ b/dubbo-spi-configcenter/dubbo-configcenter-consul/pom.xml
@@ -22,7 +22,7 @@
     <parent>
         <groupId>org.apache.dubbo</groupId>
         <artifactId>dubbo-configcenter</artifactId>
-        <version>${revision}</version>
+        <version>3.0.0-SNAPSHOT</version>
     </parent>
 
     <artifactId>dubbo-configcenter-consul</artifactId>
diff --git a/dubbo-spi-configcenter/dubbo-configcenter-etcd/pom.xml b/dubbo-spi-configcenter/dubbo-configcenter-etcd/pom.xml
index 22d5f6d..9fcc2fe 100644
--- a/dubbo-spi-configcenter/dubbo-configcenter-etcd/pom.xml
+++ b/dubbo-spi-configcenter/dubbo-configcenter-etcd/pom.xml
@@ -24,7 +24,7 @@
     <parent>
         <groupId>org.apache.dubbo</groupId>
         <artifactId>dubbo-configcenter</artifactId>
-        <version>${revision}</version>
+        <version>3.0.0-SNAPSHOT</version>
     </parent>
 
     <artifactId>dubbo-configcenter-etcd</artifactId>
diff --git a/dubbo-spi-container/dubbo-container-log4j/pom.xml b/dubbo-spi-container/dubbo-container-log4j/pom.xml
index d4503df..1b5b3d2 100644
--- a/dubbo-spi-container/dubbo-container-log4j/pom.xml
+++ b/dubbo-spi-container/dubbo-container-log4j/pom.xml
@@ -19,7 +19,7 @@
     <parent>
         <groupId>org.apache.dubbo</groupId>
         <artifactId>dubbo-container</artifactId>
-        <version>${revision}</version>
+        <version>3.0.0-SNAPSHOT</version>
     </parent>
     <artifactId>dubbo-container-log4j</artifactId>
     <packaging>jar</packaging>
diff --git a/dubbo-spi-container/dubbo-container-logback/pom.xml b/dubbo-spi-container/dubbo-container-logback/pom.xml
index a6f7014..d4437eb 100644
--- a/dubbo-spi-container/dubbo-container-logback/pom.xml
+++ b/dubbo-spi-container/dubbo-container-logback/pom.xml
@@ -19,7 +19,7 @@
     <parent>
         <groupId>org.apache.dubbo</groupId>
         <artifactId>dubbo-container</artifactId>
-        <version>${revision}</version>
+        <version>3.0.0-SNAPSHOT</version>
     </parent>
     <artifactId>dubbo-container-logback</artifactId>
     <packaging>jar</packaging>
diff --git a/dubbo-spi-metadata/dubbo-metadata-report-consul/pom.xml b/dubbo-spi-metadata/dubbo-metadata-report-consul/pom.xml
index 215fabc..4c3cc36 100644
--- a/dubbo-spi-metadata/dubbo-metadata-report-consul/pom.xml
+++ b/dubbo-spi-metadata/dubbo-metadata-report-consul/pom.xml
@@ -20,7 +20,7 @@
     <parent>
         <groupId>org.apache.dubbo</groupId>
         <artifactId>dubbo-metadata</artifactId>
-        <version>${revision}</version>
+        <version>3.0.0-SNAPSHOT</version>
     </parent>
     <modelVersion>4.0.0</modelVersion>
 
diff --git a/dubbo-spi-metadata/dubbo-metadata-report-etcd/pom.xml b/dubbo-spi-metadata/dubbo-metadata-report-etcd/pom.xml
index 0b53419..675257f 100644
--- a/dubbo-spi-metadata/dubbo-metadata-report-etcd/pom.xml
+++ b/dubbo-spi-metadata/dubbo-metadata-report-etcd/pom.xml
@@ -22,7 +22,7 @@
     <parent>
         <groupId>org.apache.dubbo</groupId>
         <artifactId>dubbo-metadata</artifactId>
-        <version>${revision}</version>
+        <version>3.0.0-SNAPSHOT</version>
     </parent>
     <modelVersion>4.0.0</modelVersion>
 
diff --git a/dubbo-spi-registry/dubbo-registry-consul/pom.xml b/dubbo-spi-registry/dubbo-registry-consul/pom.xml
index 090c3e6..43b3180 100644
--- a/dubbo-spi-registry/dubbo-registry-consul/pom.xml
+++ b/dubbo-spi-registry/dubbo-registry-consul/pom.xml
@@ -20,7 +20,7 @@
     <parent>
         <artifactId>dubbo-registry</artifactId>
         <groupId>org.apache.dubbo</groupId>
-        <version>${revision}</version>
+        <version>3.0.0-SNAPSHOT</version>
     </parent>
     <modelVersion>4.0.0</modelVersion>
 
diff --git a/dubbo-spi-registry/dubbo-registry-default/pom.xml b/dubbo-spi-registry/dubbo-registry-default/pom.xml
index 37df8f2..1dd05a9 100644
--- a/dubbo-spi-registry/dubbo-registry-default/pom.xml
+++ b/dubbo-spi-registry/dubbo-registry-default/pom.xml
@@ -20,7 +20,7 @@
     <parent>
         <groupId>org.apache.dubbo</groupId>
         <artifactId>dubbo-registry</artifactId>
-        <version>${revision}</version>
+        <version>3.0.0-SNAPSHOT</version>
     </parent>
     <artifactId>dubbo-registry-default</artifactId>
     <packaging>jar</packaging>
diff --git a/dubbo-spi-registry/dubbo-registry-etcd3/pom.xml b/dubbo-spi-registry/dubbo-registry-etcd3/pom.xml
index 6d9d60c..510ae33 100644
--- a/dubbo-spi-registry/dubbo-registry-etcd3/pom.xml
+++ b/dubbo-spi-registry/dubbo-registry-etcd3/pom.xml
@@ -21,7 +21,7 @@
     <parent>
         <artifactId>dubbo-registry</artifactId>
         <groupId>org.apache.dubbo</groupId>
-        <version>${revision}</version>
+        <version>3.0.0-SNAPSHOT</version>
     </parent>
 
     <artifactId>dubbo-registry-etcd3</artifactId>
diff --git a/dubbo-spi-registry/dubbo-registry-eureka/pom.xml b/dubbo-spi-registry/dubbo-registry-eureka/pom.xml
index b2a6abe..c71f21e 100644
--- a/dubbo-spi-registry/dubbo-registry-eureka/pom.xml
+++ b/dubbo-spi-registry/dubbo-registry-eureka/pom.xml
@@ -22,7 +22,7 @@
     <parent>
         <groupId>org.apache.dubbo</groupId>
         <artifactId>dubbo-registry</artifactId>
-        <version>${revision}</version>
+        <version>3.0.0-SNAPSHOT</version>
     </parent>
 
     <artifactId>dubbo-registry-eureka</artifactId>
diff --git a/dubbo-spi-registry/dubbo-registry-redis/pom.xml b/dubbo-spi-registry/dubbo-registry-redis/pom.xml
index fe6bd40..a8e2ec0 100644
--- a/dubbo-spi-registry/dubbo-registry-redis/pom.xml
+++ b/dubbo-spi-registry/dubbo-registry-redis/pom.xml
@@ -19,7 +19,7 @@
     <parent>
         <groupId>org.apache.dubbo</groupId>
         <artifactId>dubbo-registry</artifactId>
-        <version>${revision}</version>
+        <version>3.0.0-SNAPSHOT</version>
     </parent>
     <artifactId>dubbo-registry-redis</artifactId>
     <packaging>jar</packaging>
diff --git a/dubbo-spi-registry/dubbo-registry-sofa/pom.xml b/dubbo-spi-registry/dubbo-registry-sofa/pom.xml
index 66dc846..109a3c0 100644
--- a/dubbo-spi-registry/dubbo-registry-sofa/pom.xml
+++ b/dubbo-spi-registry/dubbo-registry-sofa/pom.xml
@@ -19,7 +19,7 @@
     <parent>
         <groupId>org.apache.dubbo</groupId>
         <artifactId>dubbo-registry</artifactId>
-        <version>${revision}</version>
+        <version>3.0.0-SNAPSHOT</version>
     </parent>
     <modelVersion>4.0.0</modelVersion>
 
diff --git a/dubbo-spi-remoting/dubbo-remoting-etcd3/pom.xml b/dubbo-spi-remoting/dubbo-remoting-etcd3/pom.xml
index e7428e0..1fab42b 100644
--- a/dubbo-spi-remoting/dubbo-remoting-etcd3/pom.xml
+++ b/dubbo-spi-remoting/dubbo-remoting-etcd3/pom.xml
@@ -23,7 +23,7 @@
     <parent>
         <artifactId>dubbo-remoting</artifactId>
         <groupId>org.apache.dubbo</groupId>
-        <version>${revision}</version>
+        <version>3.0.0-SNAPSHOT</version>
     </parent>
     <artifactId>dubbo-remoting-etcd3</artifactId>
     <packaging>jar</packaging>
diff --git a/dubbo-spi-remoting/dubbo-remoting-grizzly/pom.xml b/dubbo-spi-remoting/dubbo-remoting-grizzly/pom.xml
index cd18536..5162711 100644
--- a/dubbo-spi-remoting/dubbo-remoting-grizzly/pom.xml
+++ b/dubbo-spi-remoting/dubbo-remoting-grizzly/pom.xml
@@ -19,7 +19,7 @@
     <parent>
         <groupId>org.apache.dubbo</groupId>
         <artifactId>dubbo-remoting</artifactId>
-        <version>${revision}</version>
+        <version>3.0.0-SNAPSHOT</version>
     </parent>
     <artifactId>dubbo-remoting-grizzly</artifactId>
     <packaging>jar</packaging>
diff --git a/dubbo-spi-remoting/dubbo-remoting-http/pom.xml b/dubbo-spi-remoting/dubbo-remoting-http/pom.xml
index 19c8220..1bcdca2 100644
--- a/dubbo-spi-remoting/dubbo-remoting-http/pom.xml
+++ b/dubbo-spi-remoting/dubbo-remoting-http/pom.xml
@@ -19,7 +19,7 @@
     <parent>
         <groupId>org.apache.dubbo</groupId>
         <artifactId>dubbo-remoting</artifactId>
-        <version>${revision}</version>
+        <version>3.0.0-SNAPSHOT</version>
     </parent>
     <artifactId>dubbo-remoting-http</artifactId>
     <packaging>jar</packaging>
diff --git a/dubbo-spi-remoting/dubbo-remoting-mina/pom.xml b/dubbo-spi-remoting/dubbo-remoting-mina/pom.xml
index 4808a17..f36ce1b 100644
--- a/dubbo-spi-remoting/dubbo-remoting-mina/pom.xml
+++ b/dubbo-spi-remoting/dubbo-remoting-mina/pom.xml
@@ -19,7 +19,7 @@
     <parent>
         <groupId>org.apache.dubbo</groupId>
         <artifactId>dubbo-remoting</artifactId>
-        <version>${revision}</version>
+        <version>3.0.0-SNAPSHOT</version>
     </parent>
     <artifactId>dubbo-remoting-mina</artifactId>
     <packaging>jar</packaging>
diff --git a/dubbo-spi-remoting/dubbo-remoting-p2p/pom.xml b/dubbo-spi-remoting/dubbo-remoting-p2p/pom.xml
index f947606..bfda7ad 100644
--- a/dubbo-spi-remoting/dubbo-remoting-p2p/pom.xml
+++ b/dubbo-spi-remoting/dubbo-remoting-p2p/pom.xml
@@ -19,7 +19,7 @@
     <parent>
         <groupId>org.apache.dubbo</groupId>
         <artifactId>dubbo-remoting</artifactId>
-        <version>${revision}</version>
+        <version>3.0.0-SNAPSHOT</version>
     </parent>
     <artifactId>dubbo-remoting-p2p</artifactId>
     <packaging>jar</packaging>
diff --git a/dubbo-spi-rpc/dubbo-rpc-hessian/pom.xml b/dubbo-spi-rpc/dubbo-rpc-hessian/pom.xml
index 99ef99d..8c0ac96 100644
--- a/dubbo-spi-rpc/dubbo-rpc-hessian/pom.xml
+++ b/dubbo-spi-rpc/dubbo-rpc-hessian/pom.xml
@@ -19,7 +19,7 @@
     <parent>
         <groupId>org.apache.dubbo</groupId>
         <artifactId>dubbo-rpc</artifactId>
-        <version>${revision}</version>
+        <version>3.0.0-SNAPSHOT</version>
     </parent>
     <artifactId>dubbo-rpc-hessian</artifactId>
     <packaging>jar</packaging>
diff --git a/dubbo-spi-rpc/dubbo-rpc-http/pom.xml b/dubbo-spi-rpc/dubbo-rpc-http/pom.xml
index 8552d73..5785259 100644
--- a/dubbo-spi-rpc/dubbo-rpc-http/pom.xml
+++ b/dubbo-spi-rpc/dubbo-rpc-http/pom.xml
@@ -20,7 +20,7 @@
     <parent>
         <artifactId>dubbo-rpc</artifactId>
         <groupId>org.apache.dubbo</groupId>
-        <version>${revision}</version>
+        <version>3.0.0-SNAPSHOT</version>
     </parent>
     <modelVersion>4.0.0</modelVersion>
 
diff --git a/dubbo-spi-rpc/dubbo-rpc-memcached/pom.xml b/dubbo-spi-rpc/dubbo-rpc-memcached/pom.xml
index bcfeea6..94ef107 100644
--- a/dubbo-spi-rpc/dubbo-rpc-memcached/pom.xml
+++ b/dubbo-spi-rpc/dubbo-rpc-memcached/pom.xml
@@ -19,7 +19,7 @@
     <parent>
         <groupId>org.apache.dubbo</groupId>
         <artifactId>dubbo-rpc</artifactId>
-        <version>${revision}</version>
+        <version>3.0.0-SNAPSHOT</version>
     </parent>
     <artifactId>dubbo-rpc-memcached</artifactId>
     <packaging>jar</packaging>
diff --git a/dubbo-spi-rpc/dubbo-rpc-native-thrift/pom.xml b/dubbo-spi-rpc/dubbo-rpc-native-thrift/pom.xml
index bcc3cf9..41b8186 100644
--- a/dubbo-spi-rpc/dubbo-rpc-native-thrift/pom.xml
+++ b/dubbo-spi-rpc/dubbo-rpc-native-thrift/pom.xml
@@ -19,7 +19,7 @@
     <parent>
         <groupId>org.apache.dubbo</groupId>
         <artifactId>dubbo-rpc</artifactId>
-        <version>${revision}</version>
+        <version>3.0.0-SNAPSHOT</version>
     </parent>
     <artifactId>dubbo-rpc-native-thrift</artifactId>
     <packaging>jar</packaging>
@@ -42,7 +42,7 @@
         <dependency>
             <groupId>org.apache.dubbo</groupId>
             <artifactId>dubbo-serialization-jdk</artifactId>
-            <version>${revision}</version>
+            <version>3.0.0-SNAPSHOT</version>
             <scope>test</scope>
         </dependency>
     </dependencies>
diff --git a/dubbo-spi-rpc/dubbo-rpc-redis/pom.xml b/dubbo-spi-rpc/dubbo-rpc-redis/pom.xml
index 8145d31..5fad732 100644
--- a/dubbo-spi-rpc/dubbo-rpc-redis/pom.xml
+++ b/dubbo-spi-rpc/dubbo-rpc-redis/pom.xml
@@ -19,7 +19,7 @@
     <parent>
         <groupId>org.apache.dubbo</groupId>
         <artifactId>dubbo-rpc</artifactId>
-        <version>${revision}</version>
+        <version>3.0.0-SNAPSHOT</version>
     </parent>
     <artifactId>dubbo-rpc-redis</artifactId>
     <packaging>jar</packaging>
diff --git a/dubbo-spi-rpc/dubbo-rpc-rmi/pom.xml b/dubbo-spi-rpc/dubbo-rpc-rmi/pom.xml
index 7e560b2..3af40ac 100644
--- a/dubbo-spi-rpc/dubbo-rpc-rmi/pom.xml
+++ b/dubbo-spi-rpc/dubbo-rpc-rmi/pom.xml
@@ -19,7 +19,7 @@
     <parent>
         <groupId>org.apache.dubbo</groupId>
         <artifactId>dubbo-rpc</artifactId>
-        <version>${revision}</version>
+        <version>3.0.0-SNAPSHOT</version>
     </parent>
     <artifactId>dubbo-rpc-rmi</artifactId>
     <packaging>jar</packaging>
diff --git a/dubbo-spi-rpc/dubbo-rpc-thrift/pom.xml b/dubbo-spi-rpc/dubbo-rpc-thrift/pom.xml
index d6e20ed..4aa545f 100644
--- a/dubbo-spi-rpc/dubbo-rpc-thrift/pom.xml
+++ b/dubbo-spi-rpc/dubbo-rpc-thrift/pom.xml
@@ -19,7 +19,7 @@
     <parent>
         <groupId>org.apache.dubbo</groupId>
         <artifactId>dubbo-rpc</artifactId>
-        <version>${revision}</version>
+        <version>3.0.0-SNAPSHOT</version>
     </parent>
     <artifactId>dubbo-rpc-thrift</artifactId>
     <packaging>jar</packaging>
diff --git a/dubbo-spi-rpc/dubbo-rpc-webservice/pom.xml b/dubbo-spi-rpc/dubbo-rpc-webservice/pom.xml
index 70078f8..fab4642 100644
--- a/dubbo-spi-rpc/dubbo-rpc-webservice/pom.xml
+++ b/dubbo-spi-rpc/dubbo-rpc-webservice/pom.xml
@@ -19,7 +19,7 @@
     <parent>
         <groupId>org.apache.dubbo</groupId>
         <artifactId>dubbo-rpc</artifactId>
-        <version>${revision}</version>
+        <version>3.0.0-SNAPSHOT</version>
     </parent>
     <artifactId>dubbo-rpc-webservice</artifactId>
     <packaging>jar</packaging>
diff --git a/dubbo-spi-rpc/dubbo-rpc-xml/pom.xml b/dubbo-spi-rpc/dubbo-rpc-xml/pom.xml
index 9afede9..ea8ea27 100644
--- a/dubbo-spi-rpc/dubbo-rpc-xml/pom.xml
+++ b/dubbo-spi-rpc/dubbo-rpc-xml/pom.xml
@@ -20,7 +20,7 @@
     <parent>
         <groupId>org.apache.dubbo</groupId>
         <artifactId>dubbo-rpc</artifactId>
-        <version>${revision}</version>
+        <version>3.0.0-SNAPSHOT</version>
     </parent>
 
     <artifactId>dubbo-rpc-xml</artifactId>
diff --git a/dubbo-spi-serialization/dubbo-serialization-avro/pom.xml b/dubbo-spi-serialization/dubbo-serialization-avro/pom.xml
index 908c49e..91ee1bc 100644
--- a/dubbo-spi-serialization/dubbo-serialization-avro/pom.xml
+++ b/dubbo-spi-serialization/dubbo-serialization-avro/pom.xml
@@ -20,7 +20,7 @@
     <parent>
         <groupId>org.apache.dubbo</groupId>
         <artifactId>dubbo-serialization</artifactId>
-        <version>${revision}</version>
+        <version>3.0.0-SNAPSHOT</version>
     </parent>
     <artifactId>dubbo-serialization-avro</artifactId>
     <packaging>jar</packaging>
diff --git a/dubbo-spi-serialization/dubbo-serialization-fastjson/pom.xml b/dubbo-spi-serialization/dubbo-serialization-fastjson/pom.xml
index 6553abd..93b9879 100644
--- a/dubbo-spi-serialization/dubbo-serialization-fastjson/pom.xml
+++ b/dubbo-spi-serialization/dubbo-serialization-fastjson/pom.xml
@@ -20,7 +20,7 @@ limitations under the License.
     <parent>
         <groupId>org.apache.dubbo</groupId>
         <artifactId>dubbo-serialization</artifactId>
-        <version>${revision}</version>
+        <version>3.0.0-SNAPSHOT</version>
     </parent>
     <artifactId>dubbo-serialization-fastjson</artifactId>
     <packaging>jar</packaging>
diff --git a/dubbo-spi-serialization/dubbo-serialization-fst/pom.xml b/dubbo-spi-serialization/dubbo-serialization-fst/pom.xml
index 1f2936e..f998b9d 100644
--- a/dubbo-spi-serialization/dubbo-serialization-fst/pom.xml
+++ b/dubbo-spi-serialization/dubbo-serialization-fst/pom.xml
@@ -19,7 +19,7 @@
     <parent>
         <groupId>org.apache.dubbo</groupId>
         <artifactId>dubbo-serialization</artifactId>
-        <version>${revision}</version>
+        <version>3.0.0-SNAPSHOT</version>
     </parent>
     <artifactId>dubbo-serialization-fst</artifactId>
     <packaging>jar</packaging>
diff --git a/dubbo-spi-serialization/dubbo-serialization-gson/pom.xml b/dubbo-spi-serialization/dubbo-serialization-gson/pom.xml
index 3822d37..dfa8845 100644
--- a/dubbo-spi-serialization/dubbo-serialization-gson/pom.xml
+++ b/dubbo-spi-serialization/dubbo-serialization-gson/pom.xml
@@ -19,7 +19,7 @@ Licensed to the Apache Software Foundation (ASF) under one or more
     <parent>
         <artifactId>dubbo-serialization</artifactId>
         <groupId>org.apache.dubbo</groupId>
-        <version>${revision}</version>
+        <version>3.0.0-SNAPSHOT</version>
     </parent>
     <artifactId>dubbo-serialization-gson</artifactId>
     <packaging>jar</packaging>
diff --git a/dubbo-spi-serialization/dubbo-serialization-kryo/pom.xml b/dubbo-spi-serialization/dubbo-serialization-kryo/pom.xml
index 86b5083..ee9c1fc 100644
--- a/dubbo-spi-serialization/dubbo-serialization-kryo/pom.xml
+++ b/dubbo-spi-serialization/dubbo-serialization-kryo/pom.xml
@@ -20,7 +20,7 @@ limitations under the License.
     <parent>
         <groupId>org.apache.dubbo</groupId>
         <artifactId>dubbo-serialization</artifactId>
-        <version>${revision}</version>
+        <version>3.0.0-SNAPSHOT</version>
     </parent>
     <artifactId>dubbo-serialization-kryo</artifactId>
     <packaging>jar</packaging>
diff --git a/dubbo-spi-serialization/dubbo-serialization-native-hession/pom.xml b/dubbo-spi-serialization/dubbo-serialization-native-hession/pom.xml
index 5293b29..66fdf9e 100644
--- a/dubbo-spi-serialization/dubbo-serialization-native-hession/pom.xml
+++ b/dubbo-spi-serialization/dubbo-serialization-native-hession/pom.xml
@@ -19,7 +19,7 @@ limitations under the License.
     <parent>
         <groupId>org.apache.dubbo</groupId>
         <artifactId>dubbo-serialization</artifactId>
-        <version>${revision}</version>
+        <version>3.0.0-SNAPSHOT</version>
     </parent>
     <modelVersion>4.0.0</modelVersion>
 
diff --git a/dubbo-spi-serialization/dubbo-serialization-protobuf/pom.xml b/dubbo-spi-serialization/dubbo-serialization-protobuf/pom.xml
index c268d18..af501b4 100644
--- a/dubbo-spi-serialization/dubbo-serialization-protobuf/pom.xml
+++ b/dubbo-spi-serialization/dubbo-serialization-protobuf/pom.xml
@@ -20,7 +20,7 @@ limitations under the License.
     <parent>
         <groupId>org.apache.dubbo</groupId>
         <artifactId>dubbo-serialization</artifactId>
-        <version>${revision}</version>
+        <version>3.0.0-SNAPSHOT</version>
     </parent>
     <artifactId>dubbo-serialization-protobuf</artifactId>
     <packaging>jar</packaging>
diff --git a/dubbo-spi-serialization/dubbo-serialization-protostuff/pom.xml b/dubbo-spi-serialization/dubbo-serialization-protostuff/pom.xml
index 0631f13..45980d0 100644
--- a/dubbo-spi-serialization/dubbo-serialization-protostuff/pom.xml
+++ b/dubbo-spi-serialization/dubbo-serialization-protostuff/pom.xml
@@ -20,7 +20,7 @@ limitations under the License.
     <parent>
         <groupId>org.apache.dubbo</groupId>
         <artifactId>dubbo-serialization</artifactId>
-        <version>${revision}</version>
+        <version>3.0.0-SNAPSHOT</version>
     </parent>
 
     <artifactId>dubbo-serialization-protostuff</artifactId>
diff --git a/dubbo-spi-serialization/dubbo-serialization-test/pom.xml b/dubbo-spi-serialization/dubbo-serialization-test/pom.xml
index aac9fb0..59c9891 100644
--- a/dubbo-spi-serialization/dubbo-serialization-test/pom.xml
+++ b/dubbo-spi-serialization/dubbo-serialization-test/pom.xml
@@ -19,7 +19,7 @@
     <parent>
         <groupId>org.apache.dubbo</groupId>
         <artifactId>dubbo-serialization</artifactId>
-        <version>${revision}</version>
+        <version>3.0.0-SNAPSHOT</version>
     </parent>
     <modelVersion>4.0.0</modelVersion>
 


[dubbo-spi-extensions] 23/39: 增加 sca-example 的配制文件

Posted by li...@apache.org.
This is an automated email from the ASF dual-hosted git repository.

liujun pushed a commit to branch 2.7.x
in repository https://gitbox.apache.org/repos/asf/dubbo-spi-extensions.git

commit 7fe9de0ad874aea1adfcd908b4bb697a67640d14
Author: qq213539 <21...@qq.com>
AuthorDate: Fri Dec 18 17:48:38 2020 +0800

    增加 sca-example 的配制文件
---
 .../examples-provider-sca/src/main/resources/application.yml | 12 ++++++++++++
 .../examples-provider-sca/src/main/resources/bootstrap.yml   |  9 +++++++++
 .../src/main/resources/dubbo.properties                      |  1 +
 3 files changed, 22 insertions(+)

diff --git a/dubbo-api-docs/dubbo-api-docs-examples/examples-provider-sca/src/main/resources/application.yml b/dubbo-api-docs/dubbo-api-docs-examples/examples-provider-sca/src/main/resources/application.yml
new file mode 100644
index 0000000..c8209d5
--- /dev/null
+++ b/dubbo-api-docs/dubbo-api-docs-examples/examples-provider-sca/src/main/resources/application.yml
@@ -0,0 +1,12 @@
+dubbo:
+  registry:
+    address: spring-cloud://localhost
+  provider:
+    timeout: 2000
+  protocol:
+    port: 20882
+    name: dubbo
+spring:
+  main:
+    # Spring Boot 2.1 需要设定
+    allow-bean-definition-overriding: true
\ No newline at end of file
diff --git a/dubbo-api-docs/dubbo-api-docs-examples/examples-provider-sca/src/main/resources/bootstrap.yml b/dubbo-api-docs/dubbo-api-docs-examples/examples-provider-sca/src/main/resources/bootstrap.yml
new file mode 100644
index 0000000..d5cab0c
--- /dev/null
+++ b/dubbo-api-docs/dubbo-api-docs-examples/examples-provider-sca/src/main/resources/bootstrap.yml
@@ -0,0 +1,9 @@
+spring:
+  application:
+    name: dubbo-api-docs-example-provider-sca
+  profiles:
+    active: dev
+  cloud:
+    nacos:
+      discovery:
+        serverAddr: "127.0.0.1:8848"
\ No newline at end of file
diff --git a/dubbo-api-docs/dubbo-api-docs-examples/examples-provider-sca/src/main/resources/dubbo.properties b/dubbo-api-docs/dubbo-api-docs-examples/examples-provider-sca/src/main/resources/dubbo.properties
new file mode 100644
index 0000000..ca71826
--- /dev/null
+++ b/dubbo-api-docs/dubbo-api-docs-examples/examples-provider-sca/src/main/resources/dubbo.properties
@@ -0,0 +1 @@
+dubbo.application.qos.port=22222
\ No newline at end of file


[dubbo-spi-extensions] 06/39: unify parent pom version to {revision}

Posted by li...@apache.org.
This is an automated email from the ASF dual-hosted git repository.

liujun pushed a commit to branch 2.7.x
in repository https://gitbox.apache.org/repos/asf/dubbo-spi-extensions.git

commit 1fa6ce06c3c53f2c044bd2cafa61c7cc1d67f995
Author: ken.lj <ke...@gmail.com>
AuthorDate: Thu Aug 27 15:05:59 2020 +0800

    unify parent pom version to {revision}
---
 dubbo-all/pom.xml                                  |   4 +-
 .../dubbo-configcenter-consul/pom.xml              |   2 +-
 .../dubbo-configcenter-etcd/pom.xml                |   2 +-
 dubbo-spi-container/dubbo-container-log4j/pom.xml  |   2 +-
 .../dubbo-container-logback/pom.xml                |   2 +-
 .../dubbo-metadata-report-consul/pom.xml           |   2 +-
 .../dubbo-metadata-report-etcd/pom.xml             |   2 +-
 dubbo-spi-registry/dubbo-registry-consul/pom.xml   |   2 +-
 dubbo-spi-registry/dubbo-registry-default/pom.xml  |   2 +-
 dubbo-spi-registry/dubbo-registry-etcd3/pom.xml    |   2 +-
 dubbo-spi-registry/dubbo-registry-eureka/pom.xml   |   2 +-
 dubbo-spi-registry/dubbo-registry-redis/pom.xml    |   2 +-
 dubbo-spi-registry/dubbo-registry-sofa/pom.xml     |   2 +-
 dubbo-spi-remoting/dubbo-remoting-etcd3/pom.xml    |   2 +-
 dubbo-spi-remoting/dubbo-remoting-grizzly/pom.xml  |   2 +-
 dubbo-spi-remoting/dubbo-remoting-http/pom.xml     |   2 +-
 dubbo-spi-remoting/dubbo-remoting-mina/pom.xml     |   2 +-
 dubbo-spi-remoting/dubbo-remoting-p2p/pom.xml      |   2 +-
 dubbo-spi-rpc/dubbo-rpc-hessian/pom.xml            |   2 +-
 dubbo-spi-rpc/dubbo-rpc-http/pom.xml               |   2 +-
 dubbo-spi-rpc/dubbo-rpc-memcached/pom.xml          |   2 +-
 dubbo-spi-rpc/dubbo-rpc-native-thrift/pom.xml      |   2 +-
 dubbo-spi-rpc/dubbo-rpc-redis/pom.xml              |   2 +-
 dubbo-spi-rpc/dubbo-rpc-rmi/pom.xml                |   2 +-
 dubbo-spi-rpc/dubbo-rpc-thrift/pom.xml             |   2 +-
 dubbo-spi-rpc/dubbo-rpc-webservice/pom.xml         |   2 +-
 dubbo-spi-rpc/dubbo-rpc-xml/pom.xml                |   2 +-
 .../dubbo-serialization-avro/pom.xml               |   2 +-
 .../dubbo-serialization-fastjson/pom.xml           |   2 +-
 .../dubbo-serialization-fst/pom.xml                |   2 +-
 .../dubbo-serialization-gson/pom.xml               |   2 +-
 .../dubbo-serialization-kryo/pom.xml               |   2 +-
 .../dubbo-serialization-native-hession/pom.xml     |   2 +-
 .../dubbo-serialization-protobuf/pom.xml           |   2 +-
 .../dubbo-serialization-protostuff/pom.xml         |   2 +-
 .../dubbo-serialization-test/pom.xml               |   2 +-
 dubbo-test/pom.xml                                 | 207 +++++++++++++++++++++
 pom.xml                                            |   3 +-
 38 files changed, 245 insertions(+), 39 deletions(-)

diff --git a/dubbo-all/pom.xml b/dubbo-all/pom.xml
index dab2d12..495ef55 100644
--- a/dubbo-all/pom.xml
+++ b/dubbo-all/pom.xml
@@ -20,9 +20,9 @@
     <parent>
         <groupId>org.apache.dubbo</groupId>
         <artifactId>dubbo-parent</artifactId>
-        <version>2.7.7-SNAPSHOT</version>
+        <version>${revision}</version>
     </parent>
-    <artifactId>dubbo</artifactId>
+    <artifactId>dubbo-all</artifactId>
     <packaging>jar</packaging>
     <name>dubbo-all</name>
     <description>The all in one project of dubbo</description>
diff --git a/dubbo-spi-configcenter/dubbo-configcenter-consul/pom.xml b/dubbo-spi-configcenter/dubbo-configcenter-consul/pom.xml
index bdabca7..674728c 100644
--- a/dubbo-spi-configcenter/dubbo-configcenter-consul/pom.xml
+++ b/dubbo-spi-configcenter/dubbo-configcenter-consul/pom.xml
@@ -22,7 +22,7 @@
     <parent>
         <groupId>org.apache.dubbo</groupId>
         <artifactId>dubbo-configcenter</artifactId>
-        <version>2.7.7-SNAPSHOT</version>
+        <version>${revision}</version>
     </parent>
 
     <artifactId>dubbo-configcenter-consul</artifactId>
diff --git a/dubbo-spi-configcenter/dubbo-configcenter-etcd/pom.xml b/dubbo-spi-configcenter/dubbo-configcenter-etcd/pom.xml
index 570ec92..22d5f6d 100644
--- a/dubbo-spi-configcenter/dubbo-configcenter-etcd/pom.xml
+++ b/dubbo-spi-configcenter/dubbo-configcenter-etcd/pom.xml
@@ -24,7 +24,7 @@
     <parent>
         <groupId>org.apache.dubbo</groupId>
         <artifactId>dubbo-configcenter</artifactId>
-        <version>2.7.7-SNAPSHOT</version>
+        <version>${revision}</version>
     </parent>
 
     <artifactId>dubbo-configcenter-etcd</artifactId>
diff --git a/dubbo-spi-container/dubbo-container-log4j/pom.xml b/dubbo-spi-container/dubbo-container-log4j/pom.xml
index a92d9b4..d4503df 100644
--- a/dubbo-spi-container/dubbo-container-log4j/pom.xml
+++ b/dubbo-spi-container/dubbo-container-log4j/pom.xml
@@ -19,7 +19,7 @@
     <parent>
         <groupId>org.apache.dubbo</groupId>
         <artifactId>dubbo-container</artifactId>
-        <version>2.7.7-SNAPSHOT</version>
+        <version>${revision}</version>
     </parent>
     <artifactId>dubbo-container-log4j</artifactId>
     <packaging>jar</packaging>
diff --git a/dubbo-spi-container/dubbo-container-logback/pom.xml b/dubbo-spi-container/dubbo-container-logback/pom.xml
index dec8f54..a6f7014 100644
--- a/dubbo-spi-container/dubbo-container-logback/pom.xml
+++ b/dubbo-spi-container/dubbo-container-logback/pom.xml
@@ -19,7 +19,7 @@
     <parent>
         <groupId>org.apache.dubbo</groupId>
         <artifactId>dubbo-container</artifactId>
-        <version>2.7.7-SNAPSHOT</version>
+        <version>${revision}</version>
     </parent>
     <artifactId>dubbo-container-logback</artifactId>
     <packaging>jar</packaging>
diff --git a/dubbo-spi-metadata/dubbo-metadata-report-consul/pom.xml b/dubbo-spi-metadata/dubbo-metadata-report-consul/pom.xml
index 7a76f17..215fabc 100644
--- a/dubbo-spi-metadata/dubbo-metadata-report-consul/pom.xml
+++ b/dubbo-spi-metadata/dubbo-metadata-report-consul/pom.xml
@@ -20,7 +20,7 @@
     <parent>
         <groupId>org.apache.dubbo</groupId>
         <artifactId>dubbo-metadata</artifactId>
-        <version>2.7.7-SNAPSHOT</version>
+        <version>${revision}</version>
     </parent>
     <modelVersion>4.0.0</modelVersion>
 
diff --git a/dubbo-spi-metadata/dubbo-metadata-report-etcd/pom.xml b/dubbo-spi-metadata/dubbo-metadata-report-etcd/pom.xml
index 9199ca5..0b53419 100644
--- a/dubbo-spi-metadata/dubbo-metadata-report-etcd/pom.xml
+++ b/dubbo-spi-metadata/dubbo-metadata-report-etcd/pom.xml
@@ -22,7 +22,7 @@
     <parent>
         <groupId>org.apache.dubbo</groupId>
         <artifactId>dubbo-metadata</artifactId>
-        <version>2.7.7-SNAPSHOT</version>
+        <version>${revision}</version>
     </parent>
     <modelVersion>4.0.0</modelVersion>
 
diff --git a/dubbo-spi-registry/dubbo-registry-consul/pom.xml b/dubbo-spi-registry/dubbo-registry-consul/pom.xml
index c8d31ea..090c3e6 100644
--- a/dubbo-spi-registry/dubbo-registry-consul/pom.xml
+++ b/dubbo-spi-registry/dubbo-registry-consul/pom.xml
@@ -20,7 +20,7 @@
     <parent>
         <artifactId>dubbo-registry</artifactId>
         <groupId>org.apache.dubbo</groupId>
-        <version>2.7.7-SNAPSHOT</version>
+        <version>${revision}</version>
     </parent>
     <modelVersion>4.0.0</modelVersion>
 
diff --git a/dubbo-spi-registry/dubbo-registry-default/pom.xml b/dubbo-spi-registry/dubbo-registry-default/pom.xml
index 27b8a48..37df8f2 100644
--- a/dubbo-spi-registry/dubbo-registry-default/pom.xml
+++ b/dubbo-spi-registry/dubbo-registry-default/pom.xml
@@ -20,7 +20,7 @@
     <parent>
         <groupId>org.apache.dubbo</groupId>
         <artifactId>dubbo-registry</artifactId>
-        <version>2.7.7-SNAPSHOT</version>
+        <version>${revision}</version>
     </parent>
     <artifactId>dubbo-registry-default</artifactId>
     <packaging>jar</packaging>
diff --git a/dubbo-spi-registry/dubbo-registry-etcd3/pom.xml b/dubbo-spi-registry/dubbo-registry-etcd3/pom.xml
index c239c81..6d9d60c 100644
--- a/dubbo-spi-registry/dubbo-registry-etcd3/pom.xml
+++ b/dubbo-spi-registry/dubbo-registry-etcd3/pom.xml
@@ -21,7 +21,7 @@
     <parent>
         <artifactId>dubbo-registry</artifactId>
         <groupId>org.apache.dubbo</groupId>
-        <version>2.7.7-SNAPSHOT</version>
+        <version>${revision}</version>
     </parent>
 
     <artifactId>dubbo-registry-etcd3</artifactId>
diff --git a/dubbo-spi-registry/dubbo-registry-eureka/pom.xml b/dubbo-spi-registry/dubbo-registry-eureka/pom.xml
index a740abd..b2a6abe 100644
--- a/dubbo-spi-registry/dubbo-registry-eureka/pom.xml
+++ b/dubbo-spi-registry/dubbo-registry-eureka/pom.xml
@@ -22,7 +22,7 @@
     <parent>
         <groupId>org.apache.dubbo</groupId>
         <artifactId>dubbo-registry</artifactId>
-        <version>2.7.7-SNAPSHOT</version>
+        <version>${revision}</version>
     </parent>
 
     <artifactId>dubbo-registry-eureka</artifactId>
diff --git a/dubbo-spi-registry/dubbo-registry-redis/pom.xml b/dubbo-spi-registry/dubbo-registry-redis/pom.xml
index 64d7b0c..fe6bd40 100644
--- a/dubbo-spi-registry/dubbo-registry-redis/pom.xml
+++ b/dubbo-spi-registry/dubbo-registry-redis/pom.xml
@@ -19,7 +19,7 @@
     <parent>
         <groupId>org.apache.dubbo</groupId>
         <artifactId>dubbo-registry</artifactId>
-        <version>2.7.7-SNAPSHOT</version>
+        <version>${revision}</version>
     </parent>
     <artifactId>dubbo-registry-redis</artifactId>
     <packaging>jar</packaging>
diff --git a/dubbo-spi-registry/dubbo-registry-sofa/pom.xml b/dubbo-spi-registry/dubbo-registry-sofa/pom.xml
index c7850c3..66dc846 100644
--- a/dubbo-spi-registry/dubbo-registry-sofa/pom.xml
+++ b/dubbo-spi-registry/dubbo-registry-sofa/pom.xml
@@ -19,7 +19,7 @@
     <parent>
         <groupId>org.apache.dubbo</groupId>
         <artifactId>dubbo-registry</artifactId>
-        <version>2.7.7-SNAPSHOT</version>
+        <version>${revision}</version>
     </parent>
     <modelVersion>4.0.0</modelVersion>
 
diff --git a/dubbo-spi-remoting/dubbo-remoting-etcd3/pom.xml b/dubbo-spi-remoting/dubbo-remoting-etcd3/pom.xml
index 73d81e0..e7428e0 100644
--- a/dubbo-spi-remoting/dubbo-remoting-etcd3/pom.xml
+++ b/dubbo-spi-remoting/dubbo-remoting-etcd3/pom.xml
@@ -23,7 +23,7 @@
     <parent>
         <artifactId>dubbo-remoting</artifactId>
         <groupId>org.apache.dubbo</groupId>
-        <version>2.7.7-SNAPSHOT</version>
+        <version>${revision}</version>
     </parent>
     <artifactId>dubbo-remoting-etcd3</artifactId>
     <packaging>jar</packaging>
diff --git a/dubbo-spi-remoting/dubbo-remoting-grizzly/pom.xml b/dubbo-spi-remoting/dubbo-remoting-grizzly/pom.xml
index b53ea67..cd18536 100644
--- a/dubbo-spi-remoting/dubbo-remoting-grizzly/pom.xml
+++ b/dubbo-spi-remoting/dubbo-remoting-grizzly/pom.xml
@@ -19,7 +19,7 @@
     <parent>
         <groupId>org.apache.dubbo</groupId>
         <artifactId>dubbo-remoting</artifactId>
-        <version>2.7.7-SNAPSHOT</version>
+        <version>${revision}</version>
     </parent>
     <artifactId>dubbo-remoting-grizzly</artifactId>
     <packaging>jar</packaging>
diff --git a/dubbo-spi-remoting/dubbo-remoting-http/pom.xml b/dubbo-spi-remoting/dubbo-remoting-http/pom.xml
index b393531..19c8220 100644
--- a/dubbo-spi-remoting/dubbo-remoting-http/pom.xml
+++ b/dubbo-spi-remoting/dubbo-remoting-http/pom.xml
@@ -19,7 +19,7 @@
     <parent>
         <groupId>org.apache.dubbo</groupId>
         <artifactId>dubbo-remoting</artifactId>
-        <version>2.7.7-SNAPSHOT</version>
+        <version>${revision}</version>
     </parent>
     <artifactId>dubbo-remoting-http</artifactId>
     <packaging>jar</packaging>
diff --git a/dubbo-spi-remoting/dubbo-remoting-mina/pom.xml b/dubbo-spi-remoting/dubbo-remoting-mina/pom.xml
index 43f1fc2..4808a17 100644
--- a/dubbo-spi-remoting/dubbo-remoting-mina/pom.xml
+++ b/dubbo-spi-remoting/dubbo-remoting-mina/pom.xml
@@ -19,7 +19,7 @@
     <parent>
         <groupId>org.apache.dubbo</groupId>
         <artifactId>dubbo-remoting</artifactId>
-        <version>2.7.7-SNAPSHOT</version>
+        <version>${revision}</version>
     </parent>
     <artifactId>dubbo-remoting-mina</artifactId>
     <packaging>jar</packaging>
diff --git a/dubbo-spi-remoting/dubbo-remoting-p2p/pom.xml b/dubbo-spi-remoting/dubbo-remoting-p2p/pom.xml
index 062a415..f947606 100644
--- a/dubbo-spi-remoting/dubbo-remoting-p2p/pom.xml
+++ b/dubbo-spi-remoting/dubbo-remoting-p2p/pom.xml
@@ -19,7 +19,7 @@
     <parent>
         <groupId>org.apache.dubbo</groupId>
         <artifactId>dubbo-remoting</artifactId>
-        <version>2.7.7-SNAPSHOT</version>
+        <version>${revision}</version>
     </parent>
     <artifactId>dubbo-remoting-p2p</artifactId>
     <packaging>jar</packaging>
diff --git a/dubbo-spi-rpc/dubbo-rpc-hessian/pom.xml b/dubbo-spi-rpc/dubbo-rpc-hessian/pom.xml
index c803990..99ef99d 100644
--- a/dubbo-spi-rpc/dubbo-rpc-hessian/pom.xml
+++ b/dubbo-spi-rpc/dubbo-rpc-hessian/pom.xml
@@ -19,7 +19,7 @@
     <parent>
         <groupId>org.apache.dubbo</groupId>
         <artifactId>dubbo-rpc</artifactId>
-        <version>2.7.7-SNAPSHOT</version>
+        <version>${revision}</version>
     </parent>
     <artifactId>dubbo-rpc-hessian</artifactId>
     <packaging>jar</packaging>
diff --git a/dubbo-spi-rpc/dubbo-rpc-http/pom.xml b/dubbo-spi-rpc/dubbo-rpc-http/pom.xml
index 386f0a1..8552d73 100644
--- a/dubbo-spi-rpc/dubbo-rpc-http/pom.xml
+++ b/dubbo-spi-rpc/dubbo-rpc-http/pom.xml
@@ -20,7 +20,7 @@
     <parent>
         <artifactId>dubbo-rpc</artifactId>
         <groupId>org.apache.dubbo</groupId>
-        <version>2.7.7-SNAPSHOT</version>
+        <version>${revision}</version>
     </parent>
     <modelVersion>4.0.0</modelVersion>
 
diff --git a/dubbo-spi-rpc/dubbo-rpc-memcached/pom.xml b/dubbo-spi-rpc/dubbo-rpc-memcached/pom.xml
index c741fcc..bcfeea6 100644
--- a/dubbo-spi-rpc/dubbo-rpc-memcached/pom.xml
+++ b/dubbo-spi-rpc/dubbo-rpc-memcached/pom.xml
@@ -19,7 +19,7 @@
     <parent>
         <groupId>org.apache.dubbo</groupId>
         <artifactId>dubbo-rpc</artifactId>
-        <version>2.7.7-SNAPSHOT</version>
+        <version>${revision}</version>
     </parent>
     <artifactId>dubbo-rpc-memcached</artifactId>
     <packaging>jar</packaging>
diff --git a/dubbo-spi-rpc/dubbo-rpc-native-thrift/pom.xml b/dubbo-spi-rpc/dubbo-rpc-native-thrift/pom.xml
index d0a5ecc..bcc3cf9 100644
--- a/dubbo-spi-rpc/dubbo-rpc-native-thrift/pom.xml
+++ b/dubbo-spi-rpc/dubbo-rpc-native-thrift/pom.xml
@@ -19,7 +19,7 @@
     <parent>
         <groupId>org.apache.dubbo</groupId>
         <artifactId>dubbo-rpc</artifactId>
-        <version>2.7.7-SNAPSHOT</version>
+        <version>${revision}</version>
     </parent>
     <artifactId>dubbo-rpc-native-thrift</artifactId>
     <packaging>jar</packaging>
diff --git a/dubbo-spi-rpc/dubbo-rpc-redis/pom.xml b/dubbo-spi-rpc/dubbo-rpc-redis/pom.xml
index 016501f..8145d31 100644
--- a/dubbo-spi-rpc/dubbo-rpc-redis/pom.xml
+++ b/dubbo-spi-rpc/dubbo-rpc-redis/pom.xml
@@ -19,7 +19,7 @@
     <parent>
         <groupId>org.apache.dubbo</groupId>
         <artifactId>dubbo-rpc</artifactId>
-        <version>2.7.7-SNAPSHOT</version>
+        <version>${revision}</version>
     </parent>
     <artifactId>dubbo-rpc-redis</artifactId>
     <packaging>jar</packaging>
diff --git a/dubbo-spi-rpc/dubbo-rpc-rmi/pom.xml b/dubbo-spi-rpc/dubbo-rpc-rmi/pom.xml
index 32cb565..7e560b2 100644
--- a/dubbo-spi-rpc/dubbo-rpc-rmi/pom.xml
+++ b/dubbo-spi-rpc/dubbo-rpc-rmi/pom.xml
@@ -19,7 +19,7 @@
     <parent>
         <groupId>org.apache.dubbo</groupId>
         <artifactId>dubbo-rpc</artifactId>
-        <version>2.7.7-SNAPSHOT</version>
+        <version>${revision}</version>
     </parent>
     <artifactId>dubbo-rpc-rmi</artifactId>
     <packaging>jar</packaging>
diff --git a/dubbo-spi-rpc/dubbo-rpc-thrift/pom.xml b/dubbo-spi-rpc/dubbo-rpc-thrift/pom.xml
index 2164ed3..d6e20ed 100644
--- a/dubbo-spi-rpc/dubbo-rpc-thrift/pom.xml
+++ b/dubbo-spi-rpc/dubbo-rpc-thrift/pom.xml
@@ -19,7 +19,7 @@
     <parent>
         <groupId>org.apache.dubbo</groupId>
         <artifactId>dubbo-rpc</artifactId>
-        <version>2.7.7-SNAPSHOT</version>
+        <version>${revision}</version>
     </parent>
     <artifactId>dubbo-rpc-thrift</artifactId>
     <packaging>jar</packaging>
diff --git a/dubbo-spi-rpc/dubbo-rpc-webservice/pom.xml b/dubbo-spi-rpc/dubbo-rpc-webservice/pom.xml
index beeefed..70078f8 100644
--- a/dubbo-spi-rpc/dubbo-rpc-webservice/pom.xml
+++ b/dubbo-spi-rpc/dubbo-rpc-webservice/pom.xml
@@ -19,7 +19,7 @@
     <parent>
         <groupId>org.apache.dubbo</groupId>
         <artifactId>dubbo-rpc</artifactId>
-        <version>2.7.7-SNAPSHOT</version>
+        <version>${revision}</version>
     </parent>
     <artifactId>dubbo-rpc-webservice</artifactId>
     <packaging>jar</packaging>
diff --git a/dubbo-spi-rpc/dubbo-rpc-xml/pom.xml b/dubbo-spi-rpc/dubbo-rpc-xml/pom.xml
index 736dfb2..9afede9 100644
--- a/dubbo-spi-rpc/dubbo-rpc-xml/pom.xml
+++ b/dubbo-spi-rpc/dubbo-rpc-xml/pom.xml
@@ -20,7 +20,7 @@
     <parent>
         <groupId>org.apache.dubbo</groupId>
         <artifactId>dubbo-rpc</artifactId>
-        <version>2.7.7-SNAPSHOT</version>
+        <version>${revision}</version>
     </parent>
 
     <artifactId>dubbo-rpc-xml</artifactId>
diff --git a/dubbo-spi-serialization/dubbo-serialization-avro/pom.xml b/dubbo-spi-serialization/dubbo-serialization-avro/pom.xml
index baa15d0..908c49e 100644
--- a/dubbo-spi-serialization/dubbo-serialization-avro/pom.xml
+++ b/dubbo-spi-serialization/dubbo-serialization-avro/pom.xml
@@ -20,7 +20,7 @@
     <parent>
         <groupId>org.apache.dubbo</groupId>
         <artifactId>dubbo-serialization</artifactId>
-        <version>2.7.7-SNAPSHOT</version>
+        <version>${revision}</version>
     </parent>
     <artifactId>dubbo-serialization-avro</artifactId>
     <packaging>jar</packaging>
diff --git a/dubbo-spi-serialization/dubbo-serialization-fastjson/pom.xml b/dubbo-spi-serialization/dubbo-serialization-fastjson/pom.xml
index b0d63c2..6553abd 100644
--- a/dubbo-spi-serialization/dubbo-serialization-fastjson/pom.xml
+++ b/dubbo-spi-serialization/dubbo-serialization-fastjson/pom.xml
@@ -20,7 +20,7 @@ limitations under the License.
     <parent>
         <groupId>org.apache.dubbo</groupId>
         <artifactId>dubbo-serialization</artifactId>
-        <version>2.7.7-SNAPSHOT</version>
+        <version>${revision}</version>
     </parent>
     <artifactId>dubbo-serialization-fastjson</artifactId>
     <packaging>jar</packaging>
diff --git a/dubbo-spi-serialization/dubbo-serialization-fst/pom.xml b/dubbo-spi-serialization/dubbo-serialization-fst/pom.xml
index 31a528b..1f2936e 100644
--- a/dubbo-spi-serialization/dubbo-serialization-fst/pom.xml
+++ b/dubbo-spi-serialization/dubbo-serialization-fst/pom.xml
@@ -19,7 +19,7 @@
     <parent>
         <groupId>org.apache.dubbo</groupId>
         <artifactId>dubbo-serialization</artifactId>
-        <version>2.7.7-SNAPSHOT</version>
+        <version>${revision}</version>
     </parent>
     <artifactId>dubbo-serialization-fst</artifactId>
     <packaging>jar</packaging>
diff --git a/dubbo-spi-serialization/dubbo-serialization-gson/pom.xml b/dubbo-spi-serialization/dubbo-serialization-gson/pom.xml
index 120622b..3822d37 100644
--- a/dubbo-spi-serialization/dubbo-serialization-gson/pom.xml
+++ b/dubbo-spi-serialization/dubbo-serialization-gson/pom.xml
@@ -19,7 +19,7 @@ Licensed to the Apache Software Foundation (ASF) under one or more
     <parent>
         <artifactId>dubbo-serialization</artifactId>
         <groupId>org.apache.dubbo</groupId>
-        <version>2.7.7-SNAPSHOT</version>
+        <version>${revision}</version>
     </parent>
     <artifactId>dubbo-serialization-gson</artifactId>
     <packaging>jar</packaging>
diff --git a/dubbo-spi-serialization/dubbo-serialization-kryo/pom.xml b/dubbo-spi-serialization/dubbo-serialization-kryo/pom.xml
index 2da0979..86b5083 100644
--- a/dubbo-spi-serialization/dubbo-serialization-kryo/pom.xml
+++ b/dubbo-spi-serialization/dubbo-serialization-kryo/pom.xml
@@ -20,7 +20,7 @@ limitations under the License.
     <parent>
         <groupId>org.apache.dubbo</groupId>
         <artifactId>dubbo-serialization</artifactId>
-        <version>2.7.7-SNAPSHOT</version>
+        <version>${revision}</version>
     </parent>
     <artifactId>dubbo-serialization-kryo</artifactId>
     <packaging>jar</packaging>
diff --git a/dubbo-spi-serialization/dubbo-serialization-native-hession/pom.xml b/dubbo-spi-serialization/dubbo-serialization-native-hession/pom.xml
index 755ed8e..5293b29 100644
--- a/dubbo-spi-serialization/dubbo-serialization-native-hession/pom.xml
+++ b/dubbo-spi-serialization/dubbo-serialization-native-hession/pom.xml
@@ -19,7 +19,7 @@ limitations under the License.
     <parent>
         <groupId>org.apache.dubbo</groupId>
         <artifactId>dubbo-serialization</artifactId>
-        <version>2.7.7-SNAPSHOT</version>
+        <version>${revision}</version>
     </parent>
     <modelVersion>4.0.0</modelVersion>
 
diff --git a/dubbo-spi-serialization/dubbo-serialization-protobuf/pom.xml b/dubbo-spi-serialization/dubbo-serialization-protobuf/pom.xml
index 34cad66..c268d18 100644
--- a/dubbo-spi-serialization/dubbo-serialization-protobuf/pom.xml
+++ b/dubbo-spi-serialization/dubbo-serialization-protobuf/pom.xml
@@ -20,7 +20,7 @@ limitations under the License.
     <parent>
         <groupId>org.apache.dubbo</groupId>
         <artifactId>dubbo-serialization</artifactId>
-        <version>2.7.7-SNAPSHOT</version>
+        <version>${revision}</version>
     </parent>
     <artifactId>dubbo-serialization-protobuf</artifactId>
     <packaging>jar</packaging>
diff --git a/dubbo-spi-serialization/dubbo-serialization-protostuff/pom.xml b/dubbo-spi-serialization/dubbo-serialization-protostuff/pom.xml
index 1e6ea57..0631f13 100644
--- a/dubbo-spi-serialization/dubbo-serialization-protostuff/pom.xml
+++ b/dubbo-spi-serialization/dubbo-serialization-protostuff/pom.xml
@@ -20,7 +20,7 @@ limitations under the License.
     <parent>
         <groupId>org.apache.dubbo</groupId>
         <artifactId>dubbo-serialization</artifactId>
-        <version>2.7.7-SNAPSHOT</version>
+        <version>${revision}</version>
     </parent>
 
     <artifactId>dubbo-serialization-protostuff</artifactId>
diff --git a/dubbo-spi-serialization/dubbo-serialization-test/pom.xml b/dubbo-spi-serialization/dubbo-serialization-test/pom.xml
index 77fee1f..aac9fb0 100644
--- a/dubbo-spi-serialization/dubbo-serialization-test/pom.xml
+++ b/dubbo-spi-serialization/dubbo-serialization-test/pom.xml
@@ -19,7 +19,7 @@
     <parent>
         <groupId>org.apache.dubbo</groupId>
         <artifactId>dubbo-serialization</artifactId>
-        <version>2.7.7-SNAPSHOT</version>
+        <version>${revision}</version>
     </parent>
     <modelVersion>4.0.0</modelVersion>
 
diff --git a/dubbo-test/pom.xml b/dubbo-test/pom.xml
new file mode 100644
index 0000000..66720dc
--- /dev/null
+++ b/dubbo-test/pom.xml
@@ -0,0 +1,207 @@
+<?xml version="1.0" encoding="UTF-8"?>
+<!--
+  ~ 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.
+  -->
+
+<project xmlns="http://maven.apache.org/POM/4.0.0" xmlns:xsi="http://www.w3.org/2001/XMLSchema-instance" xsi:schemaLocation="http://maven.apache.org/POM/4.0.0 http://maven.apache.org/xsd/maven-4.0.0.xsd">
+    <parent>
+        <groupId>org.apache.dubbo.spi</groupId>
+        <artifactId>dubbo-spi-extensions</artifactId>
+        <version>${revision}</version>
+    </parent>
+    <modelVersion>4.0.0</modelVersion>
+
+    <artifactId>dubbo-test</artifactId>
+
+    <dependencies>
+        <dependency>
+            <groupId>org.apache.dubbo</groupId>
+            <artifactId>dubbo-rpc-dubbo</artifactId>
+            <version>${project.parent.version}</version>
+            <scope>test</scope>
+        </dependency>
+
+        <dependency>
+            <groupId>org.apache.dubbo</groupId>
+            <artifactId>dubbo-rpc-rest</artifactId>
+            <version>${project.parent.version}</version>
+            <scope>test</scope>
+        </dependency>
+
+        <dependency>
+            <groupId>org.apache.dubbo</groupId>
+            <artifactId>dubbo-rpc-rmi</artifactId>
+            <version>${project.parent.version}</version>
+            <scope>test</scope>
+        </dependency>
+
+        <dependency>
+            <groupId>org.apache.dubbo</groupId>
+            <artifactId>dubbo-rpc-hessian</artifactId>
+            <version>${project.parent.version}</version>
+            <scope>test</scope>
+        </dependency>
+
+        <dependency>
+            <groupId>org.apache.dubbo</groupId>
+            <artifactId>dubbo-remoting-netty4</artifactId>
+            <version>${project.parent.version}</version>
+            <scope>test</scope>
+        </dependency>
+
+        <dependency>
+            <groupId>org.apache.dubbo</groupId>
+            <artifactId>dubbo-serialization-hessian2</artifactId>
+            <version>${project.parent.version}</version>
+            <scope>test</scope>
+        </dependency>
+
+        <dependency>
+            <groupId>org.apache.dubbo</groupId>
+            <artifactId>dubbo-registry-multicast</artifactId>
+            <version>${project.parent.version}</version>
+            <scope>test</scope>
+        </dependency>
+
+        <dependency>
+            <groupId>org.apache.dubbo</groupId>
+            <artifactId>dubbo-registry-zookeeper</artifactId>
+            <version>${project.parent.version}</version>
+            <scope>test</scope>
+        </dependency>
+
+        <dependency>
+            <groupId>org.apache.dubbo</groupId>
+            <artifactId>dubbo-registry-nacos</artifactId>
+            <version>${project.parent.version}</version>
+            <scope>test</scope>
+        </dependency>
+
+        <dependency>
+            <groupId>org.apache.dubbo</groupId>
+            <artifactId>dubbo-registry-eureka</artifactId>
+            <version>${project.parent.version}</version>
+            <scope>test</scope>
+            <exclusions>
+                <exclusion>
+                    <groupId>com.google.guava</groupId>
+                    <artifactId>guava</artifactId>
+                </exclusion>
+            </exclusions>
+        </dependency>
+
+        <dependency>
+            <groupId>org.apache.dubbo</groupId>
+            <artifactId>dubbo-registry-etcd3</artifactId>
+            <version>${project.parent.version}</version>
+            <scope>test</scope>
+        </dependency>
+
+        <dependency>
+            <groupId>org.apache.dubbo</groupId>
+            <artifactId>dubbo-registry-consul</artifactId>
+            <version>${project.parent.version}</version>
+            <scope>test</scope>
+        </dependency>
+
+        <dependency>
+            <groupId>org.apache.dubbo</groupId>
+            <artifactId>dubbo-metadata-report-zookeeper</artifactId>
+            <version>${project.parent.version}</version>
+            <scope>test</scope>
+            <exclusions>
+                <exclusion>
+                    <groupId>com.google.guava</groupId>
+                    <artifactId>guava</artifactId>
+                </exclusion>
+            </exclusions>
+        </dependency>
+
+        <dependency>
+            <groupId>org.apache.dubbo</groupId>
+            <artifactId>dubbo-metadata-report-etcd</artifactId>
+            <version>${project.parent.version}</version>
+            <scope>test</scope>
+        </dependency>
+
+        <dependency>
+            <groupId>org.apache.dubbo</groupId>
+            <artifactId>dubbo-metadata-report-nacos</artifactId>
+            <version>${project.parent.version}</version>
+            <scope>test</scope>
+            <exclusions>
+                <exclusion>
+                    <groupId>com.google.guava</groupId>
+                    <artifactId>guava</artifactId>
+                </exclusion>
+            </exclusions>
+        </dependency>
+
+        <dependency>
+            <groupId>org.apache.dubbo</groupId>
+            <artifactId>dubbo-metadata-report-consul</artifactId>
+            <version>${project.parent.version}</version>
+            <scope>test</scope>
+        </dependency>
+
+        <dependency>
+            <groupId>org.apache.dubbo</groupId>
+            <artifactId>dubbo-metadata-report-redis</artifactId>
+            <version>${project.parent.version}</version>
+            <scope>test</scope>
+        </dependency>
+
+        <dependency>
+            <groupId>org.apache.dubbo</groupId>
+            <artifactId>dubbo-configcenter-zookeeper</artifactId>
+            <version>${project.parent.version}</version>
+            <scope>test</scope>
+        </dependency>
+
+        <dependency>
+            <groupId>org.apache.dubbo</groupId>
+            <artifactId>dubbo-configcenter-nacos</artifactId>
+            <version>${project.parent.version}</version>
+            <scope>test</scope>
+            <exclusions>
+                <exclusion>
+                    <groupId>com.google.guava</groupId>
+                    <artifactId>guava</artifactId>
+                </exclusion>
+            </exclusions>
+        </dependency>
+
+        <dependency>
+            <groupId>org.apache.dubbo</groupId>
+            <artifactId>dubbo-configcenter-consul</artifactId>
+            <version>${project.parent.version}</version>
+            <scope>test</scope>
+        </dependency>
+    </dependencies>
+
+    <build>
+        <plugins>
+            <plugin>
+                <groupId>org.apache.maven.plugins</groupId>
+                <artifactId>maven-surefire-plugin</artifactId>
+                <configuration>
+                    <skipTests>${skipIntegrationTests}</skipTests>
+                </configuration>
+            </plugin>
+        </plugins>
+    </build>
+
+</project>
diff --git a/pom.xml b/pom.xml
index eb10329..ce6365d 100644
--- a/pom.xml
+++ b/pom.xml
@@ -24,7 +24,7 @@
     <packaging>pom</packaging>
 
     <properties>
-        <revision>1.0.0-SNAPSHOT</revision>
+        <revision>3.0.0-SNAPSHOT</revision>
     </properties>
    
     <modules>
@@ -32,7 +32,6 @@
         <module>dubbo-spi-container</module>
         <module>dubbo-spi-remoting</module>
         <module>dubbo-spi-rpc</module>
-        <module>dubbo-spi-filter</module>
         <module>dubbo-spi-registry</module>
         <module>dubbo-spi-serialization</module>
         <module>dubbo-spi-configcenter</module>


[dubbo-spi-extensions] 28/39: Merge pull request #3 from KeRan213539/modify-usage-doc

Posted by li...@apache.org.
This is an automated email from the ASF dual-hosted git repository.

liujun pushed a commit to branch 2.7.x
in repository https://gitbox.apache.org/repos/asf/dubbo-spi-extensions.git

commit b916ed7a4c54ba14762f6f59fddc4cfced666c6c
Merge: a00ee89 048bce4
Author: Ian Luo <ia...@gmail.com>
AuthorDate: Wed Dec 23 16:02:26 2020 +0800

    Merge pull request #3 from KeRan213539/modify-usage-doc
    
    修改说明文档

 .travis.yml                 |  3 ++-
 dubbo-api-docs/README.md    | 54 +++++++++++++++++++++++++++++++--------------
 dubbo-api-docs/README_ch.md | 43 ++++++++++++++++++++++--------------
 3 files changed, 66 insertions(+), 34 deletions(-)


[dubbo-spi-extensions] 35/39: 取消调试时注释掉的代码

Posted by li...@apache.org.
This is an automated email from the ASF dual-hosted git repository.

liujun pushed a commit to branch 2.7.x
in repository https://gitbox.apache.org/repos/asf/dubbo-spi-extensions.git

commit a79a304b04b93406f8b829dbf2fbba135670d271
Author: qq213539 <21...@qq.com>
AuthorDate: Fri Jan 29 18:36:34 2021 +0800

    取消调试时注释掉的代码
---
 .../apidocs/examples/api/IQuickStartDemo.java      |  4 +--
 .../apidocs/examples/api/impl/AsyncDemoImpl.java   |  4 +--
 .../examples/api/impl/QuickStartDemoImpl.java      | 34 +++++++++++-----------
 .../apidocs/examples/api/impl/SyncDemoImpl.java    |  4 +--
 4 files changed, 23 insertions(+), 23 deletions(-)

diff --git a/dubbo-api-docs/dubbo-api-docs-examples/examples-api/src/main/java/org/apache/dubbo/apidocs/examples/api/IQuickStartDemo.java b/dubbo-api-docs/dubbo-api-docs-examples/examples-api/src/main/java/org/apache/dubbo/apidocs/examples/api/IQuickStartDemo.java
index c3bca6f..9e614c0 100644
--- a/dubbo-api-docs/dubbo-api-docs-examples/examples-api/src/main/java/org/apache/dubbo/apidocs/examples/api/IQuickStartDemo.java
+++ b/dubbo-api-docs/dubbo-api-docs-examples/examples-api/src/main/java/org/apache/dubbo/apidocs/examples/api/IQuickStartDemo.java
@@ -46,13 +46,13 @@ public interface IQuickStartDemo {
      * @param beanParam
      * @return org.apache.dubbo.apidocs.examples.params.QuickStartRespBean
      */
-//    QuickStartRespBean quickStart2(Map<String, DemoParamBean4> beanList, QuickStartRequestBase<QuickStartRequestBean, DemoParamBean4> beanParam);
+    QuickStartRespBean quickStart2(Map<String, DemoParamBean4> beanList, QuickStartRequestBase<QuickStartRequestBean, DemoParamBean4> beanParam);
 
     /**
      * quick start demo3, request use multiple generic.
      * @return org.apache.dubbo.apidocs.examples.params.QuickStartRespBean
      */
-//    QuickStartRespBean quickStart3(QuickStartRequestBean2 beanParam);
+    QuickStartRespBean quickStart3(QuickStartRequestBean2 beanParam);
 
     /**
      * quick start demo4, response use multiple generic bean, but not set generic.
diff --git a/dubbo-api-docs/dubbo-api-docs-examples/examples-provider/src/main/java/org/apache/dubbo/apidocs/examples/api/impl/AsyncDemoImpl.java b/dubbo-api-docs/dubbo-api-docs-examples/examples-provider/src/main/java/org/apache/dubbo/apidocs/examples/api/impl/AsyncDemoImpl.java
index 7f45ef2..9a4b4c7 100644
--- a/dubbo-api-docs/dubbo-api-docs-examples/examples-provider/src/main/java/org/apache/dubbo/apidocs/examples/api/impl/AsyncDemoImpl.java
+++ b/dubbo-api-docs/dubbo-api-docs-examples/examples-provider/src/main/java/org/apache/dubbo/apidocs/examples/api/impl/AsyncDemoImpl.java
@@ -37,8 +37,8 @@ import java.util.concurrent.ScheduledThreadPoolExecutor;
 /**
  * Asynchronous demo implementation.
  */
-//@DubboService(async = true)
-//@ApiModule(value = "Asynchronous demo", apiInterface = IAsyncDemo.class)
+@DubboService(async = true)
+@ApiModule(value = "Asynchronous demo", apiInterface = IAsyncDemo.class)
 public class AsyncDemoImpl implements IAsyncDemo {
 
     public static final ScheduledExecutorService EXECUTOR = new ScheduledThreadPoolExecutor(
diff --git a/dubbo-api-docs/dubbo-api-docs-examples/examples-provider/src/main/java/org/apache/dubbo/apidocs/examples/api/impl/QuickStartDemoImpl.java b/dubbo-api-docs/dubbo-api-docs-examples/examples-provider/src/main/java/org/apache/dubbo/apidocs/examples/api/impl/QuickStartDemoImpl.java
index f246c96..ded9bfd 100644
--- a/dubbo-api-docs/dubbo-api-docs-examples/examples-provider/src/main/java/org/apache/dubbo/apidocs/examples/api/impl/QuickStartDemoImpl.java
+++ b/dubbo-api-docs/dubbo-api-docs-examples/examples-provider/src/main/java/org/apache/dubbo/apidocs/examples/api/impl/QuickStartDemoImpl.java
@@ -40,23 +40,23 @@ import java.util.Map;
 @ApiModule(value = "quick start demo", apiInterface = IQuickStartDemo.class)
 public class QuickStartDemoImpl implements IQuickStartDemo {
 
-//    @ApiDoc(value = "quick start demo", version = "v0.1", description = "this api is a quick start demo", responseClassDescription="A quick star response bean")
-//    @Override
-//    public QuickStartRespBean quickStart(@RequestParam(value = "strParamxxx", required = true) List<DemoParamBean4> strParam, QuickStartRequestBean beanParam) {
-//        return new QuickStartRespBean(200, "hello " + beanParam.getName() + ", " + beanParam.toString());
-//    }
-//
-//    @ApiDoc(value = "quick start demo, request use generic.", version = "v0.1", description = "quick start demo, request use generic.", responseClassDescription="A quick star response bean")
-//    @Override
-//    public QuickStartRespBean quickStart2(Map<String, DemoParamBean4> beanList, QuickStartRequestBase<QuickStartRequestBean, DemoParamBean4> beanParam) {
-//        return new QuickStartRespBean(200, "【" + beanParam.getMethod() + "】hello " + beanParam.getBody3() + ", " + beanParam.toString());
-//    }
-//
-//    @ApiDoc(value = "multiple generic demo", version = "v0.1", description = "multiple generic demo.", responseClassDescription="A quick star response bean")
-//    @Override
-//    public QuickStartRespBean quickStart3(QuickStartRequestBean2 beanParam) {
-//        return new QuickStartRespBean(200,"quickStart3, multiple generic demo");
-//    }
+    @ApiDoc(value = "quick start demo", version = "v0.1", description = "this api is a quick start demo", responseClassDescription="A quick star response bean")
+    @Override
+    public QuickStartRespBean quickStart(@RequestParam(value = "strParamxxx", required = true) List<DemoParamBean4> strParam, QuickStartRequestBean beanParam) {
+        return new QuickStartRespBean(200, "hello " + beanParam.getName() + ", " + beanParam.toString());
+    }
+
+    @ApiDoc(value = "quick start demo, request use generic.", version = "v0.1", description = "quick start demo, request use generic.", responseClassDescription="A quick star response bean")
+    @Override
+    public QuickStartRespBean quickStart2(Map<String, DemoParamBean4> beanList, QuickStartRequestBase<QuickStartRequestBean, DemoParamBean4> beanParam) {
+        return new QuickStartRespBean(200, "【" + beanParam.getMethod() + "】hello " + beanParam.getBody3() + ", " + beanParam.toString());
+    }
+
+    @ApiDoc(value = "multiple generic demo", version = "v0.1", description = "multiple generic demo.", responseClassDescription="A quick star response bean")
+    @Override
+    public QuickStartRespBean quickStart3(QuickStartRequestBean2 beanParam) {
+        return new QuickStartRespBean(200,"quickStart3, multiple generic demo");
+    }
 
     @ApiDoc(value = "response use multiple generic bean", description = "response use multiple generic bean, but not set generic.", responseClassDescription="A quick star response bean")
     @Override
diff --git a/dubbo-api-docs/dubbo-api-docs-examples/examples-provider/src/main/java/org/apache/dubbo/apidocs/examples/api/impl/SyncDemoImpl.java b/dubbo-api-docs/dubbo-api-docs-examples/examples-provider/src/main/java/org/apache/dubbo/apidocs/examples/api/impl/SyncDemoImpl.java
index faf4166..8998566 100644
--- a/dubbo-api-docs/dubbo-api-docs-examples/examples-provider/src/main/java/org/apache/dubbo/apidocs/examples/api/impl/SyncDemoImpl.java
+++ b/dubbo-api-docs/dubbo-api-docs-examples/examples-provider/src/main/java/org/apache/dubbo/apidocs/examples/api/impl/SyncDemoImpl.java
@@ -37,8 +37,8 @@ import java.util.Map;
 /**
  * Synchronous demo implementation.
  */
-//@DubboService
-//@ApiModule(value = "Synchronous demo", apiInterface = ISyncDemo.class)
+@DubboService
+@ApiModule(value = "Synchronous demo", apiInterface = ISyncDemo.class)
 public class SyncDemoImpl implements ISyncDemo {
 
     private static final Logger log = LoggerFactory.getLogger(SyncDemoImpl.class);


[dubbo-spi-extensions] 14/39: 修改前端页脚内容

Posted by li...@apache.org.
This is an automated email from the ASF dual-hosted git repository.

liujun pushed a commit to branch 2.7.x
in repository https://gitbox.apache.org/repos/asf/dubbo-spi-extensions.git

commit 39175b43de08a0f50c551459435e1348f53637d3
Author: qq213539 <21...@qq.com>
AuthorDate: Mon Nov 16 09:37:18 2020 +0800

    修改前端页脚内容
---
 .../src/layouts/BasicLayout/components/Footer/index.tsx             | 6 ++----
 1 file changed, 2 insertions(+), 4 deletions(-)

diff --git a/dubbo-api-docs/dubbo-api-docs-ui/src/layouts/BasicLayout/components/Footer/index.tsx b/dubbo-api-docs/dubbo-api-docs-ui/src/layouts/BasicLayout/components/Footer/index.tsx
index 729aac0..4bda28c 100644
--- a/dubbo-api-docs/dubbo-api-docs-ui/src/layouts/BasicLayout/components/Footer/index.tsx
+++ b/dubbo-api-docs/dubbo-api-docs-ui/src/layouts/BasicLayout/components/Footer/index.tsx
@@ -20,9 +20,7 @@ import styles from './index.module.scss';
 export default function Footer() {
   return (
     <p className={styles.footer}>
-      <span className={styles.logo}>Dubbo Doc</span>
-      <br />
-      <span className={styles.copyright}>Mail: 213539@qq.com</span>
+      <span className={styles.logo}>Dubbo API Docs</span>
     </p>
   );
-}
\ No newline at end of file
+}


[dubbo-spi-extensions] 09/39: fix service discovery impls

Posted by li...@apache.org.
This is an automated email from the ASF dual-hosted git repository.

liujun pushed a commit to branch 2.7.x
in repository https://gitbox.apache.org/repos/asf/dubbo-spi-extensions.git

commit 7f404f6c647b3a1249f5b982123ec4787d109298
Author: ken.lj <ke...@gmail.com>
AuthorDate: Thu Aug 27 16:27:15 2020 +0800

    fix service discovery impls
---
 .../dubbo/registry/consul/ConsulServiceDiscovery.java | 19 +++++++++++--------
 .../dubbo/registry/etcd/EtcdServiceDiscovery.java     |  7 +++++--
 .../dubbo/registry/eureka/EurekaServiceDiscovery.java |  5 ++++-
 3 files changed, 20 insertions(+), 11 deletions(-)

diff --git a/dubbo-spi-registry/dubbo-registry-consul/src/main/java/org/apache/dubbo/registry/consul/ConsulServiceDiscovery.java b/dubbo-spi-registry/dubbo-registry-consul/src/main/java/org/apache/dubbo/registry/consul/ConsulServiceDiscovery.java
index 5d5e98b..f1d3d3b 100644
--- a/dubbo-spi-registry/dubbo-registry-consul/src/main/java/org/apache/dubbo/registry/consul/ConsulServiceDiscovery.java
+++ b/dubbo-spi-registry/dubbo-registry-consul/src/main/java/org/apache/dubbo/registry/consul/ConsulServiceDiscovery.java
@@ -23,6 +23,7 @@ import org.apache.dubbo.common.utils.CollectionUtils;
 import org.apache.dubbo.common.utils.NamedThreadFactory;
 import org.apache.dubbo.common.utils.StringUtils;
 import org.apache.dubbo.event.EventListener;
+import org.apache.dubbo.registry.client.AbstractServiceDiscovery;
 import org.apache.dubbo.registry.client.DefaultServiceInstance;
 import org.apache.dubbo.registry.client.ServiceDiscovery;
 import org.apache.dubbo.registry.client.ServiceInstance;
@@ -65,7 +66,7 @@ import static org.apache.dubbo.registry.consul.AbstractConsulRegistry.WATCH_TIME
 /**
  * 2019-07-31
  */
-public class ConsulServiceDiscovery implements ServiceDiscovery, EventListener<ServiceInstancesChangedEvent> {
+public class ConsulServiceDiscovery extends AbstractServiceDiscovery implements EventListener<ServiceInstancesChangedEvent> {
 
     private static final Logger logger = LoggerFactory.getLogger(ConsulServiceDiscovery.class);
 
@@ -120,6 +121,7 @@ public class ConsulServiceDiscovery implements ServiceDiscovery, EventListener<S
 
     @Override
     public void register(ServiceInstance serviceInstance) throws RuntimeException {
+        super.register(serviceInstance);
         NewService consulService = buildService(serviceInstance);
         ttlScheduler.add(consulService.getId());
         client.agentServiceRegister(consulService);
@@ -127,17 +129,18 @@ public class ConsulServiceDiscovery implements ServiceDiscovery, EventListener<S
 
     @Override
     public void addServiceInstancesChangedListener(ServiceInstancesChangedListener listener) throws NullPointerException, IllegalArgumentException {
-        if (notifier == null) {
-            String serviceName = listener.getServiceName();
-            Response<List<HealthService>> response = getHealthServices(serviceName, -1, buildWatchTimeout());
-            Long consulIndex = response.getConsulIndex();
-            notifier = new ConsulNotifier(serviceName, consulIndex);
-        }
-        notifierExecutor.execute(notifier);
+//        if (notifier == null) {
+//            String serviceName = listener.getServiceNames();
+//            Response<List<HealthService>> response = getHealthServices(serviceName, -1, buildWatchTimeout());
+//            Long consulIndex = response.getConsulIndex();
+//            notifier = new ConsulNotifier(serviceName, consulIndex);
+//        }
+//        notifierExecutor.execute(notifier);
     }
 
     @Override
     public void update(ServiceInstance serviceInstance) throws RuntimeException {
+        super.register(serviceInstance);
         // TODO
         // client.catalogRegister(buildCatalogService(serviceInstance));
     }
diff --git a/dubbo-spi-registry/dubbo-registry-etcd3/src/main/java/org/apache/dubbo/registry/etcd/EtcdServiceDiscovery.java b/dubbo-spi-registry/dubbo-registry-etcd3/src/main/java/org/apache/dubbo/registry/etcd/EtcdServiceDiscovery.java
index a26ebc6..0f41de3 100644
--- a/dubbo-spi-registry/dubbo-registry-etcd3/src/main/java/org/apache/dubbo/registry/etcd/EtcdServiceDiscovery.java
+++ b/dubbo-spi-registry/dubbo-registry-etcd3/src/main/java/org/apache/dubbo/registry/etcd/EtcdServiceDiscovery.java
@@ -24,6 +24,7 @@ import org.apache.dubbo.common.utils.CollectionUtils;
 import org.apache.dubbo.common.utils.ConcurrentHashSet;
 import org.apache.dubbo.event.EventDispatcher;
 import org.apache.dubbo.event.EventListener;
+import org.apache.dubbo.registry.client.AbstractServiceDiscovery;
 import org.apache.dubbo.registry.client.DefaultServiceInstance;
 import org.apache.dubbo.registry.client.ServiceDiscovery;
 import org.apache.dubbo.registry.client.ServiceInstance;
@@ -50,7 +51,7 @@ import java.util.concurrent.ConcurrentHashMap;
 /**
  * 2019-07-08
  */
-public class EtcdServiceDiscovery implements ServiceDiscovery, EventListener<ServiceInstancesChangedEvent> {
+public class EtcdServiceDiscovery extends AbstractServiceDiscovery implements EventListener<ServiceInstancesChangedEvent> {
 
     private final static Logger logger = LoggerFactory.getLogger(EtcdServiceDiscovery.class);
 
@@ -102,6 +103,7 @@ public class EtcdServiceDiscovery implements ServiceDiscovery, EventListener<Ser
 
     @Override
     public void register(ServiceInstance serviceInstance) throws RuntimeException {
+        super.register(serviceInstance);
         try {
             this.serviceInstance = serviceInstance;
             String path = toPath(serviceInstance);
@@ -127,6 +129,7 @@ public class EtcdServiceDiscovery implements ServiceDiscovery, EventListener<Ser
 
     @Override
     public void update(ServiceInstance serviceInstance) throws RuntimeException {
+        super.register(serviceInstance);
         try {
             String path = toPath(serviceInstance);
             etcdClient.putEphemeral(path, new Gson().toJson(serviceInstance));
@@ -158,7 +161,7 @@ public class EtcdServiceDiscovery implements ServiceDiscovery, EventListener<Ser
 
     @Override
     public void addServiceInstancesChangedListener(ServiceInstancesChangedListener listener) throws NullPointerException, IllegalArgumentException {
-        registerServiceWatcher(listener.getServiceName());
+        listener.getServiceNames().forEach(serviceName -> registerServiceWatcher(serviceName));
     }
 
     @Override
diff --git a/dubbo-spi-registry/dubbo-registry-eureka/src/main/java/org/apache/dubbo/registry/eureka/EurekaServiceDiscovery.java b/dubbo-spi-registry/dubbo-registry-eureka/src/main/java/org/apache/dubbo/registry/eureka/EurekaServiceDiscovery.java
index bb49c10..3aebd7a 100644
--- a/dubbo-spi-registry/dubbo-registry-eureka/src/main/java/org/apache/dubbo/registry/eureka/EurekaServiceDiscovery.java
+++ b/dubbo-spi-registry/dubbo-registry-eureka/src/main/java/org/apache/dubbo/registry/eureka/EurekaServiceDiscovery.java
@@ -18,6 +18,7 @@ package org.apache.dubbo.registry.eureka;
 
 import org.apache.dubbo.common.URL;
 import org.apache.dubbo.event.EventDispatcher;
+import org.apache.dubbo.registry.client.AbstractServiceDiscovery;
 import org.apache.dubbo.registry.client.DefaultServiceInstance;
 import org.apache.dubbo.registry.client.ServiceDiscovery;
 import org.apache.dubbo.registry.client.ServiceInstance;
@@ -53,7 +54,7 @@ import static org.apache.dubbo.registry.client.ServiceDiscoveryRegistry.parseSer
 /**
  * Eureka {@link ServiceDiscovery} implementation based on Eureka API
  */
-public class EurekaServiceDiscovery implements ServiceDiscovery {
+public class EurekaServiceDiscovery extends AbstractServiceDiscovery {
 
     private final EventDispatcher eventDispatcher = getDefaultExtension();
 
@@ -205,6 +206,7 @@ public class EurekaServiceDiscovery implements ServiceDiscovery {
 
     @Override
     public void register(ServiceInstance serviceInstance) throws RuntimeException {
+        super.register(serviceInstance);
         initEurekaClient(serviceInstance);
         setInstanceStatus(InstanceInfo.InstanceStatus.UP);
     }
@@ -217,6 +219,7 @@ public class EurekaServiceDiscovery implements ServiceDiscovery {
 
     @Override
     public void update(ServiceInstance serviceInstance) throws RuntimeException {
+        super.update(serviceInstance);
         setInstanceStatus(serviceInstance.isHealthy() ? InstanceInfo.InstanceStatus.UP :
                 InstanceInfo.InstanceStatus.UNKNOWN);
     }


[dubbo-spi-extensions] 37/39: 增加checkstyle 和 rat, 并相应修改

Posted by li...@apache.org.
This is an automated email from the ASF dual-hosted git repository.

liujun pushed a commit to branch 2.7.x
in repository https://gitbox.apache.org/repos/asf/dubbo-spi-extensions.git

commit fa8e7e1f83beb8336ed900d309f5980520e25db9
Author: qq213539 <21...@qq.com>
AuthorDate: Sat Jan 30 10:31:45 2021 +0800

    增加checkstyle 和 rat, 并相应修改
---
 dubbo-api-docs/codestyle/checkstyle.xml            | 25 +++++++
 .../codestyle/dubbo_codestyle_for_idea.xml         | 33 +++++++++
 .../core/DubboApiDocsAnnotationScanner.java        |  7 +-
 .../apache/dubbo/apidocs/utils/ClassTypeUtil.java  | 29 +++++---
 .../examples/params/QuickStartRequestBase.java     | 16 +++++
 .../src/main/resources/application.yml             | 17 +++++
 .../src/main/resources/bootstrap.yml               | 17 +++++
 .../examples/spi/DubboDocExporterListener.java     | 16 +++++
 .../examples/spi/TestConfigInitializer.java        | 16 +++++
 .../examples/spi/TestConfigPostProcessor.java      | 16 +++++
 .../src/main/resources/application.yml             | 17 +++++
 dubbo-api-docs/pom.xml                             | 82 +++++++++++++++++++++-
 12 files changed, 279 insertions(+), 12 deletions(-)

diff --git a/dubbo-api-docs/codestyle/checkstyle.xml b/dubbo-api-docs/codestyle/checkstyle.xml
new file mode 100644
index 0000000..9c7581b
--- /dev/null
+++ b/dubbo-api-docs/codestyle/checkstyle.xml
@@ -0,0 +1,25 @@
+<?xml version="1.0"?>
+<!DOCTYPE module PUBLIC
+        "-//Puppy Crawl//DTD Check Configuration 1.3//EN"
+        "http://checkstyle.sourceforge.net/dtds/configuration_1_3.dtd">
+
+<module name="Checker">
+    <property name="charset" value="UTF-8"/>
+    <property name="fileExtensions" value="java"/>
+
+    <!-- TreeWalker Checks -->
+    <module name="TreeWalker">
+        <module name="SuppressWarningsHolder" />
+
+        <module name="AvoidStarImport"/>
+        <module name="AvoidEscapedUnicodeCharacters">
+            <property name="allowEscapesForControlCharacters" value="true"/>
+            <property name="allowByTailComment" value="true"/>
+            <property name="allowNonPrintableEscapes" value="true"/>
+        </module>
+        <module name="NoLineWrap"/>
+        <module name="OuterTypeFilename"/>
+        <module name="UnusedImports"/>
+
+    </module>
+</module>
diff --git a/dubbo-api-docs/codestyle/dubbo_codestyle_for_idea.xml b/dubbo-api-docs/codestyle/dubbo_codestyle_for_idea.xml
new file mode 100644
index 0000000..1cbbe37
--- /dev/null
+++ b/dubbo-api-docs/codestyle/dubbo_codestyle_for_idea.xml
@@ -0,0 +1,33 @@
+<!--
+  ~ 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.
+  -->
+
+<code_scheme name="dubbo_codestyle">
+    <option name="CLASS_COUNT_TO_USE_IMPORT_ON_DEMAND" value="99"/>
+    <option name="NAMES_COUNT_TO_USE_IMPORT_ON_DEMAND" value="99"/>
+    <option name="IMPORT_LAYOUT_TABLE">
+        <value>
+            <package name="org.apache.dubbo.admin" withSubpackages="true" static="false"/>
+            <emptyLine/>
+            <package name="" withSubpackages="true" static="false"/>
+            <emptyLine/>
+            <package name="javax" withSubpackages="true" static="false"/>
+            <package name="java" withSubpackages="true" static="false"/>
+            <emptyLine/>
+            <package name="" withSubpackages="true" static="true"/>
+        </value>
+    </option>
+</code_scheme>
diff --git a/dubbo-api-docs/dubbo-api-docs-core/src/main/java/org/apache/dubbo/apidocs/core/DubboApiDocsAnnotationScanner.java b/dubbo-api-docs/dubbo-api-docs-core/src/main/java/org/apache/dubbo/apidocs/core/DubboApiDocsAnnotationScanner.java
index 5878d3c..f53f282 100644
--- a/dubbo-api-docs/dubbo-api-docs-core/src/main/java/org/apache/dubbo/apidocs/core/DubboApiDocsAnnotationScanner.java
+++ b/dubbo-api-docs/dubbo-api-docs-core/src/main/java/org/apache/dubbo/apidocs/core/DubboApiDocsAnnotationScanner.java
@@ -31,7 +31,9 @@ import org.apache.dubbo.config.RegistryConfig;
 import org.apache.dubbo.config.ServiceConfig;
 import org.apache.dubbo.config.annotation.DubboService;
 import org.apache.dubbo.config.annotation.Service;
-import org.apache.dubbo.apidocs.annotations.*;
+import org.apache.dubbo.apidocs.annotations.ApiModule;
+import org.apache.dubbo.apidocs.annotations.ApiDoc;
+import org.apache.dubbo.apidocs.annotations.RequestParam;
 import org.apache.dubbo.apidocs.utils.ClassTypeUtil;
 
 import com.alibaba.fastjson.JSON;
@@ -54,6 +56,7 @@ import java.lang.reflect.TypeVariable;
 import java.math.BigDecimal;
 import java.math.BigInteger;
 import java.util.ArrayList;
+import java.util.Collections;
 import java.util.HashMap;
 import java.util.List;
 import java.util.Map;
@@ -236,7 +239,7 @@ public class DubboApiDocsAnnotationScanner implements ApplicationListener<Applic
                 genericTypeAndNamesMap.put(typeVariables[i].getTypeName(), actualTypeArguments[i].getTypeName());
             }
         } else {
-            genericTypeAndNamesMap =  new HashMap<>(0);
+            genericTypeAndNamesMap = Collections.EMPTY_MAP;
         }
 
         List<ParamBean> apiParamsList = new ArrayList(16);
diff --git a/dubbo-api-docs/dubbo-api-docs-core/src/main/java/org/apache/dubbo/apidocs/utils/ClassTypeUtil.java b/dubbo-api-docs/dubbo-api-docs-core/src/main/java/org/apache/dubbo/apidocs/utils/ClassTypeUtil.java
index 2efacd5..7379ff9 100644
--- a/dubbo-api-docs/dubbo-api-docs-core/src/main/java/org/apache/dubbo/apidocs/utils/ClassTypeUtil.java
+++ b/dubbo-api-docs/dubbo-api-docs-core/src/main/java/org/apache/dubbo/apidocs/utils/ClassTypeUtil.java
@@ -21,15 +21,28 @@ import com.alibaba.fastjson.serializer.SerializerFeature;
 import org.apache.commons.lang3.StringUtils;
 import sun.reflect.generics.reflectiveObjects.ParameterizedTypeImpl;
 
-import java.lang.reflect.*;
+import java.lang.reflect.Field;
+import java.lang.reflect.InvocationTargetException;
+import java.lang.reflect.Method;
+import java.lang.reflect.ParameterizedType;
+import java.lang.reflect.Type;
+import java.lang.reflect.TypeVariable;
 import java.math.BigDecimal;
 import java.math.BigInteger;
 import java.time.LocalDate;
 import java.time.LocalDateTime;
-import java.util.*;
+import java.util.ArrayList;
+import java.util.Arrays;
+import java.util.Collection;
+import java.util.Collections;
+import java.util.Date;
+import java.util.HashMap;
+import java.util.List;
+import java.util.Map;
 import java.util.concurrent.CompletableFuture;
 
-import org.apache.dubbo.apidocs.annotations.*;
+import org.apache.dubbo.apidocs.annotations.RequestParam;
+import org.apache.dubbo.apidocs.annotations.ResponseProperty;
 import org.apache.dubbo.common.logger.Logger;
 import org.apache.dubbo.common.logger.LoggerFactory;
 
@@ -85,9 +98,9 @@ public class ClassTypeUtil {
     /**
      * Instantiate class and its fields.
      *
-     * @param genericType  genericType
-     * @param classType    classType
-     * @param processCount processCount
+     * @param genericType           genericType
+     * @param classType             classType
+     * @param processCount          processCount
      * @param isBuildClassAttribute isBuildClassAttribute
      * @return java.lang.Object
      */
@@ -110,12 +123,12 @@ public class ClassTypeUtil {
             ParameterizedTypeImpl parameterTypeImpl = (ParameterizedTypeImpl) genericType;
             TypeVariable<? extends Class<?>>[] typeVariables = parameterTypeImpl.getRawType().getTypeParameters();
             Type[] actualTypeArguments = parameterTypeImpl.getActualTypeArguments();
-            genericTypeAndNamesMap =  new HashMap<>(typeVariables.length);
+            genericTypeAndNamesMap = new HashMap<>(typeVariables.length);
             for (int i = 0; i < typeVariables.length; i++) {
                 genericTypeAndNamesMap.put(typeVariables[i].getTypeName(), actualTypeArguments[i].getTypeName());
             }
         } else {
-            genericTypeAndNamesMap =  new HashMap<>(0);
+            genericTypeAndNamesMap = Collections.EMPTY_MAP;
         }
 
         Map<String, Object> result = new HashMap<>(16);
diff --git a/dubbo-api-docs/dubbo-api-docs-examples/examples-api/src/main/java/org/apache/dubbo/apidocs/examples/params/QuickStartRequestBase.java b/dubbo-api-docs/dubbo-api-docs-examples/examples-api/src/main/java/org/apache/dubbo/apidocs/examples/params/QuickStartRequestBase.java
index 5453ca9..fd37785 100644
--- a/dubbo-api-docs/dubbo-api-docs-examples/examples-api/src/main/java/org/apache/dubbo/apidocs/examples/params/QuickStartRequestBase.java
+++ b/dubbo-api-docs/dubbo-api-docs-examples/examples-api/src/main/java/org/apache/dubbo/apidocs/examples/params/QuickStartRequestBase.java
@@ -1,3 +1,19 @@
+/*
+ * 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.apidocs.examples.params;
 
 import org.apache.dubbo.apidocs.annotations.RequestParam;
diff --git a/dubbo-api-docs/dubbo-api-docs-examples/examples-provider-sca/src/main/resources/application.yml b/dubbo-api-docs/dubbo-api-docs-examples/examples-provider-sca/src/main/resources/application.yml
index c8209d5..54190bd 100644
--- a/dubbo-api-docs/dubbo-api-docs-examples/examples-provider-sca/src/main/resources/application.yml
+++ b/dubbo-api-docs/dubbo-api-docs-examples/examples-provider-sca/src/main/resources/application.yml
@@ -1,3 +1,20 @@
+#
+# 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.
+#
+
 dubbo:
   registry:
     address: spring-cloud://localhost
diff --git a/dubbo-api-docs/dubbo-api-docs-examples/examples-provider-sca/src/main/resources/bootstrap.yml b/dubbo-api-docs/dubbo-api-docs-examples/examples-provider-sca/src/main/resources/bootstrap.yml
index d5cab0c..8220792 100644
--- a/dubbo-api-docs/dubbo-api-docs-examples/examples-provider-sca/src/main/resources/bootstrap.yml
+++ b/dubbo-api-docs/dubbo-api-docs-examples/examples-provider-sca/src/main/resources/bootstrap.yml
@@ -1,3 +1,20 @@
+#
+# 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.
+#
+
 spring:
   application:
     name: dubbo-api-docs-example-provider-sca
diff --git a/dubbo-api-docs/dubbo-api-docs-examples/examples-provider/src/main/java/org/apache/dubbo/apidocs/examples/spi/DubboDocExporterListener.java b/dubbo-api-docs/dubbo-api-docs-examples/examples-provider/src/main/java/org/apache/dubbo/apidocs/examples/spi/DubboDocExporterListener.java
index bf37d55..a2c4e45 100644
--- a/dubbo-api-docs/dubbo-api-docs-examples/examples-provider/src/main/java/org/apache/dubbo/apidocs/examples/spi/DubboDocExporterListener.java
+++ b/dubbo-api-docs/dubbo-api-docs-examples/examples-provider/src/main/java/org/apache/dubbo/apidocs/examples/spi/DubboDocExporterListener.java
@@ -1,3 +1,19 @@
+/*
+ * 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.apidocs.examples.spi;
 
 import org.apache.dubbo.common.extension.Activate;
diff --git a/dubbo-api-docs/dubbo-api-docs-examples/examples-provider/src/main/java/org/apache/dubbo/apidocs/examples/spi/TestConfigInitializer.java b/dubbo-api-docs/dubbo-api-docs-examples/examples-provider/src/main/java/org/apache/dubbo/apidocs/examples/spi/TestConfigInitializer.java
index e4900cd..febae4a 100644
--- a/dubbo-api-docs/dubbo-api-docs-examples/examples-provider/src/main/java/org/apache/dubbo/apidocs/examples/spi/TestConfigInitializer.java
+++ b/dubbo-api-docs/dubbo-api-docs-examples/examples-provider/src/main/java/org/apache/dubbo/apidocs/examples/spi/TestConfigInitializer.java
@@ -1,3 +1,19 @@
+/*
+ * 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.apidocs.examples.spi;
 
 import org.apache.dubbo.common.extension.Activate;
diff --git a/dubbo-api-docs/dubbo-api-docs-examples/examples-provider/src/main/java/org/apache/dubbo/apidocs/examples/spi/TestConfigPostProcessor.java b/dubbo-api-docs/dubbo-api-docs-examples/examples-provider/src/main/java/org/apache/dubbo/apidocs/examples/spi/TestConfigPostProcessor.java
index d600abd..2708594 100644
--- a/dubbo-api-docs/dubbo-api-docs-examples/examples-provider/src/main/java/org/apache/dubbo/apidocs/examples/spi/TestConfigPostProcessor.java
+++ b/dubbo-api-docs/dubbo-api-docs-examples/examples-provider/src/main/java/org/apache/dubbo/apidocs/examples/spi/TestConfigPostProcessor.java
@@ -1,3 +1,19 @@
+/*
+ * 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.apidocs.examples.spi;
 
 import org.apache.dubbo.common.extension.Activate;
diff --git a/dubbo-api-docs/dubbo-api-docs-examples/examples-provider/src/main/resources/application.yml b/dubbo-api-docs/dubbo-api-docs-examples/examples-provider/src/main/resources/application.yml
index 2e8048a..47b3b05 100644
--- a/dubbo-api-docs/dubbo-api-docs-examples/examples-provider/src/main/resources/application.yml
+++ b/dubbo-api-docs/dubbo-api-docs-examples/examples-provider/src/main/resources/application.yml
@@ -1,3 +1,20 @@
+#
+# 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.
+#
+
 spring:
   application:
     name: dubbo-api-docs-example-provider
diff --git a/dubbo-api-docs/pom.xml b/dubbo-api-docs/pom.xml
index 28c4f00..0b97573 100644
--- a/dubbo-api-docs/pom.xml
+++ b/dubbo-api-docs/pom.xml
@@ -89,9 +89,10 @@
         <project.build.jdkVersion>1.8</project.build.jdkVersion>
         <argLine>-Dfile.encoding=UTF-8</argLine>
         <project.build.sourceEncoding>UTF-8</project.build.sourceEncoding>
-        <skipJunitTest>true</skipJunitTest>
+        <skip_maven_deploy>false</skip_maven_deploy>
 
         <maven-flatten-version>1.1.0</maven-flatten-version>
+        <maven-checkstyle-plugin-version>3.0.0</maven-checkstyle-plugin-version>
 
         <spring-boot.version>2.3.4.RELEASE</spring-boot.version>
         <dubbo.version>2.7.8</dubbo.version>
@@ -215,6 +216,84 @@
     <build>
         <plugins>
             <plugin>
+                <groupId>org.apache.maven.plugins</groupId>
+                <artifactId>maven-checkstyle-plugin</artifactId>
+                <version>${maven-checkstyle-plugin-version}</version>
+                <dependencies>
+                    <dependency>
+                        <groupId>com.puppycrawl.tools</groupId>
+                        <artifactId>checkstyle</artifactId>
+                        <version>8.18</version>
+                    </dependency>
+                </dependencies>
+                <executions>
+                    <execution>
+                        <id>checkstyle-validation</id>
+                        <phase>validate</phase>
+                        <configuration>
+                            <configLocation>codestyle/checkstyle.xml</configLocation>
+                            <encoding>UTF-8</encoding>
+                            <consoleOutput>true</consoleOutput>
+                            <failOnViolation>true</failOnViolation>
+                        </configuration>
+                        <goals>
+                            <goal>check</goal>
+                        </goals>
+                    </execution>
+                </executions>
+            </plugin>
+            <plugin>
+                <groupId>org.apache.rat</groupId>
+                <artifactId>apache-rat-plugin</artifactId>
+                <version>0.12</version>
+                <executions>
+                    <execution>
+                        <id>verify.rat</id>
+                        <phase>verify</phase>
+                        <goals>
+                            <goal>check</goal>
+                        </goals>
+                        <configuration>
+                            <excludes>
+                                <exclude>**/.idea/</exclude>
+                                <exclude>**/*.iml</exclude>
+                                <exclude>**/*.txt</exclude>
+                                <exclude>**/*.sh</exclude>
+                                <exclude>**/*.bat</exclude>
+                                <exclude>**/*.md</exclude>
+                                <exclude>.git/</exclude>
+                                <exclude>**/*.git*</exclude>
+                                <exclude>.gitignore</exclude>
+                                <exclude>**/.settings/*</exclude>
+                                <exclude>**/.classpath</exclude>
+                                <exclude>**/*.properties</exclude>
+                                <exclude>**/.project</exclude>
+                                <exclude>**/target/**</exclude>
+                                <exclude>**/*.log</exclude>
+                                <exclude>.codecov.yml</exclude>
+                                <exclude>.travis.yml</exclude>
+                                <exclude>**/codestyle/*</exclude>
+                                <exclude>**/node_modules/**</exclude>
+                                <exclude>**/.babelrc</exclude>
+                                <exclude>**/.editorconfig</exclude>
+                                <exclude>**/package-lock.json</exclude>
+                                <exclude>**/package.json</exclude>
+                                <exclude>**/OpenSans.css</exclude>
+                                <exclude>**/.eslintignore</exclude>
+                                <exclude>**/.browserslistrc</exclude>
+                                <exclude>**/resources/META-INF/**</exclude>
+                                <exclude>**/src/main/resources/public/**</exclude>
+                                <exclude>**/src/licenses/**</exclude>
+                                <exclude>.github/**</exclude>
+                                <exclude>**/assets/**</exclude>
+                                <exclude>**/yarn.lock</exclude>
+                                <exclude>**/node/**</exclude>
+                            </excludes>
+                        </configuration>
+                    </execution>
+                </executions>
+            </plugin>
+            <plugin>
                 <groupId>org.codehaus.mojo</groupId>
                 <artifactId>flatten-maven-plugin</artifactId>
                 <version>${maven-flatten-version}</version>
@@ -273,7 +352,6 @@
             <plugin>
                 <artifactId>maven-surefire-plugin</artifactId>
                 <configuration>
-                    <skip>${skipJunitTest}</skip>
                 </configuration>
             </plugin>
             <plugin>


[dubbo-spi-extensions] 24/39: 移除空标签

Posted by li...@apache.org.
This is an automated email from the ASF dual-hosted git repository.

liujun pushed a commit to branch 2.7.x
in repository https://gitbox.apache.org/repos/asf/dubbo-spi-extensions.git

commit 5f057c7c7091bca74249bf29b42c9cbc3e922d06
Author: qq213539 <21...@qq.com>
AuthorDate: Mon Dec 21 16:08:31 2020 +0800

    移除空标签
---
 dubbo-api-docs/dubbo-api-docs-annotations/pom.xml | 4 ----
 1 file changed, 4 deletions(-)

diff --git a/dubbo-api-docs/dubbo-api-docs-annotations/pom.xml b/dubbo-api-docs/dubbo-api-docs-annotations/pom.xml
index 45b8615..77251b0 100644
--- a/dubbo-api-docs/dubbo-api-docs-annotations/pom.xml
+++ b/dubbo-api-docs/dubbo-api-docs-annotations/pom.xml
@@ -27,9 +27,5 @@
 
     <artifactId>dubbo-api-docs-annotations</artifactId>
 
-    <dependencies>
-        
-    </dependencies>
-
 
 </project>


[dubbo-spi-extensions] 11/39: 新增dubbo-api-docs项目

Posted by li...@apache.org.
This is an automated email from the ASF dual-hosted git repository.

liujun pushed a commit to branch 2.7.x
in repository https://gitbox.apache.org/repos/asf/dubbo-spi-extensions.git

commit 0745a05e2c7ef5cba86a89b2f5a83ea1b0f2a26d
Author: qq213539 <21...@qq.com>
AuthorDate: Fri Oct 30 16:45:25 2020 +0800

    新增dubbo-api-docs项目
---
 dubbo-api-docs/README.md                           | 132 ++++++++
 dubbo-api-docs/README_ch.md                        | 130 ++++++++
 dubbo-api-docs/dubbo-api-docs-annotations/pom.xml  |  35 +++
 .../apache/dubbo/apidocs/annotations/ApiDoc.java   |  55 ++++
 .../dubbo/apidocs/annotations/ApiModule.java       |  50 +++
 .../dubbo/apidocs/annotations/RequestParam.java    |  70 +++++
 .../apidocs/annotations/ResponseProperty.java      |  47 +++
 dubbo-api-docs/dubbo-api-docs-core/pom.xml         |  71 +++++
 .../apache/dubbo/apidocs/EnableDubboApiDocs.java   |  40 +++
 .../core/DubboApiDocsAnnotationScanner.java        | 346 +++++++++++++++++++++
 .../dubbo/apidocs/core/DubboApiDocsCache.java      | 106 +++++++
 .../dubbo/apidocs/core/beans/HtmlTypeEnum.java     |  62 ++++
 .../apache/dubbo/apidocs/core/beans/ParamBean.java |  93 ++++++
 .../core/providers/DubboDocProviderImpl.java       |  47 +++
 .../apidocs/core/providers/IDubboDocProvider.java  |  50 +++
 .../apache/dubbo/apidocs/utils/ClassTypeUtil.java  | 307 ++++++++++++++++++
 .../apache/dubbo/apidocs/utils/SimpleTypeImpl.java |  23 ++
 .../dubbo-api-docs-examples/examples-api/pom.xml   |  40 +++
 .../dubbo/apidocs/examples/api/IAsyncDemo.java     |  89 ++++++
 .../dubbo/apidocs/examples/api/ISyncDemo.java      |  97 ++++++
 .../apidocs/examples/params/DemoParamBean1.java    |  76 +++++
 .../examples/params/DemoParamBean1SubBean1.java    |  45 +++
 .../apidocs/examples/params/DemoParamBean2.java    |  39 +++
 .../dubbo/apidocs/examples/params/TestBean.java    |  33 ++
 .../dubbo/apidocs/examples/params/TestEnum.java    |  30 ++
 .../apidocs/examples/responses/BaseResponse.java   |  48 +++
 .../apidocs/examples/responses/DemoRespBean1.java  |  60 ++++
 .../examples-provider-sca/pom.xml                  |  35 +++
 .../examples-provider/pom.xml                      |  80 +++++
 .../dubbo/apidocs/examples/ExampleApplication.java |  41 +++
 .../apidocs/examples/api/impl/AsyncDemoImpl.java   |  99 ++++++
 .../apidocs/examples/api/impl/SyncDemoImpl.java    | 116 +++++++
 .../dubbo/apidocs/examples/cfg/DubboDocConfig.java |  33 ++
 .../src/main/resources/application.yml             |  15 +
 dubbo-api-docs/dubbo-api-docs-examples/pom.xml     |  53 ++++
 dubbo-api-docs/pom.xml                             | 210 +++++++++++++
 36 files changed, 2903 insertions(+)

diff --git a/dubbo-api-docs/README.md b/dubbo-api-docs/README.md
new file mode 100644
index 0000000..1a61dab
--- /dev/null
+++ b/dubbo-api-docs/README.md
@@ -0,0 +1,132 @@
+# dubboDoc
+
+[中文](./README_ch.md)
+
+Dubbo api documents, test tools, generate documents according to annotations, and provide test functions
+
+Only some annotations are needed to generate documents similar to swagger, without turning a non web's dubbo project into a web project.
+
+Welcome everyone to make complaints about it~
+
+At present, the function of the first version is relatively rough (the interface is also rough), and the user experience is not very good. It will be gradually optimized later, and all kinds of PR are welcome~
+
+
+
+```
+When testing Dubbo providers, I always thought that if Dubbo had a document + testing 
+tool similar to swagger
+I've also found that several of them are based on springfox, and will add some restful 
+interfaces to Dubbo project,if your Dubbo service itself is started through a web container 
+or mixed with web projects, that's fine.
+But my Dubbo projects are all non web projects. For those with obsessive-compulsive disorder, 
+it is a little unacceptable to turn the project into a web project for the purpose of documentation,
+so I have the idea of doing it myself...
+```
+## Version planning
+### First edition
+* Parsing annotations and generating UI
+* Unfriendly user interface (without handling some exceptions)
+### Second edition
+* Replace the JSON text area with a proper JSON editor, and verify the JSON format
+* Add tabs
+* It can save the test and facilitate the next direct loading test
+* Some exceptions are handled as friendly text prompts
+* Add remark.md and show it in the front end
+* Add changelog.md and show it in the front end
+### Follow up edition
+* Demand  based on own use and issue planning
+* Planning according to Dubbo upgrading
+## Registry center suppor
+* In theory, all registries supported by Dubbo support
+
+## How to use?
+1. Dubbo doc annotation added to method parameters of Dubbo project
+   * Dubbo provider project introduces Dubbo doc core
+   * If Dubbo's interface and parameters are a separate jar package project, introduce Dubbo doc annotations
+
+### Current Version: Same as Dubbo version
+```
+<dependency>
+    <groupId>org.apache.dubbo</groupId>
+    <artifactId>dubbo-api-docs-annotations</artifactId>
+    <version>${dubbo-version}</version>
+</dependency>
+
+<dependency>
+    <groupId>org.apache.dubbo</groupId>
+    <artifactId>dubbo-api-docs-core</artifactId>
+    <version>${dubbo-version}</version>
+</dependency>
+```
+2.Download dubbo-doc-ui-server [Download](https://github.com/KeRan213539/dubboDoc/releases)
+
+3. Start dubbo-doc-ui-server
+
+4. Visit: http:// localhost:8888
+   * Port can be modified in application.yml
+   * swagger-ui http:// localhost:8888/swagger-ui.html
+### Annotation use
+* @DubboApiModule class annotation: dubbo API module information, used to mark the purpose of an interface class module
+    * value: module name
+    * apiInterface: Provider implemented interface
+    * version: module version
+* @DubboApi method annotation: dubbo API information, used to mark the purpose of an dubbo API
+    * value: API name
+    * description: API description(HTML tags available)
+    * version: API version
+    * responseClassDescription: response class description
+* @RequestParam class property/method Parameter annotation: mark request parameters
+    * value: parameter name
+    * required: true/false required parameter
+    * description: parameter description
+    * example: parameter example
+    * defaultValue: parameter default value
+    * allowableValues: Allowed values. After setting this property, a drop-down list will be generated for the parameter
+        * Note: a drop-down selection box will be generated after using this property
+        * Parameters of boolean type do not need to be set with this property. A drop-down list of true / false will be generated by default
+        * Parameters of enumeration type will automatically generate a drop-down list. If you do not want to open all enumeration values, you can set this property separately.
+* @ResponseProperty Class attribute annotation: mark response parameters
+    * value: parameter name
+    * example: example
+### dubbo-doc-ui
+* Get API list direct connection: 
+> Because Dubbo services with different functions may be registered in the same registration center, 
+> but the name of the interface used by Dubbo doc is the same, so the interface of Dubbo doc uses direct 
+connection to obtain the list of different interfaces of different functions.
+
+* The test can be connected directly or through the registration center
+### swagger-ui TODO
+
+### Use note
+* The response bean (the return type of the interface) supports custom generics, but only one generic placeholder.
+* About the use of Map: the key of map can only use the basic data type. If the key of map is not the basic data type, the generated key is not in the standard JSON format, and an exception will occur
+* The API's synchronous / asynchronous is from org.apache.dubbo.config.annotation.Service.async
+
+## Project structure
+* dubbo-doc-annotations: Document generation annotation project
+* dubbo-doc-core: Responsible for annotation analysis and document information acquisition interface (Dubbo API)
+* dubbo-doc-ui-server: Web service, responsible for displaying doc and providing testing function
+* dubbo-doc-console: The front-end project will be packaged into Dubbo doc UI server project when it is published
+* dubbo-doc-examples: Use example
+* readmeImgs: Pictures used by README.md
+
+## Major dependent version
+* spring-boot: 2.3.4.RELEASE
+* dubbo: apache dubbo 2.7.8
+* icework in front(iceworks 4.0)
+
+## What did Dubbo Doc do ?
+### Annotations
+* Define annotations to describe interfaces and parameters
+### In Dubbo projects that need to generate documentation and tests
+* Parsing annotations and caching
+* Add Dubbo API used by Dubbo doc to obtain interface information
+###  dubbo-doc-ui-server
+* Web service
+* Restful API used by front-end UI to obtain interface information (interface list, information of specified interface)
+* Request the restful API of the Dubbo service (using the method of Dubbo generalization call)
+* Save the test and display it next time (implemented in the Second Edition)
+### dubbo-doc-console(Package to dubbo-doc-ui-server when publishing)
+* Get the interface list and display it according to the specified Dubbo service IP and port (direct connection Dubbo service)
+* Get the interface information according to the specified interface and generate the form with DOC (similar to swagger)
+* Show API request response
\ No newline at end of file
diff --git a/dubbo-api-docs/README_ch.md b/dubbo-api-docs/README_ch.md
new file mode 100644
index 0000000..91351ef
--- /dev/null
+++ b/dubbo-api-docs/README_ch.md
@@ -0,0 +1,130 @@
+# dubboDoc
+
+[English](./README.md)
+
+[Gitee镜像](https://gitee.com/213539/dubboDoc)
+
+dubbo 接口文档、测试工具,根据注解生成文档,并提供测试功能.
+
+功能参考 swagger+springfox, 只需要加一些注解就能生成类似swagger的文档, 不会把非web的dubbo项目变为web项目.
+
+欢迎大家吐槽~
+
+目前第一版功能比较粗糙(界面也粗糙),用户体验不是很好,后面会慢慢优化,也欢迎各种PR~
+
+```
+在测试dubbo提供者的时候,一直在想如果dubbo有一个类似swagger的文档+测试工具就好了.
+也找了一下,找到的几个都是基于springfox的,会在dubbo项目中加一些restful接口,
+如果你的dubbo服务本身就是通过web容器启动或者混合有web项目那还好.
+但是我这边的dubbo项目都是非web项目,对于有强迫症的我来说,为了文档要把项目变成web项目有点无法接受,就有了自己动手的想法...
+```
+## 版本规划
+### 第一版
+* 解析注解并生成界面
+* 不太友好的使用界面(没有处理一些异常)
+### 第二版
+* 放json的文本域找一个合适的json编辑器替换,校验json格式
+* 增加标签页
+* 能保存测试,方便下次直接加载测试
+* 部分异常处理为友好的文字提示
+* 增加 remark.md 并在前端展示
+* 增加 changelog.md 并在前端展示
+### 后续版本
+* 根据自用产生的需求和issue规划
+* 根据dubbo升级情况规划
+## 注册中心支持
+* 理论上dubbo支持的所有注册中心都支持
+
+## 如何使用?
+1. dubbo项目的方法参数中加上 dubbo doc注解
+   * dubbo提供者项目引入 dubbo-doc-core
+   * 如果dubbo的接口和参数是一个单独的jar包项目,引入dubbo-doc-annotations
+   
+### 当前版本: 同Dubbo版本号
+```
+<dependency>
+    <groupId>org.apache.dubbo</groupId>
+    <artifactId>dubbo-api-docs-annotations</artifactId>
+    <version>${dubbo-version}</version>
+</dependency>
+
+<dependency>
+    <groupId>org.apache.dubbo</groupId>
+                <artifactId>dubbo-api-docs-core</artifactId>
+    <version>${dubbo-version}</version>
+</dependency>
+```
+2.下载 dubbo-doc-ui-server [下载地址](https://github.com/KeRan213539/dubboDoc/releases)
+
+[国内用户可到码云下载](https://gitee.com/213539/dubboDoc/releases)
+
+3. 启动 dubbo-doc-ui-server
+
+4. 访问: http:// localhost:8888
+   * application.yml 中可以修改端口
+   * swagger-ui http:// localhost:8888/swagger-ui.html
+### 注解使用
+* @DubboApiModule 类注解: dubbo接口模块信息,用于标注一个接口类模块的用途
+    * value: 模块名称
+    * apiInterface: 提供者实现的接口
+    * version: 模块版本
+* @DubboApi 方法注解: dubbo 接口信息,用于标注一个接口的用途
+    * value: 接口名称
+    * description: 接口描述(可使用html标签)
+    * version: 接口版本
+    * responseClassDescription: 响应的数据的描述
+* @RequestParam 类属性/方法参数注解:标注请求参数
+    * value: 参数名
+    * required: 是否必传参数
+    * description: 参数描述
+    * example: 参数示例
+    * defaultValue: 参数默认值
+    * allowableValues: 允许的值,设置该属性后界面上将对参数生成下拉列表
+        * 注:使用该属性后将生成下拉选择框
+        * boolean 类型的参数不用设置该属性,将默认生成 true/false 的下拉列表
+        * 枚举类型的参数会自动生成下拉列表,如果不想开放全部的枚举值,可以单独设置此属性.
+* @ResponseProperty 类属性注解: 标注响应参数
+    * value: 参数名
+    * example: 示例
+### dubbo-doc-ui
+* 获取接口列表直连: 由于可能不同功能的dubbo服务都会注册到同一个注册中心,但是dubbo doc
+使用的接口名是一样的,所以dubbo doc的接口采用直连方式以获取到不同功能服务的不同接口列表
+* 测试可以直连或者走注册中心
+### swagger-ui TODO
+
+### 使用注意
+* 响应bean(接口的返回类型)支持自定义泛型, 但只支持一个泛型占位符
+* 关于Map的使用:Map的key只能用基本数据类型.如果Map的key不是基础数据类型,生成的
+就不是标准json格式,会出异常
+* 接口的同步/异步取自 org.apache.dubbo.config.annotation.Service.async
+
+## 项目结构
+* dubbo-doc-annotations: 文档生成辅助注解项目
+* dubbo-doc-core: 负责注解解析,文档信息获取接口(dubbo接口)
+* dubbo-doc-ui-server: web服务,负责展示doc,并提供测试功能
+* dubbo-doc-console: 前端项目, 发布时会打包到 dubbo-doc-ui-server 项目中
+* dubbo-doc-examples: 使用示例
+* readmeImgs: README.md 用到的图片
+
+## 主要依赖版本
+* spring-boot: 2.3.4.RELEASE
+* dubbo: apache dubbo 2.7.8
+* 前端使用飞冰(iceworks 4.0)
+
+## Dubbo Doc 做了什么?
+### 注解
+* 定义一些注解用于描述接口和参数的注解
+### 在需要生成文档和测试的 dubbo 项目中
+* 解析注解并缓存
+* 增加dubbo doc使用的获取接口信息的 dubbo 接口
+###  dubbo-doc-ui-server
+* web服务
+* 前端ui使用的获取接口信息的 web 接口(接口列表, 指定接口的信息)
+* 请求 dubbo 服务的web接口(使用 dubbo 泛化调用的方式)
+* 保存测试,并可在下次展现(第二版实现)
+### dubbo-doc-console(发布时打包到 dubbo-doc-ui-server 中)
+* 根据指定的dubbo服务IP和端口获取接口列表并展示(直连dubbo服务)
+* 根据指定的接口获取接口信息并生成带doc的表单(类似swagger)
+* 展示接口请求的响应
+
+![界面](https://github.com/KeRan213539/dubboDoc/blob/develop/readmeImgs/DubboDoc.png)
\ No newline at end of file
diff --git a/dubbo-api-docs/dubbo-api-docs-annotations/pom.xml b/dubbo-api-docs/dubbo-api-docs-annotations/pom.xml
new file mode 100644
index 0000000..3437ad5
--- /dev/null
+++ b/dubbo-api-docs/dubbo-api-docs-annotations/pom.xml
@@ -0,0 +1,35 @@
+<!--
+  ~ 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.
+  -->
+<project xmlns="http://maven.apache.org/POM/4.0.0" xmlns:xsi="http://www.w3.org/2001/XMLSchema-instance"
+         xsi:schemaLocation="http://maven.apache.org/POM/4.0.0 http://maven.apache.org/maven-v4_0_0.xsd">
+    <modelVersion>4.0.0</modelVersion>
+
+    <parent>
+        <groupId>org.apache.dubbo</groupId>
+        <artifactId>dubbo-api-docs</artifactId>
+        <version>2.7.9-SNAPSHOT</version>
+        <relativePath>../pom.xml</relativePath>
+    </parent>
+
+    <artifactId>dubbo-api-docs-annotations</artifactId>
+
+    <dependencies>
+        
+    </dependencies>
+
+
+</project>
diff --git a/dubbo-api-docs/dubbo-api-docs-annotations/src/main/java/org/apache/dubbo/apidocs/annotations/ApiDoc.java b/dubbo-api-docs/dubbo-api-docs-annotations/src/main/java/org/apache/dubbo/apidocs/annotations/ApiDoc.java
new file mode 100644
index 0000000..f55c4c9
--- /dev/null
+++ b/dubbo-api-docs/dubbo-api-docs-annotations/src/main/java/org/apache/dubbo/apidocs/annotations/ApiDoc.java
@@ -0,0 +1,55 @@
+/*
+ * 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.apidocs.annotations;
+
+import java.lang.annotation.Documented;
+import java.lang.annotation.ElementType;
+import java.lang.annotation.Retention;
+import java.lang.annotation.RetentionPolicy;
+import java.lang.annotation.Target;
+
+/**
+ * dubbo api docs annotation,use to label of api.
+ * @author klw(213539@qq.com)
+ * 2020/10/29 14:46
+ */
+@Retention(RetentionPolicy.RUNTIME)
+@Target({ElementType.METHOD})
+@Documented
+public @interface ApiDoc {
+
+    /**
+     * api name.
+     */
+    String value();
+
+    /**
+     * api description(HTML tags available).
+     */
+    String description() default "";
+
+    /**
+     * api version.
+     */
+    String version() default "";
+
+    /**
+     * response class description.
+     */
+    String responseClassDescription() default "";
+
+}
diff --git a/dubbo-api-docs/dubbo-api-docs-annotations/src/main/java/org/apache/dubbo/apidocs/annotations/ApiModule.java b/dubbo-api-docs/dubbo-api-docs-annotations/src/main/java/org/apache/dubbo/apidocs/annotations/ApiModule.java
new file mode 100644
index 0000000..27d2bdc
--- /dev/null
+++ b/dubbo-api-docs/dubbo-api-docs-annotations/src/main/java/org/apache/dubbo/apidocs/annotations/ApiModule.java
@@ -0,0 +1,50 @@
+/*
+ * 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.apidocs.annotations;
+
+import java.lang.annotation.Documented;
+import java.lang.annotation.ElementType;
+import java.lang.annotation.Retention;
+import java.lang.annotation.RetentionPolicy;
+import java.lang.annotation.Target;
+
+/**
+ * api module, used to mark the purpose of an interface class module.
+ * @author klw(213539@qq.com)
+ * 2020/10/29 14:51
+ */
+@Retention(RetentionPolicy.RUNTIME)
+@Target({ElementType.TYPE})
+@Documented
+public @interface ApiModule {
+
+    /**
+     * module name
+     */
+    String value();
+
+    /**
+     * dubbo api interface class
+     */
+    Class<?> apiInterface();
+
+    /**
+     * module version
+     */
+    String version() default "";
+
+}
diff --git a/dubbo-api-docs/dubbo-api-docs-annotations/src/main/java/org/apache/dubbo/apidocs/annotations/RequestParam.java b/dubbo-api-docs/dubbo-api-docs-annotations/src/main/java/org/apache/dubbo/apidocs/annotations/RequestParam.java
new file mode 100644
index 0000000..a42f765
--- /dev/null
+++ b/dubbo-api-docs/dubbo-api-docs-annotations/src/main/java/org/apache/dubbo/apidocs/annotations/RequestParam.java
@@ -0,0 +1,70 @@
+/*
+ * 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.apidocs.annotations;
+
+import java.lang.annotation.Documented;
+import java.lang.annotation.ElementType;
+import java.lang.annotation.Inherited;
+import java.lang.annotation.Retention;
+import java.lang.annotation.RetentionPolicy;
+import java.lang.annotation.Target;
+
+/**
+ * Dimension request parameter.
+ * @author klw(213539@qq.com)
+ * 2020/10/29 14:48
+ */
+@Retention(RetentionPolicy.RUNTIME)
+@Target({ElementType.FIELD, ElementType.PARAMETER})
+@Documented
+@Inherited
+public @interface RequestParam {
+
+    /**
+     * param name
+     */
+    String value();
+
+    /**
+     * required
+     */
+    boolean required() default false;
+
+    /**
+     * description(HTML tags available)
+     */
+    String description() default "";
+
+    /**
+     * example(HTML tags available)
+     */
+    String example() default "";
+
+    /**
+     * default value
+     */
+    String defaultValue() default "";
+
+    /**
+     * Allowed values. After setting this property, a drop-down list will be generated for the parameter <br />
+     * Note: a drop-down selection box will be generated after using this property<br />
+     * 1. Parameters of boolean type do not need to be set with this property. A drop-down list of true / false will be generated by default<br />
+     * 2. Parameters of enumeration type will automatically generate a drop-down list. If you do not want to open all enumeration values, you can set this property separately.
+     */
+    String[] allowableValues() default {};
+
+}
diff --git a/dubbo-api-docs/dubbo-api-docs-annotations/src/main/java/org/apache/dubbo/apidocs/annotations/ResponseProperty.java b/dubbo-api-docs/dubbo-api-docs-annotations/src/main/java/org/apache/dubbo/apidocs/annotations/ResponseProperty.java
new file mode 100644
index 0000000..f18c184
--- /dev/null
+++ b/dubbo-api-docs/dubbo-api-docs-annotations/src/main/java/org/apache/dubbo/apidocs/annotations/ResponseProperty.java
@@ -0,0 +1,47 @@
+/*
+ * 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.apidocs.annotations;
+
+import java.lang.annotation.Documented;
+import java.lang.annotation.ElementType;
+import java.lang.annotation.Inherited;
+import java.lang.annotation.Retention;
+import java.lang.annotation.RetentionPolicy;
+import java.lang.annotation.Target;
+
+/**
+ * Dimension response property.
+ * @author klw(213539@qq.com)
+ * 2020/10/29 14:50
+ */
+@Retention(RetentionPolicy.RUNTIME)
+@Target({ElementType.FIELD})
+@Documented
+@Inherited
+public @interface ResponseProperty {
+
+    /**
+     * property name
+     */
+    String value();
+
+    /**
+     * example
+     */
+    String example() default "";
+
+}
diff --git a/dubbo-api-docs/dubbo-api-docs-core/pom.xml b/dubbo-api-docs/dubbo-api-docs-core/pom.xml
new file mode 100644
index 0000000..c251cd2
--- /dev/null
+++ b/dubbo-api-docs/dubbo-api-docs-core/pom.xml
@@ -0,0 +1,71 @@
+<!--
+  ~ 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.
+  -->
+
+<project xmlns="http://maven.apache.org/POM/4.0.0" xmlns:xsi="http://www.w3.org/2001/XMLSchema-instance"
+         xsi:schemaLocation="http://maven.apache.org/POM/4.0.0 http://maven.apache.org/maven-v4_0_0.xsd">
+    <modelVersion>4.0.0</modelVersion>
+
+    <parent>
+        <groupId>org.apache.dubbo</groupId>
+        <artifactId>dubbo-api-docs</artifactId>
+        <version>2.7.9-SNAPSHOT</version>
+        <relativePath>../pom.xml</relativePath>
+    </parent>
+
+    <artifactId>dubbo-api-docs-core</artifactId>
+
+    <dependencies>
+
+        <dependency>
+            <groupId>org.apache.dubbo</groupId>
+            <artifactId>dubbo-api-docs-annotations</artifactId>
+        </dependency>
+
+        <dependency>
+            <groupId>org.apache.dubbo</groupId>
+            <artifactId>dubbo</artifactId>
+            <scope>compile</scope>
+        </dependency>
+
+        <dependency>
+            <groupId>com.alibaba</groupId>
+            <artifactId>fastjson</artifactId>
+            <scope>compile</scope>
+        </dependency>
+
+        <dependency>
+            <groupId>org.apache.commons</groupId>
+            <artifactId>commons-lang3</artifactId>
+            <scope>compile</scope>
+        </dependency>
+
+        <dependency>
+            <groupId>org.springframework.boot</groupId>
+            <artifactId>spring-boot</artifactId>
+            <scope>compile</scope>
+        </dependency>
+
+        <dependency>
+            <groupId>org.slf4j</groupId>
+            <artifactId>slf4j-api</artifactId>
+            <scope>compile</scope>
+        </dependency>
+
+    </dependencies>
+
+
+</project>
diff --git a/dubbo-api-docs/dubbo-api-docs-core/src/main/java/org/apache/dubbo/apidocs/EnableDubboApiDocs.java b/dubbo-api-docs/dubbo-api-docs-core/src/main/java/org/apache/dubbo/apidocs/EnableDubboApiDocs.java
new file mode 100644
index 0000000..435a056
--- /dev/null
+++ b/dubbo-api-docs/dubbo-api-docs-core/src/main/java/org/apache/dubbo/apidocs/EnableDubboApiDocs.java
@@ -0,0 +1,40 @@
+/*
+ * 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.apidocs;
+
+import org.apache.dubbo.apidocs.core.DubboApiDocsAnnotationScanner;
+
+import org.springframework.context.annotation.Import;
+import java.lang.annotation.Documented;
+import java.lang.annotation.ElementType;
+import java.lang.annotation.Inherited;
+import java.lang.annotation.Retention;
+import java.lang.annotation.RetentionPolicy;
+import java.lang.annotation.Target;
+
+/**
+ * Enable dubbo api doc.
+ * @author klw(213539@qq.com)
+ * 2020/10/29 17:48
+ */
+@Retention(RetentionPolicy.RUNTIME)
+@Target({ElementType.TYPE})
+@Documented
+@Inherited
+@Import({DubboApiDocsAnnotationScanner.class})
+public @interface EnableDubboApiDocs {
+}
diff --git a/dubbo-api-docs/dubbo-api-docs-core/src/main/java/org/apache/dubbo/apidocs/core/DubboApiDocsAnnotationScanner.java b/dubbo-api-docs/dubbo-api-docs-core/src/main/java/org/apache/dubbo/apidocs/core/DubboApiDocsAnnotationScanner.java
new file mode 100644
index 0000000..a089805
--- /dev/null
+++ b/dubbo-api-docs/dubbo-api-docs-core/src/main/java/org/apache/dubbo/apidocs/core/DubboApiDocsAnnotationScanner.java
@@ -0,0 +1,346 @@
+/*
+ * 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.apidocs.core;
+
+import org.apache.dubbo.apidocs.core.beans.HtmlTypeEnum;
+import org.apache.dubbo.apidocs.core.beans.ParamBean;
+import org.apache.dubbo.apidocs.core.providers.DubboDocProviderImpl;
+import org.apache.dubbo.apidocs.core.providers.IDubboDocProvider;
+import org.apache.dubbo.config.ApplicationConfig;
+import org.apache.dubbo.config.ProtocolConfig;
+import org.apache.dubbo.config.RegistryConfig;
+import org.apache.dubbo.config.ServiceConfig;
+import org.apache.dubbo.config.annotation.DubboService;
+import org.apache.dubbo.config.annotation.Service;
+import org.apache.dubbo.apidocs.annotations.*;
+import org.apache.dubbo.apidocs.utils.ClassTypeUtil;
+
+import com.alibaba.fastjson.JSON;
+import lombok.extern.slf4j.Slf4j;
+import org.springframework.aop.support.AopUtils;
+import org.springframework.beans.factory.annotation.Autowired;
+import org.springframework.boot.context.event.ApplicationReadyEvent;
+import org.springframework.context.ApplicationContext;
+import org.springframework.context.ApplicationListener;
+import org.springframework.context.annotation.Import;
+
+import java.lang.annotation.Annotation;
+import java.lang.reflect.Field;
+import java.lang.reflect.InvocationTargetException;
+import java.lang.reflect.Method;
+import java.lang.reflect.Parameter;
+import java.util.ArrayList;
+import java.util.HashMap;
+import java.util.List;
+import java.util.Map;
+
+/**
+ * Scan and process dubbo doc annotations.
+ *
+ * @author klw(213539 @ qq.com)
+ * 2020/10/29 17:55
+ */
+@Slf4j
+@Import({DubboDocProviderImpl.class})
+public class DubboApiDocsAnnotationScanner implements ApplicationListener<ApplicationReadyEvent> {
+
+    @Autowired
+    private ApplicationContext applicationContext;
+
+    @Autowired
+    private ApplicationConfig application;
+
+    @Autowired
+    private RegistryConfig registry;
+
+    @Autowired
+    private ProtocolConfig protocol;
+
+    @Override
+    public void onApplicationEvent(ApplicationReadyEvent applicationReadyEvent) {
+        // Register dubbo doc provider
+        IDubboDocProvider dubboDocProvider = applicationContext.getBean(IDubboDocProvider.class);
+        exportDubboService(IDubboDocProvider.class, dubboDocProvider, false);
+
+        log.info("================= Dubbo API Docs--Start scanning and processing doc annotations ================");
+
+        Map<String, Object> apiModules = applicationContext.getBeansWithAnnotation(ApiModule.class);
+        apiModules.forEach((key, apiModuleTemp) -> {
+            Class<?> apiModuleClass;
+            if (AopUtils.isAopProxy(apiModuleTemp)) {
+                apiModuleClass = AopUtils.getTargetClass(apiModuleTemp);
+            } else {
+                apiModuleClass = apiModuleTemp.getClass();
+            }
+            ApiModule moduleAnn = apiModuleClass.getAnnotation(ApiModule.class);
+            if (!apiModuleClass.isAnnotationPresent(Service.class) && !apiModuleClass.isAnnotationPresent(DubboService.class)) {
+                log.warn(
+                        "【Warning】{} @ApiModule annotation is used, but it is not a dubbo provider (without {} annotation)",
+                        apiModuleClass.getName(), Service.class.getName() + " or " + DubboService.class.getName());
+                return;
+            }
+            boolean async;
+            if (apiModuleClass.isAnnotationPresent(Service.class)) {
+                Service dubboService = apiModuleClass.getAnnotation(Service.class);
+                async = dubboService.async();
+            } else {
+                DubboService dubboService = apiModuleClass.getAnnotation(DubboService.class);
+                async = dubboService.async();
+            }
+            Map<String, Object> moduleCacheItem = new HashMap<>(4);
+            DubboApiDocsCache.addApiModule(moduleAnn.apiInterface().getCanonicalName(), moduleCacheItem);
+            //module name
+            moduleCacheItem.put("moduleChName", moduleAnn.value());
+            //interface name containing package path
+            moduleCacheItem.put("moduleClassName", moduleAnn.apiInterface().getCanonicalName());
+            //module version
+            moduleCacheItem.put("moduleVersion", moduleAnn.version());
+
+            Method[] apiModuleMethods = apiModuleClass.getMethods();
+            // API basic information list in module cache
+            List<Map<String, Object>> moduleApiList = new ArrayList<>(apiModuleMethods.length);
+            moduleCacheItem.put("moduleApiList", moduleApiList);
+            for (Method method : apiModuleMethods) {
+                if (method.isAnnotationPresent(ApiDoc.class)) {
+                    processApiDocAnnotation(method, moduleApiList, moduleAnn, async, moduleCacheItem);
+                }
+            }
+        });
+        log.info("================= Dubbo API Docs-- doc annotations scanning and processing completed ================");
+    }
+
+    private void processApiDocAnnotation(Method method, List<Map<String, Object>> moduleApiList, ApiModule moduleAnn,
+                                         boolean async, Map<String, Object> moduleCacheItem) {
+        ApiDoc dubboApi = method.getAnnotation(ApiDoc.class);
+
+        // API basic information in API list in module
+        Map<String, Object> apiListItem = new HashMap<>(4);
+        moduleApiList.add(apiListItem);
+        //API method name
+        apiListItem.put("apiName", method.getName());
+        //API name
+        apiListItem.put("apiChName", dubboApi.value());
+        // API description
+        apiListItem.put("description", dubboApi.description());
+        //API version
+        apiListItem.put("apiVersion", dubboApi.version());
+        //Description of API return data
+        apiListItem.put("apiRespDec", dubboApi.responseClassDescription());
+
+        // Interface parameters and response information
+        Map<String, Object> apiParamsAndResp = new HashMap<>(2);
+        DubboApiDocsCache.addApiParamsAndResp(
+                moduleAnn.apiInterface().getCanonicalName() + "." + method.getName(), apiParamsAndResp);
+
+        Class<?>[] argsClass = method.getParameterTypes();
+        Annotation[][] argsAnns = method.getParameterAnnotations();
+        Parameter[] parameters = method.getParameters();
+        List<Map<String, Object>> paramList = new ArrayList<>(argsClass.length);
+        apiParamsAndResp.put("async", async);
+        apiParamsAndResp.put("apiName", method.getName());
+        apiParamsAndResp.put("apiChName", dubboApi.value());
+        apiParamsAndResp.put("apiVersion", dubboApi.version());
+        apiParamsAndResp.put("apiRespDec", dubboApi.responseClassDescription());
+        apiParamsAndResp.put("apiModelClass", moduleCacheItem.get("moduleClassName"));
+        apiParamsAndResp.put("params", paramList);
+        apiParamsAndResp.put("response", ClassTypeUtil.calss2Json(method.getGenericReturnType(), method.getReturnType()));
+        for (int i = 0; i < argsClass.length; i++) {
+            Class<?> argClass = argsClass[i];
+            Annotation[] argAnns = argsAnns[i];
+            Map<String, Object> prarmListItem = new HashMap<>(2);
+            paramList.add(prarmListItem);
+            prarmListItem.put("prarmType", argClass.getCanonicalName());
+            prarmListItem.put("prarmIndex", i);
+            RequestParam requestParam = null;
+            // Handling @RequestParam annotations on parameters
+            for (Annotation ann : argAnns) {
+                if (ann instanceof RequestParam) {
+                    requestParam = (RequestParam) ann;
+                }
+            }
+            ParamBean paramBean = this.processHtmlType(argClass, requestParam, null);
+            if (paramBean == null) {
+                // Not a basic type, handling properties in method parameters
+                List<ParamBean> apiParamsList = processField(argClass);
+                if (apiParamsList != null && !apiParamsList.isEmpty()) {
+                    prarmListItem.put("prarmInfo", apiParamsList);
+                }
+            } else {
+                // Is the basic type
+                Parameter methodParameter = parameters[i];
+                prarmListItem.put("name", methodParameter.getName());
+                prarmListItem.put("htmlType", paramBean.getHtmlType().name());
+                prarmListItem.put("allowableValues", paramBean.getAllowableValues());
+                if (requestParam != null) {
+
+                    // Handling requestparam annotations on parameters
+                    prarmListItem.put("nameCh", requestParam.value());
+                    prarmListItem.put("description", requestParam.description());
+                    prarmListItem.put("example", requestParam.example());
+                    prarmListItem.put("defaultValue", requestParam.defaultValue());
+                    prarmListItem.put("required", requestParam.required());
+                } else {
+                    prarmListItem.put("required", false);
+                }
+            }
+        }
+    }
+
+    /**
+     * For the attributes in the method parameters, only one layer is processed.
+     * The deeper layer is directly converted to JSON, and the deeper layer is up to 5 layers
+     */
+    private List<ParamBean> processField(Class<?> argClass) {
+
+        List<ParamBean> apiParamsList = new ArrayList(16);
+        // get all fields
+        List<Field> allFields = ClassTypeUtil.getAllFields(null, argClass);
+        for (Field field : allFields) {
+            ParamBean paramBean = new ParamBean();
+            paramBean.setName(field.getName());
+            paramBean.setJavaType(field.getType().getCanonicalName());
+            RequestParam requestParam = null;
+            if (field.isAnnotationPresent(RequestParam.class)) {
+                // Handling @RequestParam annotations on properties
+                requestParam = field.getAnnotation(RequestParam.class);
+                paramBean.setNameCh(requestParam.value());
+                paramBean.setRequired(requestParam.required());
+                paramBean.setDescription(requestParam.description());
+                paramBean.setExample(requestParam.example());
+                paramBean.setDefaultValue(requestParam.defaultValue());
+            } else {
+                paramBean.setRequired(false);
+            }
+
+            if (this.processHtmlType(field.getType(), requestParam, paramBean) == null) {
+                // Not a basic type, handle as JSON
+                Object objResult = ClassTypeUtil.initClassTypeWithDefaultValue(
+                        field.getGenericType(), field.getType(), 0);
+                if (!ClassTypeUtil.isBaseType(objResult)) {
+                    paramBean.setHtmlType(HtmlTypeEnum.TEXT_AREA);
+                    paramBean.setSubParamsJson(JSON.toJSONString(objResult, ClassTypeUtil.FAST_JSON_FEATURES));
+                }
+            }
+            apiParamsList.add(paramBean);
+        }
+        return apiParamsList;
+    }
+
+    /**
+     * Determine what HTML form elements to use.
+     * 2020/10/29 18:24
+     *
+     * @param classType  classType
+     * @param annotation annotation
+     * @param prarm      prarm
+     * @return org.apache.dubbo.apidocs.core.beans.ParamBean
+     */
+    private ParamBean processHtmlType(Class<?> classType, RequestParam annotation, ParamBean prarm) {
+        if (prarm == null) {
+            prarm = new ParamBean();
+        }
+        if (annotation != null) {
+            prarm.setAllowableValues(annotation.allowableValues());
+        }
+        // Is there any allowed values
+        boolean hasAllowableValues = (prarm.getAllowableValues() != null && prarm.getAllowableValues().length > 0);
+        // Processed or not
+        boolean processed = false;
+        if (Integer.class.isAssignableFrom(classType)) {
+            prarm.setHtmlType(HtmlTypeEnum.NUMBER_INTEGER);
+            processed = true;
+        } else if (Byte.class.isAssignableFrom(classType)) {
+            prarm.setHtmlType(HtmlTypeEnum.TEXT_BYTE);
+            processed = true;
+        } else if (Long.class.isAssignableFrom(classType)) {
+            prarm.setHtmlType(HtmlTypeEnum.NUMBER_INTEGER);
+            processed = true;
+        } else if (Double.class.isAssignableFrom(classType)) {
+            prarm.setHtmlType(HtmlTypeEnum.NUMBER_DECIMAL);
+            processed = true;
+        } else if (Float.class.isAssignableFrom(classType)) {
+            prarm.setHtmlType(HtmlTypeEnum.NUMBER_DECIMAL);
+            processed = true;
+        } else if (String.class.isAssignableFrom(classType)) {
+            prarm.setHtmlType(HtmlTypeEnum.TEXT);
+            processed = true;
+        } else if (Character.class.isAssignableFrom(classType)) {
+            prarm.setHtmlType(HtmlTypeEnum.TEXT_CHAR);
+            processed = true;
+        } else if (Short.class.isAssignableFrom(classType)) {
+            prarm.setHtmlType(HtmlTypeEnum.NUMBER_INTEGER);
+            processed = true;
+        }
+        if (processed) {
+            // Processed, time to return
+            if (hasAllowableValues) {
+                // Allowed values has value, change to select
+                prarm.setHtmlType(HtmlTypeEnum.SELECT);
+            }
+            return prarm;
+        }
+
+        // haven't dealt with it. Go on
+        if (Boolean.class.isAssignableFrom(classType)) {
+            prarm.setHtmlType(HtmlTypeEnum.SELECT);
+            // Boolean can only be true / false. No matter what the previous allowed value is, it is forced to replace
+            prarm.setAllowableValues(new String[]{"true", "false"});
+            processed = true;
+        } else if (Enum.class.isAssignableFrom(classType)) {
+            // process enum
+            prarm.setHtmlType(HtmlTypeEnum.SELECT);
+            if (!hasAllowableValues) {
+                // If there is no optional value, it is taken from the enumeration.
+                //TODO If there is an optional value, it is necessary
+                // to check whether the optional value matches the enumeration. It is add it later
+                Object[] enumConstants = classType.getEnumConstants();
+                String[] enumAllowableValues = new String[enumConstants.length];
+                try {
+                    Method getNameMethod = classType.getMethod("name");
+                    for (int i = 0; i < enumConstants.length; i++) {
+                        Object obj = enumConstants[i];
+                        enumAllowableValues[i] = (String) getNameMethod.invoke(obj);
+                    }
+                } catch (NoSuchMethodException | IllegalAccessException | InvocationTargetException e) {
+                    log.error("", e);
+                }
+                prarm.setAllowableValues(enumAllowableValues);
+            }
+            processed = true;
+        }
+        if (processed) {
+            return prarm;
+        }
+        return null;
+    }
+
+    /**
+     * export dubbo service for dubbo doc
+     */
+    private <I, T> void exportDubboService(Class<I> serviceClass, T serviceImplInstance, boolean async) {
+        ServiceConfig<T> service = new ServiceConfig<>();
+        service.setApplication(application);
+        service.setRegistry(registry);
+        service.setProtocol(protocol);
+        service.setInterface(serviceClass);
+        service.setRef(serviceImplInstance);
+        service.setAsync(async);
+//        service.setVersion("1.0.0");
+        service.export();
+    }
+
+}
diff --git a/dubbo-api-docs/dubbo-api-docs-core/src/main/java/org/apache/dubbo/apidocs/core/DubboApiDocsCache.java b/dubbo-api-docs/dubbo-api-docs-core/src/main/java/org/apache/dubbo/apidocs/core/DubboApiDocsCache.java
new file mode 100644
index 0000000..e3b5b6d
--- /dev/null
+++ b/dubbo-api-docs/dubbo-api-docs-core/src/main/java/org/apache/dubbo/apidocs/core/DubboApiDocsCache.java
@@ -0,0 +1,106 @@
+/*
+ * 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.apidocs.core;
+
+import org.apache.dubbo.apidocs.utils.ClassTypeUtil;
+
+import com.alibaba.fastjson.JSON;
+
+import java.util.ArrayList;
+import java.util.List;
+import java.util.Map;
+import java.util.concurrent.ConcurrentHashMap;
+
+/**
+ * dubbo doc cache.
+ * @author klw(213539@qq.com)
+ * 2020/10/29 17:40
+ */
+public class DubboApiDocsCache {
+
+    /**
+     * module cache.
+     */
+    private static Map<String, Map<String, Object>> apiModulesCache = new ConcurrentHashMap<>(16);
+    /**
+     * module cache.
+     */
+    private static Map<String, String> apiModulesStrCache = new ConcurrentHashMap<>(16);
+
+    /**
+     * API details cache in module.
+     */
+    private static Map<String, Map<String, Object>> apiParamsAndRespCache = new ConcurrentHashMap<>(16);
+    /**
+     * API details cache in module.
+     */
+    private static Map<String, String> apiParamsAndRespStrCache = new ConcurrentHashMap<>(16);
+
+    private static String allApiModuleInfo = null;
+
+    public static void addApiModule(String key, Map<String, Object> moduleCacheItem){
+        apiModulesCache.put(key, moduleCacheItem);
+    }
+
+    public static void addApiParamsAndResp(String key, Map<String, Object> apiParamsAndResp){
+        apiParamsAndRespCache.put(key, apiParamsAndResp);
+    }
+
+    public static Map<String, Object> getApiModule(String key){
+        return apiModulesCache.get(key);
+    }
+
+    public static String getApiModuleStr(String key){
+        String result = apiModulesStrCache.get(key);
+        if(result == null){
+            Map<String, Object> temp = apiModulesCache.get(key);
+            if(temp != null) {
+                result = JSON.toJSONString(temp, ClassTypeUtil.FAST_JSON_FEATURES);
+                apiModulesStrCache.put(key, result);
+            }
+        }
+        return result;
+    }
+
+    public static Map<String, Object> getApiParamsAndResp(String key){
+        return apiParamsAndRespCache.get(key);
+    }
+
+    public static String getApiParamsAndRespStr(String key){
+        String result = apiParamsAndRespStrCache.get(key);
+        if(result == null){
+            Map<String, Object> temp = apiParamsAndRespCache.get(key);
+            if(temp != null) {
+                result = JSON.toJSONString(temp, ClassTypeUtil.FAST_JSON_FEATURES);
+                apiParamsAndRespStrCache.put(key, result);
+            }
+        }
+        return result;
+    }
+
+    public static String getAllApiModuleInfo(){
+        if(allApiModuleInfo == null){
+            List<Map<String, Object>> tempList = new ArrayList<>(apiModulesCache.size());
+            apiModulesCache.forEach((k, v) -> {
+                tempList.add(v);
+            });
+            allApiModuleInfo = JSON.toJSONString(tempList, ClassTypeUtil.FAST_JSON_FEATURES);
+        }
+        return allApiModuleInfo;
+    }
+
+}
diff --git a/dubbo-api-docs/dubbo-api-docs-core/src/main/java/org/apache/dubbo/apidocs/core/beans/HtmlTypeEnum.java b/dubbo-api-docs/dubbo-api-docs-core/src/main/java/org/apache/dubbo/apidocs/core/beans/HtmlTypeEnum.java
new file mode 100644
index 0000000..37303d6
--- /dev/null
+++ b/dubbo-api-docs/dubbo-api-docs-core/src/main/java/org/apache/dubbo/apidocs/core/beans/HtmlTypeEnum.java
@@ -0,0 +1,62 @@
+/*
+ * 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.apidocs.core.beans;
+
+/**
+ * html type enum.
+ * @author klw(213539@qq.com)
+ * 2020/10/29 16:56
+ */
+public enum HtmlTypeEnum {
+
+    /**
+     * Textbox.
+     */
+    TEXT,
+
+    /**
+     * Textbox, This type will be converted to byte before calling dubbo API.
+     */
+    TEXT_BYTE,
+
+    /**
+     * Textbox, will be limited to one character. This type will be converted to char before calling dubbo API.
+     */
+    TEXT_CHAR,
+
+    /**
+     * Numeric input box, integer.
+     */
+    NUMBER_INTEGER,
+
+    /**
+     * Numeric input box, decimal.
+     */
+    NUMBER_DECIMAL,
+
+    /**
+     * Drop down selection box.
+     */
+    SELECT,
+
+    /**
+     * Text area, which is generally used to show the JSON string of the Java Bean contained in the parameter.
+     */
+    TEXT_AREA,
+    ;
+
+}
diff --git a/dubbo-api-docs/dubbo-api-docs-core/src/main/java/org/apache/dubbo/apidocs/core/beans/ParamBean.java b/dubbo-api-docs/dubbo-api-docs-core/src/main/java/org/apache/dubbo/apidocs/core/beans/ParamBean.java
new file mode 100644
index 0000000..abac9a8
--- /dev/null
+++ b/dubbo-api-docs/dubbo-api-docs-core/src/main/java/org/apache/dubbo/apidocs/core/beans/ParamBean.java
@@ -0,0 +1,93 @@
+/*
+ * 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.apidocs.core.beans;
+
+import com.alibaba.fastjson.annotation.JSONField;
+import lombok.Getter;
+import lombok.Setter;
+
+import java.util.List;
+
+/**
+ * Parameter bean corresponding to {@link org.apache.dubbo.apidocs.annotations.RequestParam}, for caching.
+ * @author klw(213539@qq.com)
+ * 2020/10/29 17:32
+ */
+@Getter
+@Setter
+public class ParamBean {
+
+    /**
+     * parameter name.
+     */
+    private String name;
+
+    /**
+     * parameter name, for display.
+     */
+    private String nameCh;
+
+    /**
+     * required.
+     */
+    private Boolean required;
+
+    /**
+     * description.
+     */
+    private String description;
+
+    /**
+     * example.
+     */
+    private String example;
+
+    /**
+     * default value.
+     */
+    private String defaultValue;
+
+    /**
+     * java type of parameter.
+     */
+    private String javaType;
+
+    /**
+     * What HTML elements should this parameter display.
+     */
+    private HtmlTypeEnum htmlType;
+
+    /**
+     * allowed values
+     */
+    private String[] allowableValues;
+
+    /**
+     * If the parameter in a request bean is not a basic data type,
+     * the {@link #subParams} will have a value.
+     * Because the HTML form is not easy to display this parameter,
+     * it will be displayed as a text area, and the JSON string of this parameter will be filled in.
+     */
+    @JSONField(serialize = false)
+    private List<ParamBean> subParams;
+
+    /**
+     * JSON string corresponding to {@link #subParams}.
+     */
+    private String subParamsJson;
+
+}
diff --git a/dubbo-api-docs/dubbo-api-docs-core/src/main/java/org/apache/dubbo/apidocs/core/providers/DubboDocProviderImpl.java b/dubbo-api-docs/dubbo-api-docs-core/src/main/java/org/apache/dubbo/apidocs/core/providers/DubboDocProviderImpl.java
new file mode 100644
index 0000000..d8cfb2b
--- /dev/null
+++ b/dubbo-api-docs/dubbo-api-docs-core/src/main/java/org/apache/dubbo/apidocs/core/providers/DubboDocProviderImpl.java
@@ -0,0 +1,47 @@
+/*
+ * 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.apidocs.core.providers;
+
+import org.apache.dubbo.apidocs.core.DubboApiDocsCache;
+import org.apache.dubbo.config.annotation.DubboService;
+
+import lombok.extern.slf4j.Slf4j;
+
+/**
+ * The api implementation of Dubbo doc.
+ * @author klw(213539@qq.com)
+ * 2020/10/29 17:38
+ */
+@Slf4j
+@DubboService
+public class DubboDocProviderImpl implements IDubboDocProvider {
+
+    @Override
+    public String apiModuleList() {
+        return DubboApiDocsCache.getAllApiModuleInfo();
+    }
+
+    @Override
+    public String apiModuleInfo(String apiInterfaceClassName) {
+        return DubboApiDocsCache.getApiModuleStr(apiInterfaceClassName);
+    }
+
+    @Override
+    public String apiParamsResponseInfo(String apiInterfaceClassNameMethodName) {
+        return DubboApiDocsCache.getApiParamsAndRespStr(apiInterfaceClassNameMethodName);
+    }
+}
diff --git a/dubbo-api-docs/dubbo-api-docs-core/src/main/java/org/apache/dubbo/apidocs/core/providers/IDubboDocProvider.java b/dubbo-api-docs/dubbo-api-docs-core/src/main/java/org/apache/dubbo/apidocs/core/providers/IDubboDocProvider.java
new file mode 100644
index 0000000..38899dc
--- /dev/null
+++ b/dubbo-api-docs/dubbo-api-docs-core/src/main/java/org/apache/dubbo/apidocs/core/providers/IDubboDocProvider.java
@@ -0,0 +1,50 @@
+/*
+ * 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.apidocs.core.providers;
+
+/**
+ * The api used by Dubbo doc, get the parsed API information.
+ * @author klw(213539@qq.com)
+ * 2020/10/29 16:57
+ */
+public interface IDubboDocProvider {
+
+    /**
+     * Get basic information of all modules, excluding API parameter information.
+     * 2020/10/30 16:38
+     * @param
+     * @return java.lang.String
+     */
+    String apiModuleList();
+
+    /**
+     * Get module information according to the complete class name of Dubbo provider interface.
+     * 2020/10/30 16:38
+     * @param apiInterfaceClassName
+     * @return java.lang.String
+     */
+    String apiModuleInfo(String apiInterfaceClassName);
+
+    /**
+     * Get method parameters and return information according to the complete class name and method name of Dubbo provider interface.
+     * 2020/10/30 16:38
+     * @param apiInterfaceClassNameMethodName
+     * @return java.lang.String
+     */
+    String apiParamsResponseInfo(String apiInterfaceClassNameMethodName);
+
+}
diff --git a/dubbo-api-docs/dubbo-api-docs-core/src/main/java/org/apache/dubbo/apidocs/utils/ClassTypeUtil.java b/dubbo-api-docs/dubbo-api-docs-core/src/main/java/org/apache/dubbo/apidocs/utils/ClassTypeUtil.java
new file mode 100644
index 0000000..cdb872c
--- /dev/null
+++ b/dubbo-api-docs/dubbo-api-docs-core/src/main/java/org/apache/dubbo/apidocs/utils/ClassTypeUtil.java
@@ -0,0 +1,307 @@
+/*
+ * 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.apidocs.utils;
+
+import com.alibaba.fastjson.JSON;
+import com.alibaba.fastjson.serializer.SerializerFeature;
+import lombok.extern.slf4j.Slf4j;
+import org.apache.commons.lang3.StringUtils;
+import sun.reflect.generics.reflectiveObjects.ParameterizedTypeImpl;
+
+import java.lang.reflect.*;
+import java.time.LocalDate;
+import java.time.LocalDateTime;
+import java.util.*;
+import java.util.concurrent.CompletableFuture;
+import org.apache.dubbo.apidocs.annotations.*;
+
+/**
+ * Java class tool class, special for Dubbo doc.
+ * @author klw(213539@qq.com)
+ * 2020/10/29 18:08
+ */
+@Slf4j
+public class ClassTypeUtil {
+
+    /**
+     * fastjson features
+     */
+    public static SerializerFeature[] FAST_JSON_FEATURES = {
+            //Whether to output the field with null value. The default value is false.
+            SerializerFeature.WriteMapNullValue,
+            //If the list field is null, the output is [], not null
+            SerializerFeature.WriteNullListAsEmpty,
+            //If the character type field is null, the output is' ', not null
+            SerializerFeature.WriteNullStringAsEmpty,
+            //If the Boolean field is null, the output is false instead of null
+            SerializerFeature.WriteNullBooleanAsFalse,
+            // Null number output 0
+            SerializerFeature.WriteNullNumberAsZero,
+            //Eliminate the problem of circular reference to the same object.
+            // The default value is false (it may enter a dead cycle if not configured)
+            SerializerFeature.DisableCircularReferenceDetect,
+            // Use. Name() to handle enumeration
+            SerializerFeature.WriteEnumUsingName
+    };
+
+    private static final int PROCESS_COUNT_MAX = 10;
+
+    private static final String GENERIC_START_SYMBOL = "<";
+
+    public static String calss2Json(Type genericType, Class<?> classType) {
+        Object obj = initClassTypeWithDefaultValue(genericType, classType, 0);
+        return JSON.toJSONString(obj, FAST_JSON_FEATURES);
+    }
+
+    /**
+     * Instantiate class and its fields.
+     * 2020/10/29 18:08
+     * @param genericType genericType
+     * @param classType classType
+     * @param processCount processCount
+     * @return java.lang.Object
+     */
+    public static Object initClassTypeWithDefaultValue(Type genericType, Class<?> classType, int processCount) {
+        if (processCount >= PROCESS_COUNT_MAX) {
+            log.warn("The depth of bean has exceeded 10 layers, the deeper layer will be ignored! " +
+                    "Please modify the parameter structure or check whether there is circular reference in bean!");
+            return null;
+        }
+        processCount++;
+
+        Object initResult = initClassTypeWithDefaultValueNoProceeField(genericType, classType, processCount);
+        if (null != initResult) {
+            return initResult;
+        }
+
+        Map<String, Object> result = new HashMap<>(16);
+        // get all fields
+        List<Field> allFields = getAllFields(null, classType);
+        for (Field field2 : allFields) {
+            if ("serialVersionUID".equals(field2.getName())) {
+                continue;
+            }
+            if (String.class.isAssignableFrom(field2.getType())) {
+                if (field2.isAnnotationPresent(RequestParam.class)) {
+                    RequestParam requestParam = field2.getAnnotation(RequestParam.class);
+                    result.put(field2.getName(), requestParam.value());
+                } else if (field2.isAnnotationPresent(ResponseProperty.class)) {
+                    ResponseProperty responseProperty = field2.getAnnotation(ResponseProperty.class);
+                    StringBuilder strValue = new StringBuilder(responseProperty.value());
+                    if (StringUtils.isNotBlank(responseProperty.example())) {
+                        strValue.append("【example: ").append(responseProperty.example()).append("】");
+                    }
+                    result.put(field2.getName(), strValue.toString());
+                } else {
+                    // It's string, but there's no annotation
+                    result.put(field2.getName(), initClassTypeWithDefaultValue(field2.getGenericType(), field2.getType(), processCount));
+                }
+            } else {
+                // Check if the type of the property is generic
+                if ("T".equals(field2.getGenericType().getTypeName())) {
+                    // The type of the attribute is generic. Find the generic from the definition of
+                    // the class in which the attribute is located
+                    ParameterizedType pt = (ParameterizedType) genericType;
+                    Type[] actualTypeArguments = pt.getActualTypeArguments();
+                    if (actualTypeArguments.length > 0) {
+                        if (actualTypeArguments.length == 1) {
+                            result.put(field2.getName(), initClassTypeWithDefaultValue(
+                                    makeParameterizedType(actualTypeArguments[0].getTypeName()),
+                                    makeClass(pt.getActualTypeArguments()[0].getTypeName()), processCount));
+                        } else {
+                            log.warn("{}#{} generics are not supported temporarily. " +
+                                    "This property will be ignored", classType.getName(), field2.getName());
+                        }
+                    } else {
+                        result.put(field2.getName(), initClassTypeWithDefaultValue(field2.getGenericType(), field2.getType(), processCount));
+                    }
+                } else {
+                    // Not generic
+                    result.put(field2.getName(), initClassTypeWithDefaultValue(field2.getGenericType(), field2.getType(), processCount));
+                }
+            }
+        }
+        return result;
+    }
+
+    private static Object initClassTypeWithDefaultValueNoProceeField(Type genericType, Class<?> classType, int processCount) {
+        if (Integer.class.isAssignableFrom(classType)) {
+            return 0;
+        } else if (Byte.class.isAssignableFrom(classType)) {
+            return (byte) 0;
+        } else if (Long.class.isAssignableFrom(classType)) {
+            return 0L;
+        } else if (Double.class.isAssignableFrom(classType)) {
+            return 0.0D;
+        } else if (Float.class.isAssignableFrom(classType)) {
+            return 0.0F;
+        } else if (String.class.isAssignableFrom(classType)) {
+            return "";
+        } else if (Character.class.isAssignableFrom(classType)) {
+            return 'c';
+        } else if (Short.class.isAssignableFrom(classType)) {
+            return (short) 0;
+        } else if (Boolean.class.isAssignableFrom(classType)) {
+            return false;
+        } else if (Date.class.isAssignableFrom(classType)) {
+            return "【" + Date.class.getName() + "】yyyy-MM-dd HH:mm:ss";
+        } else if (LocalDate.class.isAssignableFrom(classType)) {
+            return "【" + LocalDate.class.getName() + "】yyyy-MM-dd";
+        } else if (LocalDateTime.class.isAssignableFrom(classType)) {
+            return "【" + LocalDateTime.class.getName() + "】yyyy-MM-dd HH:mm:ss";
+        } else if (Enum.class.isAssignableFrom(classType)) {
+            Object[] enumConstants = classType.getEnumConstants();
+            StringBuilder sb = new StringBuilder("|");
+            try {
+                Method getName = classType.getMethod("name");
+                for (Object obj : enumConstants) {
+                    sb.append(getName.invoke(obj)).append("|");
+                }
+            } catch (NoSuchMethodException | IllegalAccessException | InvocationTargetException e) {
+                log.error("", e);
+            }
+            return sb.toString();
+        } else if (classType.isArray()) {
+            Class<?> arrType = classType.getComponentType();
+            Object obj = initClassTypeWithDefaultValue(null, arrType, processCount);
+            return new Object[]{obj};
+        } else if (Collection.class.isAssignableFrom(classType)) {
+            List<Object> list = new ArrayList<>(1);
+            if (genericType == null) {
+                list.add(new Object());
+                return list;
+            }
+            Object obj;
+            if (genericType instanceof ParameterizedType) {
+                ParameterizedType pt = (ParameterizedType) genericType;
+                String subTypeName = pt.getActualTypeArguments()[0].getTypeName();
+                obj = initClassTypeWithDefaultValue(makeParameterizedType(subTypeName), makeClass(subTypeName), processCount);
+                list.add(obj);
+            }
+            return list;
+        } else if (Map.class.isAssignableFrom(classType)) {
+            Map<String, Object> map = new HashMap<>(1);
+            if (genericType == null) {
+                map.put("", new Object());
+                return map;
+            }
+            if (genericType instanceof ParameterizedType) {
+                ParameterizedType pt = (ParameterizedType) genericType;
+                String subTypeName = pt.getActualTypeArguments()[1].getTypeName();
+                Object objValue = initClassTypeWithDefaultValue(makeParameterizedType(subTypeName), makeClass(subTypeName), processCount);
+                map.put("", objValue);
+            }
+            return map;
+        } else if (CompletableFuture.class.isAssignableFrom(classType)) {
+            // process CompletableFuture
+            if (genericType == null) {
+                return new Object();
+            }
+            ParameterizedType pt = (ParameterizedType) genericType;
+            String typeName = pt.getActualTypeArguments()[0].getTypeName();
+            return initClassTypeWithDefaultValue(makeParameterizedType(typeName), makeClass(typeName), processCount);
+        }
+        return null;
+    }
+
+    /**
+     * Check if it is a basic data type.
+     * 2020/10/29 18:09
+     * @param o
+     * @return boolean
+     */
+    public static boolean isBaseType(Object o) {
+        if (o instanceof Integer ||
+                o instanceof Byte ||
+                o instanceof Long ||
+                o instanceof Double ||
+                o instanceof Float ||
+                o instanceof Character ||
+                o instanceof Short ||
+                o instanceof Boolean ||
+                o instanceof String) {
+            return true;
+        }
+        return false;
+    }
+
+    /**
+     * Get all fields in the class.
+     * 2020/10/29 18:10
+     * @param fieldList fieldList
+     * @param classz classz
+     * @return java.util.List<java.lang.reflect.Field>
+     */
+    public static List<Field> getAllFields(List<Field> fieldList, Class<?> classz) {
+        if (classz == null) {
+            return fieldList;
+        }
+        if (fieldList == null) {
+            fieldList = new ArrayList<>(Arrays.asList(classz.getDeclaredFields()));
+        } else {
+            fieldList.addAll(Arrays.asList(classz.getDeclaredFields()));
+        }
+        return getAllFields(fieldList, classz.getSuperclass());
+    }
+
+    public static ParameterizedType makeParameterizedType(String typeName) {
+        if (typeName.indexOf(GENERIC_START_SYMBOL) == -1) {
+            return null;
+        }
+        try {
+            Class<?> typeClass;
+            typeClass = Class.forName(typeName.substring(0, typeName.indexOf("<")));
+            String subTypeNames = typeName.substring((typeName.indexOf("<") + 1), (typeName.length() - 1));
+            String[] subTypeNamesArray = subTypeNames.split(",");
+            Type[] subTypes = makeSubClass(subTypeNamesArray);
+            return ParameterizedTypeImpl.make(typeClass, subTypes, null);
+        } catch (ClassNotFoundException e) {
+            log.warn("Exception getting generics in completabilefuture", e);
+            return null;
+        }
+    }
+
+    public static Class<?> makeClass(String className) {
+        className = className.trim();
+        try {
+            if (className.indexOf(GENERIC_START_SYMBOL) == -1) {
+                // CompletableFuture 中的类没有泛型
+                return Class.forName(className);
+            } else {
+                return Class.forName(className.substring(0, className.indexOf("<")));
+            }
+        } catch (ClassNotFoundException e) {
+            log.warn("Exception getting generics in completabilefuture", e);
+            return null;
+        }
+    }
+
+    private static Type[] makeSubClass(String... classNames) {
+        Type[] types;
+        if (classNames != null) {
+            types = new Type[classNames.length];
+            for (int i = 0; i < classNames.length; i++) {
+                String className = classNames[i];
+                types[i] = new SimpleTypeImpl(className);
+            }
+        } else {
+            types = new Type[0];
+        }
+        return types;
+    }
+
+}
diff --git a/dubbo-api-docs/dubbo-api-docs-core/src/main/java/org/apache/dubbo/apidocs/utils/SimpleTypeImpl.java b/dubbo-api-docs/dubbo-api-docs-core/src/main/java/org/apache/dubbo/apidocs/utils/SimpleTypeImpl.java
new file mode 100644
index 0000000..a71a468
--- /dev/null
+++ b/dubbo-api-docs/dubbo-api-docs-core/src/main/java/org/apache/dubbo/apidocs/utils/SimpleTypeImpl.java
@@ -0,0 +1,23 @@
+package org.apache.dubbo.apidocs.utils;
+
+import java.lang.reflect.Type;
+
+/**
+ * Simple implementation of {@link Type}.
+ * @author klw(213539@qq.com)
+ * 2020/10/29 14:55
+ */
+public class SimpleTypeImpl implements Type {
+
+    private String typeName;
+
+    public SimpleTypeImpl(String typeName){
+        this.typeName = typeName;
+    }
+
+    @Override
+    public String getTypeName(){
+        return typeName;
+    }
+
+}
diff --git a/dubbo-api-docs/dubbo-api-docs-examples/examples-api/pom.xml b/dubbo-api-docs/dubbo-api-docs-examples/examples-api/pom.xml
new file mode 100644
index 0000000..252a1df
--- /dev/null
+++ b/dubbo-api-docs/dubbo-api-docs-examples/examples-api/pom.xml
@@ -0,0 +1,40 @@
+<!--
+  ~ 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.
+  -->
+<project xmlns="http://maven.apache.org/POM/4.0.0" xmlns:xsi="http://www.w3.org/2001/XMLSchema-instance"
+         xsi:schemaLocation="http://maven.apache.org/POM/4.0.0 http://maven.apache.org/maven-v4_0_0.xsd">
+    <modelVersion>4.0.0</modelVersion>
+
+    <parent>
+        <groupId>org.apache.dubbo.examples.apidocs</groupId>
+        <artifactId>dubbo-api-docs-examples</artifactId>
+        <version>2.7.9-SNAPSHOT</version>
+        <relativePath>../pom.xml</relativePath>
+    </parent>
+
+    <artifactId>examples-api</artifactId>
+
+    <dependencies>
+
+        <dependency>
+            <groupId>org.apache.dubbo</groupId>
+            <artifactId>dubbo-api-docs-annotations</artifactId>
+        </dependency>
+        
+    </dependencies>
+
+
+</project>
diff --git a/dubbo-api-docs/dubbo-api-docs-examples/examples-api/src/main/java/org/apache/dubbo/apidocs/examples/api/IAsyncDemo.java b/dubbo-api-docs/dubbo-api-docs-examples/examples-api/src/main/java/org/apache/dubbo/apidocs/examples/api/IAsyncDemo.java
new file mode 100644
index 0000000..1d953aa
--- /dev/null
+++ b/dubbo-api-docs/dubbo-api-docs-examples/examples-api/src/main/java/org/apache/dubbo/apidocs/examples/api/IAsyncDemo.java
@@ -0,0 +1,89 @@
+/*
+ * 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.apidocs.examples.api;
+
+import org.apache.dubbo.apidocs.examples.params.DemoParamBean1;
+import org.apache.dubbo.apidocs.examples.params.DemoParamBean2;
+import org.apache.dubbo.apidocs.examples.responses.DemoRespBean1;
+
+import java.util.List;
+import java.util.Map;
+import java.util.concurrent.CompletableFuture;
+
+/**
+ * asynchronous demo.
+ * @author klw(213539@qq.com)
+ * 2020/10/30 10:13
+ */
+public interface IAsyncDemo {
+
+    /**
+     * @author klw(213539@qq.com)
+     * request and response parameters are beans
+     * @Date 2020/2/4 0:01
+     * @param: param
+     * @return top.klw8.alita.examples.dubbodoc.responses.DemoRespBean1
+     */
+    CompletableFuture<DemoRespBean1> demoApi1(DemoParamBean1 param1, DemoParamBean2 param2);
+
+    /**
+     * @author klw(213539@qq.com)
+     * Map without generics
+     */
+    CompletableFuture<Map> demoApi6();
+
+    /**
+     * @author klw(213539@qq.com)
+     * Map generic with Object
+     */
+    CompletableFuture<Map<Object, Object>> demoApi7();
+
+    /**
+     * @author klw(213539@qq.com)
+     * List without generics
+     */
+    CompletableFuture<List> demoApi10();
+
+    /**
+     * @author klw(213539@qq.com)
+     * List generic with Object
+     */
+    CompletableFuture<List<Object>> demoApi9();
+
+    /**
+     * @author klw(213539@qq.com)
+     * Object
+     */
+    CompletableFuture<Object> demoApi8();
+
+    /**
+     * @author klw(213539@qq.com)
+     * Integer
+     */
+    CompletableFuture<Integer> demoApi11();
+
+
+    /**
+     * @author klw(213539@qq.com)
+     * many generics
+     * @Date 2020/7/30 17:02
+     * @param:
+     * @return java.util.concurrent.CompletableFuture<java.util.List<java.util.List<java.lang.String>>>
+     */
+    CompletableFuture<List<List<String>>> demoApi12();
+
+}
diff --git a/dubbo-api-docs/dubbo-api-docs-examples/examples-api/src/main/java/org/apache/dubbo/apidocs/examples/api/ISyncDemo.java b/dubbo-api-docs/dubbo-api-docs-examples/examples-api/src/main/java/org/apache/dubbo/apidocs/examples/api/ISyncDemo.java
new file mode 100644
index 0000000..f842140
--- /dev/null
+++ b/dubbo-api-docs/dubbo-api-docs-examples/examples-api/src/main/java/org/apache/dubbo/apidocs/examples/api/ISyncDemo.java
@@ -0,0 +1,97 @@
+/*
+ * 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.apidocs.examples.api;
+
+import org.apache.dubbo.apidocs.examples.params.DemoParamBean1;
+import org.apache.dubbo.apidocs.examples.params.DemoParamBean2;
+import org.apache.dubbo.apidocs.examples.responses.BaseResponse;
+import org.apache.dubbo.apidocs.examples.responses.DemoRespBean1;
+
+import java.util.List;
+import java.util.Map;
+
+/**
+ * synchronization demo.
+ * @author klw(213539@qq.com)
+ * 2020/10/30 10:13
+ */
+public interface ISyncDemo {
+
+    /**
+     * request and response parameters are beans
+     * @Date 2020/2/4 0:01
+     * @param: param
+     * @return top.klw8.alita.examples.dubbodoc.responses.DemoRespBean1
+     */
+    DemoRespBean1 demoApi1(DemoParamBean1 param1, DemoParamBean2 param2);
+
+    /**
+     * request and response parameters are Strings
+     * @Date 2020/2/4 0:02
+     * @param: prarm1
+     * @param: prarm2
+     * @return java.lang.String
+     */
+    String demoApi2(String prarm1, String prarm2);
+
+    /**
+     * Without Dubbo doc annotation, no document will be generated
+     * @Date 2020/2/4 0:22
+     * @param: prarm1
+     * @return java.lang.String
+     */
+    String demoApi3(String prarm1);
+
+    /**
+     * Nonparametric method with Dubbo doc annotation
+     * @Date 2020/2/4 0:02
+     * @param:
+     * @return java.lang.String
+     */
+    String demoApi4();
+
+    /**
+     * Use generics in response
+     */
+    BaseResponse<DemoRespBean1> demoApi5();
+
+    /**
+     * Map without generics
+     */
+    Map demoApi6();
+
+    /**
+     * Map generic with Object
+     */
+    Map<Object, Object> demoApi7();
+
+    /**
+     * List without generics
+     */
+    List demoApi10();
+
+    /**
+     * List generic with Object
+     */
+    List<Object> demoApi9();
+
+    /**
+     * Object
+     */
+    Object demoApi8();
+
+}
diff --git a/dubbo-api-docs/dubbo-api-docs-examples/examples-api/src/main/java/org/apache/dubbo/apidocs/examples/params/DemoParamBean1.java b/dubbo-api-docs/dubbo-api-docs-examples/examples-api/src/main/java/org/apache/dubbo/apidocs/examples/params/DemoParamBean1.java
new file mode 100644
index 0000000..8617515
--- /dev/null
+++ b/dubbo-api-docs/dubbo-api-docs-examples/examples-api/src/main/java/org/apache/dubbo/apidocs/examples/params/DemoParamBean1.java
@@ -0,0 +1,76 @@
+/*
+ * 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.apidocs.examples.params;
+
+import org.apache.dubbo.apidocs.annotations.RequestParam;
+
+import lombok.Getter;
+import lombok.Setter;
+
+import java.util.List;
+import java.util.Map;
+
+/**
+ * demo request bean.
+ * @author klw(213539@qq.com)
+ * 2020/10/30 9:58
+ */
+@Getter
+@Setter
+public class DemoParamBean1 {
+
+    @RequestParam("Name")
+    private String name;
+
+    @RequestParam("Age")
+    private Integer age;
+
+    private Boolean man;
+
+    @RequestParam("====subBean")
+    private List<DemoParamBean1SubBean1> subBean;
+
+    @RequestParam("Map")
+    private Map<String, DemoParamBean1SubBean1> subBean2;
+
+    @RequestParam("Array")
+    private String[] strArray;
+
+    @RequestParam("Array 2")
+    private DemoParamBean1SubBean1[] strArray2;
+
+    @RequestParam("Enumeration for test")
+    private TestEnum testEnum;
+
+    private DemoParamBean1SubBean1 subBean3;
+
+    @RequestParam("Map without generics")
+    private Map map1;
+
+    @RequestParam("Map generic with Object")
+    private Map<Object, Object> map2;
+
+    @RequestParam("List without generics")
+    private List list1;
+
+    @RequestParam("List generic with Object")
+    private List<Object> list2;
+
+    @RequestParam("Object")
+    private Object obj1;
+
+}
diff --git a/dubbo-api-docs/dubbo-api-docs-examples/examples-api/src/main/java/org/apache/dubbo/apidocs/examples/params/DemoParamBean1SubBean1.java b/dubbo-api-docs/dubbo-api-docs-examples/examples-api/src/main/java/org/apache/dubbo/apidocs/examples/params/DemoParamBean1SubBean1.java
new file mode 100644
index 0000000..d12f73f
--- /dev/null
+++ b/dubbo-api-docs/dubbo-api-docs-examples/examples-api/src/main/java/org/apache/dubbo/apidocs/examples/params/DemoParamBean1SubBean1.java
@@ -0,0 +1,45 @@
+/*
+ * 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.apidocs.examples.params;
+
+import org.apache.dubbo.apidocs.annotations.RequestParam;
+
+import lombok.Getter;
+import lombok.Setter;
+
+/**
+ * Attribute bean in DemoParamBean1.
+ * @author klw(213539@qq.com)
+ * 2020/10/30 9:49
+ */
+@Getter
+@Setter
+public class DemoParamBean1SubBean1 {
+
+    @RequestParam("Sub Name")
+    private String subName;
+
+    @RequestParam("Sub Age")
+    private Integer subAge;
+
+    private TestEnum testEnum;
+
+    // Circular reference for test
+//    @RequestParam("====bean")
+//    private DemoParamBean1 bean;
+
+}
diff --git a/dubbo-api-docs/dubbo-api-docs-examples/examples-api/src/main/java/org/apache/dubbo/apidocs/examples/params/DemoParamBean2.java b/dubbo-api-docs/dubbo-api-docs-examples/examples-api/src/main/java/org/apache/dubbo/apidocs/examples/params/DemoParamBean2.java
new file mode 100644
index 0000000..52a64ba
--- /dev/null
+++ b/dubbo-api-docs/dubbo-api-docs-examples/examples-api/src/main/java/org/apache/dubbo/apidocs/examples/params/DemoParamBean2.java
@@ -0,0 +1,39 @@
+/*
+ * Licensed to the Apache Software Foundation (ASF) under one or more
+ * contributor license agreements.  See the NOTICE file distributed with
+ * this work for additional information regarding copyright ownership.
+ * The ASF licenses this file to You under the Apache License, Version 2.0
+ * (the "License"); you may not use this file except in compliance with
+ * the License.  You may obtain a copy of the License at
+ *
+ *     http://www.apache.org/licenses/LICENSE-2.0
+ *
+ * Unless required by applicable law or agreed to in writing, software
+ * distributed under the License is distributed on an "AS IS" BASIS,
+ * WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied.
+ * See the License for the specific language governing permissions and
+ * limitations under the License.
+ */
+package org.apache.dubbo.apidocs.examples.params;
+
+import org.apache.dubbo.apidocs.annotations.RequestParam;
+
+import lombok.Getter;
+import lombok.Setter;
+
+/**
+ * demo request bean 2.
+ * @author klw(213539@qq.com)
+ * 2020/10/30 9:57
+ */
+@Getter
+@Setter
+public class DemoParamBean2 {
+
+    @RequestParam(value = "Name 2", allowableValues = {"San Zhang", "Si Li"})
+    private String name2;
+
+    @RequestParam("Age 2")
+    private Double age2;
+
+}
diff --git a/dubbo-api-docs/dubbo-api-docs-examples/examples-api/src/main/java/org/apache/dubbo/apidocs/examples/params/TestBean.java b/dubbo-api-docs/dubbo-api-docs-examples/examples-api/src/main/java/org/apache/dubbo/apidocs/examples/params/TestBean.java
new file mode 100644
index 0000000..267ff7f
--- /dev/null
+++ b/dubbo-api-docs/dubbo-api-docs-examples/examples-api/src/main/java/org/apache/dubbo/apidocs/examples/params/TestBean.java
@@ -0,0 +1,33 @@
+/*
+ * 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.apidocs.examples.params;
+
+import lombok.Getter;
+import lombok.Setter;
+
+/**
+ * test.
+ * @author klw(213539@qq.com)
+ * 2020/10/30 9:57
+ */
+@Getter
+@Setter
+public class TestBean {
+
+    private DemoParamBean1 demoParamBean1;
+
+}
diff --git a/dubbo-api-docs/dubbo-api-docs-examples/examples-api/src/main/java/org/apache/dubbo/apidocs/examples/params/TestEnum.java b/dubbo-api-docs/dubbo-api-docs-examples/examples-api/src/main/java/org/apache/dubbo/apidocs/examples/params/TestEnum.java
new file mode 100644
index 0000000..38bb180
--- /dev/null
+++ b/dubbo-api-docs/dubbo-api-docs-examples/examples-api/src/main/java/org/apache/dubbo/apidocs/examples/params/TestEnum.java
@@ -0,0 +1,30 @@
+/*
+ * 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.apidocs.examples.params;
+
+/**
+ * Enumeration for test.
+ * @author klw(213539@qq.com)
+ * 2020/10/30 9:48
+ */
+public enum TestEnum {
+
+    TEST_ENUM_1,
+    TEST_ENUM_2,
+    TEST_ENUM_3;
+
+}
diff --git a/dubbo-api-docs/dubbo-api-docs-examples/examples-api/src/main/java/org/apache/dubbo/apidocs/examples/responses/BaseResponse.java b/dubbo-api-docs/dubbo-api-docs-examples/examples-api/src/main/java/org/apache/dubbo/apidocs/examples/responses/BaseResponse.java
new file mode 100644
index 0000000..59ef44b
--- /dev/null
+++ b/dubbo-api-docs/dubbo-api-docs-examples/examples-api/src/main/java/org/apache/dubbo/apidocs/examples/responses/BaseResponse.java
@@ -0,0 +1,48 @@
+/*
+ * 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.apidocs.examples.responses;
+
+import lombok.Getter;
+import lombok.Setter;
+import lombok.ToString;
+
+/**
+ * BaseResponse.
+ * @author klw(213539@qq.com)
+ * 2020/10/30 9:46
+ */
+@Getter
+@Setter
+@ToString
+public class BaseResponse<T> implements java.io.Serializable {
+
+    /**
+     * response code.
+     */
+    private String code;
+
+    /**
+     * response message.
+     */
+    private String message;
+
+    /**
+     * response data.
+     */
+    private T data;
+
+}
diff --git a/dubbo-api-docs/dubbo-api-docs-examples/examples-api/src/main/java/org/apache/dubbo/apidocs/examples/responses/DemoRespBean1.java b/dubbo-api-docs/dubbo-api-docs-examples/examples-api/src/main/java/org/apache/dubbo/apidocs/examples/responses/DemoRespBean1.java
new file mode 100644
index 0000000..e8aec9c
--- /dev/null
+++ b/dubbo-api-docs/dubbo-api-docs-examples/examples-api/src/main/java/org/apache/dubbo/apidocs/examples/responses/DemoRespBean1.java
@@ -0,0 +1,60 @@
+/*
+ * 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.apidocs.examples.responses;
+
+import org.apache.dubbo.apidocs.annotations.ResponseProperty;
+
+import lombok.Getter;
+import lombok.Setter;
+
+import java.util.List;
+import java.util.Map;
+
+/**
+ * demo response bean 1.
+ * @author klw(213539@qq.com)
+ * 2020/10/30 9:56
+ */
+@Getter
+@Setter
+public class DemoRespBean1 {
+
+    @ResponseProperty("Response code")
+    private String code;
+
+    @ResponseProperty("Response message")
+    private String message;
+
+    @ResponseProperty(value = "Response message 2", example = "This is response message 2")
+    private String message2;
+
+    @ResponseProperty("Map without generics")
+    private Map map1;
+
+    @ResponseProperty("Map generic with Object")
+    private Map<Object, Object> map2;
+
+    @ResponseProperty("List without generics")
+    private List list1;
+
+    @ResponseProperty("List generic with Object")
+    private List<Object> list2;
+
+    @ResponseProperty("Object")
+    private Object obj1;
+
+}
diff --git a/dubbo-api-docs/dubbo-api-docs-examples/examples-provider-sca/pom.xml b/dubbo-api-docs/dubbo-api-docs-examples/examples-provider-sca/pom.xml
new file mode 100644
index 0000000..00d09d5
--- /dev/null
+++ b/dubbo-api-docs/dubbo-api-docs-examples/examples-provider-sca/pom.xml
@@ -0,0 +1,35 @@
+<!--
+  ~ 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.
+  -->
+<project xmlns="http://maven.apache.org/POM/4.0.0" xmlns:xsi="http://www.w3.org/2001/XMLSchema-instance"
+         xsi:schemaLocation="http://maven.apache.org/POM/4.0.0 http://maven.apache.org/maven-v4_0_0.xsd">
+    <modelVersion>4.0.0</modelVersion>
+
+    <parent>
+        <groupId>org.apache.dubbo.examples.apidocs</groupId>
+        <artifactId>dubbo-api-docs-examples</artifactId>
+        <version>2.7.9-SNAPSHOT</version>
+        <relativePath>../pom.xml</relativePath>
+    </parent>
+
+    <artifactId>examples-provider-sca</artifactId>
+
+    <dependencies>
+
+    </dependencies>
+
+
+</project>
diff --git a/dubbo-api-docs/dubbo-api-docs-examples/examples-provider/pom.xml b/dubbo-api-docs/dubbo-api-docs-examples/examples-provider/pom.xml
new file mode 100644
index 0000000..acc63d4
--- /dev/null
+++ b/dubbo-api-docs/dubbo-api-docs-examples/examples-provider/pom.xml
@@ -0,0 +1,80 @@
+<!--
+  ~ 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.
+  -->
+<project xmlns="http://maven.apache.org/POM/4.0.0" xmlns:xsi="http://www.w3.org/2001/XMLSchema-instance"
+         xsi:schemaLocation="http://maven.apache.org/POM/4.0.0 http://maven.apache.org/maven-v4_0_0.xsd">
+    <modelVersion>4.0.0</modelVersion>
+
+    <parent>
+        <groupId>org.apache.dubbo.examples.apidocs</groupId>
+        <artifactId>dubbo-api-docs-examples</artifactId>
+        <version>2.7.9-SNAPSHOT</version>
+        <relativePath>../pom.xml</relativePath>
+    </parent>
+
+    <artifactId>examples-provider</artifactId>
+
+    <dependencies>
+        <dependency>
+            <groupId>org.apache.dubbo</groupId>
+            <artifactId>dubbo-api-docs-core</artifactId>
+        </dependency>
+        <dependency>
+            <groupId>org.apache.dubbo.examples.apidocs</groupId>
+            <artifactId>examples-api</artifactId>
+        </dependency>
+        <dependency>
+            <groupId>org.springframework.boot</groupId>
+            <artifactId>spring-boot-autoconfigure</artifactId>
+        </dependency>
+
+        <dependency>
+            <groupId>org.apache.dubbo</groupId>
+            <artifactId>dubbo-registry-nacos</artifactId>
+            <exclusions>
+                <exclusion>
+                    <artifactId>log4j</artifactId>
+                    <groupId>log4j</groupId>
+                </exclusion>
+                <exclusion>
+                    <groupId>org.apache.dubbo</groupId>
+                    <artifactId>dubbo-remoting-api</artifactId>
+                </exclusion>
+                <exclusion>
+                    <artifactId>dubbo-common</artifactId>
+                    <groupId>org.apache.dubbo</groupId>
+                </exclusion>
+            </exclusions>
+        </dependency>
+
+        <dependency>
+            <groupId>org.apache.dubbo</groupId>
+            <artifactId>dubbo</artifactId>
+        </dependency>
+
+        <dependency>
+            <groupId>org.apache.dubbo</groupId>
+            <artifactId>dubbo-spring-boot-starter</artifactId>
+        </dependency>
+
+        <dependency>
+            <groupId>org.springframework.boot</groupId>
+            <artifactId>spring-boot-starter-logging</artifactId>
+        </dependency>
+    </dependencies>
+
+
+</project>
diff --git a/dubbo-api-docs/dubbo-api-docs-examples/examples-provider/src/main/java/org/apache/dubbo/apidocs/examples/ExampleApplication.java b/dubbo-api-docs/dubbo-api-docs-examples/examples-provider/src/main/java/org/apache/dubbo/apidocs/examples/ExampleApplication.java
new file mode 100644
index 0000000..6d4039f
--- /dev/null
+++ b/dubbo-api-docs/dubbo-api-docs-examples/examples-provider/src/main/java/org/apache/dubbo/apidocs/examples/ExampleApplication.java
@@ -0,0 +1,41 @@
+/*
+ * 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.apidocs.examples;
+
+import org.apache.dubbo.config.spring.context.annotation.EnableDubbo;
+
+import org.springframework.boot.WebApplicationType;
+import org.springframework.boot.autoconfigure.SpringBootApplication;
+import org.springframework.boot.builder.SpringApplicationBuilder;
+
+/**
+ * example dubbo provider service application.
+ * @author klw(213539@qq.com)
+ * 2020/10/30 14:54
+ */
+@SpringBootApplication
+@EnableDubbo(scanBasePackages = {"org.apache.dubbo.apidocs.examples.api"})
+public class ExampleApplication {
+
+    public static void main(String[] args) {
+        new SpringApplicationBuilder(ExampleApplication.class)
+                // Non web applications
+                .web(WebApplicationType.NONE)
+                .run(args);
+    }
+
+}
diff --git a/dubbo-api-docs/dubbo-api-docs-examples/examples-provider/src/main/java/org/apache/dubbo/apidocs/examples/api/impl/AsyncDemoImpl.java b/dubbo-api-docs/dubbo-api-docs-examples/examples-provider/src/main/java/org/apache/dubbo/apidocs/examples/api/impl/AsyncDemoImpl.java
new file mode 100644
index 0000000..9706290
--- /dev/null
+++ b/dubbo-api-docs/dubbo-api-docs-examples/examples-provider/src/main/java/org/apache/dubbo/apidocs/examples/api/impl/AsyncDemoImpl.java
@@ -0,0 +1,99 @@
+/*
+ * 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.apidocs.examples.api.impl;
+
+import org.apache.dubbo.apidocs.annotations.ApiDoc;
+import org.apache.dubbo.apidocs.annotations.ApiModule;
+import org.apache.dubbo.apidocs.examples.api.IAsyncDemo;
+import org.apache.dubbo.apidocs.examples.params.DemoParamBean1;
+import org.apache.dubbo.apidocs.examples.params.DemoParamBean2;
+import org.apache.dubbo.apidocs.examples.responses.DemoRespBean1;
+import org.apache.dubbo.config.annotation.DubboService;
+
+import org.apache.commons.lang3.concurrent.BasicThreadFactory;
+
+import java.util.List;
+import java.util.Map;
+import java.util.concurrent.CompletableFuture;
+import java.util.concurrent.ScheduledExecutorService;
+import java.util.concurrent.ScheduledThreadPoolExecutor;
+
+/**
+ * Asynchronous demo implementation.
+ * @author klw(213539@qq.com)
+ * 2020/10/30 14:54
+ */
+@DubboService(async = true)
+@ApiModule(value = "Asynchronous demo", apiInterface = IAsyncDemo.class)
+public class AsyncDemoImpl implements IAsyncDemo {
+
+    public static final ScheduledExecutorService EXECUTOR = new ScheduledThreadPoolExecutor(
+            Runtime.getRuntime().availableProcessors() * 40 * 3,
+            new BasicThreadFactory.Builder().namingPattern("dubbo-async-executor-pool-%d").daemon(true).build());
+
+    @ApiDoc("request and response parameters are beans")
+    @Override
+    public CompletableFuture<DemoRespBean1> demoApi1(DemoParamBean1 param1, DemoParamBean2 param2) {
+        DemoRespBean1 result = new DemoRespBean1();
+        result.setCode("123456789");
+        result.setMessage("called demoApi1 msg1");
+        result.setMessage2("called demoApi1 msg2");
+        return CompletableFuture.supplyAsync(() -> result, EXECUTOR);
+    }
+
+    @Override
+    @ApiDoc(value = "Map without generics", responseClassDescription="Map without generics")
+    public CompletableFuture<Map> demoApi6() {
+        return null;
+    }
+
+    @Override
+    @ApiDoc(value = "Map generic with Object", responseClassDescription="Map generic with Object")
+    public CompletableFuture<Map<Object, Object>> demoApi7() {
+        return null;
+    }
+
+    @Override
+    @ApiDoc(value = "List without generics", responseClassDescription="List without generics")
+    public CompletableFuture<List> demoApi10() {
+        return null;
+    }
+
+    @Override
+    @ApiDoc(value = "List generic with Object", responseClassDescription="List generic with Object")
+    public CompletableFuture<List<Object>> demoApi9() {
+        return null;
+    }
+
+    @Override
+    @ApiDoc(value = "Object", responseClassDescription="Object")
+    public CompletableFuture<Object> demoApi8() {
+        return null;
+    }
+
+    @Override
+    @ApiDoc(value = "Integer", responseClassDescription="Integer")
+    public CompletableFuture<Integer> demoApi11() {
+        return null;
+    }
+
+    @Override
+    @ApiDoc(value = "many generics", responseClassDescription="many generics")
+    public CompletableFuture<List<List<String>>> demoApi12(){
+        return null;
+    }
+}
diff --git a/dubbo-api-docs/dubbo-api-docs-examples/examples-provider/src/main/java/org/apache/dubbo/apidocs/examples/api/impl/SyncDemoImpl.java b/dubbo-api-docs/dubbo-api-docs-examples/examples-provider/src/main/java/org/apache/dubbo/apidocs/examples/api/impl/SyncDemoImpl.java
new file mode 100644
index 0000000..243a2e3
--- /dev/null
+++ b/dubbo-api-docs/dubbo-api-docs-examples/examples-provider/src/main/java/org/apache/dubbo/apidocs/examples/api/impl/SyncDemoImpl.java
@@ -0,0 +1,116 @@
+/*
+ * 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.apidocs.examples.api.impl;
+
+import lombok.extern.slf4j.Slf4j;
+
+import org.apache.dubbo.apidocs.annotations.ApiDoc;
+import org.apache.dubbo.apidocs.annotations.ApiModule;
+import org.apache.dubbo.apidocs.annotations.RequestParam;
+import org.apache.dubbo.apidocs.examples.api.ISyncDemo;
+import org.apache.dubbo.apidocs.examples.params.DemoParamBean1;
+import org.apache.dubbo.apidocs.examples.params.DemoParamBean2;
+import org.apache.dubbo.apidocs.examples.responses.BaseResponse;
+import org.apache.dubbo.apidocs.examples.responses.DemoRespBean1;
+import org.apache.dubbo.config.annotation.DubboService;
+
+import java.util.List;
+import java.util.Map;
+
+/**
+ * Synchronous demo implementation.
+ * @author klw(213539@qq.com)
+ * 2020/10/30 14:57
+ */
+@Slf4j
+@DubboService
+@ApiModule(value = "Synchronous demo", apiInterface = ISyncDemo.class)
+public class SyncDemoImpl implements ISyncDemo {
+
+    @ApiDoc("request and response parameters are beans")
+    @Override
+    public DemoRespBean1 demoApi1(DemoParamBean1 param1, DemoParamBean2 param2) {
+        log.info("called demoApi1");
+        DemoRespBean1 result = new DemoRespBean1();
+        result.setCode("123456789");
+        result.setMessage("called demoApi1 msg1");
+        result.setMessage2("called demoApi1 msg2");
+        return result;
+    }
+
+    @ApiDoc(value = "request and response parameters are Strings", responseClassDescription="A string")
+    @Override
+    public String demoApi2(@RequestParam(value = "Parameter 1", required = true) String prarm1, String prarm2) {
+        log.info(" called demoApi2");
+        return "demoApi2";
+    }
+
+    @Override
+    public String demoApi3(String prarm1) {
+        return null;
+    }
+
+    @ApiDoc(value = "Nonparametric method with Dubbo doc annotation", responseClassDescription="A string")
+    @Override
+    public String demoApi4() {
+        return "asdfasdfsdafds";
+    }
+
+    @ApiDoc(value = " Use generics in response", responseClassDescription=" Use generics in response")
+    @Override
+    public BaseResponse<DemoRespBean1> demoApi5(){
+        BaseResponse<DemoRespBean1> response = new BaseResponse<>();
+        DemoRespBean1 responseData = new DemoRespBean1();
+        responseData.setCode("2222");
+        responseData.setMessage("msg1");
+        responseData.setMessage2("msg2");
+        response.setData(responseData);
+        response.setCode("1111");
+        response.setMessage("msg");
+        return response;
+    }
+
+    @Override
+    @ApiDoc(value = "Map without generics", responseClassDescription="Map without generics")
+    public Map demoApi6() {
+        return null;
+    }
+
+    @Override
+    @ApiDoc(value = "Map generic with Object", responseClassDescription="Map generic with Object")
+    public Map<Object, Object> demoApi7() {
+        return null;
+    }
+
+    @Override
+    @ApiDoc(value = "List without generics", responseClassDescription="List without generics")
+    public List demoApi10() {
+        return null;
+    }
+
+    @Override
+    @ApiDoc(value = "List generic with Object", responseClassDescription="List generic with Object")
+    public List<Object> demoApi9() {
+        return null;
+    }
+
+    @Override
+    @ApiDoc(value = "Object", responseClassDescription="Object")
+    public Object demoApi8() {
+        return null;
+    }
+}
diff --git a/dubbo-api-docs/dubbo-api-docs-examples/examples-provider/src/main/java/org/apache/dubbo/apidocs/examples/cfg/DubboDocConfig.java b/dubbo-api-docs/dubbo-api-docs-examples/examples-provider/src/main/java/org/apache/dubbo/apidocs/examples/cfg/DubboDocConfig.java
new file mode 100644
index 0000000..29c0401
--- /dev/null
+++ b/dubbo-api-docs/dubbo-api-docs-examples/examples-provider/src/main/java/org/apache/dubbo/apidocs/examples/cfg/DubboDocConfig.java
@@ -0,0 +1,33 @@
+/*
+ * 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.apidocs.examples.cfg;
+
+import org.apache.dubbo.apidocs.EnableDubboApiDocs;
+
+import org.springframework.context.annotation.Configuration;
+import org.springframework.context.annotation.Profile;
+
+/**
+ * dubbo doc config.
+ * @author klw(213539@qq.com)
+ * 2020/10/30 14:58
+ */
+@Configuration
+@EnableDubboApiDocs
+@Profile("dev")
+public class DubboDocConfig {
+}
diff --git a/dubbo-api-docs/dubbo-api-docs-examples/examples-provider/src/main/resources/application.yml b/dubbo-api-docs/dubbo-api-docs-examples/examples-provider/src/main/resources/application.yml
new file mode 100644
index 0000000..87423b4
--- /dev/null
+++ b/dubbo-api-docs/dubbo-api-docs-examples/examples-provider/src/main/resources/application.yml
@@ -0,0 +1,15 @@
+spring:
+  application:
+    name: dubbo-doc-example-provider
+  profiles:
+    active: dev
+dubbo:
+  registry:
+    address: nacos://127.0.0.1:8848
+  provider:
+    timeout: 2000
+  protocol:
+    port: 20881
+    name: dubbo
+  application:
+    name: dubbo-doc-example-provider
\ No newline at end of file
diff --git a/dubbo-api-docs/dubbo-api-docs-examples/pom.xml b/dubbo-api-docs/dubbo-api-docs-examples/pom.xml
new file mode 100644
index 0000000..bf7686b
--- /dev/null
+++ b/dubbo-api-docs/dubbo-api-docs-examples/pom.xml
@@ -0,0 +1,53 @@
+<!--
+  ~ 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.
+  -->
+<project xmlns="http://maven.apache.org/POM/4.0.0" xmlns:xsi="http://www.w3.org/2001/XMLSchema-instance"
+         xsi:schemaLocation="http://maven.apache.org/POM/4.0.0 http://maven.apache.org/maven-v4_0_0.xsd">
+    <modelVersion>4.0.0</modelVersion>
+
+    <parent>
+        <groupId>org.apache.dubbo</groupId>
+        <artifactId>dubbo-api-docs</artifactId>
+        <version>2.7.9-SNAPSHOT</version>
+        <relativePath>../pom.xml</relativePath>
+    </parent>
+
+    <groupId>org.apache.dubbo.examples.apidocs</groupId>
+    <artifactId>dubbo-api-docs-examples</artifactId>
+
+    <packaging>pom</packaging>
+    <name>${project.artifactId}</name>
+    <description>Dubbo interface documentation examples</description>
+    
+    <modules>
+        <module>examples-api</module>
+        <module>examples-provider</module>
+        <module>examples-provider-sca</module>
+    </modules>
+
+    <dependencyManagement>
+        <dependencies>
+            <!-- Internal libs -->
+            <dependency>
+                <groupId>org.apache.dubbo.examples.apidocs</groupId>
+                <artifactId>examples-api</artifactId>
+                <version>${project.version}</version>
+            </dependency>
+        </dependencies>
+    </dependencyManagement>
+
+
+</project>
diff --git a/dubbo-api-docs/pom.xml b/dubbo-api-docs/pom.xml
new file mode 100644
index 0000000..44c810c
--- /dev/null
+++ b/dubbo-api-docs/pom.xml
@@ -0,0 +1,210 @@
+<!--
+  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.
+  -->
+<project xmlns="http://maven.apache.org/POM/4.0.0" xmlns:xsi="http://www.w3.org/2001/XMLSchema-instance"
+         xsi:schemaLocation="http://maven.apache.org/POM/4.0.0 http://maven.apache.org/maven-v4_0_0.xsd">
+    <modelVersion>4.0.0</modelVersion>
+    <parent>
+        <groupId>org.apache.dubbo</groupId>
+        <artifactId>dubbo-parent</artifactId>
+        <version>2.7.9-SNAPSHOT</version>
+        <relativePath />
+    </parent>
+    <artifactId>dubbo-api-docs</artifactId>
+    <packaging>pom</packaging>
+    <name>${project.artifactId}</name>
+    <description>Dubbo interface documentation, testing tools</description>
+    <properties>
+        <revision>2.7.9-SNAPSHOT</revision>
+        <project.build.jdkVersion>1.8</project.build.jdkVersion>
+        <argLine>-Dfile.encoding=UTF-8</argLine>
+        <project.build.sourceEncoding>UTF-8</project.build.sourceEncoding>
+        <skipJunitTest>true</skipJunitTest>
+
+        <skip_maven_deploy>true</skip_maven_deploy>
+        <lombok.version>1.18.12</lombok.version>
+        <maven-flatten-version>1.1.0</maven-flatten-version>
+
+        <spring-boot.version>2.3.4.RELEASE</spring-boot.version>
+        <dubbo-spring-boot.version>2.7.8</dubbo-spring-boot.version>
+    </properties>
+
+    <dependencyManagement>
+        <dependencies>
+            <dependency>
+                <groupId>org.springframework.boot</groupId>
+                <artifactId>spring-boot-dependencies</artifactId>
+                <version>${spring-boot.version}</version>
+                <type>pom</type>
+                <scope>import</scope>
+            </dependency>
+
+            <!-- Internal libs -->
+            <dependency>
+                <groupId>org.apache.dubbo</groupId>
+                <artifactId>dubbo-api-docs-annotations</artifactId>
+                <version>${project.version}</version>
+            </dependency>
+            <dependency>
+                <groupId>org.apache.dubbo</groupId>
+                <artifactId>dubbo-api-docs-core</artifactId>
+                <version>${project.version}</version>
+            </dependency>
+
+            <dependency>
+                <groupId>org.apache.dubbo</groupId>
+                <artifactId>dubbo</artifactId>
+                <version>${project.version}</version>
+            </dependency>
+
+            <dependency>
+                <groupId>org.apache.dubbo</groupId>
+                <artifactId>dubbo-registry-nacos</artifactId>
+                <version>${project.version}</version>
+            </dependency>
+
+            <dependency>
+                <groupId>org.projectlombok</groupId>
+                <artifactId>lombok</artifactId>
+                <version>${lombok.version}</version>
+                <scope>compile</scope>
+            </dependency>
+
+            <dependency>
+                <groupId>org.apache.dubbo</groupId>
+                <artifactId>dubbo-spring-boot-starter</artifactId>
+                <version>${dubbo-spring-boot.version}</version>
+            </dependency>
+
+        </dependencies>
+    </dependencyManagement>
+
+    <dependencies>
+        <dependency>
+            <groupId>org.projectlombok</groupId>
+            <artifactId>lombok</artifactId>
+        </dependency>
+    </dependencies>
+
+    <modules>
+        <module>dubbo-api-docs-annotations</module>
+        <module>dubbo-api-docs-core</module>
+        <module>dubbo-api-docs-examples</module>
+    </modules>
+
+    <build>
+        <plugins>
+            <plugin>
+                <groupId>org.codehaus.mojo</groupId>
+                <artifactId>flatten-maven-plugin</artifactId>
+                <version>${maven-flatten-version}</version>
+                <configuration>
+                    <updatePomFile>true</updatePomFile>
+                    <flattenMode>resolveCiFriendliesOnly</flattenMode>
+                    <pomElements>
+                        <dependencies>expand</dependencies>
+                    </pomElements>
+                </configuration>
+                <executions>
+                    <execution>
+                        <id>flatten</id>
+                        <phase>process-resources</phase>
+                        <goals>
+                            <goal>flatten</goal>
+                        </goals>
+                    </execution>
+                    <execution>
+                        <id>flatten.clean</id>
+                        <phase>clean</phase>
+                        <goals>
+                            <goal>clean</goal>
+                        </goals>
+                    </execution>
+                </executions>
+            </plugin>
+            <plugin>
+                <artifactId>maven-compiler-plugin</artifactId>
+                <configuration>
+                    <source>${project.build.jdkVersion}</source>
+                    <target>${project.build.jdkVersion}</target>
+                    <encoding>${project.build.sourceEncoding}</encoding>
+                    <compilerArguments>
+                        <verbose/>
+                    </compilerArguments>
+                </configuration>
+            </plugin>
+            <plugin>
+                <artifactId>maven-resources-plugin</artifactId>
+                <configuration>
+                    <!-- We are not suppose to setup the customer resources here -->
+                    <encoding>${project.build.sourceEncoding}</encoding>
+                </configuration>
+            </plugin>
+            <plugin>
+                <groupId>org.projectlombok</groupId>
+                <artifactId>lombok-maven-plugin</artifactId>
+                <version>1.18.6.0</version>
+                <executions>
+                    <execution>
+                        <phase>generate-sources</phase>
+                        <goals>
+                            <goal>delombok</goal>
+                        </goals>
+                    </execution>
+                </executions>
+            </plugin>
+
+            <plugin>
+                <artifactId>maven-surefire-plugin</artifactId>
+                <configuration>
+                    <skip>${skipJunitTest}</skip>
+                </configuration>
+            </plugin>
+            <plugin>
+                <artifactId>maven-source-plugin</artifactId>
+                <version>2.2.1</version>
+                <executions>
+                    <execution>
+                        <phase>package</phase>
+                        <goals>
+                            <goal>jar-no-fork</goal>
+                        </goals>
+                    </execution>
+                </executions>
+            </plugin>
+            <plugin>
+                <artifactId>maven-javadoc-plugin</artifactId>
+                <version>2.9.1</version>
+                <executions>
+                    <execution>
+                        <phase>package</phase>
+                        <goals>
+                            <goal>jar</goal>
+                        </goals>
+                    </execution>
+                </executions>
+                <configuration>
+                    <show>private</show>
+                    <nohelp>true</nohelp>
+                    <charset>UTF-8</charset>
+                    <encoding>UTF-8</encoding>
+                    <docencoding>UTF-8</docencoding>
+                    <additionalparam>-Xdoclint:none</additionalparam>
+                </configuration>
+            </plugin>
+        </plugins>
+    </build>
+</project>


[dubbo-spi-extensions] 03/39: add dubbo-all module

Posted by li...@apache.org.
This is an automated email from the ASF dual-hosted git repository.

liujun pushed a commit to branch 2.7.x
in repository https://gitbox.apache.org/repos/asf/dubbo-spi-extensions.git

commit c3690bd48f29298156c32f5e7c09fc0831e503be
Author: ken.lj <ke...@gmail.com>
AuthorDate: Mon May 18 14:05:48 2020 +0800

    add dubbo-all module
---
 dubbo-all/pom.xml | 1057 +++++++++++++++++++++++++++++++++++++++++++++++++++++
 pom.xml           |    1 +
 2 files changed, 1058 insertions(+)

diff --git a/dubbo-all/pom.xml b/dubbo-all/pom.xml
new file mode 100644
index 0000000..dab2d12
--- /dev/null
+++ b/dubbo-all/pom.xml
@@ -0,0 +1,1057 @@
+<!--
+  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.
+  -->
+<project xmlns="http://maven.apache.org/POM/4.0.0" xmlns:xsi="http://www.w3.org/2001/XMLSchema-instance"
+         xsi:schemaLocation="http://maven.apache.org/POM/4.0.0 http://maven.apache.org/maven-v4_0_0.xsd">
+    <modelVersion>4.0.0</modelVersion>
+    <parent>
+        <groupId>org.apache.dubbo</groupId>
+        <artifactId>dubbo-parent</artifactId>
+        <version>2.7.7-SNAPSHOT</version>
+    </parent>
+    <artifactId>dubbo</artifactId>
+    <packaging>jar</packaging>
+    <name>dubbo-all</name>
+    <description>The all in one project of dubbo</description>
+    <properties>
+        <skip_maven_deploy>false</skip_maven_deploy>
+    </properties>
+    <dependencies>
+        <dependency>
+            <groupId>org.apache.dubbo</groupId>
+            <artifactId>dubbo-config-api</artifactId>
+            <version>${project.version}</version>
+            <scope>compile</scope>
+            <optional>true</optional>
+        </dependency>
+        <dependency>
+            <groupId>org.apache.dubbo</groupId>
+            <artifactId>dubbo-config-spring</artifactId>
+            <version>${project.version}</version>
+            <scope>compile</scope>
+            <optional>true</optional>
+        </dependency>
+        <dependency>
+            <groupId>org.apache.dubbo</groupId>
+            <artifactId>dubbo-cluster</artifactId>
+            <version>${project.version}</version>
+            <scope>compile</scope>
+            <optional>true</optional>
+        </dependency>
+        <dependency>
+            <groupId>org.apache.dubbo</groupId>
+            <artifactId>dubbo-common</artifactId>
+            <version>${project.version}</version>
+            <scope>compile</scope>
+            <optional>true</optional>
+        </dependency>
+        <dependency>
+            <groupId>org.apache.dubbo</groupId>
+            <artifactId>dubbo-filter-cache</artifactId>
+            <version>${project.version}</version>
+            <scope>compile</scope>
+            <optional>true</optional>
+        </dependency>
+        <dependency>
+            <groupId>org.apache.dubbo</groupId>
+            <artifactId>dubbo-filter-validation</artifactId>
+            <version>${project.version}</version>
+            <scope>compile</scope>
+            <optional>true</optional>
+        </dependency>
+        <dependency>
+            <groupId>org.apache.dubbo</groupId>
+            <artifactId>dubbo-remoting-api</artifactId>
+            <version>${project.version}</version>
+            <scope>compile</scope>
+            <optional>true</optional>
+        </dependency>
+        <dependency>
+            <groupId>org.apache.dubbo</groupId>
+            <artifactId>dubbo-remoting-netty</artifactId>
+            <version>${project.version}</version>
+            <scope>compile</scope>
+            <optional>true</optional>
+        </dependency>
+        <dependency>
+            <groupId>org.apache.dubbo</groupId>
+            <artifactId>dubbo-remoting-netty4</artifactId>
+            <version>${project.version}</version>
+            <scope>compile</scope>
+            <optional>true</optional>
+        </dependency>
+        <dependency>
+            <groupId>org.apache.dubbo</groupId>
+            <artifactId>dubbo-remoting-etcd3</artifactId>
+            <version>${project.version}</version>
+            <scope>compile</scope>
+            <optional>true</optional>
+        </dependency>
+        <dependency>
+            <groupId>org.apache.dubbo</groupId>
+            <artifactId>dubbo-remoting-mina</artifactId>
+            <version>${project.version}</version>
+            <scope>compile</scope>
+            <optional>true</optional>
+        </dependency>
+        <dependency>
+            <groupId>org.apache.dubbo</groupId>
+            <artifactId>dubbo-remoting-grizzly</artifactId>
+            <version>${project.version}</version>
+            <scope>compile</scope>
+            <optional>true</optional>
+        </dependency>
+        <dependency>
+            <groupId>org.apache.dubbo</groupId>
+            <artifactId>dubbo-remoting-p2p</artifactId>
+            <version>${project.version}</version>
+            <scope>compile</scope>
+            <optional>true</optional>
+        </dependency>
+        <dependency>
+            <groupId>org.apache.dubbo</groupId>
+            <artifactId>dubbo-remoting-http</artifactId>
+            <version>${project.version}</version>
+            <scope>compile</scope>
+            <optional>true</optional>
+        </dependency>
+        <dependency>
+            <groupId>org.apache.dubbo</groupId>
+            <artifactId>dubbo-rpc-api</artifactId>
+            <version>${project.version}</version>
+            <scope>compile</scope>
+            <optional>true</optional>
+        </dependency>
+        <dependency>
+            <groupId>org.apache.dubbo</groupId>
+            <artifactId>dubbo-rpc-dubbo</artifactId>
+            <version>${project.version}</version>
+            <scope>compile</scope>
+            <optional>true</optional>
+        </dependency>
+        <dependency>
+            <groupId>org.apache.dubbo</groupId>
+            <artifactId>dubbo-rpc-injvm</artifactId>
+            <version>${project.version}</version>
+            <scope>compile</scope>
+            <optional>true</optional>
+        </dependency>
+        <dependency>
+            <groupId>org.apache.dubbo</groupId>
+            <artifactId>dubbo-rpc-http</artifactId>
+            <version>${project.version}</version>
+            <scope>compile</scope>
+            <optional>true</optional>
+        </dependency>
+        <dependency>
+            <groupId>org.apache.dubbo</groupId>
+            <artifactId>dubbo-rpc-rmi</artifactId>
+            <version>${project.version}</version>
+            <scope>compile</scope>
+            <optional>true</optional>
+        </dependency>
+        <dependency>
+            <groupId>org.apache.dubbo</groupId>
+            <artifactId>dubbo-rpc-hessian</artifactId>
+            <version>${project.version}</version>
+            <scope>compile</scope>
+            <optional>true</optional>
+        </dependency>
+        <dependency>
+            <groupId>org.apache.dubbo</groupId>
+            <artifactId>dubbo-rpc-webservice</artifactId>
+            <version>${project.version}</version>
+            <scope>compile</scope>
+            <optional>true</optional>
+        </dependency>
+        <dependency>
+            <groupId>org.apache.dubbo</groupId>
+            <artifactId>dubbo-rpc-thrift</artifactId>
+            <version>${project.version}</version>
+            <scope>compile</scope>
+            <optional>true</optional>
+        </dependency>
+        <dependency>
+            <groupId>org.apache.dubbo</groupId>
+            <artifactId>dubbo-rpc-native-thrift</artifactId>
+            <version>${project.version}</version>
+            <scope>compile</scope>
+            <optional>true</optional>
+        </dependency>
+        <dependency>
+            <groupId>org.apache.dubbo</groupId>
+            <artifactId>dubbo-rpc-memcached</artifactId>
+            <version>${project.version}</version>
+            <scope>compile</scope>
+            <optional>true</optional>
+        </dependency>
+        <dependency>
+            <groupId>org.apache.dubbo</groupId>
+            <artifactId>dubbo-rpc-redis</artifactId>
+            <version>${project.version}</version>
+            <scope>compile</scope>
+            <optional>true</optional>
+        </dependency>
+        <dependency>
+            <groupId>org.apache.dubbo</groupId>
+            <artifactId>dubbo-rpc-rest</artifactId>
+            <version>${project.version}</version>
+            <scope>compile</scope>
+            <optional>true</optional>
+        </dependency>
+        <dependency>
+            <groupId>org.apache.dubbo</groupId>
+            <artifactId>dubbo-rpc-xml</artifactId>
+            <version>${project.version}</version>
+            <scope>compile</scope>
+            <optional>true</optional>
+        </dependency>
+        <dependency>
+            <groupId>org.apache.dubbo</groupId>
+            <artifactId>dubbo-rpc-grpc</artifactId>
+            <version>${project.version}</version>
+            <scope>compile</scope>
+            <optional>true</optional>
+        </dependency>
+        <dependency>
+            <groupId>org.apache.dubbo</groupId>
+            <artifactId>dubbo-registry-api</artifactId>
+            <version>${project.version}</version>
+            <scope>compile</scope>
+            <optional>true</optional>
+        </dependency>
+        <dependency>
+            <groupId>org.apache.dubbo</groupId>
+            <artifactId>dubbo-registry-default</artifactId>
+            <version>${project.version}</version>
+            <scope>compile</scope>
+            <optional>true</optional>
+        </dependency>
+        <dependency>
+            <groupId>org.apache.dubbo</groupId>
+            <artifactId>dubbo-registry-multicast</artifactId>
+            <version>${project.version}</version>
+            <scope>compile</scope>
+            <optional>true</optional>
+        </dependency>
+        <dependency>
+            <groupId>org.apache.dubbo</groupId>
+            <artifactId>dubbo-registry-zookeeper</artifactId>
+            <version>${project.version}</version>
+            <scope>compile</scope>
+            <optional>true</optional>
+        </dependency>
+        <dependency>
+            <groupId>org.apache.dubbo</groupId>
+            <artifactId>dubbo-registry-redis</artifactId>
+            <version>${project.version}</version>
+            <scope>compile</scope>
+            <optional>true</optional>
+        </dependency>
+        <dependency>
+            <groupId>org.apache.dubbo</groupId>
+            <artifactId>dubbo-registry-consul</artifactId>
+            <version>${project.version}</version>
+            <scope>compile</scope>
+            <optional>true</optional>
+        </dependency>
+        <dependency>
+            <groupId>org.apache.dubbo</groupId>
+            <artifactId>dubbo-registry-etcd3</artifactId>
+            <version>${project.version}</version>
+            <scope>compile</scope>
+            <optional>true</optional>
+            <exclusions>
+                <exclusion>
+                    <groupId>io.grpc</groupId>
+                    <artifactId>grpc-core</artifactId>
+                </exclusion>
+                <exclusion>
+                    <groupId>io.grpc</groupId>
+                    <artifactId>grpc-netty</artifactId>
+                </exclusion>
+            </exclusions>
+        </dependency>
+        <dependency>
+            <groupId>org.apache.dubbo</groupId>
+            <artifactId>dubbo-registry-eureka</artifactId>
+            <version>${project.version}</version>
+            <scope>compile</scope>
+            <optional>true</optional>
+        </dependency>
+        <dependency>
+            <groupId>org.apache.dubbo</groupId>
+            <artifactId>dubbo-registry-nacos</artifactId>
+            <version>${project.version}</version>
+            <scope>compile</scope>
+            <optional>true</optional>
+        </dependency>
+        <dependency>
+            <groupId>org.apache.dubbo</groupId>
+            <artifactId>dubbo-registry-sofa</artifactId>
+            <version>${project.version}</version>
+            <scope>compile</scope>
+            <optional>true</optional>
+        </dependency>
+        <dependency>
+            <groupId>org.apache.dubbo</groupId>
+            <artifactId>dubbo-registry-multiple</artifactId>
+            <version>${project.version}</version>
+            <scope>compile</scope>
+            <optional>true</optional>
+        </dependency>
+        <dependency>
+            <groupId>org.apache.dubbo</groupId>
+            <artifactId>dubbo-monitor-api</artifactId>
+            <version>${project.version}</version>
+            <scope>compile</scope>
+            <optional>true</optional>
+        </dependency>
+        <dependency>
+            <groupId>org.apache.dubbo</groupId>
+            <artifactId>dubbo-monitor-default</artifactId>
+            <version>${project.version}</version>
+            <scope>compile</scope>
+            <optional>true</optional>
+        </dependency>
+        <dependency>
+            <groupId>org.apache.dubbo</groupId>
+            <artifactId>dubbo-container-spring</artifactId>
+            <version>${project.version}</version>
+            <scope>compile</scope>
+            <optional>true</optional>
+        </dependency>
+        <dependency>
+            <groupId>org.apache.dubbo</groupId>
+            <artifactId>dubbo-container-log4j</artifactId>
+            <version>${project.version}</version>
+            <scope>compile</scope>
+            <optional>true</optional>
+        </dependency>
+        <dependency>
+            <groupId>org.apache.dubbo</groupId>
+            <artifactId>dubbo-container-logback</artifactId>
+            <version>${project.version}</version>
+            <scope>compile</scope>
+            <optional>true</optional>
+        </dependency>
+        <dependency>
+            <groupId>org.apache.dubbo</groupId>
+            <artifactId>dubbo-qos</artifactId>
+            <version>${project.version}</version>
+            <scope>compile</scope>
+            <optional>true</optional>
+        </dependency>
+        <dependency>
+            <groupId>org.apache.dubbo</groupId>
+            <artifactId>dubbo-serialization-api</artifactId>
+            <version>${project.version}</version>
+            <scope>compile</scope>
+            <optional>true</optional>
+        </dependency>
+        <dependency>
+            <groupId>org.apache.dubbo</groupId>
+            <artifactId>dubbo-serialization-fastjson</artifactId>
+            <version>${project.version}</version>
+            <scope>compile</scope>
+            <optional>true</optional>
+        </dependency>
+        <dependency>
+            <groupId>org.apache.dubbo</groupId>
+            <artifactId>dubbo-serialization-fst</artifactId>
+            <version>${project.version}</version>
+            <scope>compile</scope>
+            <optional>true</optional>
+        </dependency>
+        <dependency>
+            <groupId>org.apache.dubbo</groupId>
+            <artifactId>dubbo-serialization-hessian2</artifactId>
+            <version>${project.version}</version>
+            <scope>compile</scope>
+            <optional>true</optional>
+        </dependency>
+        <dependency>
+            <groupId>org.apache.dubbo</groupId>
+            <artifactId>dubbo-serialization-native-hession</artifactId>
+            <version>${project.version}</version>
+            <scope>compile</scope>
+            <optional>true</optional>
+        </dependency>
+        <dependency>
+            <groupId>org.apache.dubbo</groupId>
+            <artifactId>dubbo-serialization-jdk</artifactId>
+            <version>${project.version}</version>
+            <scope>compile</scope>
+            <optional>true</optional>
+        </dependency>
+        <dependency>
+            <groupId>org.apache.dubbo</groupId>
+            <artifactId>dubbo-serialization-kryo</artifactId>
+            <version>${project.version}</version>
+            <scope>compile</scope>
+            <optional>true</optional>
+        </dependency>
+        <dependency>
+            <groupId>org.apache.dubbo</groupId>
+            <artifactId>dubbo-serialization-avro</artifactId>
+            <version>${project.version}</version>
+            <scope>compile</scope>
+            <optional>true</optional>
+        </dependency>
+        <dependency>
+            <groupId>org.apache.dubbo</groupId>
+            <artifactId>dubbo-serialization-protostuff</artifactId>
+            <version>${project.version}</version>
+            <scope>compile</scope>
+            <optional>true</optional>
+        </dependency>
+        <dependency>
+            <groupId>org.apache.dubbo</groupId>
+            <artifactId>dubbo-serialization-gson</artifactId>
+            <version>${project.version}</version>
+            <scope>compile</scope>
+            <optional>true</optional>
+        </dependency>
+        <dependency>
+            <groupId>org.apache.dubbo</groupId>
+            <artifactId>dubbo-serialization-protobuf</artifactId>
+            <version>${project.version}</version>
+            <scope>compile</scope>
+            <optional>true</optional>
+        </dependency>
+        <dependency>
+            <groupId>org.apache.dubbo</groupId>
+            <artifactId>dubbo-configcenter-zookeeper</artifactId>
+            <version>${project.version}</version>
+            <scope>compile</scope>
+            <optional>true</optional>
+        </dependency>
+        <dependency>
+            <groupId>org.apache.dubbo</groupId>
+            <artifactId>dubbo-configcenter-apollo</artifactId>
+            <version>${project.version}</version>
+            <scope>compile</scope>
+            <optional>true</optional>
+        </dependency>
+        <dependency>
+            <groupId>org.apache.dubbo</groupId>
+            <artifactId>dubbo-configcenter-nacos</artifactId>
+            <version>${project.version}</version>
+            <scope>compile</scope>
+            <optional>true</optional>
+        </dependency>
+        <dependency>
+            <groupId>org.apache.dubbo</groupId>
+            <artifactId>dubbo-configcenter-consul</artifactId>
+            <version>${project.version}</version>
+            <scope>compile</scope>
+            <optional>true</optional>
+        </dependency>
+        <dependency>
+            <groupId>org.apache.dubbo</groupId>
+            <artifactId>dubbo-configcenter-etcd</artifactId>
+            <version>${project.version}</version>
+            <scope>compile</scope>
+            <optional>true</optional>
+            <exclusions>
+                <exclusion>
+                    <groupId>io.grpc</groupId>
+                    <artifactId>grpc-core</artifactId>
+                </exclusion>
+                <exclusion>
+                    <groupId>io.grpc</groupId>
+                    <artifactId>grpc-netty</artifactId>
+                </exclusion>
+            </exclusions>
+        </dependency>
+        <dependency>
+            <groupId>org.apache.dubbo</groupId>
+            <artifactId>dubbo-compatible</artifactId>
+            <version>${project.version}</version>
+            <scope>compile</scope>
+            <optional>true</optional>
+        </dependency>
+        <dependency>
+            <groupId>com.alibaba</groupId>
+            <artifactId>hessian-lite</artifactId>
+            <scope>compile</scope>
+            <optional>true</optional>
+        </dependency>
+        <!-- metadata -->
+        <dependency>
+            <groupId>org.apache.dubbo</groupId>
+            <artifactId>dubbo-metadata-api</artifactId>
+            <version>${project.version}</version>
+            <scope>compile</scope>
+            <optional>true</optional>
+        </dependency>
+        <dependency>
+            <groupId>org.apache.dubbo</groupId>
+            <artifactId>dubbo-metadata-report-zookeeper</artifactId>
+            <version>${project.version}</version>
+            <scope>compile</scope>
+            <optional>true</optional>
+        </dependency>
+        <dependency>
+            <groupId>org.apache.dubbo</groupId>
+            <artifactId>dubbo-metadata-report-redis</artifactId>
+            <version>${project.version}</version>
+            <scope>compile</scope>
+            <optional>true</optional>
+        </dependency>
+        <dependency>
+            <groupId>org.apache.dubbo</groupId>
+            <artifactId>dubbo-metadata-report-consul</artifactId>
+            <version>${project.version}</version>
+            <scope>compile</scope>
+            <optional>true</optional>
+        </dependency>
+        <dependency>
+            <groupId>org.apache.dubbo</groupId>
+            <artifactId>dubbo-metadata-report-etcd</artifactId>
+            <version>${project.version}</version>
+            <scope>compile</scope>
+            <optional>true</optional>
+            <exclusions>
+                <exclusion>
+                    <groupId>io.grpc</groupId>
+                    <artifactId>grpc-core</artifactId>
+                </exclusion>
+                <exclusion>
+                    <groupId>io.grpc</groupId>
+                    <artifactId>grpc-netty</artifactId>
+                </exclusion>
+            </exclusions>
+        </dependency>
+        <dependency>
+            <groupId>org.apache.dubbo</groupId>
+            <artifactId>dubbo-metadata-report-nacos</artifactId>
+            <version>${project.version}</version>
+            <scope>compile</scope>
+            <optional>true</optional>
+        </dependency>
+        <dependency>
+            <groupId>org.apache.dubbo</groupId>
+            <artifactId>dubbo-auth</artifactId>
+            <version>${project.version}</version>
+            <scope>compile</scope>
+            <optional>true</optional>
+        </dependency>
+
+        <!-- Transitive dependencies -->
+        <dependency>
+            <groupId>org.springframework</groupId>
+            <artifactId>spring-context</artifactId>
+        </dependency>
+        <dependency>
+            <groupId>com.alibaba.spring</groupId>
+            <artifactId>spring-context-support</artifactId>
+        </dependency>
+        <dependency>
+            <groupId>org.javassist</groupId>
+            <artifactId>javassist</artifactId>
+        </dependency>
+        <dependency>
+            <groupId>io.netty</groupId>
+            <artifactId>netty-all</artifactId>
+        </dependency>
+        <dependency>
+            <groupId>com.google.code.gson</groupId>
+            <artifactId>gson</artifactId>
+        </dependency>
+        <dependency>
+            <groupId>org.yaml</groupId>
+            <artifactId>snakeyaml</artifactId>
+        </dependency>
+
+        <!-- Temporarily add this part to exclude transitive dependency -->
+        <dependency>
+            <groupId>org.junit.jupiter</groupId>
+            <artifactId>junit-jupiter-engine</artifactId>
+            <version>${junit_jupiter_version}</version>
+            <scope>test</scope>
+        </dependency>
+        <dependency>
+            <groupId>org.junit.jupiter</groupId>
+            <artifactId>junit-jupiter-params</artifactId>
+            <version>${junit_jupiter_version}</version>
+            <scope>test</scope>
+        </dependency>
+        <dependency>
+            <groupId>cglib</groupId>
+            <artifactId>cglib-nodep</artifactId>
+            <version>${cglib_version}</version>
+            <scope>test</scope>
+            <optional>true</optional>
+        </dependency>
+    </dependencies>
+    <build>
+        <plugins>
+            <plugin>
+                <groupId>org.apache.maven.plugins</groupId>
+                <artifactId>maven-shade-plugin</artifactId>
+                <executions>
+                    <execution>
+                        <phase>package</phase>
+                        <goals>
+                            <goal>shade</goal>
+                        </goals>
+                        <configuration>
+                            <createSourcesJar>true</createSourcesJar>
+                            <promoteTransitiveDependencies>false</promoteTransitiveDependencies>
+                            <artifactSet>
+                                <includes>
+                                    <include>com.alibaba:hessian-lite</include>
+                                    <include>org.apache.dubbo:dubbo-config-api</include>
+                                    <include>org.apache.dubbo:dubbo-config-spring</include>
+                                    <include>org.apache.dubbo:dubbo-compatible</include>
+                                    <include>org.apache.dubbo:dubbo-common</include>
+                                    <include>org.apache.dubbo:dubbo-remoting-api</include>
+                                    <include>org.apache.dubbo:dubbo-remoting-netty</include>
+                                    <include>org.apache.dubbo:dubbo-remoting-netty4</include>
+                                    <include>org.apache.dubbo:dubbo-remoting-etcd3</include>
+                                    <include>org.apache.dubbo:dubbo-remoting-mina</include>
+                                    <include>org.apache.dubbo:dubbo-remoting-grizzly</include>
+                                    <include>org.apache.dubbo:dubbo-remoting-p2p</include>
+                                    <include>org.apache.dubbo:dubbo-remoting-http</include>
+                                    <include>org.apache.dubbo:dubbo-remoting-zookeeper</include>
+                                    <include>org.apache.dubbo:dubbo-rpc-api</include>
+                                    <include>org.apache.dubbo:dubbo-rpc-dubbo</include>
+                                    <include>org.apache.dubbo:dubbo-rpc-injvm</include>
+                                    <include>org.apache.dubbo:dubbo-rpc-http</include>
+                                    <include>org.apache.dubbo:dubbo-rpc-rmi</include>
+                                    <include>org.apache.dubbo:dubbo-rpc-hessian</include>
+                                    <include>org.apache.dubbo:dubbo-rpc-webservice</include>
+                                    <include>org.apache.dubbo:dubbo-rpc-thrift</include>
+                                    <include>org.apache.dubbo:dubbo-rpc-native-thrift</include>
+                                    <include>org.apache.dubbo:dubbo-rpc-memcached</include>
+                                    <include>org.apache.dubbo:dubbo-rpc-redis</include>
+                                    <include>org.apache.dubbo:dubbo-rpc-rest</include>
+                                    <include>org.apache.dubbo:dubbo-rpc-xml</include>
+                                    <include>org.apache.dubbo:dubbo-rpc-grpc</include>
+                                    <include>org.apache.dubbo:dubbo-filter-validation</include>
+                                    <include>org.apache.dubbo:dubbo-filter-cache</include>
+                                    <include>org.apache.dubbo:dubbo-cluster</include>
+                                    <include>org.apache.dubbo:dubbo-registry-api</include>
+                                    <include>org.apache.dubbo:dubbo-registry-default</include>
+                                    <include>org.apache.dubbo:dubbo-registry-multicast</include>
+                                    <include>org.apache.dubbo:dubbo-registry-zookeeper</include>
+                                    <include>org.apache.dubbo:dubbo-registry-redis</include>
+                                    <include>org.apache.dubbo:dubbo-registry-consul</include>
+                                    <include>org.apache.dubbo:dubbo-registry-etcd3</include>
+                                    <include>org.apache.dubbo:dubbo-registry-eureka</include>
+                                    <include>org.apache.dubbo:dubbo-registry-nacos</include>
+                                    <include>org.apache.dubbo:dubbo-registry-sofa</include>
+                                    <include>org.apache.dubbo:dubbo-registry-multiple</include>
+                                    <include>org.apache.dubbo:dubbo-monitor-api</include>
+                                    <include>org.apache.dubbo:dubbo-monitor-default</include>
+                                    <include>org.apache.dubbo:dubbo-container-api</include>
+                                    <include>org.apache.dubbo:dubbo-container-spring</include>
+                                    <include>org.apache.dubbo:dubbo-container-log4j</include>
+                                    <include>org.apache.dubbo:dubbo-container-logback</include>
+                                    <include>org.apache.dubbo:dubbo-qos</include>
+                                    <include>org.apache.dubbo:dubbo-serialization-api</include>
+                                    <include>org.apache.dubbo:dubbo-serialization-fastjson</include>
+                                    <include>org.apache.dubbo:dubbo-serialization-hessian2</include>
+                                    <include>org.apache.dubbo:dubbo-serialization-fst</include>
+                                    <include>org.apache.dubbo:dubbo-serialization-kryo</include>
+                                    <include>org.apache.dubbo:dubbo-serialization-avro</include>
+                                    <include>org.apache.dubbo:dubbo-serialization-jdk</include>
+                                    <include>org.apache.dubbo:dubbo-serialization-protostuff</include>
+                                    <include>org.apache.dubbo:dubbo-serialization-gson</include>
+                                    <include>org.apache.dubbo:dubbo-serialization-protobuf</include>
+                                    <include>org.apache.dubbo:dubbo-configcenter-api</include>
+                                    <include>org.apache.dubbo:dubbo-configcenter-definition</include>
+                                    <include>org.apache.dubbo:dubbo-configcenter-apollo</include>
+                                    <include>org.apache.dubbo:dubbo-configcenter-zookeeper</include>
+                                    <include>org.apache.dubbo:dubbo-configcenter-consul</include>
+                                    <include>org.apache.dubbo:dubbo-configcenter-etcd</include>
+                                    <include>org.apache.dubbo:dubbo-configcenter-nacos</include>
+                                    <include>org.apache.dubbo:dubbo-metadata-api</include>
+                                    <include>org.apache.dubbo:dubbo-metadata-report-redis</include>
+                                    <include>org.apache.dubbo:dubbo-metadata-report-zookeeper</include>
+                                    <include>org.apache.dubbo:dubbo-metadata-report-consul</include>
+                                    <include>org.apache.dubbo:dubbo-metadata-report-etcd</include>
+                                    <include>org.apache.dubbo:dubbo-metadata-report-nacos</include>
+                                    <include>org.apache.dubbo:dubbo-serialization-native-hession</include>
+                                    <include>org.apache.dubbo:dubbo-auth</include>
+                                </includes>
+                            </artifactSet>
+                            <transformers>
+                                <!-- dubbo-common beginning -->
+                                <transformer
+                                        implementation="org.apache.maven.plugins.shade.resource.AppendingTransformer">
+                                    <resource>
+                                        META-INF/dubbo/internal/org.apache.dubbo.common.compiler.Compiler
+                                    </resource>
+                                </transformer>
+                                <transformer
+                                        implementation="org.apache.maven.plugins.shade.resource.AppendingTransformer">
+                                    <resource>
+                                        META-INF/dubbo/internal/org.apache.dubbo.common.config.configcenter.DynamicConfigurationFactory
+                                    </resource>
+                                </transformer>
+                                <transformer
+                                        implementation="org.apache.maven.plugins.shade.resource.AppendingTransformer">
+                                    <resource>
+                                        META-INF/dubbo/internal/org.apache.dubbo.common.extension.ExtensionFactory
+                                    </resource>
+                                </transformer>
+                                <transformer
+                                        implementation="org.apache.maven.plugins.shade.resource.AppendingTransformer">
+                                    <resource>
+                                        META-INF/dubbo/internal/org.apache.dubbo.common.infra.InfraAdapter
+                                    </resource>
+                                </transformer>
+                                <transformer
+                                        implementation="org.apache.maven.plugins.shade.resource.AppendingTransformer">
+                                    <resource>
+                                        META-INF/dubbo/internal/org.apache.dubbo.common.logger.LoggerAdapter
+                                    </resource>
+                                </transformer>
+                                <transformer
+                                        implementation="org.apache.maven.plugins.shade.resource.AppendingTransformer">
+                                    <resource>
+                                        META-INF/dubbo/internal/org.apache.dubbo.common.status.StatusChecker
+                                    </resource>
+                                </transformer>
+                                <transformer
+                                        implementation="org.apache.maven.plugins.shade.resource.AppendingTransformer">
+                                    <resource>
+                                        META-INF/dubbo/internal/org.apache.dubbo.common.store.DataStore
+                                    </resource>
+                                </transformer>
+                                <transformer
+                                        implementation="org.apache.maven.plugins.shade.resource.AppendingTransformer">
+                                    <resource>
+                                        META-INF/dubbo/internal/org.apache.dubbo.common.threadpool.ThreadPool
+                                    </resource>
+                                </transformer>
+                                <!-- dubbo-common end -->
+
+                                <transformer
+                                        implementation="org.apache.maven.plugins.shade.resource.AppendingTransformer">
+                                    <resource>META-INF/dubbo/internal/org.apache.dubbo.common.serialize.Serialization
+                                    </resource>
+                                </transformer>
+                                <transformer
+                                        implementation="org.apache.maven.plugins.shade.resource.AppendingTransformer">
+                                    <resource>META-INF/dubbo/internal/org.apache.dubbo.remoting.Dispatcher</resource>
+                                </transformer>
+                                <transformer
+                                        implementation="org.apache.maven.plugins.shade.resource.AppendingTransformer">
+                                    <resource>META-INF/dubbo/internal/org.apache.dubbo.remoting.Codec2</resource>
+                                </transformer>
+                                <transformer
+                                        implementation="org.apache.maven.plugins.shade.resource.AppendingTransformer">
+                                    <resource>META-INF/dubbo/internal/org.apache.dubbo.remoting.Transporter</resource>
+                                </transformer>
+                                <transformer
+                                        implementation="org.apache.maven.plugins.shade.resource.AppendingTransformer">
+                                    <resource>META-INF/dubbo/internal/org.apache.dubbo.remoting.exchange.Exchanger
+                                    </resource>
+                                </transformer>
+                                <transformer
+                                        implementation="org.apache.maven.plugins.shade.resource.AppendingTransformer">
+                                    <resource>META-INF/dubbo/internal/org.apache.dubbo.remoting.http.HttpBinder
+                                    </resource>
+                                </transformer>
+                                <transformer
+                                        implementation="org.apache.maven.plugins.shade.resource.AppendingTransformer">
+                                    <resource>META-INF/dubbo/internal/org.apache.dubbo.remoting.p2p.Networker
+                                    </resource>
+                                </transformer>
+                                <transformer
+                                        implementation="org.apache.maven.plugins.shade.resource.AppendingTransformer">
+                                    <resource>META-INF/dubbo/internal/org.apache.dubbo.remoting.telnet.TelnetHandler
+                                    </resource>
+                                </transformer>
+                                <transformer
+                                        implementation="org.apache.maven.plugins.shade.resource.AppendingTransformer">
+                                    <resource>
+                                        META-INF/dubbo/internal/org.apache.dubbo.remoting.zookeeper.ZookeeperTransporter
+                                    </resource>
+                                </transformer>
+                                <transformer
+                                        implementation="org.apache.maven.plugins.shade.resource.AppendingTransformer">
+                                    <resource>META-INF/dubbo/internal/org.apache.dubbo.rpc.Protocol</resource>
+                                </transformer>
+                                <transformer
+                                        implementation="org.apache.maven.plugins.shade.resource.AppendingTransformer">
+                                    <resource>META-INF/dubbo/internal/org.apache.dubbo.rpc.Filter</resource>
+                                </transformer>
+                                <transformer
+                                        implementation="org.apache.maven.plugins.shade.resource.AppendingTransformer">
+                                    <resource>META-INF/dubbo/internal/org.apache.dubbo.rpc.InvokerListener</resource>
+                                </transformer>
+                                <transformer
+                                        implementation="org.apache.maven.plugins.shade.resource.AppendingTransformer">
+                                    <resource>META-INF/dubbo/internal/org.apache.dubbo.rpc.ExporterListener</resource>
+                                </transformer>
+                                <transformer
+                                        implementation="org.apache.maven.plugins.shade.resource.AppendingTransformer">
+                                    <resource>META-INF/dubbo/internal/org.apache.dubbo.rpc.ProxyFactory</resource>
+                                </transformer>
+                                <transformer
+                                        implementation="org.apache.maven.plugins.shade.resource.AppendingTransformer">
+                                    <resource>META-INF/dubbo/internal/org.apache.dubbo.rpc.cluster.Cluster</resource>
+                                </transformer>
+                                <transformer
+                                        implementation="org.apache.maven.plugins.shade.resource.AppendingTransformer">
+                                    <resource>META-INF/dubbo/internal/org.apache.dubbo.rpc.cluster.LoadBalance
+                                    </resource>
+                                </transformer>
+                                <transformer
+                                        implementation="org.apache.maven.plugins.shade.resource.AppendingTransformer">
+                                    <resource>META-INF/dubbo/internal/org.apache.dubbo.rpc.cluster.Merger</resource>
+                                </transformer>
+                                <transformer
+                                        implementation="org.apache.maven.plugins.shade.resource.AppendingTransformer">
+                                    <resource>META-INF/dubbo/internal/org.apache.dubbo.rpc.cluster.RouterFactory
+                                    </resource>
+                                </transformer>
+                                <transformer
+                                        implementation="org.apache.maven.plugins.shade.resource.AppendingTransformer">
+                                    <resource>
+                                        META-INF/dubbo/internal/org.apache.dubbo.rpc.cluster.ConfiguratorFactory
+                                    </resource>
+                                </transformer>
+                                <transformer
+                                        implementation="org.apache.maven.plugins.shade.resource.AppendingTransformer">
+                                    <resource>META-INF/dubbo/internal/org.apache.dubbo.container.Container</resource>
+                                </transformer>
+                                <transformer
+                                        implementation="org.apache.maven.plugins.shade.resource.AppendingTransformer">
+                                    <resource>META-INF/dubbo/internal/org.apache.dubbo.monitor.MonitorFactory
+                                    </resource>
+                                </transformer>
+                                <transformer
+                                        implementation="org.apache.maven.plugins.shade.resource.AppendingTransformer">
+                                    <resource>META-INF/dubbo/internal/org.apache.dubbo.registry.RegistryFactory
+                                    </resource>
+                                </transformer>
+                                <transformer
+                                        implementation="org.apache.maven.plugins.shade.resource.AppendingTransformer">
+                                    <resource>META-INF/dubbo/internal/org.apache.dubbo.validation.Validation</resource>
+                                </transformer>
+                                <transformer
+                                        implementation="org.apache.maven.plugins.shade.resource.AppendingTransformer">
+                                    <resource>META-INF/dubbo/internal/org.apache.dubbo.cache.CacheFactory</resource>
+                                </transformer>
+                                <transformer
+                                        implementation="org.apache.maven.plugins.shade.resource.AppendingTransformer">
+                                    <resource>META-INF/dubbo/internal/org.apache.dubbo.qos.command.BaseCommand
+                                    </resource>
+                                </transformer>
+                                <transformer
+                                        implementation="org.apache.maven.plugins.shade.resource.AppendingTransformer">
+                                    <resource>
+                                        META-INF/dubbo/internal/org.apache.dubbo.metadata.report.MetadataReportFactory
+                                    </resource>
+                                </transformer>
+                                <!-- @since 2.7.5 -->
+                                <transformer
+                                        implementation="org.apache.maven.plugins.shade.resource.AppendingTransformer">
+                                    <resource>META-INF/dubbo/internal/org.apache.dubbo.event.EventDispatcher
+                                    </resource>
+                                </transformer>
+                                <transformer
+                                        implementation="org.apache.maven.plugins.shade.resource.AppendingTransformer">
+                                    <resource>META-INF/dubbo/internal/org.apache.dubbo.metadata.MetadataServiceExporter
+                                    </resource>
+                                </transformer>
+                                <transformer
+                                        implementation="org.apache.maven.plugins.shade.resource.AppendingTransformer">
+                                    <resource>META-INF/dubbo/internal/org.apache.dubbo.metadata.WritableMetadataService
+                                    </resource>
+                                </transformer>
+                                <transformer
+                                        implementation="org.apache.maven.plugins.shade.resource.AppendingTransformer">
+                                    <resource>META-INF/dubbo/internal/org.apache.dubbo.metadata.ServiceNameMapping
+                                    </resource>
+                                </transformer>
+                                <transformer
+                                        implementation="org.apache.maven.plugins.shade.resource.AppendingTransformer">
+                                    <resource>
+                                        META-INF/dubbo/internal/org.apache.dubbo.registry.client.metadata.proxy.MetadataServiceProxyFactory
+                                    </resource>
+                                </transformer>
+                                <transformer
+                                        implementation="org.apache.maven.plugins.shade.resource.AppendingTransformer">
+                                    <resource>
+                                        META-INF/dubbo/internal/org.apache.dubbo.registry.client.ServiceDiscoveryFactory
+                                    </resource>
+                                </transformer>
+                                <transformer
+                                        implementation="org.apache.maven.plugins.shade.resource.AppendingTransformer">
+                                    <resource>META-INF/dubbo/internal/org.apache.dubbo.registry.client.ServiceDiscovery
+                                    </resource>
+                                </transformer>
+                                <transformer
+                                        implementation="org.apache.maven.plugins.shade.resource.AppendingTransformer">
+                                    <resource>
+                                        META-INF/dubbo/internal/org.apache.dubbo.metadata.definition.builder.TypeBuilder
+                                    </resource>
+                                </transformer>
+                                <transformer
+                                        implementation="org.apache.maven.plugins.shade.resource.AppendingTransformer">
+                                    <resource>META-INF/dubbo/internal/org.apache.dubbo.event.EventListener
+                                    </resource>
+                                </transformer>
+                                <transformer
+                                        implementation="org.apache.maven.plugins.shade.resource.AppendingTransformer">
+                                    <resource>
+                                        META-INF/dubbo/internal/org.apache.dubbo.registry.client.ServiceInstanceCustomizer
+                                    </resource>
+                                </transformer>
+                                <transformer
+                                        implementation="org.apache.maven.plugins.shade.resource.AppendingTransformer">
+                                    <resource>
+                                        META-INF/dubbo/internal/org.apache.dubbo.registry.client.metadata.MetadataServiceURLBuilder
+                                    </resource>
+                                </transformer>
+
+                                <!-- @since 2.7.6 -->
+
+                                <!-- 'dubbo-common' module -->
+                                <transformer
+                                        implementation="org.apache.maven.plugins.shade.resource.AppendingTransformer">
+                                    <resource>
+                                        META-INF/dubbo/internal/org.apache.dubbo.common.convert.Converter
+                                    </resource>
+                                </transformer>
+                                <transformer
+                                        implementation="org.apache.maven.plugins.shade.resource.AppendingTransformer">
+                                    <resource>
+                                        META-INF/dubbo/internal/org.apache.dubbo.common.convert.multiple.MultiValueConverter
+                                    </resource>
+                                </transformer>
+
+                                <!-- 'dubbo-metadata-api' module -->
+                                <transformer
+                                        implementation="org.apache.maven.plugins.shade.resource.AppendingTransformer">
+                                    <resource>
+                                        META-INF/dubbo/internal/org.apache.dubbo.metadata.rest.AnnotatedMethodParameterProcessor
+                                    </resource>
+                                </transformer>
+                                <transformer
+                                        implementation="org.apache.maven.plugins.shade.resource.AppendingTransformer">
+                                    <resource>
+                                        META-INF/dubbo/internal/org.apache.dubbo.metadata.rest.ServiceRestMetadataResolver
+                                    </resource>
+                                </transformer>
+
+                                <!-- 'dubbo-metadata-processor' module -->
+                                <transformer
+                                        implementation="org.apache.maven.plugins.shade.resource.AppendingTransformer">
+                                    <resource>
+                                        META-INF/dubbo/internal/org.apache.dubbo.metadata.annotation.processing.builder.TypeDefinitionBuilder
+                                    </resource>
+                                </transformer>
+                                <transformer
+                                        implementation="org.apache.maven.plugins.shade.resource.AppendingTransformer">
+                                    <resource>
+                                        META-INF/dubbo/internal/org.apache.dubbo.metadata.annotation.processing.rest.AnnotatedMethodParameterProcessor
+                                    </resource>
+                                </transformer>
+                                <transformer
+                                        implementation="org.apache.maven.plugins.shade.resource.AppendingTransformer">
+                                    <resource>
+                                        META-INF/dubbo/internal/org.apache.dubbo.metadata.annotation.processing.rest.ServiceRestMetadataResolver
+                                    </resource>
+                                </transformer>
+
+                                <!-- @since 2.7.7 -->
+
+                                <!-- 'dubbo-common' module -->
+                                <transformer
+                                        implementation="org.apache.maven.plugins.shade.resource.AppendingTransformer">
+                                    <resource>
+                                        META-INF/services/org.apache.dubbo.common.extension.LoadingStrategy
+                                    </resource>
+                                </transformer>
+                                <transformer
+                                        implementation="org.apache.maven.plugins.shade.resource.AppendingTransformer">
+                                    <resource>
+                                        META-INF/dubbo/internal/org.apache.dubbo.auth.spi.AccessKeyStorage
+                                    </resource>
+                                </transformer>
+                                <transformer
+                                        implementation="org.apache.maven.plugins.shade.resource.AppendingTransformer">
+                                    <resource>
+                                        META-INF/dubbo/internal/org.apache.dubbo.auth.spi.Authenticator
+                                    </resource>
+                                </transformer>
+
+                            </transformers>
+                            <filters>
+                                <filter>
+                                    <artifact>org.apache.dubbo:dubbo</artifact>
+                                    <excludes>
+                                        <!-- These following two line is optional, it can remove some warn log -->
+                                        <exclude>com/**</exclude>
+                                        <exclude>org/**</exclude>
+                                        <!-- This one is required -->
+                                        <exclude>META-INF/dubbo/**</exclude>
+                                    </excludes>
+                                </filter>
+                            </filters>
+                        </configuration>
+                    </execution>
+                </executions>
+            </plugin>
+        </plugins>
+    </build>
+
+    <profiles>
+        <profile>
+            <id>release</id>
+            <build>
+                <plugins>
+                    <plugin>
+                        <artifactId>maven-javadoc-plugin</artifactId>
+                        <version>${maven_javadoc_version}</version>
+                        <executions>
+                            <execution>
+                                <id>attach-javadoc</id>
+                                <goals>
+                                    <goal>jar</goal>
+                                </goals>
+                                <configuration>
+                                    <doclint>none</doclint>
+                                </configuration>
+                            </execution>
+                        </executions>
+                        <configuration>
+                            <includeDependencySources>true</includeDependencySources>
+                            <dependencySourceIncludes>
+                                <dependencySourceInclude>org.apache.dubbo:dubbo-*</dependencySourceInclude>
+                                <dependencySourceExclude>com.alibaba:hessian-*</dependencySourceExclude>
+                            </dependencySourceIncludes>
+                            <show>public</show>
+                            <charset>UTF-8</charset>
+                            <encoding>UTF-8</encoding>
+                            <docencoding>UTF-8</docencoding>
+                            <links>
+                                <link>http://docs.oracle.com/javase/7/docs/api</link>
+                            </links>
+                        </configuration>
+                    </plugin>
+                </plugins>
+            </build>
+        </profile>
+    </profiles>
+</project>
diff --git a/pom.xml b/pom.xml
index 1e5b70e..eb10329 100644
--- a/pom.xml
+++ b/pom.xml
@@ -28,6 +28,7 @@
     </properties>
    
     <modules>
+        <module>dubbo-all</module>
         <module>dubbo-spi-container</module>
         <module>dubbo-spi-remoting</module>
         <module>dubbo-spi-rpc</module>


[dubbo-spi-extensions] 08/39: add travis job

Posted by li...@apache.org.
This is an automated email from the ASF dual-hosted git repository.

liujun pushed a commit to branch 2.7.x
in repository https://gitbox.apache.org/repos/asf/dubbo-spi-extensions.git

commit 408c748986ab7995efbe8a8e5d2f521aa8783f6e
Author: ken.lj <ke...@gmail.com>
AuthorDate: Thu Aug 27 16:26:58 2020 +0800

    add travis job
---
 .travis.yml | 22 ++++++++++++++++++++++
 README.md   |  1 +
 2 files changed, 23 insertions(+)

diff --git a/.travis.yml b/.travis.yml
new file mode 100644
index 0000000..f13d3e6
--- /dev/null
+++ b/.travis.yml
@@ -0,0 +1,22 @@
+language: java
+sudo: false # faster builds
+
+jdk:
+  - openjdk11
+  - openjdk8
+
+cache:
+  directories:
+    - $HOME/.m2
+
+install: true
+
+script:
+  - rm -rf $HOME/.m2/repository/org/glassfish/javax.el/3.0.1-b08
+  - travis_wait 30 ./mvnw --batch-mode --no-transfer-progress clean install -DskipTests=false -DskipIntegrationTests=false -Dcheckstyle.skip=false -Drat.skip=false -Dmaven.javadoc.skip=true
+
+after_success:
+  - bash <(curl -s https://codecov.io/bash)
+
+after_failure:
+  - echo "build failed!"
diff --git a/README.md b/README.md
index 3b188df..8d875cc 100644
--- a/README.md
+++ b/README.md
@@ -1 +1,2 @@
 # dubbo-spi-extensions
+[![Build Status](https://travis-ci.org/apache/dubbo-spi-extensions.svg?branch=master)](https://travis-ci.org/apache/dubbo-spi-extensions)
\ No newline at end of file


[dubbo-spi-extensions] 17/39: 当远程调用失败时,移除缓存中的Reference. 更新前端打包

Posted by li...@apache.org.
This is an automated email from the ASF dual-hosted git repository.

liujun pushed a commit to branch 2.7.x
in repository https://gitbox.apache.org/repos/asf/dubbo-spi-extensions.git

commit 7653d0cdd423722e46784be21ca6da4b4fffa7c1
Author: qq213539 <21...@qq.com>
AuthorDate: Mon Nov 23 10:40:35 2020 +0800

    当远程调用失败时,移除缓存中的Reference. 更新前端打包
---
 .../dubbo/apidocs/utils/DubboGenericUtil.java      | 44 ++++++++++++++++++++--
 .../src/main/resources/static/css/index.css        |  2 +-
 .../src/main/resources/static/js/index.js          | 28 +++++++-------
 3 files changed, 56 insertions(+), 18 deletions(-)

diff --git a/dubbo-api-docs/dubbo-api-docs-ui-server/src/main/java/org/apache/dubbo/apidocs/utils/DubboGenericUtil.java b/dubbo-api-docs/dubbo-api-docs-ui-server/src/main/java/org/apache/dubbo/apidocs/utils/DubboGenericUtil.java
index 1c085bc..6d98388 100644
--- a/dubbo-api-docs/dubbo-api-docs-ui-server/src/main/java/org/apache/dubbo/apidocs/utils/DubboGenericUtil.java
+++ b/dubbo-api-docs/dubbo-api-docs-ui-server/src/main/java/org/apache/dubbo/apidocs/utils/DubboGenericUtil.java
@@ -21,6 +21,8 @@ import org.apache.dubbo.config.ReferenceConfig;
 import org.apache.dubbo.config.RegistryConfig;
 import org.apache.dubbo.rpc.service.GenericService;
 
+import org.apache.commons.lang3.StringUtils;
+
 import java.util.Map;
 import java.util.concurrent.CompletableFuture;
 import java.util.concurrent.ConcurrentHashMap;
@@ -93,6 +95,16 @@ public class DubboGenericUtil {
     }
 
     /**
+     * remove cached registry information.
+     * 2020/11/20 17:36
+     * @param address Address of Registration Center
+     * @return void
+     */
+    private static void removeRegistryConfig(String address) {
+        registryConfigCache.remove(address);
+    }
+
+    /**
      * Get proxy object for dubbo service.
      * 2019/9/19 17:43
      * @param: address  address Address of Registration Center
@@ -120,6 +132,18 @@ public class DubboGenericUtil {
     }
 
     /**
+     * remove cached proxy object.
+     * 2020/11/20 17:38
+     * @param address
+     * @param interfaceName
+     * @return void
+     */
+    private static void removeReferenceConfig(String address, String interfaceName) {
+        removeRegistryConfig(address);
+        referenceCache.remove(address + "/" + interfaceName);
+    }
+
+    /**
      * Call duboo provider and return {@link CompletableFuture}.
      * 2020/3/1 14:55
      * @param: address
@@ -139,12 +163,18 @@ public class DubboGenericUtil {
         if (null != reference) {
             GenericService genericService = reference.get();
             if (null != genericService) {
-                if(async){
+                if (async) {
                     future = genericService.$invokeAsync(methodName, paramTypes, paramValues);
                 } else {
                     future = CompletableFuture.supplyAsync(() -> genericService.$invoke(methodName, paramTypes, paramValues), executor);
                 }
             }
+            future.exceptionally(ex -> {
+                if (StringUtils.contains(ex.toString(), "Failed to invoke remote method")) {
+                    removeReferenceConfig(address, interfaceName);
+                }
+                return ex;
+            });
         }
         return future;
     }
@@ -165,8 +195,16 @@ public class DubboGenericUtil {
         ReferenceConfig<GenericService> reference = getReferenceConfig(address, interfaceName);
         if (null != reference) {
             GenericService genericService = reference.get();
-            if (null != genericService) {
-                return genericService.$invoke(methodName, paramTypes, paramValues);
+            try {
+                if (null != genericService) {
+                    return genericService.$invoke(methodName, paramTypes, paramValues);
+                }
+            } catch (Exception ex) {
+                if (StringUtils.contains(ex.toString(), "Failed to invoke remote method")) {
+                    removeReferenceConfig(address, interfaceName);
+                } else {
+                    throw ex;
+                }
             }
         }
         return null;
diff --git a/dubbo-api-docs/dubbo-api-docs-ui-server/src/main/resources/static/css/index.css b/dubbo-api-docs/dubbo-api-docs-ui-server/src/main/resources/static/css/index.css
index 6642125..88e0239 100644
--- a/dubbo-api-docs/dubbo-api-docs-ui-server/src/main/resources/static/css/index.css
+++ b/dubbo-api-docs/dubbo-api-docs-ui-server/src/main/resources/static/css/index.css
@@ -1 +1 @@
-.next-sr-only{position:absolute;width:1px;height:1px;padding:0;overflow:hidden;clip:rect(0,0,0,0);white-space:nowrap;border:0;margin:-1px}/*! normalize.css v7.0.0 | MIT License | github.com/necolas/normalize.css */html{line-height:1.15;-ms-text-size-adjust:100%;-webkit-text-size-adjust:100%}body{margin:0}article,aside,footer,header,nav,section{display:block}h1{font-size:2em;margin:.67em 0}figcaption,figure,main{display:block}figure{margin:1em 40px}hr{-webkit-box-sizing:content-box;box-si [...]
\ No newline at end of file
+.next-sr-only{position:absolute;width:1px;height:1px;padding:0;overflow:hidden;clip:rect(0,0,0,0);white-space:nowrap;border:0;margin:-1px}/*! normalize.css v7.0.0 | MIT License | github.com/necolas/normalize.css */html{line-height:1.15;-ms-text-size-adjust:100%;-webkit-text-size-adjust:100%}body{margin:0}article,aside,footer,header,nav,section{display:block}h1{font-size:2em;margin:.67em 0}figcaption,figure,main{display:block}figure{margin:1em 40px}hr{-webkit-box-sizing:content-box;box-si [...]
\ No newline at end of file
diff --git a/dubbo-api-docs/dubbo-api-docs-ui-server/src/main/resources/static/js/index.js b/dubbo-api-docs/dubbo-api-docs-ui-server/src/main/resources/static/js/index.js
index 496947b..6120326 100644
--- a/dubbo-api-docs/dubbo-api-docs-ui-server/src/main/resources/static/js/index.js
+++ b/dubbo-api-docs/dubbo-api-docs-ui-server/src/main/resources/static/js/index.js
@@ -1,9 +1,9 @@
-!function(e){var t={};function n(r){if(t[r])return t[r].exports;var o=t[r]={i:r,l:!1,exports:{}};return e[r].call(o.exports,o,o.exports,n),o.l=!0,o.exports}n.m=e,n.c=t,n.d=function(e,t,r){n.o(e,t)||Object.defineProperty(e,t,{enumerable:!0,get:r})},n.r=function(e){"undefined"!=typeof Symbol&&Symbol.toStringTag&&Object.defineProperty(e,Symbol.toStringTag,{value:"Module"}),Object.defineProperty(e,"__esModule",{value:!0})},n.t=function(e,t){if(1&t&&(e=n(e)),8&t)return e;if(4&t&&"object"==typ [...]
+!function(e){var t={};function n(r){if(t[r])return t[r].exports;var o=t[r]={i:r,l:!1,exports:{}};return e[r].call(o.exports,o,o.exports,n),o.l=!0,o.exports}n.m=e,n.c=t,n.d=function(e,t,r){n.o(e,t)||Object.defineProperty(e,t,{enumerable:!0,get:r})},n.r=function(e){"undefined"!=typeof Symbol&&Symbol.toStringTag&&Object.defineProperty(e,Symbol.toStringTag,{value:"Module"}),Object.defineProperty(e,"__esModule",{value:!0})},n.t=function(e,t){if(1&t&&(e=n(e)),8&t)return e;if(4&t&&"object"==typ [...]
 /*!
   Copyright (c) 2017 Jed Watson.
   Licensed under the MIT License (MIT), see
   http://jedwatson.github.io/classnames
-*/!function(){"use strict";var n={}.hasOwnProperty;function a(){for(var e=[],t=0;t<arguments.length;t++){var r=arguments[t];if(r){var o=typeof r;if("string"===o||"number"===o)e.push(r);else if(Array.isArray(r)&&r.length){var i=a.apply(null,r);i&&e.push(i)}else if("object"===o)for(var s in r)n.call(r,s)&&r[s]&&e.push(s)}}return e.join(" ")}e.exports?(a.default=a,e.exports=a):void 0===(o=function(){return a}.apply(t,r=[]))||(e.exports=o)}()},function(e,t,n){"use strict";t.__esModule=!0;var [...]
+*/!function(){"use strict";var n={}.hasOwnProperty;function a(){for(var e=[],t=0;t<arguments.length;t++){var r=arguments[t];if(r){var o=typeof r;if("string"===o||"number"===o)e.push(r);else if(Array.isArray(r)&&r.length){var i=a.apply(null,r);i&&e.push(i)}else if("object"===o)for(var s in r)n.call(r,s)&&r[s]&&e.push(s)}}return e.join(" ")}e.exports?(a.default=a,e.exports=a):void 0===(o=function(){return a}.apply(t,r=[]))||(e.exports=o)}()},function(e,t,n){"use strict";t.__esModule=!0,t.d [...]
 /*! *****************************************************************************
 Copyright (c) Microsoft Corporation.
 
@@ -18,7 +18,7 @@ LOSS OF USE, DATA OR PROFITS, WHETHER IN AN ACTION OF CONTRACT, NEGLIGENCE OR
 OTHER TORTIOUS ACTION, ARISING OUT OF OR IN CONNECTION WITH THE USE OR
 PERFORMANCE OF THIS SOFTWARE.
 ***************************************************************************** */
-var r=function(e,t){return(r=Object.setPrototypeOf||{__proto__:[]}instanceof Array&&function(e,t){e.__proto__=t}||function(e,t){for(var n in t)t.hasOwnProperty(n)&&(e[n]=t[n])})(e,t)};function o(e,t){function n(){this.constructor=e}r(e,t),e.prototype=null===t?Object.create(t):(n.prototype=t.prototype,new n)}var a=function(){return(a=Object.assign||function e(t){for(var n,r=1,o=arguments.length;r<o;r++)for(var a in n=arguments[r])Object.prototype.hasOwnProperty.call(n,a)&&(t[a]=n[a]);retu [...]
+var r=function(e,t){return(r=Object.setPrototypeOf||{__proto__:[]}instanceof Array&&function(e,t){e.__proto__=t}||function(e,t){for(var n in t)t.hasOwnProperty(n)&&(e[n]=t[n])})(e,t)};function o(e,t){function n(){this.constructor=e}r(e,t),e.prototype=null===t?Object.create(t):(n.prototype=t.prototype,new n)}var a=function(){return(a=Object.assign||function e(t){for(var n,r=1,o=arguments.length;r<o;r++)for(var a in n=arguments[r])Object.prototype.hasOwnProperty.call(n,a)&&(t[a]=n[a]);retu [...]
 /*!
  * jQuery JavaScript Library v3.5.1
  * https://jquery.com/
@@ -42,27 +42,27 @@ var r=function(e,t){return(r=Object.setPrototypeOf||{__proto__:[]}instanceof Arr
  *
  * Date: 2020-03-14
  */
-function(e){var t,n,r,o,a,i,s,u,l,c,f,p,d,h,v,m,y,g,b,w="sizzle"+1*new Date,x=e.document,E=0,_=0,O=ue(),S=ue(),C=ue(),k=ue(),P=function(e,t){return e===t&&(f=!0),0},T={}.hasOwnProperty,j=[],A=j.pop,N=j.push,M=j.push,D=j.slice,R=function(e,t){for(var n=0,r=e.length;n<r;n++)if(e[n]===t)return n;return-1},L="checked|selected|async|autofocus|autoplay|controls|defer|disabled|hidden|ismap|loop|multiple|open|readonly|required|scoped",I="[\\x20\\t\\r\\n\\f]",F="(?:\\\\[\\da-fA-F]{1,6}"+I+"?|\\\\ [...]
+function(e){var t,n,r,o,a,i,s,u,l,c,f,p,d,h,v,m,y,g,b,w="sizzle"+1*new Date,x=e.document,E=0,_=0,O=ue(),S=ue(),C=ue(),k=ue(),P=function(e,t){return e===t&&(f=!0),0},T={}.hasOwnProperty,j=[],A=j.pop,N=j.push,M=j.push,D=j.slice,R=function(e,t){for(var n=0,r=e.length;n<r;n++)if(e[n]===t)return n;return-1},L="checked|selected|async|autofocus|autoplay|controls|defer|disabled|hidden|ismap|loop|multiple|open|readonly|required|scoped",I="[\\x20\\t\\r\\n\\f]",F="(?:\\\\[\\da-fA-F]{1,6}"+I+"?|\\\\ [...]
 /*
 object-assign
 (c) Sindre Sorhus
 @license MIT
-*/var r=Object.getOwnPropertySymbols,o=Object.prototype.hasOwnProperty,a=Object.prototype.propertyIsEnumerable;function i(e){if(null==e)throw new TypeError("Object.assign cannot be called with null or undefined");return Object(e)}function s(){try{if(!Object.assign)return!1;var e=new String("abc"),t;if(e[5]="de","5"===Object.getOwnPropertyNames(e)[0])return!1;for(var n={},r=0;r<10;r++)n["_"+String.fromCharCode(r)]=r;if("0123456789"!==Object.getOwnPropertyNames(n).map((function(e){return n [...]
+*/var r=Object.getOwnPropertySymbols,o=Object.prototype.hasOwnProperty,a=Object.prototype.propertyIsEnumerable;function i(e){if(null==e)throw new TypeError("Object.assign cannot be called with null or undefined");return Object(e)}function s(){try{if(!Object.assign)return!1;var e=new String("abc"),t;if(e[5]="de","5"===Object.getOwnPropertyNames(e)[0])return!1;for(var n={},r=0;r<10;r++)n["_"+String.fromCharCode(r)]=r;if("0123456789"!==Object.getOwnPropertyNames(n).map((function(e){return n [...]
 /*!
  * cookie
  * Copyright(c) 2012-2014 Roman Shtylman
  * Copyright(c) 2015 Douglas Christopher Wilson
  * MIT Licensed
- */t.parse=s,t.serialize=u;var r=decodeURIComponent,o=encodeURIComponent,a=/; */,i=/^[\u0009\u0020-\u007e\u0080-\u00ff]+$/;function s(e,t){if("string"!=typeof e)throw new TypeError("argument str must be a string");for(var n={},o=t||{},i=e.split(a),s=o.decode||r,u=0;u<i.length;u++){var c=i[u],f=c.indexOf("=");if(!(f<0)){var p=c.substr(0,f).trim(),d=c.substr(++f,c.length).trim();'"'==d[0]&&(d=d.slice(1,-1)),null==n[p]&&(n[p]=l(d,s))}}return n}function u(e,t,n){var r=n||{},a=r.encode||o;if( [...]
+ */t.parse=s,t.serialize=u;var r=decodeURIComponent,o=encodeURIComponent,a=/; */,i=/^[\u0009\u0020-\u007e\u0080-\u00ff]+$/;function s(e,t){if("string"!=typeof e)throw new TypeError("argument str must be a string");for(var n={},o=t||{},i=e.split(a),s=o.decode||r,u=0;u<i.length;u++){var c=i[u],f=c.indexOf("=");if(!(f<0)){var p=c.substr(0,f).trim(),d=c.substr(++f,c.length).trim();'"'==d[0]&&(d=d.slice(1,-1)),null==n[p]&&(n[p]=l(d,s))}}return n}function u(e,t,n){var r=n||{},a=r.encode||o;if( [...]
 //! version : 2.29.1
 //! authors : Tim Wood, Iskren Chernev, Moment.js contributors
 //! license : MIT
 //! momentjs.com
-r=this,o=function(){"use strict";var t,r;function o(){return t.apply(null,arguments)}function a(e){t=e}function i(e){return e instanceof Array||"[object Array]"===Object.prototype.toString.call(e)}function s(e){return null!=e&&"[object Object]"===Object.prototype.toString.call(e)}function u(e,t){return Object.prototype.hasOwnProperty.call(e,t)}function l(e){if(Object.getOwnPropertyNames)return 0===Object.getOwnPropertyNames(e).length;var t;for(t in e)if(u(e,t))return!1;return!0}function  [...]
+r=this,o=function(){"use strict";var t,r;function o(){return t.apply(null,arguments)}function a(e){t=e}function i(e){return e instanceof Array||"[object Array]"===Object.prototype.toString.call(e)}function s(e){return null!=e&&"[object Object]"===Object.prototype.toString.call(e)}function u(e,t){return Object.prototype.hasOwnProperty.call(e,t)}function l(e){if(Object.getOwnPropertyNames)return 0===Object.getOwnPropertyNames(e).length;var t;for(t in e)if(u(e,t))return!1;return!0}function  [...]
 //! moment.js
-o.version="2.29.1",a($n),o.fn=la,o.min=Qn,o.max=er,o.now=tr,o.utc=v,o.unix=ca,o.months=ya,o.isDate=p,o.locale=vn,o.invalid=b,o.duration=Pr,o.isMoment=O,o.weekdays=ba,o.parseZone=fa,o.localeData=gn,o.isDuration=sr,o.monthsShort=ga,o.weekdaysMin=xa,o.defineLocale=mn,o.updateLocale=yn,o.locales=bn,o.weekdaysShort=wa,o.normalizeUnits=oe,o.relativeTimeRounding=oi,o.relativeTimeThreshold=ai,o.calendarFormat=Ur,o.prototype=la,o.HTML5_FMT={DATETIME_LOCAL:"YYYY-MM-DDTHH:mm",DATETIME_LOCAL_SECONDS [...]
+o.version="2.29.1",a($n),o.fn=la,o.min=Qn,o.max=er,o.now=tr,o.utc=v,o.unix=ca,o.months=ya,o.isDate=p,o.locale=vn,o.invalid=b,o.duration=Pr,o.isMoment=O,o.weekdays=ba,o.parseZone=fa,o.localeData=gn,o.isDuration=sr,o.monthsShort=ga,o.weekdaysMin=xa,o.defineLocale=mn,o.updateLocale=yn,o.locales=bn,o.weekdaysShort=wa,o.normalizeUnits=oe,o.relativeTimeRounding=oi,o.relativeTimeThreshold=ai,o.calendarFormat=Ur,o.prototype=la,o.HTML5_FMT={DATETIME_LOCAL:"YYYY-MM-DDTHH:mm",DATETIME_LOCAL_SECONDS [...]
 //! moment.js locale configuration
-var t;return e.defineLocale("zh-cn",{months:"\u4e00\u6708_\u4e8c\u6708_\u4e09\u6708_\u56db\u6708_\u4e94\u6708_\u516d\u6708_\u4e03\u6708_\u516b\u6708_\u4e5d\u6708_\u5341\u6708_\u5341\u4e00\u6708_\u5341\u4e8c\u6708".split("_"),monthsShort:"1\u6708_2\u6708_3\u6708_4\u6708_5\u6708_6\u6708_7\u6708_8\u6708_9\u6708_10\u6708_11\u6708_12\u6708".split("_"),weekdays:"\u661f\u671f\u65e5_\u661f\u671f\u4e00_\u661f\u671f\u4e8c_\u661f\u671f\u4e09_\u661f\u671f\u56db_\u661f\u671f\u4e94_\u661f\u671f\u516d" [...]
+var t;return e.defineLocale("zh-cn",{months:"\u4e00\u6708_\u4e8c\u6708_\u4e09\u6708_\u56db\u6708_\u4e94\u6708_\u516d\u6708_\u4e03\u6708_\u516b\u6708_\u4e5d\u6708_\u5341\u6708_\u5341\u4e00\u6708_\u5341\u4e8c\u6708".split("_"),monthsShort:"1\u6708_2\u6708_3\u6708_4\u6708_5\u6708_6\u6708_7\u6708_8\u6708_9\u6708_10\u6708_11\u6708_12\u6708".split("_"),weekdays:"\u661f\u671f\u65e5_\u661f\u671f\u4e00_\u661f\u671f\u4e8c_\u661f\u671f\u4e09_\u661f\u671f\u56db_\u661f\u671f\u4e94_\u661f\u671f\u516d" [...]
 /** @license React v16.14.0
  * react.production.min.js
  *
@@ -70,7 +70,7 @@ var t;return e.defineLocale("zh-cn",{months:"\u4e00\u6708_\u4e8c\u6708_\u4e09\u6
  *
  * This source code is licensed under the MIT license found in the
  * LICENSE file in the root directory of this source tree.
- */var r=n(189),o="function"==typeof Symbol&&Symbol.for,a=o?Symbol.for("react.element"):60103,i=o?Symbol.for("react.portal"):60106,s=o?Symbol.for("react.fragment"):60107,u=o?Symbol.for("react.strict_mode"):60108,l=o?Symbol.for("react.profiler"):60114,c=o?Symbol.for("react.provider"):60109,f=o?Symbol.for("react.context"):60110,p=o?Symbol.for("react.forward_ref"):60112,d=o?Symbol.for("react.suspense"):60113,h=o?Symbol.for("react.memo"):60115,v=o?Symbol.for("react.lazy"):60116,m="function"= [...]
+ */var r=n(188),o="function"==typeof Symbol&&Symbol.for,a=o?Symbol.for("react.element"):60103,i=o?Symbol.for("react.portal"):60106,s=o?Symbol.for("react.fragment"):60107,u=o?Symbol.for("react.strict_mode"):60108,l=o?Symbol.for("react.profiler"):60114,c=o?Symbol.for("react.provider"):60109,f=o?Symbol.for("react.context"):60110,p=o?Symbol.for("react.forward_ref"):60112,d=o?Symbol.for("react.suspense"):60113,h=o?Symbol.for("react.memo"):60115,v=o?Symbol.for("react.lazy"):60116,m="function"= [...]
 /** @license React v16.14.0
  * react-dom.production.min.js
  *
@@ -78,7 +78,7 @@ var t;return e.defineLocale("zh-cn",{months:"\u4e00\u6708_\u4e8c\u6708_\u4e09\u6
  *
  * This source code is licensed under the MIT license found in the
  * LICENSE file in the root directory of this source tree.
- */var r=n(1),o=n(189),a=n(562);function i(e){for(var t="https://reactjs.org/docs/error-decoder.html?invariant="+e,n=1;n<arguments.length;n++)t+="&args[]="+encodeURIComponent(arguments[n]);return"Minified React error #"+e+"; visit "+t+" for the full message or use the non-minified dev environment for full errors and additional helpful warnings."}if(!r)throw Error(i(227));function s(e,t,n,r,o,a,i,s,u){var l=Array.prototype.slice.call(arguments,3);try{t.apply(n,l)}catch(e){this.onError(e)} [...]
+ */var r=n(1),o=n(188),a=n(562);function i(e){for(var t="https://reactjs.org/docs/error-decoder.html?invariant="+e,n=1;n<arguments.length;n++)t+="&args[]="+encodeURIComponent(arguments[n]);return"Minified React error #"+e+"; visit "+t+" for the full message or use the non-minified dev environment for full errors and additional helpful warnings."}if(!r)throw Error(i(227));function s(e,t,n,r,o,a,i,s,u){var l=Array.prototype.slice.call(arguments,3);try{t.apply(n,l)}catch(e){this.onError(e)} [...]
 /** @license React v0.19.1
  * scheduler.production.min.js
  *
@@ -94,14 +94,14 @@ var t;return e.defineLocale("zh-cn",{months:"\u4e00\u6708_\u4e8c\u6708_\u4e09\u6
  *
  * This source code is licensed under the MIT license found in the
  * LICENSE file in the root directory of this source tree.
- */var r=n(189),o=n(1);function a(e){for(var t="https://reactjs.org/docs/error-decoder.html?invariant="+e,n=1;n<arguments.length;n++)t+="&args[]="+encodeURIComponent(arguments[n]);return"Minified React error #"+e+"; visit "+t+" for the full message or use the non-minified dev environment for full errors and additional helpful warnings."}var i="function"==typeof Symbol&&Symbol.for,s=i?Symbol.for("react.portal"):60106,u=i?Symbol.for("react.fragment"):60107,l=i?Symbol.for("react.strict_mode [...]
+ */var r=n(188),o=n(1);function a(e){for(var t="https://reactjs.org/docs/error-decoder.html?invariant="+e,n=1;n<arguments.length;n++)t+="&args[]="+encodeURIComponent(arguments[n]);return"Minified React error #"+e+"; visit "+t+" for the full message or use the non-minified dev environment for full errors and additional helpful warnings."}var i="function"==typeof Symbol&&Symbol.for,s=i?Symbol.for("react.portal"):60106,u=i?Symbol.for("react.fragment"):60107,l=i?Symbol.for("react.strict_mode [...]
 /*!
  * escape-html
  * Copyright(c) 2012-2013 TJ Holowaychuk
  * Copyright(c) 2015 Andreas Lubbe
  * Copyright(c) 2015 Tiancheng "Timothy" Gu
  * MIT Licensed
- */var r=/["'&<>]/;function o(e){var t=""+e,n=r.exec(t),o;if(!n)return t;var a="",i=0,s=0;for(i=n.index;i<t.length;i++){switch(t.charCodeAt(i)){case 34:o="&quot;";break;case 38:o="&amp;";break;case 39:o="&#39;";break;case 60:o="&lt;";break;case 62:o="&gt;";break;default:continue}s!==i&&(a+=t.substring(s,i)),s=i+1,a+=o}return s!==i?a+t.substring(s,i):a}e.exports=o},function(e,t,n){"use strict";t.decode=t.parse=n(597),t.encode=t.stringify=n(598)},function(e,t,n){"use strict";function r(e,t [...]
+ */var r=/["'&<>]/;function o(e){var t=""+e,n=r.exec(t),o;if(!n)return t;var a="",i=0,s=0;for(i=n.index;i<t.length;i++){switch(t.charCodeAt(i)){case 34:o="&quot;";break;case 38:o="&amp;";break;case 39:o="&#39;";break;case 60:o="&lt;";break;case 62:o="&gt;";break;default:continue}s!==i&&(a+=t.substring(s,i)),s=i+1,a+=o}return s!==i?a+t.substring(s,i):a}e.exports=o},function(e,t,n){"use strict";t.decode=t.parse=n(598),t.encode=t.stringify=n(599)},function(e,t,n){"use strict";function r(e,t [...]
 /** @license React v16.13.1
  * react-is.production.min.js
  *
@@ -109,4 +109,4 @@ var t;return e.defineLocale("zh-cn",{months:"\u4e00\u6708_\u4e8c\u6708_\u4e09\u6
  *
  * This source code is licensed under the MIT license found in the
  * LICENSE file in the root directory of this source tree.
- */var r="function"==typeof Symbol&&Symbol.for,o=r?Symbol.for("react.element"):60103,a=r?Symbol.for("react.portal"):60106,i=r?Symbol.for("react.fragment"):60107,s=r?Symbol.for("react.strict_mode"):60108,u=r?Symbol.for("react.profiler"):60114,l=r?Symbol.for("react.provider"):60109,c=r?Symbol.for("react.context"):60110,f=r?Symbol.for("react.async_mode"):60111,p=r?Symbol.for("react.concurrent_mode"):60111,d=r?Symbol.for("react.forward_ref"):60112,h=r?Symbol.for("react.suspense"):60113,v=r?S [...]
\ No newline at end of file
+ */var r="function"==typeof Symbol&&Symbol.for,o=r?Symbol.for("react.element"):60103,a=r?Symbol.for("react.portal"):60106,i=r?Symbol.for("react.fragment"):60107,s=r?Symbol.for("react.strict_mode"):60108,u=r?Symbol.for("react.profiler"):60114,l=r?Symbol.for("react.provider"):60109,c=r?Symbol.for("react.context"):60110,f=r?Symbol.for("react.async_mode"):60111,p=r?Symbol.for("react.concurrent_mode"):60111,d=r?Symbol.for("react.forward_ref"):60112,h=r?Symbol.for("react.suspense"):60113,v=r?S [...]
\ No newline at end of file


[dubbo-spi-extensions] 32/39: add flatten plugin

Posted by li...@apache.org.
This is an automated email from the ASF dual-hosted git repository.

liujun pushed a commit to branch 2.7.x
in repository https://gitbox.apache.org/repos/asf/dubbo-spi-extensions.git

commit ce6bc207ccbcdb7e52a12c36203bc09345706810
Author: ken.lj <ke...@gmail.com>
AuthorDate: Tue Jan 12 10:19:34 2021 +0800

    add flatten plugin
---
 dubbo-api-docs/pom.xml | 30 +++++++++++++++++++++++++++++-
 1 file changed, 29 insertions(+), 1 deletion(-)

diff --git a/dubbo-api-docs/pom.xml b/dubbo-api-docs/pom.xml
index ed3449d..42c634e 100644
--- a/dubbo-api-docs/pom.xml
+++ b/dubbo-api-docs/pom.xml
@@ -85,7 +85,7 @@
     </issueManagement>
 
     <properties>
-        <revision>2.7.8</revision>
+        <revision>2.7.8.1</revision>
         <project.build.jdkVersion>1.8</project.build.jdkVersion>
         <argLine>-Dfile.encoding=UTF-8</argLine>
         <project.build.sourceEncoding>UTF-8</project.build.sourceEncoding>
@@ -215,6 +215,34 @@
     <build>
         <plugins>
             <plugin>
+                <groupId>org.codehaus.mojo</groupId>
+                <artifactId>flatten-maven-plugin</artifactId>
+                <version>${maven-flatten-version}</version>
+                <configuration>
+                    <updatePomFile>true</updatePomFile>
+                    <flattenMode>resolveCiFriendliesOnly</flattenMode>
+                    <pomElements>
+                        <dependencies>expand</dependencies>
+                    </pomElements>
+                </configuration>
+                <executions>
+                    <execution>
+                        <id>flatten</id>
+                        <phase>process-resources</phase>
+                        <goals>
+                            <goal>flatten</goal>
+                        </goals>
+                    </execution>
+                    <execution>
+                        <id>flatten.clean</id>
+                        <phase>clean</phase>
+                        <goals>
+                            <goal>clean</goal>
+                        </goals>
+                    </execution>
+                </executions>
+            </plugin>
+            <plugin>
                 <artifactId>maven-compiler-plugin</artifactId>
                 <configuration>
                     <source>${project.build.jdkVersion}</source>


[dubbo-spi-extensions] 36/39: no message

Posted by li...@apache.org.
This is an automated email from the ASF dual-hosted git repository.

liujun pushed a commit to branch 2.7.x
in repository https://gitbox.apache.org/repos/asf/dubbo-spi-extensions.git

commit 3f3407aeba8d9c367e70ef5ac921458579659826
Author: qq213539 <21...@qq.com>
AuthorDate: Fri Jan 29 18:47:58 2021 +0800

    no message
---
 .../java/org/apache/dubbo/apidocs/examples/api/IQuickStartDemo.java     | 2 +-
 1 file changed, 1 insertion(+), 1 deletion(-)

diff --git a/dubbo-api-docs/dubbo-api-docs-examples/examples-api/src/main/java/org/apache/dubbo/apidocs/examples/api/IQuickStartDemo.java b/dubbo-api-docs/dubbo-api-docs-examples/examples-api/src/main/java/org/apache/dubbo/apidocs/examples/api/IQuickStartDemo.java
index 9e614c0..190f08e 100644
--- a/dubbo-api-docs/dubbo-api-docs-examples/examples-api/src/main/java/org/apache/dubbo/apidocs/examples/api/IQuickStartDemo.java
+++ b/dubbo-api-docs/dubbo-api-docs-examples/examples-api/src/main/java/org/apache/dubbo/apidocs/examples/api/IQuickStartDemo.java
@@ -38,7 +38,7 @@ public interface IQuickStartDemo {
      * @param beanParam
      * @return org.apache.dubbo.apidocs.examples.params.QuickStartRespBean
      */
-//    QuickStartRespBean quickStart(List<DemoParamBean4> strParam, QuickStartRequestBean beanParam);
+    QuickStartRespBean quickStart(List<DemoParamBean4> strParam, QuickStartRequestBean beanParam);
 
     /**
      * quick start demo2, request use generic.


[dubbo-spi-extensions] 38/39: 彻底解决 #10 中的3号问题

Posted by li...@apache.org.
This is an automated email from the ASF dual-hosted git repository.

liujun pushed a commit to branch 2.7.x
in repository https://gitbox.apache.org/repos/asf/dubbo-spi-extensions.git

commit 1d0cb55f3c953b6a2092a4a69d68299bd4eea232
Author: qq213539 <21...@qq.com>
AuthorDate: Sat Jan 30 17:44:04 2021 +0800

    彻底解决 #10 中的3号问题
---
 .../core/DubboApiDocsAnnotationScanner.java        | 25 ++++++++++++++++++++--
 .../apidocs/core/beans/ApiParamsCacheItem.java     | 13 +++++++++++
 .../dubbo/apidocs/core/beans/HtmlTypeEnum.java     | 10 +++++++++
 .../apache/dubbo/apidocs/utils/ClassTypeUtil.java  |  2 +-
 4 files changed, 47 insertions(+), 3 deletions(-)

diff --git a/dubbo-api-docs/dubbo-api-docs-core/src/main/java/org/apache/dubbo/apidocs/core/DubboApiDocsAnnotationScanner.java b/dubbo-api-docs/dubbo-api-docs-core/src/main/java/org/apache/dubbo/apidocs/core/DubboApiDocsAnnotationScanner.java
index f53f282..2114c26 100644
--- a/dubbo-api-docs/dubbo-api-docs-core/src/main/java/org/apache/dubbo/apidocs/core/DubboApiDocsAnnotationScanner.java
+++ b/dubbo-api-docs/dubbo-api-docs-core/src/main/java/org/apache/dubbo/apidocs/core/DubboApiDocsAnnotationScanner.java
@@ -55,8 +55,12 @@ import java.lang.reflect.Type;
 import java.lang.reflect.TypeVariable;
 import java.math.BigDecimal;
 import java.math.BigInteger;
+import java.time.LocalDate;
+import java.time.LocalDateTime;
 import java.util.ArrayList;
+import java.util.Collection;
 import java.util.Collections;
+import java.util.Date;
 import java.util.HashMap;
 import java.util.List;
 import java.util.Map;
@@ -219,6 +223,12 @@ public class DubboApiDocsAnnotationScanner implements ApplicationListener<Applic
                 } else {
                     paramListItem.setRequired(false);
                 }
+
+                if (HtmlTypeEnum.TEXT_AREA.name().equals(paramListItem.getHtmlType())) {
+                    List<ParamBean> apiParamsList = processField(argClass, parameterType, methodParameter);
+                    paramListItem.setAllowableValues(apiParamsList.get(0).getAllowableValues());
+                    paramListItem.setSubParamsJson(apiParamsList.get(0).getSubParamsJson());
+                }
             }
         }
         apiParamsAndResp.setMethodParamInfo(methodParamInfoSb.toString());
@@ -273,8 +283,8 @@ public class DubboApiDocsAnnotationScanner implements ApplicationListener<Applic
                     paramBean.setRequired(false);
                 }
 
-                if (this.processHtmlType(null == genericType ? field.getType() : genericType, requestParam, paramBean) == null) {
-                    // Not a basic type, handle as JSON
+                ParamBean tempParamBean = this.processHtmlType(null == genericType ? field.getType() : genericType, requestParam, paramBean);
+                if (tempParamBean == null || HtmlTypeEnum.TEXT_AREA.equals(tempParamBean.getHtmlType())) {
                     Object objResult;
                     if (null == genericType) {
                         objResult = ClassTypeUtil.initClassTypeWithDefaultValue(
@@ -362,7 +372,18 @@ public class DubboApiDocsAnnotationScanner implements ApplicationListener<Applic
         } else if (Short.class.isAssignableFrom(classType) || short.class.isAssignableFrom(classType)) {
             param.setHtmlType(HtmlTypeEnum.NUMBER_INTEGER);
             processed = true;
+        } else if (Date.class.isAssignableFrom(classType) || LocalDateTime.class.isAssignableFrom(classType)) {
+            param.setHtmlType(HtmlTypeEnum.DATETIME_SELECTOR);
+            processed = true;
+        } else if (LocalDate.class.isAssignableFrom(classType)) {
+            param.setHtmlType(HtmlTypeEnum.DATE_SELECTOR);
+            processed = true;
+        } else if (classType.isArray() || Collection.class.isAssignableFrom(classType) ||
+                Map.class.isAssignableFrom(classType)) {
+            param.setHtmlType(HtmlTypeEnum.TEXT_AREA);
+            processed = true;
         }
+
         if (processed) {
             // Processed, time to return
             if (hasAllowableValues) {
diff --git a/dubbo-api-docs/dubbo-api-docs-core/src/main/java/org/apache/dubbo/apidocs/core/beans/ApiParamsCacheItem.java b/dubbo-api-docs/dubbo-api-docs-core/src/main/java/org/apache/dubbo/apidocs/core/beans/ApiParamsCacheItem.java
index 3571da2..bdd2a4c 100644
--- a/dubbo-api-docs/dubbo-api-docs-core/src/main/java/org/apache/dubbo/apidocs/core/beans/ApiParamsCacheItem.java
+++ b/dubbo-api-docs/dubbo-api-docs-core/src/main/java/org/apache/dubbo/apidocs/core/beans/ApiParamsCacheItem.java
@@ -45,6 +45,11 @@ public class ApiParamsCacheItem {
 
     private Boolean required;
 
+    /**
+     * JSON string corresponding.
+     */
+    private String subParamsJson;
+
     public String getName() {
         return name;
     }
@@ -132,4 +137,12 @@ public class ApiParamsCacheItem {
     public void setRequired(Boolean required) {
         this.required = required;
     }
+
+    public String getSubParamsJson() {
+        return subParamsJson;
+    }
+
+    public void setSubParamsJson(String subParamsJson) {
+        this.subParamsJson = subParamsJson;
+    }
 }
diff --git a/dubbo-api-docs/dubbo-api-docs-core/src/main/java/org/apache/dubbo/apidocs/core/beans/HtmlTypeEnum.java b/dubbo-api-docs/dubbo-api-docs-core/src/main/java/org/apache/dubbo/apidocs/core/beans/HtmlTypeEnum.java
index e5339f1..38bc8a0 100644
--- a/dubbo-api-docs/dubbo-api-docs-core/src/main/java/org/apache/dubbo/apidocs/core/beans/HtmlTypeEnum.java
+++ b/dubbo-api-docs/dubbo-api-docs-core/src/main/java/org/apache/dubbo/apidocs/core/beans/HtmlTypeEnum.java
@@ -55,6 +55,16 @@ public enum HtmlTypeEnum {
      * Text area, which is generally used to show the JSON string of the Java Bean contained in the parameter.
      */
     TEXT_AREA,
+
+    /**
+     * date selector.
+     */
+    DATE_SELECTOR,
+
+    /**
+     * datetime selector.
+     */
+    DATETIME_SELECTOR,
     ;
 
 }
diff --git a/dubbo-api-docs/dubbo-api-docs-core/src/main/java/org/apache/dubbo/apidocs/utils/ClassTypeUtil.java b/dubbo-api-docs/dubbo-api-docs-core/src/main/java/org/apache/dubbo/apidocs/utils/ClassTypeUtil.java
index 7379ff9..ddd56e4 100644
--- a/dubbo-api-docs/dubbo-api-docs-core/src/main/java/org/apache/dubbo/apidocs/utils/ClassTypeUtil.java
+++ b/dubbo-api-docs/dubbo-api-docs-core/src/main/java/org/apache/dubbo/apidocs/utils/ClassTypeUtil.java
@@ -172,7 +172,7 @@ public class ClassTypeUtil {
         return result;
     }
 
-    private static Object initClassTypeWithDefaultValueNoProceeField(Type genericType, Class<?> classType, int processCount) {
+    public static Object initClassTypeWithDefaultValueNoProceeField(Type genericType, Class<?> classType, int processCount) {
         if (Integer.class.isAssignableFrom(classType) || int.class.isAssignableFrom(classType)) {
             return 0;
         } else if (Byte.class.isAssignableFrom(classType) || byte.class.isAssignableFrom(classType)) {