You are viewing a plain text version of this content. The canonical link for it is here.
Posted to notifications@shenyu.apache.org by li...@apache.org on 2023/05/07 13:10:24 UTC

[shenyu] branch master updated: [ISSUE #4560] spring-mvc(boot) client support collect api-doc (#4615)

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

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


The following commit(s) were added to refs/heads/master by this push:
     new cc8ad5dc3 [ISSUE #4560] spring-mvc(boot) client support collect api-doc (#4615)
cc8ad5dc3 is described below

commit cc8ad5dc36c678af47720b62151eeb1605276c7a
Author: 愿凌飞 <ti...@foxmail.com>
AuthorDate: Sun May 7 21:10:18 2023 +0800

    [ISSUE #4560] spring-mvc(boot) client support collect api-doc (#4615)
    
    * [ISSUE #4560] spring-mvc(boot) client support collect api-meta
    
    * fix style
    
    * move sub package
    
    * add  test
    
    * fix something
    
    * fix something
    
    * add doc
    
    * added Client Register Config.
    
    * added Client Register Config.
    
    * removed @EnableClientRegister from ShenyuTestHttpApplication,cause passed the Integration Test
    
    ---------
    
    Co-authored-by: tian-pengfei <ti...@apache.org>
    Co-authored-by: xiaoyu <xi...@apache.org>
---
 .../shenyu/client/core/register/ApiBean.java       |  67 +++++++++
 .../register/ClientInfoRefreshedEventListener.java |  49 ++-----
 .../client/core/register/ClientRegisterConfig.java |  66 +++++++++
 .../core/register/ClientRegisterConfigImpl.java    | 126 +++++++++++++++++
 .../core/register/matcher/ApiDocBeanMatcher.java   |  35 +++++
 .../register/matcher/ApiDocDefinitionMatcher.java  |  35 +++++
 .../parser/AbstractApiDocDefinitionParser.java     | 153 +++++++++++++++++++++
 .../parser/HttpApiDocDefinitionParser.java         |  57 ++++++++
 .../parser/NoHttpApiDocDefinitionParser.java       |  45 ++++++
 .../apimeta/SpringMvcApiMetaDefinitionParser.java  |  26 ++--
 .../apimeta/SpringMvcPreApiMetaBeanParser.java     |  15 +-
 .../SpringMvcApiMetaDefinitionParserTest.java      |  20 ++-
 .../apimeta/SpringMvcPreApiMetaBeanParserTest.java |  20 ++-
 ...yuSpringMvcClientInfoRegisterConfiguration.java |  91 ++++++------
 14 files changed, 698 insertions(+), 107 deletions(-)

diff --git a/shenyu-client/shenyu-client-core/src/main/java/org/apache/shenyu/client/core/register/ApiBean.java b/shenyu-client/shenyu-client-core/src/main/java/org/apache/shenyu/client/core/register/ApiBean.java
index 029bfe404..a1128e2a7 100644
--- a/shenyu-client/shenyu-client-core/src/main/java/org/apache/shenyu/client/core/register/ApiBean.java
+++ b/shenyu-client/shenyu-client-core/src/main/java/org/apache/shenyu/client/core/register/ApiBean.java
@@ -23,7 +23,10 @@ import org.springframework.core.annotation.AnnotatedElementUtils;
 import java.lang.annotation.Annotation;
 import java.lang.reflect.Method;
 import java.util.ArrayList;
+import java.util.Arrays;
 import java.util.List;
+import java.util.Optional;
+import java.util.stream.Collectors;
 
 public class ApiBean<T> {
 
@@ -39,6 +42,8 @@ public class ApiBean<T> {
 
     private final List<ApiDefinition> apiDefinitions = new ArrayList<>();
 
+    private final String serviceName;
+
     public ApiBean(final String contextPath, final String beanName, final T beanInstance, final String beanPath, final Class<?> beanClass) {
 
         this.contextPath = contextPath;
@@ -50,6 +55,8 @@ public class ApiBean<T> {
         this.beanPath = beanPath;
 
         this.beanClass = beanClass;
+
+        this.serviceName = beanClass.getName();
     }
 
     /**
@@ -63,6 +70,18 @@ public class ApiBean<T> {
         apiDefinitions.add(apiDefinition);
     }
 
+    /**
+     * Adds apiDefinition to apiBean.
+     *
+     * @param method     apiMethod
+     * @param methodPath methodPath
+     * @param rpcExt     rpcExt
+     */
+    public void addApiDefinition(final Method method, final String methodPath, final String rpcExt) {
+        ApiDefinition apiDefinition = new ApiDefinition(method, methodPath, rpcExt);
+        apiDefinitions.add(apiDefinition);
+    }
+
     /**
      * Gets apiDefinitions.
      *
@@ -128,15 +147,36 @@ public class ApiBean<T> {
         return contextPath;
     }
 
+    /**
+     * Gets serviceName.
+     *
+     * @return serviceName
+     */
+    public String getServiceName() {
+        return serviceName;
+    }
+
     public final class ApiDefinition {
 
         private final Method apiMethod;
 
         private final String methodPath;
 
+        private final String rpcExt;
+
+        private final String parameterTypes;
+
         private ApiDefinition(final Method apiMethod, final String methodPath) {
+            this(apiMethod, methodPath, "{}");
+        }
+
+        private ApiDefinition(final Method apiMethod, final String methodPath, final String rpcExt) {
             this.apiMethod = apiMethod;
             this.methodPath = methodPath;
+            this.rpcExt = rpcExt;
+            this.parameterTypes = Optional.ofNullable(apiMethod)
+                    .map(m -> Arrays.stream(m.getParameterTypes()).map(Class::getName)
+                            .collect(Collectors.joining(","))).orElse(null);
         }
 
         /**
@@ -221,5 +261,32 @@ public class ApiBean<T> {
         public <A extends Annotation> A getAnnotation(final Class<A> annotationClass) {
             return AnnotatedElementUtils.findMergedAnnotation(apiMethod, annotationClass);
         }
+
+        /**
+         * Gets serviceName.
+         *
+         * @return serviceName
+         */
+        public String getServiceName() {
+            return serviceName;
+        }
+
+        /**
+         * Gets rpcExt.
+         *
+         * @return rpcExt.
+         */
+        public String getRpcExt() {
+            return rpcExt;
+        }
+
+        /**
+         * Gets parameterTypes.
+         *
+         * @return parameterTypes
+         */
+        public String getParameterTypes() {
+            return parameterTypes;
+        }
     }
 }
diff --git a/shenyu-client/shenyu-client-core/src/main/java/org/apache/shenyu/client/core/register/ClientInfoRefreshedEventListener.java b/shenyu-client/shenyu-client-core/src/main/java/org/apache/shenyu/client/core/register/ClientInfoRefreshedEventListener.java
index 330a3b516..ed8f27e24 100644
--- a/shenyu-client/shenyu-client-core/src/main/java/org/apache/shenyu/client/core/register/ClientInfoRefreshedEventListener.java
+++ b/shenyu-client/shenyu-client-core/src/main/java/org/apache/shenyu/client/core/register/ClientInfoRefreshedEventListener.java
@@ -17,64 +17,38 @@
 
 package org.apache.shenyu.client.core.register;
 
-import org.apache.shenyu.client.core.constant.ShenyuClientConstants;
 import org.apache.shenyu.client.core.disruptor.ShenyuClientRegisterEventPublisher;
-import org.apache.shenyu.client.core.utils.PortUtils;
 import org.apache.shenyu.common.enums.RpcTypeEnum;
-import org.apache.shenyu.common.utils.IpUtils;
-import org.apache.shenyu.common.utils.UriUtils;
-import org.apache.shenyu.register.common.config.PropertiesConfig;
 import org.apache.shenyu.register.common.dto.URIRegisterDTO;
 import org.springframework.context.ApplicationListener;
 import org.springframework.context.event.ContextRefreshedEvent;
 
-import java.util.Optional;
-import java.util.Properties;
-
 public final class ClientInfoRefreshedEventListener implements ApplicationListener<ContextRefreshedEvent> {
 
-    private final boolean addPrefixed;
-
-    private final boolean isFull;
-
     private final String contextPath;
 
     private final String appName;
 
     private final RpcTypeEnum rpcTypeEnum;
 
-    private final String ipAndPort;
-
     private final String host;
 
-    private final String port;
+    private final Integer port;
 
     private final ShenyuClientRegisterEventPublisher publisher;
 
-    public ClientInfoRefreshedEventListener(final PropertiesConfig clientConfig,
-                                            final ShenyuClientRegisterEventPublisher publisher,
-                                            final RpcTypeEnum rpcTypeEnum) {
-
-        Properties props = clientConfig.getProps();
+    public ClientInfoRefreshedEventListener(final ClientRegisterConfig clientRegisterConfig,
+                                            final ShenyuClientRegisterEventPublisher publisher) {
 
-        this.addPrefixed = Boolean.parseBoolean(props.getProperty(ShenyuClientConstants.ADD_PREFIXED,
-                Boolean.FALSE.toString()));
+        this.contextPath = clientRegisterConfig.getContextPath();
 
-        this.isFull = Boolean.parseBoolean(props.getProperty(ShenyuClientConstants.IS_FULL, Boolean.FALSE.toString()));
+        this.appName = clientRegisterConfig.getAppName();
 
-        this.contextPath = Optional.ofNullable(props
-                .getProperty(ShenyuClientConstants.CONTEXT_PATH))
-                .map(UriUtils::repairData).orElse("");
+        this.rpcTypeEnum = clientRegisterConfig.getRpcTypeEnum();
 
-        this.appName = props.getProperty(ShenyuClientConstants.APP_NAME);
+        this.host = clientRegisterConfig.getHost();
 
-        this.rpcTypeEnum = rpcTypeEnum;
-
-        this.ipAndPort = props.getProperty(ShenyuClientConstants.IP_PORT);
-
-        this.host = props.getProperty(ShenyuClientConstants.HOST);
-
-        this.port = props.getProperty(ShenyuClientConstants.PORT);
+        this.port = clientRegisterConfig.getPort();
 
         this.publisher = publisher;
     }
@@ -82,15 +56,12 @@ public final class ClientInfoRefreshedEventListener implements ApplicationListen
     @Override
     public void onApplicationEvent(final ContextRefreshedEvent event) {
 
-        final int port = Integer.parseInt(Optional.ofNullable(host).orElseGet(() -> "-1"));
-        final int mergedPort = port <= 0 ? PortUtils.findPort(event.getApplicationContext().getAutowireCapableBeanFactory()) : port;
-
         URIRegisterDTO uriRegisterDTO = URIRegisterDTO.builder()
                 .contextPath(contextPath)
                 .appName(appName)
                 .rpcType(rpcTypeEnum.getName())
-                .host(IpUtils.isCompleteHost(host) ? host : IpUtils.getHost(host))
-                .port(mergedPort)
+                .host(host)
+                .port(port)
                 .build();
 
         publisher.publishEvent(uriRegisterDTO);
diff --git a/shenyu-client/shenyu-client-core/src/main/java/org/apache/shenyu/client/core/register/ClientRegisterConfig.java b/shenyu-client/shenyu-client-core/src/main/java/org/apache/shenyu/client/core/register/ClientRegisterConfig.java
new file mode 100644
index 000000000..f1b5e623d
--- /dev/null
+++ b/shenyu-client/shenyu-client-core/src/main/java/org/apache/shenyu/client/core/register/ClientRegisterConfig.java
@@ -0,0 +1,66 @@
+/*
+ * Licensed to the Apache Software Foundation (ASF) under one or more
+ * contributor license agreements.  See the NOTICE file distributed with
+ * this work for additional information regarding copyright ownership.
+ * The ASF licenses this file to You under the Apache License, Version 2.0
+ * (the "License"); you may not use this file except in compliance with
+ * the License.  You may obtain a copy of the License at
+ *
+ *     http://www.apache.org/licenses/LICENSE-2.0
+ *
+ * Unless required by applicable law or agreed to in writing, software
+ * distributed under the License is distributed on an "AS IS" BASIS,
+ * WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied.
+ * See the License for the specific language governing permissions and
+ * limitations under the License.
+ */
+
+package org.apache.shenyu.client.core.register;
+
+import org.apache.shenyu.common.enums.RpcTypeEnum;
+
+public interface ClientRegisterConfig {
+
+    /**
+     * Gets port.
+     * @return port
+     */
+    Integer getPort();
+
+    /**
+     * Gets host.
+     * @return host
+     */
+    String getHost();
+
+    /**
+     * Gets appName.
+     * @return appName
+     */
+    String getAppName();
+
+    /**
+     * Gets contextPath.
+     * @return contextPath
+     */
+    String getContextPath();
+
+    /**
+     * Gets ipAndPort.
+     * @return ipAndPort
+     */
+    String getIpAndPort();
+
+    /**
+     * Gets addPrefixed.
+     * @return dddPrefixed
+     */
+    Boolean getAddPrefixed();
+
+    /**
+     * Gets rpcTypeEnum.
+     * @return rpcTypeEnum
+     */
+    RpcTypeEnum getRpcTypeEnum();
+
+}
diff --git a/shenyu-client/shenyu-client-core/src/main/java/org/apache/shenyu/client/core/register/ClientRegisterConfigImpl.java b/shenyu-client/shenyu-client-core/src/main/java/org/apache/shenyu/client/core/register/ClientRegisterConfigImpl.java
new file mode 100644
index 000000000..6483e9686
--- /dev/null
+++ b/shenyu-client/shenyu-client-core/src/main/java/org/apache/shenyu/client/core/register/ClientRegisterConfigImpl.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.shenyu.client.core.register;
+
+import org.apache.shenyu.client.core.constant.ShenyuClientConstants;
+import org.apache.shenyu.client.core.utils.PortUtils;
+import org.apache.shenyu.common.enums.RpcTypeEnum;
+import org.apache.shenyu.common.utils.IpUtils;
+import org.apache.shenyu.common.utils.UriUtils;
+import org.apache.shenyu.register.common.config.ShenyuClientConfig;
+import org.springframework.context.ApplicationContext;
+import org.springframework.core.env.Environment;
+
+import java.util.Objects;
+import java.util.Optional;
+import java.util.Properties;
+
+public class ClientRegisterConfigImpl implements ClientRegisterConfig {
+
+    private final Properties props;
+
+    private Integer port;
+
+    private String host;
+
+    private String appName;
+
+    private final Environment env;
+
+    private final ApplicationContext applicationContext;
+
+    private final RpcTypeEnum rpcTypeEnum;
+
+    public ClientRegisterConfigImpl(final ShenyuClientConfig shenyuClientConfig,
+                                    final RpcTypeEnum rpcTypeEnum,
+                                    final ApplicationContext applicationContext,
+                                    final Environment env) {
+
+        this.props = shenyuClientConfig.getClient().get(rpcTypeEnum.getName()).getProps();
+
+        this.applicationContext = applicationContext;
+
+        this.rpcTypeEnum = rpcTypeEnum;
+
+        this.env = env;
+
+    }
+
+    @Override
+    public Integer getPort() {
+
+        if (Objects.isNull(port)) {
+            this.port = Optional
+                    .ofNullable(props.getProperty(ShenyuClientConstants.PORT))
+                    .map(Integer::parseInt)
+                    .orElseGet(() -> PortUtils
+                            .findPort(applicationContext.getAutowireCapableBeanFactory()));
+        }
+
+        return this.port;
+    }
+
+    @Override
+    public String getHost() {
+
+        if (Objects.isNull(this.host)) {
+
+            this.host = props.getProperty(ShenyuClientConstants.HOST);
+
+            this.host = IpUtils.isCompleteHost(this.host) ? this.host
+                    : IpUtils.getHost(this.host);
+        }
+
+        return this.host;
+    }
+
+    @Override
+    public String getAppName() {
+
+        if (Objects.isNull(this.appName)) {
+
+            this.appName = Optional.ofNullable(props.getProperty(ShenyuClientConstants.APP_NAME))
+                    .orElseGet(() -> env.getProperty("spring.application.name"));
+        }
+
+        return this.appName;
+    }
+
+    @Override
+    public String getContextPath() {
+        return Optional
+                .ofNullable(props.getProperty(ShenyuClientConstants.CONTEXT_PATH))
+                .map(UriUtils::repairData).orElse("");
+    }
+
+    @Override
+    public String getIpAndPort() {
+        return props.getProperty(ShenyuClientConstants.IP_PORT);
+    }
+
+    @Override
+    public Boolean getAddPrefixed() {
+        return Optional.ofNullable(props.getProperty(ShenyuClientConstants.ADD_PREFIXED))
+                .map(Boolean::parseBoolean).orElse(false);
+    }
+
+    @Override
+    public RpcTypeEnum getRpcTypeEnum() {
+        return rpcTypeEnum;
+    }
+}
diff --git a/shenyu-client/shenyu-client-core/src/main/java/org/apache/shenyu/client/core/register/matcher/ApiDocBeanMatcher.java b/shenyu-client/shenyu-client-core/src/main/java/org/apache/shenyu/client/core/register/matcher/ApiDocBeanMatcher.java
new file mode 100644
index 000000000..66e662340
--- /dev/null
+++ b/shenyu-client/shenyu-client-core/src/main/java/org/apache/shenyu/client/core/register/matcher/ApiDocBeanMatcher.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.shenyu.client.core.register.matcher;
+
+import org.apache.shenyu.client.apidocs.annotations.ApiModule;
+import org.apache.shenyu.client.core.register.ApiBean;
+
+public class ApiDocBeanMatcher implements Matcher<ApiBean<Object>> {
+
+    private final Matcher<ApiBean<Object>> matcher;
+
+    public ApiDocBeanMatcher() {
+        matcher = new AnnotatedApiBeanMatcher<>(ApiModule.class);
+    }
+
+    @Override
+    public boolean match(final ApiBean<Object> element) {
+        return matcher.match(element);
+    }
+}
diff --git a/shenyu-client/shenyu-client-core/src/main/java/org/apache/shenyu/client/core/register/matcher/ApiDocDefinitionMatcher.java b/shenyu-client/shenyu-client-core/src/main/java/org/apache/shenyu/client/core/register/matcher/ApiDocDefinitionMatcher.java
new file mode 100644
index 000000000..7024578dd
--- /dev/null
+++ b/shenyu-client/shenyu-client-core/src/main/java/org/apache/shenyu/client/core/register/matcher/ApiDocDefinitionMatcher.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.shenyu.client.core.register.matcher;
+
+import org.apache.shenyu.client.apidocs.annotations.ApiDoc;
+import org.apache.shenyu.client.core.register.ApiBean;
+
+public class ApiDocDefinitionMatcher implements Matcher<ApiBean<Object>.ApiDefinition> {
+
+    private final Matcher<ApiBean<Object>.ApiDefinition> matcher;
+
+    public ApiDocDefinitionMatcher() {
+        this.matcher = new AnnotatedApiDefinitionMatcher<>(ApiDoc.class);
+    }
+
+    @Override
+    public boolean match(final ApiBean<Object>.ApiDefinition element) {
+        return matcher.match(element);
+    }
+}
diff --git a/shenyu-client/shenyu-client-core/src/main/java/org/apache/shenyu/client/core/register/parser/AbstractApiDocDefinitionParser.java b/shenyu-client/shenyu-client-core/src/main/java/org/apache/shenyu/client/core/register/parser/AbstractApiDocDefinitionParser.java
new file mode 100644
index 000000000..32e4e92d6
--- /dev/null
+++ b/shenyu-client/shenyu-client-core/src/main/java/org/apache/shenyu/client/core/register/parser/AbstractApiDocDefinitionParser.java
@@ -0,0 +1,153 @@
+/*
+ * Licensed to the Apache Software Foundation (ASF) under one or more
+ * contributor license agreements.  See the NOTICE file distributed with
+ * this work for additional information regarding copyright ownership.
+ * The ASF licenses this file to You under the Apache License, Version 2.0
+ * (the "License"); you may not use this file except in compliance with
+ * the License.  You may obtain a copy of the License at
+ *
+ *     http://www.apache.org/licenses/LICENSE-2.0
+ *
+ * Unless required by applicable law or agreed to in writing, software
+ * distributed under the License is distributed on an "AS IS" BASIS,
+ * WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied.
+ * See the License for the specific language governing permissions and
+ * limitations under the License.
+ */
+
+package org.apache.shenyu.client.core.register.parser;
+
+import com.google.common.collect.ImmutableMap;
+import com.google.common.collect.Lists;
+import org.apache.commons.lang3.StringUtils;
+import org.apache.shenyu.client.apidocs.annotations.ApiDoc;
+import org.apache.shenyu.client.core.constant.ShenyuClientConstants;
+import org.apache.shenyu.client.core.register.ApiBean;
+import org.apache.shenyu.client.core.register.ClientRegisterConfig;
+import org.apache.shenyu.client.core.utils.OpenApiUtils;
+import org.apache.shenyu.common.enums.ApiHttpMethodEnum;
+import org.apache.shenyu.common.enums.ApiSourceEnum;
+import org.apache.shenyu.common.enums.ApiStateEnum;
+import org.apache.shenyu.common.enums.RpcTypeEnum;
+import org.apache.shenyu.common.utils.GsonUtils;
+import org.apache.shenyu.register.common.dto.ApiDocRegisterDTO;
+import org.apache.shenyu.register.common.enums.EventType;
+
+import java.lang.reflect.Method;
+import java.util.ArrayList;
+import java.util.Arrays;
+import java.util.List;
+import java.util.Map;
+
+public abstract class AbstractApiDocDefinitionParser<T> implements ApiDocDefinitionParser<T> {
+
+    private static final String API_DOC_VERSION = "v0.01";
+
+    private final RpcTypeEnum rpcTypeEnum;
+
+    private final String host;
+
+    private final Integer port;
+
+    private final Boolean addPrefixed;
+
+    public AbstractApiDocDefinitionParser(final ClientRegisterConfig clientRegisterConfig) {
+        this.rpcTypeEnum = clientRegisterConfig.getRpcTypeEnum();
+        this.host = clientRegisterConfig.getHost();
+        this.port = clientRegisterConfig.getPort();
+        this.addPrefixed = clientRegisterConfig.getAddPrefixed();
+    }
+
+    @Override
+    public List<ApiDocRegisterDTO> parse(final ApiBean<T>.ApiDefinition apiDefinition) {
+
+        ApiDoc apiDoc = apiDefinition.getAnnotation(ApiDoc.class);
+
+        List<String> tags = apiDoc.tags().length == 1 && StringUtils.isBlank(apiDoc.tags()[0]) ? Lists.newArrayList() : Arrays.asList(apiDoc.tags());
+
+        String desc = apiDoc.desc();
+
+        String apiPath = apiDefinition.getApiPath();
+
+        HttpApiSpecificInfo httpApiSpecificInfo = doParse(apiDefinition);
+
+        List<ApiDocRegisterDTO> apiDocRegisters = new ArrayList<>();
+
+        String documentJson = buildDocumentJson(tags, apiPath, apiDefinition.getApiMethod());
+
+        String extJson = buildExtJson(apiDefinition);
+
+        for (ApiHttpMethodEnum apiHttpMethodEnum : httpApiSpecificInfo.apiHttpMethodEnums) {
+            ApiDocRegisterDTO build = ApiDocRegisterDTO.builder()
+                    .consume(httpApiSpecificInfo.consume)
+                    .produce(httpApiSpecificInfo.produce)
+                    .httpMethod(apiHttpMethodEnum.getValue())
+                    .contextPath(apiDefinition.getContextPath())
+                    .ext(extJson)
+                    .document(documentJson)
+                    .rpcType(rpcTypeEnum.getName())
+                    .version(API_DOC_VERSION)
+                    .apiDesc(desc)
+                    .tags(tags)
+                    .apiPath(apiPath)
+                    .apiSource(ApiSourceEnum.ANNOTATION_GENERATION.getValue())
+                    .state(ApiStateEnum.PUBLISHED.getState())
+                    .apiOwner("admin")
+                    .eventType(EventType.REGISTER)
+                    .build();
+            apiDocRegisters.add(build);
+        }
+        return apiDocRegisters;
+    }
+
+    private String buildDocumentJson(final List<String> tags, final String path, final Method method) {
+        Map<String, Object> documentMap = ImmutableMap.<String, Object>builder()
+                .put("tags", tags)
+                .put("operationId", path)
+                .put("parameters", OpenApiUtils.generateDocumentParameters(path, method))
+                .put("responses", OpenApiUtils.generateDocumentResponse(path)).build();
+        return GsonUtils.getInstance().toJson(documentMap);
+    }
+
+    private String buildExtJson(final ApiBean<T>.ApiDefinition apiDefinition) {
+
+        ApiDocRegisterDTO.ApiExt ext = new ApiDocRegisterDTO.ApiExt();
+
+        ext.setHost(host);
+        ext.setPort(port);
+        ext.setServiceName(apiDefinition.getServiceName());
+        ext.setMethodName(apiDefinition.getApiMethodName());
+        ext.setParameterTypes(apiDefinition.getParameterTypes());
+        ext.setRpcExt(apiDefinition.getRpcExt());
+        ext.setAddPrefixed(addPrefixed);
+
+        if (rpcTypeEnum == RpcTypeEnum.HTTP) {
+            ext.setProtocol(ShenyuClientConstants.HTTP);
+        }
+
+        if (rpcTypeEnum == RpcTypeEnum.WEB_SOCKET) {
+            ext.setProtocol(ShenyuClientConstants.WS);
+        }
+
+        return GsonUtils.getInstance().toJson(ext);
+    }
+
+    protected abstract HttpApiSpecificInfo doParse(ApiBean<T>.ApiDefinition apiDefinition);
+
+    public static class HttpApiSpecificInfo {
+
+        private final String produce;
+
+        private final String consume;
+
+        private final List<ApiHttpMethodEnum> apiHttpMethodEnums;
+
+        public HttpApiSpecificInfo(final String produce,
+                                   final String consume,
+                                   final List<ApiHttpMethodEnum> apiHttpMethodEnums) {
+            this.produce = produce;
+            this.consume = consume;
+            this.apiHttpMethodEnums = apiHttpMethodEnums;
+        }
+    }
+}
diff --git a/shenyu-client/shenyu-client-core/src/main/java/org/apache/shenyu/client/core/register/parser/HttpApiDocDefinitionParser.java b/shenyu-client/shenyu-client-core/src/main/java/org/apache/shenyu/client/core/register/parser/HttpApiDocDefinitionParser.java
new file mode 100644
index 000000000..3aee67378
--- /dev/null
+++ b/shenyu-client/shenyu-client-core/src/main/java/org/apache/shenyu/client/core/register/parser/HttpApiDocDefinitionParser.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.shenyu.client.core.register.parser;
+
+import org.apache.shenyu.client.core.constant.ShenyuClientConstants;
+import org.apache.shenyu.client.core.register.ApiBean;
+import org.apache.shenyu.client.core.register.ClientRegisterConfig;
+import org.apache.shenyu.common.enums.ApiHttpMethodEnum;
+import org.springframework.web.bind.annotation.RequestMapping;
+import org.springframework.web.bind.annotation.RequestMethod;
+
+import java.util.List;
+import java.util.stream.Collectors;
+import java.util.stream.Stream;
+
+public class HttpApiDocDefinitionParser extends AbstractApiDocDefinitionParser<Object> {
+
+    public HttpApiDocDefinitionParser(final ClientRegisterConfig clientRegisterConfig) {
+        super(clientRegisterConfig);
+    }
+
+    @Override
+    protected HttpApiSpecificInfo doParse(final ApiBean<Object>.ApiDefinition apiDefinition) {
+
+        RequestMapping requestMapping = apiDefinition.getAnnotation(RequestMapping.class);
+
+        String produce = requestMapping.produces().length == 0 ? ShenyuClientConstants.MEDIA_TYPE_ALL_VALUE : String.join(",", requestMapping.produces());
+        String consume = requestMapping.consumes().length == 0 ? ShenyuClientConstants.MEDIA_TYPE_ALL_VALUE : String.join(",", requestMapping.consumes());
+
+        RequestMethod[] requestMethods = requestMapping.method();
+        if (requestMethods.length == 0) {
+            requestMethods = RequestMethod.values();
+        }
+
+        List<ApiHttpMethodEnum> apiHttpMethodEnums =
+                Stream.of(requestMethods)
+                        .map(item -> ApiHttpMethodEnum.of(item.name()))
+                        .collect(Collectors.toList());
+
+        return new HttpApiSpecificInfo(produce, consume, apiHttpMethodEnums);
+    }
+}
diff --git a/shenyu-client/shenyu-client-core/src/main/java/org/apache/shenyu/client/core/register/parser/NoHttpApiDocDefinitionParser.java b/shenyu-client/shenyu-client-core/src/main/java/org/apache/shenyu/client/core/register/parser/NoHttpApiDocDefinitionParser.java
new file mode 100644
index 000000000..effc45ce6
--- /dev/null
+++ b/shenyu-client/shenyu-client-core/src/main/java/org/apache/shenyu/client/core/register/parser/NoHttpApiDocDefinitionParser.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.shenyu.client.core.register.parser;
+
+import com.google.common.collect.Lists;
+import org.apache.shenyu.client.core.constant.ShenyuClientConstants;
+import org.apache.shenyu.client.core.register.ApiBean;
+import org.apache.shenyu.client.core.register.ClientRegisterConfig;
+import org.apache.shenyu.common.enums.ApiHttpMethodEnum;
+
+import java.util.List;
+
+public class NoHttpApiDocDefinitionParser extends AbstractApiDocDefinitionParser<Object> {
+
+    public NoHttpApiDocDefinitionParser(final ClientRegisterConfig clientRegisterConfig) {
+        super(clientRegisterConfig);
+    }
+
+    @Override
+    protected HttpApiSpecificInfo doParse(final ApiBean<Object>.ApiDefinition apiDefinition) {
+
+        String produce = ShenyuClientConstants.MEDIA_TYPE_ALL_VALUE;
+
+        String consume = ShenyuClientConstants.MEDIA_TYPE_ALL_VALUE;
+
+        List<ApiHttpMethodEnum> apiHttpMethodEnums = Lists.newArrayList(ApiHttpMethodEnum.NOT_HTTP);
+
+        return new HttpApiSpecificInfo(produce, consume, apiHttpMethodEnums);
+    }
+}
diff --git a/shenyu-client/shenyu-client-http/shenyu-client-springmvc/src/main/java/org/apache/shenyu/client/springmvc/register/apimeta/SpringMvcApiMetaDefinitionParser.java b/shenyu-client/shenyu-client-http/shenyu-client-springmvc/src/main/java/org/apache/shenyu/client/springmvc/register/apimeta/SpringMvcApiMetaDefinitionParser.java
index 025f2a53b..7a1287c00 100644
--- a/shenyu-client/shenyu-client-http/shenyu-client-springmvc/src/main/java/org/apache/shenyu/client/springmvc/register/apimeta/SpringMvcApiMetaDefinitionParser.java
+++ b/shenyu-client/shenyu-client-http/shenyu-client-springmvc/src/main/java/org/apache/shenyu/client/springmvc/register/apimeta/SpringMvcApiMetaDefinitionParser.java
@@ -20,17 +20,15 @@ package org.apache.shenyu.client.springmvc.register.apimeta;
 import com.google.common.collect.Lists;
 import org.apache.commons.lang3.StringUtils;
 import org.apache.shenyu.client.core.register.ApiBean;
+import org.apache.shenyu.client.core.register.ClientRegisterConfig;
 import org.apache.shenyu.client.core.register.parser.ApiMetaDefinitionParser;
 import org.apache.shenyu.client.springmvc.annotation.ShenyuSpringMvcClient;
 import org.apache.shenyu.common.enums.RpcTypeEnum;
 import org.apache.shenyu.common.utils.PathUtils;
 import org.apache.shenyu.register.common.dto.MetaDataRegisterDTO;
 
-import java.util.Arrays;
 import java.util.List;
 import java.util.Objects;
-import java.util.Optional;
-import java.util.stream.Collectors;
 
 public class SpringMvcApiMetaDefinitionParser implements ApiMetaDefinitionParser<Object> {
 
@@ -38,9 +36,17 @@ public class SpringMvcApiMetaDefinitionParser implements ApiMetaDefinitionParser
 
     private final String appName;
 
-    public SpringMvcApiMetaDefinitionParser(final Boolean addPrefixed, final String appName) {
-        this.addPrefixed = addPrefixed;
-        this.appName = appName;
+    private final String host;
+
+    private final Integer port;
+
+    public SpringMvcApiMetaDefinitionParser(final ClientRegisterConfig clientRegisterConfig) {
+
+        this.addPrefixed = clientRegisterConfig.getAddPrefixed();
+        this.appName = clientRegisterConfig.getAppName();
+        this.host = clientRegisterConfig.getHost();
+        this.port = clientRegisterConfig.getPort();
+
     }
 
     @Override
@@ -56,10 +62,6 @@ public class SpringMvcApiMetaDefinitionParser implements ApiMetaDefinitionParser
 
         String apiPath = PathUtils.pathJoin(apiDefinition.getContextPath(), apiDefinition.getBeanPath(), methodPath);
 
-        String parameterTypes = Optional.ofNullable(apiDefinition.getApiMethod())
-                .map(m -> Arrays.stream(m.getParameterTypes()).map(Class::getName)
-                        .collect(Collectors.joining(","))).orElse(null);
-
         ShenyuSpringMvcClient classAnnotation = apiDefinition.getApiBean()
                 .getAnnotation(ShenyuSpringMvcClient.class);
 
@@ -78,11 +80,13 @@ public class SpringMvcApiMetaDefinitionParser implements ApiMetaDefinitionParser
                 .contextPath(apiDefinition.getContextPath())
                 .addPrefixed(addPrefixed)
                 .appName(appName)
+                .host(host)
+                .port(port)
                 .serviceName(apiDefinition.getBeanClass().getName())
                 .methodName(apiDefinition.getApiMethodName())
                 .path(apiPath)
                 .pathDesc(pathDesc)
-                .parameterTypes(parameterTypes)
+                .parameterTypes(apiDefinition.getParameterTypes())
                 .rpcType(RpcTypeEnum.HTTP.getName())
                 .enabled(enabled)
                 .ruleName(ruleName)
diff --git a/shenyu-client/shenyu-client-http/shenyu-client-springmvc/src/main/java/org/apache/shenyu/client/springmvc/register/apimeta/SpringMvcPreApiMetaBeanParser.java b/shenyu-client/shenyu-client-http/shenyu-client-springmvc/src/main/java/org/apache/shenyu/client/springmvc/register/apimeta/SpringMvcPreApiMetaBeanParser.java
index e93f8b0c6..7ea9059fa 100644
--- a/shenyu-client/shenyu-client-http/shenyu-client-springmvc/src/main/java/org/apache/shenyu/client/springmvc/register/apimeta/SpringMvcPreApiMetaBeanParser.java
+++ b/shenyu-client/shenyu-client-http/shenyu-client-springmvc/src/main/java/org/apache/shenyu/client/springmvc/register/apimeta/SpringMvcPreApiMetaBeanParser.java
@@ -19,6 +19,7 @@ package org.apache.shenyu.client.springmvc.register.apimeta;
 
 import org.apache.commons.lang3.StringUtils;
 import org.apache.shenyu.client.core.register.ApiBean;
+import org.apache.shenyu.client.core.register.ClientRegisterConfig;
 import org.apache.shenyu.client.core.register.parser.PreApiMetaBeanParser;
 import org.apache.shenyu.client.springmvc.annotation.ShenyuSpringMvcClient;
 import org.apache.shenyu.common.enums.RpcTypeEnum;
@@ -31,9 +32,15 @@ public class SpringMvcPreApiMetaBeanParser implements PreApiMetaBeanParser<Objec
 
     private final String appName;
 
-    public SpringMvcPreApiMetaBeanParser(final Boolean addPrefixed, final String appName) {
-        this.addPrefixed = addPrefixed;
-        this.appName = appName;
+    private final String host;
+
+    private final Integer port;
+
+    public SpringMvcPreApiMetaBeanParser(final ClientRegisterConfig clientRegisterConfig) {
+        this.addPrefixed = clientRegisterConfig.getAddPrefixed();
+        this.appName = clientRegisterConfig.getAppName();
+        this.host = clientRegisterConfig.getHost();
+        this.port = clientRegisterConfig.getPort();
     }
 
     @Override
@@ -51,6 +58,8 @@ public class SpringMvcPreApiMetaBeanParser implements PreApiMetaBeanParser<Objec
                 .addPrefixed(addPrefixed)
                 .appName(appName)
                 .serviceName(apiBean.getBeanClass().getName())
+                .host(host)
+                .port(port)
                 .methodName(null)
                 .path(apiPath)
                 .pathDesc(annotation.desc())
diff --git a/shenyu-client/shenyu-client-http/shenyu-client-springmvc/src/test/java/org/apache/shenyu/client/springmvc/register/apimeta/SpringMvcApiMetaDefinitionParserTest.java b/shenyu-client/shenyu-client-http/shenyu-client-springmvc/src/test/java/org/apache/shenyu/client/springmvc/register/apimeta/SpringMvcApiMetaDefinitionParserTest.java
index 9a5b8a0ac..1d3c0cb61 100644
--- a/shenyu-client/shenyu-client-http/shenyu-client-springmvc/src/test/java/org/apache/shenyu/client/springmvc/register/apimeta/SpringMvcApiMetaDefinitionParserTest.java
+++ b/shenyu-client/shenyu-client-http/shenyu-client-springmvc/src/test/java/org/apache/shenyu/client/springmvc/register/apimeta/SpringMvcApiMetaDefinitionParserTest.java
@@ -18,8 +18,10 @@
 package org.apache.shenyu.client.springmvc.register.apimeta;
 
 import org.apache.shenyu.client.core.register.ApiBean;
+import org.apache.shenyu.client.core.register.ClientRegisterConfig;
 import org.apache.shenyu.client.springmvc.annotation.ShenyuSpringMvcClient;
 import org.apache.shenyu.register.common.dto.MetaDataRegisterDTO;
+import org.junit.jupiter.api.BeforeEach;
 import org.junit.jupiter.api.Test;
 import org.springframework.web.bind.annotation.PathVariable;
 import org.springframework.web.bind.annotation.RequestMapping;
@@ -30,15 +32,29 @@ import java.util.List;
 
 import static org.hamcrest.MatcherAssert.assertThat;
 import static org.hamcrest.Matchers.is;
+import static org.mockito.Mockito.mock;
+import static org.mockito.Mockito.when;
 
 public class SpringMvcApiMetaDefinitionParserTest {
 
-    private final SpringMvcApiMetaDefinitionParser apiMetaDefinitionParser =
-            new SpringMvcApiMetaDefinitionParser(false, "http");
+    private SpringMvcApiMetaDefinitionParser apiMetaDefinitionParser;
+
+    @BeforeEach
+    public void init() {
+
+        ClientRegisterConfig clientRegisterConfig = mock(ClientRegisterConfig.class);
+        when(clientRegisterConfig.getAddPrefixed()).thenReturn(true);
+        when(clientRegisterConfig.getAppName()).thenReturn("http");
+        when(clientRegisterConfig.getHost()).thenReturn("127.0.0.1");
+        when(clientRegisterConfig.getContextPath()).thenReturn("/http");
+
+        apiMetaDefinitionParser = new SpringMvcApiMetaDefinitionParser(clientRegisterConfig);
+    }
 
     @Test
     public void testParse() throws Exception {
         Method method = TestBeanMatchClass.class.getMethod("testMethod");
+
         ApiBean<Object>.ApiDefinition apiDefinition =
                 createApiDefinition(TestBeanMatchClass.class, method, "/testMethod");
 
diff --git a/shenyu-client/shenyu-client-http/shenyu-client-springmvc/src/test/java/org/apache/shenyu/client/springmvc/register/apimeta/SpringMvcPreApiMetaBeanParserTest.java b/shenyu-client/shenyu-client-http/shenyu-client-springmvc/src/test/java/org/apache/shenyu/client/springmvc/register/apimeta/SpringMvcPreApiMetaBeanParserTest.java
index 07ed67c12..c1fccd9d1 100644
--- a/shenyu-client/shenyu-client-http/shenyu-client-springmvc/src/test/java/org/apache/shenyu/client/springmvc/register/apimeta/SpringMvcPreApiMetaBeanParserTest.java
+++ b/shenyu-client/shenyu-client-http/shenyu-client-springmvc/src/test/java/org/apache/shenyu/client/springmvc/register/apimeta/SpringMvcPreApiMetaBeanParserTest.java
@@ -18,8 +18,10 @@
 package org.apache.shenyu.client.springmvc.register.apimeta;
 
 import org.apache.shenyu.client.core.register.ApiBean;
+import org.apache.shenyu.client.core.register.ClientRegisterConfig;
 import org.apache.shenyu.client.springmvc.annotation.ShenyuSpringMvcClient;
 import org.apache.shenyu.register.common.dto.MetaDataRegisterDTO;
+import org.junit.jupiter.api.BeforeEach;
 import org.junit.jupiter.api.Test;
 import org.springframework.web.bind.annotation.PathVariable;
 import org.springframework.web.bind.annotation.RequestMapping;
@@ -27,10 +29,24 @@ import org.springframework.web.bind.annotation.RestController;
 
 import static org.hamcrest.MatcherAssert.assertThat;
 import static org.hamcrest.Matchers.is;
+import static org.mockito.Mockito.mock;
+import static org.mockito.Mockito.when;
 
 public class SpringMvcPreApiMetaBeanParserTest {
-    private final SpringMvcPreApiMetaBeanParser springMvcPreApiMetaBeanParser =
-            new SpringMvcPreApiMetaBeanParser(false, "http");
+
+    private SpringMvcPreApiMetaBeanParser springMvcPreApiMetaBeanParser;
+
+    @BeforeEach
+    public void init() {
+
+        ClientRegisterConfig clientRegisterConfig = mock(ClientRegisterConfig.class);
+        when(clientRegisterConfig.getAddPrefixed()).thenReturn(true);
+        when(clientRegisterConfig.getAppName()).thenReturn("http");
+        when(clientRegisterConfig.getHost()).thenReturn("127.0.0.1");
+        when(clientRegisterConfig.getContextPath()).thenReturn("/http");
+
+        springMvcPreApiMetaBeanParser = new SpringMvcPreApiMetaBeanParser(clientRegisterConfig);
+    }
 
     @Test
     public void testParse() throws Exception {
diff --git a/shenyu-spring-boot-starter/shenyu-spring-boot-starter-client/shenyu-spring-boot-starter-client-springmvc/src/main/java/org/apache/shenyu/springboot/starter/client/springmvc/ShenyuSpringMvcClientInfoRegisterConfiguration.java b/shenyu-spring-boot-starter/shenyu-spring-boot-starter-client/shenyu-spring-boot-starter-client-springmvc/src/main/java/org/apache/shenyu/springboot/starter/client/springmvc/ShenyuSpringMvcClientInfoRegisterConfiguration.java
index cee24fbe4..4c7c05a68 100644
--- a/shenyu-spring-boot-starter/shenyu-spring-boot-starter-client/shenyu-spring-boot-starter-client-springmvc/src/main/java/org/apache/shenyu/springboot/starter/client/springmvc/ShenyuSpringMvcClientInfoRegisterConfiguration.java
+++ b/shenyu-spring-boot-starter/shenyu-spring-boot-starter-client/shenyu-spring-boot-starter-client-springmvc/src/main/java/org/apache/shenyu/springboot/starter/client/springmvc/ShenyuSpringMvcClientInfoRegisterConfiguration.java
@@ -18,33 +18,33 @@
 package org.apache.shenyu.springboot.starter.client.springmvc;
 
 import org.apache.shenyu.client.auto.config.ClientRegisterConfiguration;
-import org.apache.shenyu.client.core.constant.ShenyuClientConstants;
 import org.apache.shenyu.client.core.disruptor.ShenyuClientRegisterEventPublisher;
 import org.apache.shenyu.client.core.register.ApiBean;
 import org.apache.shenyu.client.core.register.ClientInfoRefreshedEventListener;
+import org.apache.shenyu.client.core.register.ClientRegisterConfig;
+import org.apache.shenyu.client.core.register.ClientRegisterConfigImpl;
 import org.apache.shenyu.client.core.register.extractor.ApiBeansExtractor;
+import org.apache.shenyu.client.core.register.matcher.ApiDocBeanMatcher;
+import org.apache.shenyu.client.core.register.matcher.ApiDocDefinitionMatcher;
 import org.apache.shenyu.client.core.register.matcher.Matcher;
 import org.apache.shenyu.client.core.register.parser.ApiDocDefinitionParser;
 import org.apache.shenyu.client.core.register.parser.ApiMetaDefinitionParser;
+import org.apache.shenyu.client.core.register.parser.HttpApiDocDefinitionParser;
 import org.apache.shenyu.client.core.register.parser.PreApiMetaBeanParser;
 import org.apache.shenyu.client.springmvc.register.SpringMvcApiBeansExtractor;
-import org.apache.shenyu.client.springmvc.register.apimeta.SpringMvcApiMetaDefinitionMatcher;
 import org.apache.shenyu.client.springmvc.register.apimeta.SpringMvcApiMetaBeanMatcher;
+import org.apache.shenyu.client.springmvc.register.apimeta.SpringMvcApiMetaDefinitionMatcher;
 import org.apache.shenyu.client.springmvc.register.apimeta.SpringMvcApiMetaDefinitionParser;
 import org.apache.shenyu.client.springmvc.register.apimeta.SpringMvcPreApiMetaBeanMatcher;
 import org.apache.shenyu.client.springmvc.register.apimeta.SpringMvcPreApiMetaBeanParser;
 import org.apache.shenyu.common.enums.RpcTypeEnum;
-import org.apache.shenyu.common.utils.UriUtils;
-import org.apache.shenyu.register.common.config.PropertiesConfig;
 import org.apache.shenyu.register.common.config.ShenyuClientConfig;
 import org.springframework.boot.autoconfigure.condition.ConditionalOnBean;
 import org.springframework.boot.autoconfigure.condition.ConditionalOnMissingBean;
+import org.springframework.context.ApplicationContext;
 import org.springframework.context.annotation.Bean;
 import org.springframework.context.annotation.Configuration;
-
-import java.util.Collections;
-import java.util.Optional;
-import java.util.Properties;
+import org.springframework.core.env.Environment;
 
 import static org.apache.shenyu.client.core.constant.ShenyuClientConstants.API_DOC_BEAN_MATCHER;
 import static org.apache.shenyu.client.core.constant.ShenyuClientConstants.API_DOC_DEFINITION_MATCHER;
@@ -56,54 +56,31 @@ import static org.apache.shenyu.client.core.constant.ShenyuClientConstants.PRE_A
 @ConditionalOnBean(ClientRegisterConfiguration.class)
 public class ShenyuSpringMvcClientInfoRegisterConfiguration {
 
-    private final boolean addPrefixed;
-
-    private final boolean isFull;
-
-    private final String contextPath;
-
-    private final String appName;
-
-    private final PropertiesConfig clientConfig;
-
-    public ShenyuSpringMvcClientInfoRegisterConfiguration(final ShenyuClientConfig clientConfig) {
-
-        this.clientConfig = clientConfig.getClient().get(RpcTypeEnum.HTTP.getName());
-
-        Properties props = this.clientConfig.getProps();
-
-        this.addPrefixed = Boolean.parseBoolean(props.getProperty(ShenyuClientConstants.ADD_PREFIXED,
-                Boolean.FALSE.toString()));
-
-        this.isFull = Boolean.parseBoolean(props.getProperty(ShenyuClientConstants.IS_FULL, Boolean.FALSE.toString()));
-
-        this.contextPath = Optional.ofNullable(props
-                .getProperty(ShenyuClientConstants.CONTEXT_PATH))
-                .map(UriUtils::repairData).orElse("");
-
-        this.appName = props.getProperty(ShenyuClientConstants.APP_NAME);
+    public ShenyuSpringMvcClientInfoRegisterConfiguration() {
     }
 
     /**
      * ClientInfoRefreshedEventListener Bean.
      *
+     * @param clientRegisterConfig clientRegisterConfig
      * @param publisher publisher
      * @return clientInfoRefreshedEventListener
      */
     @Bean
-    public ClientInfoRefreshedEventListener clientInfoEventListener(final ShenyuClientRegisterEventPublisher publisher) {
-        return new ClientInfoRefreshedEventListener(clientConfig, publisher, RpcTypeEnum.HTTP);
+    public ClientInfoRefreshedEventListener clientInfoEventListener(final ClientRegisterConfig clientRegisterConfig,
+                                                                    final ShenyuClientRegisterEventPublisher publisher) {
+        return new ClientInfoRefreshedEventListener(clientRegisterConfig, publisher);
     }
 
     /**
      * ApiBeansExtractor Bean.
-     *
+     * @param clientRegisterConfig clientRegisterConfig
      * @return apiBeansExtractor
      */
     @Bean
     @ConditionalOnMissingBean
-    public ApiBeansExtractor<Object> apiBeansExtractor() {
-        return new SpringMvcApiBeansExtractor(contextPath);
+    public ApiBeansExtractor<Object> apiBeansExtractor(final ClientRegisterConfig clientRegisterConfig) {
+        return new SpringMvcApiBeansExtractor(clientRegisterConfig.getContextPath());
     }
 
     /**
@@ -131,11 +108,12 @@ public class ShenyuSpringMvcClientInfoRegisterConfiguration {
     /**
      * ApiMetaDefinitionParser Bean.
      *
+     * @param clientRegisterConfig clientRegisterConfig
      * @return apiMetaParser
      */
     @Bean
-    public ApiMetaDefinitionParser<Object> apiMetaDefinitionParser() {
-        return new SpringMvcApiMetaDefinitionParser(addPrefixed, appName);
+    public ApiMetaDefinitionParser<Object> apiMetaDefinitionParser(final ClientRegisterConfig clientRegisterConfig) {
+        return new SpringMvcApiMetaDefinitionParser(clientRegisterConfig);
     }
 
     /**
@@ -152,11 +130,12 @@ public class ShenyuSpringMvcClientInfoRegisterConfiguration {
     /**
      * apiBeanMetaParser Bean.
      *
+     * @param clientRegisterConfig clientRegisterConfig
      * @return apiBeanMetaParser
      */
     @Bean
-    public PreApiMetaBeanParser<Object> apiBeanMetaParser() {
-        return new SpringMvcPreApiMetaBeanParser(addPrefixed, appName);
+    public PreApiMetaBeanParser<Object> apiBeanMetaParser(final ClientRegisterConfig clientRegisterConfig) {
+        return new SpringMvcPreApiMetaBeanParser(clientRegisterConfig);
     }
 
     /**
@@ -167,8 +146,7 @@ public class ShenyuSpringMvcClientInfoRegisterConfiguration {
     @Bean(name = API_DOC_BEAN_MATCHER)
     @ConditionalOnMissingBean(name = API_DOC_BEAN_MATCHER)
     public Matcher<ApiBean<Object>> apiDocBeanMatcher() {
-        //todo implements spring mvc doc collection
-        return e -> false;
+        return new ApiDocBeanMatcher();
     }
 
     /**
@@ -179,19 +157,32 @@ public class ShenyuSpringMvcClientInfoRegisterConfiguration {
     @Bean(name = API_DOC_DEFINITION_MATCHER)
     @ConditionalOnMissingBean(name = API_DOC_DEFINITION_MATCHER)
     public Matcher<ApiBean<Object>.ApiDefinition> apiDocDefinitionMatcher() {
-        //todo implements spring mvc doc collection
-        return e -> false;
+        return new ApiDocDefinitionMatcher();
     }
 
     /**
      * ApiDocDefinitionParser Bean.
      *
+     * @param clientRegisterConfig clientRegisterConfig
      * @return apiDocDefinitionParser
      */
     @Bean
     @ConditionalOnMissingBean
-    public ApiDocDefinitionParser<Object> apiDocDefinitionParser() {
-        //todo implements spring mvc doc collection
-        return t -> Collections.emptyList();
+    public ApiDocDefinitionParser<Object> apiDocDefinitionParser(final ClientRegisterConfig clientRegisterConfig) {
+        return new HttpApiDocDefinitionParser(clientRegisterConfig);
+    }
+
+    /**
+     * ClientRegisterConfig Bean.
+     * @param shenyuClientConfig shenyuClientConfig
+     * @param applicationContext applicationContext
+     * @param env env
+     * @return clientRegisterConfig
+     */
+    @Bean
+    public ClientRegisterConfig clientRegisterConfig(final ShenyuClientConfig shenyuClientConfig,
+                                                     final ApplicationContext applicationContext,
+                                                     final Environment env) {
+        return new ClientRegisterConfigImpl(shenyuClientConfig, RpcTypeEnum.HTTP, applicationContext, env);
     }
 }