使用Feign发送http请求以及源码分析
简介
Feign是一个http请求调用的轻量级框架,可以用Java接口注解的方式调用Http请求,而不用像Java中通过封装HTTP请求报文的方式直接调用。
注解(Annotation)
注解 | 作用域 | 用法 |
---|---|---|
@RequestLine | 方法 | 定义HttpMethod和UriTemplate请求。 {expression}使用大括号括起来的值使用其相应的带@Param注释参数进行解析。 |
@Param | 参数 | 作用于参数上,定义一个模板变量,其值将用于Expression按名称解析相应的模板。 |
@Headers | 方法,类型 | 定义一个HeaderTemplate; 的变体UriTemplate。使用带@Param注释的值来解析相应的Expressions。在上使用时Type,该模板将应用于每个请求。当在上使用时Method,模板将仅应用于带注释的方法。 |
@QueryMap | 参数 | 定义一个Map名称-值对或POJO,以扩展为查询字符串。 |
@HeaderMap | 参数 | 定义一个Map名称-值对,以扩展为Http Headers |
@Body | 方法 | 定义Template,类似于UriTemplate和HeaderTemplate,使用@Param注释值来解决相应的Expressions。 |
如果需要将请求定向到其他主机,则需要在创建Feign客户端时提供的主机,或者要为每个请求提供目标主机,请包含一个java.net.URI参数,Feign将使用该值作为请求目标。
@RequestLine(“POST /repos/{owner}/{repo}/issues”)
void createIssue(URI host, Issue issue, @Param(“owner”) String owner, @Param(“repo”) String repo);
Demo
ready
idea创建一个springboot项目(此处本人项目端口设置为8089,可自行设置),勾选openfeign如下图所示:
test
创建controller作为服务接口
1 | package com.reallinxu.cloud.controller; |
创建接口,用来作为feign客户端
1 | package com.reallinxu.cloud.feign; |
创建一个Demo4用到的pojo
1 | package com.reallinxu.cloud.entity; |
创建测试案例进行测试
1 | package com.reallinxu.cloud.test; |
启动springboot项目,运行Test查看执行结果。
源码分析
定义feign客户端接口
TestInterface testInterface = Feign.builder().target(TestInterface.class, "http://localhost:8089");
feign.builder()时可以设置一些参数,未设置为默认值,参数对应如下:
1 | //控制日志级别 |
接下来我们看下target方法,原理主要是根据接口生成一个Proxy代理类,主要方法是build().newInstance(target)
特别注意框中的几个参数,我们debug进去看下,各自是什么东西
可以看出nameToHandler中的key为接口中的方法,value为初始化Feign时设置的参数,注意target中有传入的host地址
methodToHandler也很简单直白,明显就是为了以后的反射
1 | default void defaultMethod(){ |
我们将TestInterface接口中加入上方默认方法再debug可以看到defaultMehthodHandlers用于存放接口的默认方法,默认方法需要另外绑定到代理对象上。
调用feign客户端接口
代理类就已经生成完成,接下来我们看调用。
除了object中自带的一些方法其他的都走反射
这里可以看到创建了RestTemplate用来发起请求,并使用创建时设置的配置
创建RestTemplate时会将表达式进行转换为正确的连接
通过client发送请求,整个请求完成。
end
Feign的Http调用到此处就完结了,Feign微服务中还可以通过service-id进行调用,内部使用ribbon进行负载均衡,等后续有兴趣再继续更新,over~