【问题标题】:Change FeignClient url at runtime在运行时更改 FeignClient url
【发布时间】:2018-03-04 02:42:50
【问题描述】:

拥有 Feign 客户端:

@FeignClient(name = "storeClient", url = "${feign.url}")
public interface StoreClient {
    //..
}

是否可以利用 Spring Cloud 的环境变化能力在运行时改变 Feign url? (更改feign.url 属性并调用/refresh 端点)

【问题讨论】:

    标签: spring-cloud spring-cloud-feign


    【解决方案1】:

    作为一种可能的解决方案 - 可以引入 RequestInterceptor 以便通过在 RefreshScope 中定义的属性在 RequestTemplate 中设置 URL。

    要实施这种方法,您应该执行以下操作:

    1. RefreshScope 中定义ConfigurationProperties Component

      @Component
      @RefreshScope
      @ConfigurationProperties("storeclient")
      public class StoreClientProperties {
          private String url;
          ...
      }
      
    2. application.yml中指定客户端的默认URL

      storeclient
          url: https://someurl
      
    3. 定义RequestInterceptor来切换URL

      @Configuration
      public class StoreClientConfiguration {
      
          @Autowired
          private StoreClientProperties storeClientProperties;
      
          @Bean
          public RequestInterceptor urlInterceptor() {
              return template -> template.insert(0, storeClientProperties.getUrl());
          }
      
      }
      
    4. 在 URL 的 FeignClient 定义中使用一些占位符,因为它不会被使用

      @FeignClient(name = "storeClient", url = "NOT_USED")
      public interface StoreClient {
          //..
      }
      

    现在storeclient.url可以刷新,定义的URL将用于RequestTemplate发送http请求。

    【讨论】:

      【解决方案2】:

      RequestInterceptor 有点扩展答案:

      1. application.yml
      app:
        api-url: http://external.system/messages
        callback-url: http://localhost:8085/callback
      
      1. @ConfigurationProperties
      @Component
      @RefreshScope
      @ConfigurationProperties("app")
      public class AppProperties {
          private String apiUrl;
          private String callbackUrl;
          ...
      }
      
      1. @FeignClient-s 配置

      确保您的 ...ClientConfig 类未使用任何 @Component/... 注释进行注释,也未通过组件扫描找到。

      public class ApiClientConfig {
          @Bean
          public RequestInterceptor requestInterceptor(AppProperties appProperties) {
              return requestTemplate -> requestTemplate.target(appProperties.getApiUrl());
          }
      }
      
      public class CallbackClientConfig {
          @Bean
          public RequestInterceptor requestInterceptor(AppProperties appProperties) {
              return requestTemplate -> requestTemplate.target(appProperties.getCallbackUrl());
          }
      }
      
      1. @FeignClient-s
      @FeignClient(name = "apiClient", url = "NOT_USED", configuration = ApiClientConfig.class)
      public interface ApiClient {
          ...
      }
      
      @FeignClient(name = "callbackClient", url = "NOT_USED", configuration = CallbackClientConfig.class)
      public interface CallbackClient {
          ...
      }
      

      【讨论】:

        猜你喜欢
        • 1970-01-01
        • 2020-06-26
        • 1970-01-01
        • 2022-11-10
        • 1970-01-01
        • 2018-04-27
        • 1970-01-01
        • 2016-05-31
        • 1970-01-01
        相关资源
        最近更新 更多