首页 > 解决方案 > 如何将自定义 Http 客户端注入 Spring Cloud openfeign?

问题描述

我正在尝试向 Spring Cloud OpenFeign 提供 CloseableHttpClient。 Spring Cloud Open Feign Documentation说它支持 CloeableHttpClient。Spring 文档没有给出任何实际替换 HTTP 客户端的示例。

基本上,我正在向 HTTP 客户端提供 SSLContext,并且我希望 Feign 使用这个加载了 SSLContext 的客户端。如何将此 CloseableHttpClient 注入 Feign?

以下是我的相关配置:

  1. 我正在使用 SpringBootApp
@SpringBootApplication
@EnableFeignClients
public class Application extends SpringBootServletInitializer {

    public static void main(String[] args) {
        SpringApplication.run(Application.class, args);
    }
  1. Feign客户端界面如下:
import org.springframework.cloud.openfeign.FeignClient;
//skipping rest of the imports for brevity
    @FeignClient(name ="remote-service", url = "${remote.service-url}", configuration = FeignConfig.class)
        public interface RemoteServiceApi {
            @GetMapping(value = "/api/v1/resources/{Id}")
            public String getResource(@PathVariable("Id") String Id);
        }
  1. FeignConfig 类
import org.apache.http.impl.client.CloseableHttpClient;
//skipping rest of the imports for brevity
public class FeignConfig {
    @Bean
    public CloseableHttpClient client() {
         CloseableHttpClient httpClient=null;
         try {
                    //... Skipping code for brevity.  
                    //here creating "sslSocketFactory" used in the HttpClient builder below
                    httpClient = HttpClients.custom().setSSLSocketFactory(sslSocketFactory)
                    .setMaxConnTotal(10)
                    .setMaxConnPerRoute(10)
                    .build();
                
            }catch(IOException | KeyManagementException | UnrecoverableKeyException | NoSuchAlgorithmException | KeyStoreException | CertificateException e) {
                System.err.println("Exception during creation of HttpClient. : "+e.getMessage());
            }
        return httpClient;
    }
}
  1. 在 application.properties 中将 feign.httpclient.enabled 设置为 true
  2. Springboot 版本为 2.4.4。Feign 版本是 feign-core-10.10.1

我不明白的其他部分,Spring 将如何将这个自定义的 CloseableHttpClient 挂钩到 Feign,因为它声称。因为当我调试时,在运行时我看到 Feign 带注释的接口是由 feign.SynchronousMethodHandler 类实现的,并且此类中的 'client' 字段是 feign.Client 类型,并且在运行时它得到 com.sun.security.ntlm.Client (可能是默认实现)。CloseableHttpClient 应该如何注入到 feign.Client 中?网络上很少有这样的例子,他们也没有解释。

我在 SOF 上找到了这篇文章,但是

  1. 这里还注入了一个 CloseableHttpClient 类型的 @Bean
  2. 对此没有有用的答案。

标签: javaspringspring-bootopenfeign

解决方案


在我们注入的 bean 中,我们必须提供feign.Client的实现。最简单的是new Client.Default(SSLSocketFactory, HostnameVerifier)。我在我的问题中更改了代码中的 httpClient @Bean 注入:

@Bean
    public CloseableHttpClient client() {
 CloseableHttpClient httpClient=null;
         try {
                    //... Skipping code for brevity.  
                    //here creating "sslSocketFactory" used in the HttpClient builder below
                    httpClient = HttpClients.custom().setSSLSocketFactory(sslSocketFactory)
                    .setMaxConnTotal(10)
                    .setMaxConnPerRoute(10)
                    .build();
                
            }catch(IOException | KeyManagementException | UnrecoverableKeyException | NoSuchAlgorithmException | KeyStoreException | CertificateException e) {
                System.err.println("Exception during creation of HttpClient. : "+e.getMessage());
            }
        return httpClient;
    }
              

至 :

@Bean
    public feign.Client client() {
      
       feign.Client client=null;
        try {

      //... Skipping code for brevity.  
                    //here creating "sslSocketFactory" used in the HttpClient builder below
      client = new Client.Default(sslSocketFactory, new DefaultHostnameVerifier());
            
        }catch(IOException | KeyManagementException | UnrecoverableKeyException | NoSuchAlgorithmException | KeyStoreException | CertificateException e) {
            System.err.println("Exception during creation of HttpClient. : "+e.getMessage());
        }
}

经验教训:

文档说:“您可以通过在使用 Apache 时提供 ClosableHttpClient 或在使用 OK HTTP 时提供 OkHttpClient 的 bean 来自定义使用的 HTTP 客户端。”

然后人们说他们提供了 CloseableHttpClient ,因为它在这个问题中没有得到正确回答。这里的 bean 注入永远不会起作用。

最重要的是,OpenFeign 的 Github 文档谈到了使用 ApacheHttpClient。

这可能会使人感到困惑。我的问题的第二部分“我不明白的其他部分,Spring 如何将这个自定义的 CloseableHttpClient 挂钩到 Feign,因为它声称......这个类中的 'client' 字段的类型是 feign.Client ”

答案:

没有什么神奇的,ApacheHttpClient OpenFeign Github 文档所讨论的是 OpenFeign 对 Apache 的 HttpClient 库ApacheHttpClient的包装器,它实现了 feign.Client接口。

并且这个 ApacheHttpClient 实现在 Openfeign 的 Spring Boot starter 附带的 feign core 10.1.1 依赖项中不可用。


推荐阅读