01、Feign的核心概念及入门案例

1. 什么是Feign

概念

Feign是—个声明式、模板化的HTTP客户端,GitHub源码地址

在HTTP协议中,发送请求的一方就是HTTP 客户端,在JAVA 中,有很多HTTP 客户端框架。

实际Feign 是为了简化HTTP 客户端开发,实际通信部分还是调用了其他客户端框架。

工作原理

Feign 的工作原理是将注解处理成模板化的请求。

核心思想

Feign是声明式服务调用组件,其核心就是:像调用本地方法一样调用远程方法,无感知远程HTTP请求。

它解决了让开发者调用远程接口就跟调用本地方法一样的体验,开发者完全感知不到这是远程方法,更感知不到这是个HTTP请求。无需关注与远程的交互细节,更无需关注分布式环境开发。

Java 版本兼容性

Feign 10.x 及以上版本基于 Java 8 构建,应该适用于 Java 9、10 和 11。对于需要兼容 JDK 6 的用户,请使用 Feign 9.x。

功能

这是一张包含 feign 提供的当前关键功能的图:
 

1. Clients

Clients 包含了Feign支持的HTTP 客户端:

  • java.net.URL:JDK 提供的网络编程工具包
  • Apache HTTP:Apache 提供的HTTP Client包
  • Apache HC5:Apache 提供的HTTP Client 5.0 版本包
  • Google HTTP:Google 提供的Http 客户端工具包
  • Java 11 Http2:JDK 11 提供的对HTTP2 的支持工具包
  • OK Http : 开源的OkHttp 框架
  • Ribbon:基于HTTP和TCP的客户端负载均衡工具,基于Netflix Ribbon实现

2. async clients

Feign 还支持异步的HTTP 客户端:
 

3. contracts

contracts 部分,包含了Feign 遵守的一些协议规范。
 

4. encoders/decoders

encoders/decoders 是编码解码相关支持,Feign 在请求之前会进行编码操作,获取响应的时候会进行解码,之所以要进行编解码,是因为发送请求可能是对象,需要编码成服务端能解析的数据格式,比如Json。

Feign 支持常用的Jackson、Gson 及其他JAVA Json工具进行编解码。
 

5. metrics

metrics 模块,是对Dropwizard 、Micrometer 度量检测工具的支持。
 

6. extras

extras额外的其他功能,是对熔断器(Hystrix)、日志(SLF4J)等工具的支持。
 

2. 常用HTTP客户端案例演示

HttpURLConnection

HttpURLConnection是在JDK的java.net包中提供的用于HTTP协议访问的基本功能的类,但是由于使用步骤比较复杂,灵活性不够,所以一般很少直接用。

比如可以通过以下示例发送一个请求并获取响应信息。

        // 创建URL
        URL url = new URL("https://www.baidu.com");
        // 创建连接
        HttpURLConnection connection = (HttpURLConnection) url.openConnection();
        // 设置请求方法
        connection.setRequestMethod("GET");
        // 设置连接超时时间
        connection.setConnectTimeout(5 * 1000);
        // 连接
        connection.connect();
        // 获取响应的流并专为字符串输出
        InputStream inputStream = connection.getInputStream();
        byte[] data = new byte[1024];
        StringBuilder sb = new StringBuilder();
        int length = 0;
        while ((length = inputStream.read(data)) != -1) {

            String s = new String(data, Charset.forName("utf-8"));
            sb.append(s);
        }
        String message = sb.toString();
        System.out.println(message);
        // 关闭
        inputStream.close();
        connection.disconnect();

HttpURLConnection是基于HTTP协议的,其底层通过socket通信实现。其connect()方法,实际上只是建立了一个与服务器的tcp连接,并没有实际发送http请求,实际上直到其getInputStream()方法执行时才正式发送出去。

HttpClient

官方文档

尽管java.net包提供了通过 HTTP 访问资源的基本功能,但它并没有提供许多应用程序所需的灵活性或全部功能。

HttpClientApache Jakarta Common下的子项目,用来提供高效的、最新的、功能丰富的支持HTTP协议的客户端编程工具包,并且它支持HTTP协议最新的版本和建议。像很多开源框架通信的底层都是用的HttpClient。

在示例中可以看到,只需要几行代码就可以实现请求了。

        // 创建 Http Client
        try (CloseableHttpClient httpclient = HttpClients.createDefault()) {

            // 创建Get请求
            HttpGet httpGet = new HttpGet("https://www.baidu.com");
            // 执行请求
            try (CloseableHttpResponse response = httpclient.execute(httpGet)) {

                // 获取结果集
                HttpEntity entity1 = response.getEntity();
                InputStream content = entity1.getContent();
                byte[] buff = new byte[1024];
                StringBuilder sb1 = new StringBuilder();
                int length1 = 0;
                while ((length1 = content.read(buff)) != -1) {

                    String s = new String(buff, StandardCharsets.UTF_8);
                    sb1.append(s);
                }
                String message1 = sb1.toString();
                System.out.println(message1);
            }
        }

注意,最新版为5.X,不要引错依赖包了。

        <dependency>
            <groupId>org.apache.httpcomponents.client5</groupId>
            <artifactId>httpclient5</artifactId>
            <version>5.1.1</version>
        </dependency>

OkHttp

GitHub地址
官方文档地址

OkHttp不仅支持Java,还支持Android ,虽然资历没有HttpClient老,但是性能更加卓越,设计更加优秀。

示例如下:

        OkHttpClient client = new OkHttpClient();
        Request request = new Request.Builder()
                .url("https://www.baidu.com")
                .get()
                .build();
        try (Response response = client.newCall(request).execute()) {

            String string = response.body().string();
            System.out.println(string);
        }

Feign

Feign 最初是由Netfilx (网飞) 公司开源的,最初叫 Netfilx Feign ,2016年改名为 Open Feign,所以我们在使用的时候需要注意要使用Open Feign。

接下来使用一个简单案例,看下如何使用Feign 来发送HTTP 请求,和微服务整合会后续再详细介绍。

参考文档

首先进行环境搭建,为了节约时间,可以参考上面的搭建Spring Cloud 文档。

1. 引入依赖

        <dependency>
            <groupId>org.springframework.cloud</groupId>
            <artifactId>spring-cloud-starter-openfeign</artifactId>
        </dependency>

可以看到,这个版本的Feign 是10.12 。
&nbsp;

2. 编写Feign 接口

Feign 是声明式+模板式的,其原理是通过注解来处理模式化的请求,所以需要定义一个接口,使用注解声明HTTP 请求所需要的请求方式、参数、返回值等内容。

@RequestLine注解,声明了请求方式和请求路径,关于注解的具体使用方式,后续再介绍

public interface TestFeignClient {

    @RequestLine("GET /aa")
    String test();
}

3. 发送请求

使用Feign 的构造者模式,创建一个客户端,其会根据接口采用JDK动态代理生成,然后通过客户端发送请求。

    public static void main(String[] args) {

        TestFeignClient feignClient = Feign.builder().target(TestFeignClient.class, "https://baike.baidu.com/");
        String test = feignClient.test();
        System.out.println(test);
    }

最后获取到了该请求的响应数据。
&nbsp;