You are viewing a plain text version of this content. The canonical link for it is here.
Posted to notifications@shenyu.apache.org by xi...@apache.org on 2023/01/09 09:41:13 UTC

[shenyu] branch master updated: [type:refactor] refactor sdk. (#4295)

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

xiaoyu 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 70a9a5ac5 [type:refactor] refactor sdk. (#4295)
70a9a5ac5 is described below

commit 70a9a5ac569f1797046fe2e9a5ff060d12ecc438
Author: yunlongn <yu...@outlook.com>
AuthorDate: Mon Jan 9 17:41:07 2023 +0800

    [type:refactor] refactor sdk. (#4295)
    
    * [type:refactor] refactor sdk.
    
    * [type:refactor] refactor sdk.
    
    * [type:refactor] refactor sdk.
    
    * [type:refactor] refactor sdk.
    
    * [type:refactor] refactor sdk.
    
    * [type:refactor] refactor sdk.
    
    Co-authored-by: xiaoyu <xi...@apache.org>
---
 .../consumer/api/ShenyuAlibabaDubboClientApi.java  |  2 +-
 .../src/main/http/sdk-apache-dubbo-test-api.http   | 73 +++++++++++++---------
 .../consumer/api/ShenyuApacheDubboClientApi.java   | 22 +++----
 .../impl/ShenyuApacheDubboClientAplFallBack.java   |  5 +-
 .../sdk/grpc/consumer/api/ShenyuGrpcClientApi.java |  2 +-
 .../consumer/api/ShenyuSpringCloudClientApi.java   |  4 +-
 .../src/main/resources/application.yml             |  2 +-
 .../test/apache/dubbo/ApacheDubboPluginTest.java   |  3 +-
 .../apache/shenyu/sdk/spring/factory/Contract.java | 15 +++--
 .../proxy/ShenyuClientInvocationHandler.java       | 37 ++++++-----
 .../spring/proxy/ShenyuClientMethodHandler.java    |  4 ++
 .../sdk/spring/support/SpringMvcContract.java      | 12 ++--
 12 files changed, 104 insertions(+), 77 deletions(-)

diff --git a/shenyu-examples/shenyu-examples-sdk/shenyu-examples-sdk-dubbo/shenyu-examples-sdk-alibaba-dubbo-consumer/src/main/java/org/apache/shenyu/examples/sdk/alibaba/dubbo/consumer/api/ShenyuAlibabaDubboClientApi.java b/shenyu-examples/shenyu-examples-sdk/shenyu-examples-sdk-dubbo/shenyu-examples-sdk-alibaba-dubbo-consumer/src/main/java/org/apache/shenyu/examples/sdk/alibaba/dubbo/consumer/api/ShenyuAlibabaDubboClientApi.java
index 0a64783ef..cd0a27ac1 100644
--- a/shenyu-examples/shenyu-examples-sdk/shenyu-examples-sdk-dubbo/shenyu-examples-sdk-alibaba-dubbo-consumer/src/main/java/org/apache/shenyu/examples/sdk/alibaba/dubbo/consumer/api/ShenyuAlibabaDubboClientApi.java
+++ b/shenyu-examples/shenyu-examples-sdk/shenyu-examples-sdk-dubbo/shenyu-examples-sdk-alibaba-dubbo-consumer/src/main/java/org/apache/shenyu/examples/sdk/alibaba/dubbo/consumer/api/ShenyuAlibabaDubboClientApi.java
@@ -34,7 +34,7 @@ import java.util.List;
 /**
  * ShenyuApacheDubboClientApi.
  */
-@ShenyuClient(contextId = "shenyu-gateway", name = "ShenyuSdkApiName", fallback = ShenyuAlibabaDubboClientApiFallBack.class)
+@ShenyuClient(value = "shenyu-gateway", fallback = ShenyuAlibabaDubboClientApiFallBack.class)
 public interface ShenyuAlibabaDubboClientApi {
 
     /**
diff --git a/shenyu-examples/shenyu-examples-sdk/shenyu-examples-sdk-dubbo/shenyu-examples-sdk-apache-dubbo-consumer/src/main/http/sdk-apache-dubbo-test-api.http b/shenyu-examples/shenyu-examples-sdk/shenyu-examples-sdk-dubbo/shenyu-examples-sdk-apache-dubbo-consumer/src/main/http/sdk-apache-dubbo-test-api.http
index 013905c52..400ae6587 100644
--- a/shenyu-examples/shenyu-examples-sdk/shenyu-examples-sdk-dubbo/shenyu-examples-sdk-apache-dubbo-consumer/src/main/http/sdk-apache-dubbo-test-api.http
+++ b/shenyu-examples/shenyu-examples-sdk/shenyu-examples-sdk-dubbo/shenyu-examples-sdk-apache-dubbo-consumer/src/main/http/sdk-apache-dubbo-test-api.http
@@ -35,51 +35,60 @@ Content-Type: application/json
 POST http://localhost:8899/sdk/dubbo/findByListId
 Accept: application/json
 Content-Type: application/json
+
 {
-    "ids":["1","2"]
+  "ids": [
+    123,
+    124,
+    125
+  ]
 }
 
 ### shengyu apache dubbo /sdk/dubbo/insert
 POST http://localhost:8899/sdk/dubbo/insert
 Accept: application/json
 Content-Type: application/json
+
 {
-    "id":1L,
-    "name":"helloworld"
+  "id": 1,
+  "name":"helloworld"
 }
 
 ### shengyu apache dubbo /sdk/dubbo/findByIdsAndName
-POST http://localhost:8899/sdk/dubbo/findByIdsAndName
+POST http://localhost:8899/sdk/dubbo/demo/findByIdsAndName
 Accept: application/json
 Content-Type: application/json
+
 {
-    "ids":["1","2"],
-    "name":"333"
+  "ids":["1","2"],
+  "name":"333"
 }
 
 ### shengyu apache dubbo /sdk/dubbo/findByArrayIdsAndName
 POST http://localhost:8899/sdk/dubbo/findByArrayIdsAndName
 Accept: application/json
 Content-Type: application/json
+
 {
-    "ids":[1,12],
-    "name":"999"
+  "ids":[1,12],
+  "name":"999"
 }
 
 ### shengyu apache dubbo /sdk/dubbo/saveComplexBeanTest
 POST http://localhost:8899/sdk/dubbo/saveComplexBeanTest
 Accept: application/json
 Content-Type: application/json
+
 {
-    "dubboTest":{
-        "id": "123",
-        "name": "test1"
-    },
-    "idLists": [
-        "1",
-        "2"
-    ],
-    "idMaps": {
+  "dubboTest":{
+    "id": "123",
+    "name": "test1"
+  },
+  "idLists": [
+    "1",
+    "2"
+  ],
+  "idMaps": {
   }
 }
 
@@ -87,26 +96,28 @@ Content-Type: application/json
 POST http://localhost:8899/sdk/dubbo/batchSave
 Accept: application/json
 Content-Type: application/json
+
 {
-    "dubboTestList": [
-        {
-            "name": "22222",
-            "id": "122"
-        }
-    ]
+  "dubboTestList": [
+    {
+      "name": "22222",
+      "id": "122"
+    }
+  ]
 }
 
 ### shengyu apache dubbo /sdk/dubbo/batchSaveAndNameAndId
 POST http://localhost:8899/sdk/dubbo/batchSaveAndNameAndId
 Accept: application/json
 Content-Type: application/json
+
 {
-    "dubboTestList": [
-        {
-            "name": "22222",
-            "id": "122"
-        }
-    ],
-    "id":"123344",
-    "name":"testete"
+  "dubboTestList": [
+    {
+      "name": "22222",
+      "id": "122"
+    }
+  ],
+  "id":"123344",
+  "name":"testete"
 }
diff --git a/shenyu-examples/shenyu-examples-sdk/shenyu-examples-sdk-dubbo/shenyu-examples-sdk-apache-dubbo-consumer/src/main/java/org/apache/shenyu/examples/sdk/apache/dubbo/consumer/api/ShenyuApacheDubboClientApi.java b/shenyu-examples/shenyu-examples-sdk/shenyu-examples-sdk-dubbo/shenyu-examples-sdk-apache-dubbo-consumer/src/main/java/org/apache/shenyu/examples/sdk/apache/dubbo/consumer/api/ShenyuApacheDubboClientApi.java
index 1ade101d5..be8b3de08 100644
--- a/shenyu-examples/shenyu-examples-sdk/shenyu-examples-sdk-dubbo/shenyu-examples-sdk-apache-dubbo-consumer/src/main/java/org/apache/shenyu/examples/sdk/apache/dubbo/consumer/api/ShenyuApacheDubboClientApi.java
+++ b/shenyu-examples/shenyu-examples-sdk/shenyu-examples-sdk-dubbo/shenyu-examples-sdk-apache-dubbo-consumer/src/main/java/org/apache/shenyu/examples/sdk/apache/dubbo/consumer/api/ShenyuApacheDubboClientApi.java
@@ -34,7 +34,7 @@ import java.util.List;
 /**
  * ShenyuApacheDubboClientApi.
  */
-@ShenyuClient(contextId = "shenyu-gateway", name = "ShenyuSdkApiName", fallback = ShenyuApacheDubboClientAplFallBack.class)
+@ShenyuClient(value = "shenyu-gateway", path = "/dubbo/demo", fallback = ShenyuApacheDubboClientAplFallBack.class)
 public interface ShenyuApacheDubboClientApi {
 
     /**
@@ -43,7 +43,7 @@ public interface ShenyuApacheDubboClientApi {
      *
      * @return DubboTest
      */
-    @GetMapping("/dubbo/findAll")
+    @GetMapping("findAll")
     DubboTest findAll();
 
     /**
@@ -51,7 +51,7 @@ public interface ShenyuApacheDubboClientApi {
      *
      * @return ListResp
      */
-    @GetMapping("/dubbo/findList")
+    @GetMapping("findList")
     ListResp findList();
 
     /**
@@ -60,7 +60,7 @@ public interface ShenyuApacheDubboClientApi {
      * @param id id
      * @return DubboTest
      */
-    @GetMapping("/dubbo/findById")
+    @GetMapping("findById")
     DubboTest findById(@RequestParam("id") String id);
 
     /**
@@ -69,7 +69,7 @@ public interface ShenyuApacheDubboClientApi {
      * @param dubboTest dubboTest
      * @return DubboTest
      */
-    @PostMapping("/dubbo/insert")
+    @PostMapping("insert")
     DubboTest insert(@RequestBody DubboTest dubboTest);
 
     /**
@@ -78,7 +78,7 @@ public interface ShenyuApacheDubboClientApi {
      * @param ids ids
      * @return DubboTest
      */
-    @PostMapping("/dubbo/findByListId")
+    @PostMapping("findByListId")
     DubboTest findByListId(@RequestBody List<String> ids);
 
     /**
@@ -87,7 +87,7 @@ public interface ShenyuApacheDubboClientApi {
      * @param dubboRequestBody dubboRequestBody
      * @return DubboTest
      */
-    @PostMapping("/dubbo/demo/findByIdsAndName")
+    @PostMapping("findByIdsAndName")
     DubboTest findByIdsAndName(@RequestBody DubboRequestBody dubboRequestBody);
 
     /**
@@ -96,7 +96,7 @@ public interface ShenyuApacheDubboClientApi {
      * @param dubboRequestBody dubboRequestBody
      * @return DubboTest
      */
-    @PostMapping("/dubbo/demo/findByIdsAndName")
+    @PostMapping("findByIdsAndName")
     DubboTest findByArrayIdsAndName(@RequestBody DubboRequestBody dubboRequestBody);
 
     /**
@@ -105,7 +105,7 @@ public interface ShenyuApacheDubboClientApi {
      * @param complexBeanTest complexBeanTest
      * @return DubboTest
      */
-    @PostMapping("/dubbo/saveComplexBeanTest")
+    @PostMapping("saveComplexBeanTest")
     DubboTest saveComplexBeanTest(@RequestBody ComplexBeanTest complexBeanTest);
 
     /**
@@ -114,7 +114,7 @@ public interface ShenyuApacheDubboClientApi {
      * @param dubboTestSaveRequest dubboTestSaveRequest
      * @return DubboTest
      */
-    @PostMapping("/dubbo/batchSave")
+    @PostMapping("batchSave")
     DubboTest batchSave(@RequestBody DubboTestSaveRequest dubboTestSaveRequest);
 
     /**
@@ -123,6 +123,6 @@ public interface ShenyuApacheDubboClientApi {
      * @param dubboTestSaveRequest dubboTestSaveRequest
      * @return DubboTest
      */
-    @PostMapping("/dubbo/batchSaveAndNameAndId")
+    @PostMapping("batchSaveAndNameAndId")
     DubboTest batchSaveAndNameAndId(@RequestBody DubboTestSaveRequest dubboTestSaveRequest);
 }
diff --git a/shenyu-examples/shenyu-examples-sdk/shenyu-examples-sdk-dubbo/shenyu-examples-sdk-apache-dubbo-consumer/src/main/java/org/apache/shenyu/examples/sdk/apache/dubbo/consumer/impl/ShenyuApacheDubboClientAplFallBack.java b/shenyu-examples/shenyu-examples-sdk/shenyu-examples-sdk-dubbo/shenyu-examples-sdk-apache-dubbo-consumer/src/main/java/org/apache/shenyu/examples/sdk/apache/dubbo/consumer/impl/ShenyuApacheDubboClientAplFallBack.java
index 14d69bd5e..48e739d33 100644
--- a/shenyu-examples/shenyu-examples-sdk/shenyu-examples-sdk-dubbo/shenyu-examples-sdk-apache-dubbo-consumer/src/main/java/org/apache/shenyu/examples/sdk/apache/dubbo/consumer/impl/ShenyuApacheDubboClientAplFallBack.java
+++ b/shenyu-examples/shenyu-examples-sdk/shenyu-examples-sdk-dubbo/shenyu-examples-sdk-apache-dubbo-consumer/src/main/java/org/apache/shenyu/examples/sdk/apache/dubbo/consumer/impl/ShenyuApacheDubboClientAplFallBack.java
@@ -56,7 +56,10 @@ public class ShenyuApacheDubboClientAplFallBack implements ShenyuApacheDubboClie
 
     @Override
     public DubboTest findByListId(final List<String> ids) {
-        return null;
+        DubboTest dubboTest = new DubboTest();
+        dubboTest.setId("a");
+        dubboTest.setName("fallback");
+        return dubboTest;
     }
 
     @Override
diff --git a/shenyu-examples/shenyu-examples-sdk/shenyu-examples-sdk-grpc/shenyu-examples-sdk-grpc-consumer/src/main/java/org/apache/shenyu/examples/sdk/grpc/consumer/api/ShenyuGrpcClientApi.java b/shenyu-examples/shenyu-examples-sdk/shenyu-examples-sdk-grpc/shenyu-examples-sdk-grpc-consumer/src/main/java/org/apache/shenyu/examples/sdk/grpc/consumer/api/ShenyuGrpcClientApi.java
index 3722ddaf3..a0d45eaf3 100644
--- a/shenyu-examples/shenyu-examples-sdk/shenyu-examples-sdk-grpc/shenyu-examples-sdk-grpc-consumer/src/main/java/org/apache/shenyu/examples/sdk/grpc/consumer/api/ShenyuGrpcClientApi.java
+++ b/shenyu-examples/shenyu-examples-sdk/shenyu-examples-sdk-grpc/shenyu-examples-sdk-grpc-consumer/src/main/java/org/apache/shenyu/examples/sdk/grpc/consumer/api/ShenyuGrpcClientApi.java
@@ -28,7 +28,7 @@ import org.springframework.web.bind.annotation.RequestBody;
 
 import java.util.List;
 
-@ShenyuClient(contextId = "SHENYU-BOOTSTRAP", name = "ShenyuGrpclientApi")
+@ShenyuClient(value = "shenyu-gateway")
 public interface ShenyuGrpcClientApi {
 
     /**
diff --git a/shenyu-examples/shenyu-examples-sdk/shenyu-examples-sdk-springcloud/shenyu-examples-sdk-springcloud-consumer/src/main/java/org/apache/shenyu/examples/sdk/springcloud/consumer/api/ShenyuSpringCloudClientApi.java b/shenyu-examples/shenyu-examples-sdk/shenyu-examples-sdk-springcloud/shenyu-examples-sdk-springcloud-consumer/src/main/java/org/apache/shenyu/examples/sdk/springcloud/consumer/api/ShenyuSpringCloudClientApi.java
index 3f6fe580e..3c7f32da0 100644
--- a/shenyu-examples/shenyu-examples-sdk/shenyu-examples-sdk-springcloud/shenyu-examples-sdk-springcloud-consumer/src/main/java/org/apache/shenyu/examples/sdk/springcloud/consumer/api/ShenyuSpringCloudClientApi.java
+++ b/shenyu-examples/shenyu-examples-sdk/shenyu-examples-sdk-springcloud/shenyu-examples-sdk-springcloud-consumer/src/main/java/org/apache/shenyu/examples/sdk/springcloud/consumer/api/ShenyuSpringCloudClientApi.java
@@ -26,9 +26,7 @@ import org.springframework.web.bind.annotation.PostMapping;
 import org.springframework.web.bind.annotation.RequestBody;
 import org.springframework.web.bind.annotation.RequestParam;
 
-@ShenyuClient(contextId = "SHENYU-BOOTSTRAP",
-        name = "ShenyuSpringCloudClientApi",
-        fallbackFactory = ShenyuSpringCloudClientApiFallbackFactory.class)
+@ShenyuClient(value = "shenyu-gateway", fallbackFactory = ShenyuSpringCloudClientApiFallbackFactory.class)
 public interface ShenyuSpringCloudClientApi {
 
     /**
diff --git a/shenyu-integrated-test/shenyu-integrated-test-sdk-apache-dubbo/src/main/resources/application.yml b/shenyu-integrated-test/shenyu-integrated-test-sdk-apache-dubbo/src/main/resources/application.yml
index ea8e73bba..031a7d8ee 100644
--- a/shenyu-integrated-test/shenyu-integrated-test-sdk-apache-dubbo/src/main/resources/application.yml
+++ b/shenyu-integrated-test/shenyu-integrated-test-sdk-apache-dubbo/src/main/resources/application.yml
@@ -139,7 +139,7 @@ shenyu:
   #  plugins:
   #    rate-limiter.enabled: false
   local:
-    enabled: false
+    enabled: true
     sha512Key: "BA3253876AED6BC22D4A6FF53D8406C6AD864195ED144AB5C87621B6C233B548BAEAE6956DF346EC8C17F5EA10F35EE3CBC514797ED7DDD3145464E2A0BAB413"
 
 logging:
diff --git a/shenyu-integrated-test/shenyu-integrated-test-sdk-apache-dubbo/src/test/java/org/apache/shenyu/integrated/test/apache/dubbo/ApacheDubboPluginTest.java b/shenyu-integrated-test/shenyu-integrated-test-sdk-apache-dubbo/src/test/java/org/apache/shenyu/integrated/test/apache/dubbo/ApacheDubboPluginTest.java
index 920975c42..ca15cabd8 100644
--- a/shenyu-integrated-test/shenyu-integrated-test-sdk-apache-dubbo/src/test/java/org/apache/shenyu/integrated/test/apache/dubbo/ApacheDubboPluginTest.java
+++ b/shenyu-integrated-test/shenyu-integrated-test-sdk-apache-dubbo/src/test/java/org/apache/shenyu/integrated/test/apache/dubbo/ApacheDubboPluginTest.java
@@ -25,6 +25,7 @@ import org.junit.jupiter.api.BeforeAll;
 import org.junit.jupiter.api.Test;
 
 import java.io.IOException;
+import java.util.ArrayList;
 
 import static org.hamcrest.MatcherAssert.assertThat;
 import static org.hamcrest.Matchers.is;
@@ -47,7 +48,7 @@ public class ApacheDubboPluginTest extends AbstractPluginDataInit {
     @Test
     public void testFindAllFallBck() throws IOException {
 
-        DubboTest dubboTest = HttpHelper.INSTANCE.getHttpService("http://localhost:8899/sdk/dubbo/findAll", null, DubboTest.class);
+        DubboTest dubboTest = HttpHelper.INSTANCE.postHttpService("http://localhost:8899/sdk/dubbo/findByListId", null, new ArrayList<>(), DubboTest.class);
         assertEquals("fallback", dubboTest.getName());
     }
 
diff --git a/shenyu-sdk/shenyu-sdk-spring/src/main/java/org/apache/shenyu/sdk/spring/factory/Contract.java b/shenyu-sdk/shenyu-sdk-spring/src/main/java/org/apache/shenyu/sdk/spring/factory/Contract.java
index 091b7af62..d989a1079 100644
--- a/shenyu-sdk/shenyu-sdk-spring/src/main/java/org/apache/shenyu/sdk/spring/factory/Contract.java
+++ b/shenyu-sdk/shenyu-sdk-spring/src/main/java/org/apache/shenyu/sdk/spring/factory/Contract.java
@@ -20,6 +20,7 @@ package org.apache.shenyu.sdk.spring.factory;
 import org.apache.shenyu.sdk.core.common.RequestTemplate;
 import org.apache.shenyu.sdk.core.util.Types;
 import org.apache.shenyu.sdk.core.util.Util;
+import org.apache.shenyu.sdk.spring.ShenyuClientFactoryBean;
 import org.springframework.context.ResourceLoaderAware;
 
 import java.lang.annotation.Annotation;
@@ -44,10 +45,11 @@ public interface Contract extends ResourceLoaderAware {
     /**
      * parseAndValidateMetadata.
      *
-     * @param targetType targetType
+     * @param targetType              targetType
+     * @param shenyuClientFactoryBean shenyuClientFactoryBean
      * @return {@link List}
      */
-    List<RequestTemplate> parseAndValidateRequestTemplate(Class<?> targetType);
+    List<RequestTemplate> parseAndValidateRequestTemplate(Class<?> targetType, ShenyuClientFactoryBean shenyuClientFactoryBean);
 
     /**
      * BaseContract.
@@ -55,7 +57,7 @@ public interface Contract extends ResourceLoaderAware {
     abstract class BaseContract implements Contract {
 
         @Override
-        public List<RequestTemplate> parseAndValidateRequestTemplate(final Class<?> targetType) {
+        public List<RequestTemplate> parseAndValidateRequestTemplate(final Class<?> targetType, final ShenyuClientFactoryBean shenyuClientFactoryBean) {
             checkState(targetType.getTypeParameters().length == 0, "Parameterized types unsupported: %s",
                     targetType.getSimpleName());
             checkState(targetType.getInterfaces().length <= 1, "Only single inheritance supported: %s",
@@ -67,7 +69,7 @@ public interface Contract extends ResourceLoaderAware {
                         || Util.isDefault(method)) {
                     continue;
                 }
-                final RequestTemplate parseRequestTemplate = parseRequestTemplate(method);
+                final RequestTemplate parseRequestTemplate = parseRequestTemplate(method, shenyuClientFactoryBean);
 
                 // paramMetadata
                 parseRequestTemplate.setParamMetadataList(analysisParamMetadata(method));
@@ -113,10 +115,11 @@ public interface Contract extends ResourceLoaderAware {
         /**
          * parseRequestTemplate.
          *
-         * @param method method
+         * @param method                  method
+         * @param shenyuClientFactoryBean shenyuClientFactoryBean
          * @return {@link RequestTemplate}
          */
-        public abstract RequestTemplate parseRequestTemplate(Method method);
+        public abstract RequestTemplate parseRequestTemplate(Method method, ShenyuClientFactoryBean shenyuClientFactoryBean);
     }
 
 }
diff --git a/shenyu-sdk/shenyu-sdk-spring/src/main/java/org/apache/shenyu/sdk/spring/proxy/ShenyuClientInvocationHandler.java b/shenyu-sdk/shenyu-sdk-spring/src/main/java/org/apache/shenyu/sdk/spring/proxy/ShenyuClientInvocationHandler.java
index c7db70e83..be22d0803 100644
--- a/shenyu-sdk/shenyu-sdk-spring/src/main/java/org/apache/shenyu/sdk/spring/proxy/ShenyuClientInvocationHandler.java
+++ b/shenyu-sdk/shenyu-sdk-spring/src/main/java/org/apache/shenyu/sdk/spring/proxy/ShenyuClientInvocationHandler.java
@@ -26,6 +26,9 @@ import org.apache.shenyu.sdk.spring.ShenyuClient;
 import org.apache.shenyu.sdk.spring.ShenyuClientFactoryBean;
 import org.apache.shenyu.sdk.spring.factory.AnnotatedParameterProcessor;
 import org.apache.shenyu.sdk.spring.factory.Contract;
+import org.slf4j.Logger;
+import org.slf4j.LoggerFactory;
+import org.springframework.beans.BeansException;
 import org.springframework.context.ApplicationContext;
 import org.springframework.util.ObjectUtils;
 import org.springframework.util.StringUtils;
@@ -46,6 +49,7 @@ import java.util.stream.Collectors;
  * ShenyuClientInvocationHandler.
  */
 public class ShenyuClientInvocationHandler implements InvocationHandler {
+    protected static final Logger LOG = LoggerFactory.getLogger(ShenyuClientInvocationHandler.class);
 
     private final Map<Method, ShenyuClientMethodHandler> methodHandlerMap = new ConcurrentHashMap<>();
 
@@ -55,12 +59,16 @@ public class ShenyuClientInvocationHandler implements InvocationHandler {
 
     private final ShenyuClientFactoryBean shenyuClientFactoryBean;
 
+    private final FallbackFactory<?> fallbackFactory;
+
     public ShenyuClientInvocationHandler(final Class<?> apiClass, final ApplicationContext applicationContext,
                                          final ShenyuClientFactoryBean shenyuClientFactoryBean) {
         this.shenyuClientFactoryBean = shenyuClientFactoryBean;
         this.applicationContext = applicationContext;
         this.contract = applicationContext.getBean(Contract.class);
         ShenyuClient shenyuClient = apiClass.getAnnotation(ShenyuClient.class);
+        fallbackFactory = getFallbackFactory(shenyuClientFactoryBean.getFallback(),
+                shenyuClientFactoryBean.getFallbackFactory());
         buildMethodHandlerMap(apiClass, shenyuClient);
     }
 
@@ -71,12 +79,11 @@ public class ShenyuClientInvocationHandler implements InvocationHandler {
         if (ObjectUtils.isEmpty(handler)) {
             throw new ShenyuException(String.format("the method cannot be called, please check the annotation and configuration, method %s", method.getName()));
         }
-        FallbackFactory<?> fallbackFactory = getFallbackFactory(shenyuClientFactoryBean.getFallback(),
-                shenyuClientFactoryBean.getFallbackFactory());
         Object result;
         try {
             result = handler.invoke(args);
         } catch (Throwable throwable) {
+            LOG.error("ShenYu Client invoke error  ", throwable);
             if (fallbackFactory == null) {
                 throw new NoFallbackAvailableException("No fallback available.", throwable);
             }
@@ -88,7 +95,7 @@ public class ShenyuClientInvocationHandler implements InvocationHandler {
 
     private void buildMethodHandlerMap(final Class<?> apiClass, final ShenyuClient shenyuClient) {
         // parseAndValidate RequestTemplate
-        final List<RequestTemplate> requestTemplates = contract.parseAndValidateRequestTemplate(apiClass);
+        final List<RequestTemplate> requestTemplates = contract.parseAndValidateRequestTemplate(apiClass, shenyuClientFactoryBean);
 
         final ShenyuSdkClient shenyuSdkClient = applicationContext.getBean(ShenyuSdkClient.class);
         final Map<String, AnnotatedParameterProcessor> annotatedParameterProcessorMap = applicationContext.getBeansOfType(AnnotatedParameterProcessor.class);
@@ -100,7 +107,7 @@ public class ShenyuClientInvocationHandler implements InvocationHandler {
             requestTemplate.setName(shenyuClientFactoryBean.getName());
             requestTemplate.setContextId(Optional.ofNullable(shenyuClientFactoryBean.getContextId()).orElse(shenyuClientFactoryBean.getName()));
             if (StringUtils.hasText(shenyuClientFactoryBean.getPath())) {
-                requestTemplate.setPath(shenyuClientFactoryBean.getPath() + "/" + requestTemplate.getPath());
+                requestTemplate.setPath(shenyuClientFactoryBean.getPath() + requestTemplate.getPath());
             }
             methodHandlerMap.put(requestTemplate.getMethod(),
                     new ShenyuClientMethodHandler(shenyuClient, requestTemplate, shenyuSdkClient, annotatedArgumentProcessors));
@@ -117,20 +124,16 @@ public class ShenyuClientInvocationHandler implements InvocationHandler {
     }
 
     private FallbackFactory<?> getFallbackFactory(final Class<?> fallback, final Class<?> fallbackFactory) {
-
-        if (fallback != void.class) {
-            Object fallbackInstance = applicationContext.getBean(fallback);
-            if (fallbackInstance == null) {
-                throw new IllegalStateException("No fallback instance found for shenyu client");
-            }
-            return new FallbackFactory.Default<>(fallbackInstance);
-        } else if (fallbackFactory != void.class) {
-            FallbackFactory<?> fallbackFactoryInstance = (FallbackFactory<?>) applicationContext.getBean(fallbackFactory);
-            if (fallbackFactoryInstance == null) {
-                throw new IllegalStateException("No fallbackFactory instance found for shenyu client");
+        try {
+            if (fallback != void.class) {
+                Object fallbackInstance = applicationContext.getBean(fallback);
+                return new FallbackFactory.Default<>(fallbackInstance);
+            } else if (fallbackFactory != void.class) {
+                return (FallbackFactory<?>) applicationContext.getBean(fallbackFactory);
             }
-            return fallbackFactoryInstance;
-        } else {
+            return null;
+        } catch (BeansException exception) {
+            LOG.error("No fallback available ", exception);
             return null;
         }
     }
diff --git a/shenyu-sdk/shenyu-sdk-spring/src/main/java/org/apache/shenyu/sdk/spring/proxy/ShenyuClientMethodHandler.java b/shenyu-sdk/shenyu-sdk-spring/src/main/java/org/apache/shenyu/sdk/spring/proxy/ShenyuClientMethodHandler.java
index 71f6b3483..64909f63b 100644
--- a/shenyu-sdk/shenyu-sdk-spring/src/main/java/org/apache/shenyu/sdk/spring/proxy/ShenyuClientMethodHandler.java
+++ b/shenyu-sdk/shenyu-sdk-spring/src/main/java/org/apache/shenyu/sdk/spring/proxy/ShenyuClientMethodHandler.java
@@ -24,8 +24,10 @@ import org.apache.shenyu.sdk.core.client.ShenyuSdkClient;
 import org.apache.shenyu.sdk.core.common.RequestTemplate;
 import org.apache.shenyu.sdk.spring.ShenyuClient;
 import org.apache.shenyu.sdk.spring.factory.AnnotatedParameterProcessor;
+import org.springframework.http.HttpStatus;
 import org.springframework.util.ObjectUtils;
 import org.springframework.util.StringUtils;
+import org.springframework.web.client.HttpClientErrorException;
 
 import java.io.IOException;
 import java.lang.annotation.Annotation;
@@ -72,6 +74,8 @@ public class ShenyuClientMethodHandler {
             return null;
         } else if (ShenyuResponse.class == returnType) {
             return shenyuResponse;
+        } else if (shenyuResponse.getStatus() != HttpStatus.OK.value()) {
+            throw new HttpClientErrorException(HttpStatus.valueOf(shenyuResponse.getStatus()));
         } else if (StringUtils.hasText(shenyuResponse.getBody())) {
             return JsonUtils.jsonToObject(shenyuResponse.getBody(), returnType);
         } else {
diff --git a/shenyu-sdk/shenyu-sdk-spring/src/main/java/org/apache/shenyu/sdk/spring/support/SpringMvcContract.java b/shenyu-sdk/shenyu-sdk-spring/src/main/java/org/apache/shenyu/sdk/spring/support/SpringMvcContract.java
index 53beb80d8..1e958f87c 100644
--- a/shenyu-sdk/shenyu-sdk-spring/src/main/java/org/apache/shenyu/sdk/spring/support/SpringMvcContract.java
+++ b/shenyu-sdk/shenyu-sdk-spring/src/main/java/org/apache/shenyu/sdk/spring/support/SpringMvcContract.java
@@ -19,6 +19,7 @@ package org.apache.shenyu.sdk.spring.support;
 
 import org.apache.shenyu.sdk.core.ShenyuRequest;
 import org.apache.shenyu.sdk.core.common.RequestTemplate;
+import org.apache.shenyu.sdk.spring.ShenyuClientFactoryBean;
 import org.apache.shenyu.sdk.spring.factory.Contract;
 import org.springframework.context.ConfigurableApplicationContext;
 import org.springframework.core.io.DefaultResourceLoader;
@@ -47,17 +48,18 @@ public class SpringMvcContract extends Contract.BaseContract {
     private ResourceLoader resourceLoader = new DefaultResourceLoader();
 
     @Override
-    public RequestTemplate parseRequestTemplate(final Method method) {
+    public RequestTemplate parseRequestTemplate(final Method method, final ShenyuClientFactoryBean shenyuClientFactoryBean) {
         final RequestTemplate requestTemplate = new RequestTemplate();
         requestTemplate.setMethod(method);
         requestTemplate.setReturnType(method.getReturnType());
         for (final Annotation methodAnnotation : method.getAnnotations()) {
-            this.processAnnotationOnMethod(requestTemplate, methodAnnotation, method);
+            this.processAnnotationOnMethod(requestTemplate, methodAnnotation, method, shenyuClientFactoryBean);
         }
         return requestTemplate;
     }
 
-    protected void processAnnotationOnMethod(final RequestTemplate requestTemplate, final Annotation methodAnnotation, final Method method) {
+    protected void processAnnotationOnMethod(final RequestTemplate requestTemplate, final Annotation methodAnnotation,
+                                             final Method method, final ShenyuClientFactoryBean shenyuClientFactoryBean) {
 
         if (!RequestMapping.class.isInstance(methodAnnotation)
                 && !methodAnnotation.annotationType().isAnnotationPresent(RequestMapping.class)) {
@@ -81,7 +83,9 @@ public class SpringMvcContract extends Contract.BaseContract {
             if (pathValue != null && !pathValue.isEmpty()) {
                 pathValue = resolve(pathValue);
                 // Append path from @RequestMapping if value is present on method
-                if (!pathValue.startsWith("/") && !requestTemplate.getPath().endsWith("/")) {
+                if (!pathValue.startsWith("/")
+                        && StringUtils.hasText(shenyuClientFactoryBean.getPath())
+                        && !shenyuClientFactoryBean.getPath().endsWith("/")) {
                     pathValue = "/" + pathValue;
                 }
                 requestTemplate.setPath(pathValue);