Feign是一种声明式、模板化的HTTP客户端,Spring Cloud将其整合到了Netflix项目下。其主要目的是为了简化web service客户端开发,在springcloud体系中负责调用集群服务,降低开发量,擅长于RPC的调用领域。
Feign与eureka、ribbon集成后,就具备负载均衡的功能。其对自带注解和第三方注解都支持,另外提供编码器和解码器来帮助用户封装请求、解析响应。
一、基本操作
1、编码器
如果需要对请求内容进行处理,例如把客户端对象转成JSON、XML等场景,则需要使用Feign的编码器
2、解码器
客户端对服务响应的内容进行处理,例如把响应的JSON、XML转成对象
3、自定义解码器和编码器
如果对编码和解码有特殊要求,则可以进行自定义编码器和解码器。实现方法也非常简单:
编码器:实现Encoder的encode方法
解码器:实现Decoder的decode方法
4、自定义Feign客户端
Feign通过Client接口发送请求,Client有多种实现方式包括httpclient,默认使用java.net.HttpURLConnection。我们可以通过实现Feign.Client来自定义Feign客户端,逻辑写在execute方法里面。整个过程本质上是一个对象转换过程。
5、解析第三方注解
Feign支持第三方注解的使用。不过Feign本身不清楚第三方注解的意义,需要通过一个翻译器来进行翻译使用方法。
一个翻译器需要继承Feign.BaseContract类,BaseContract则是实现Contract接口。类如JARSContract这种第三方注解翻译器,也是继承了BaseContract。BaseContract有三个级别的注解处理方法,一般我们实现方法注解的那个即可。相关步骤:
5.1 定义新注解
5.2 新建Contract类,需要继承Contract.BaseContract,并实现其处理方法级注解等接口。
5.3 把contract传给feign.Client
6、请求拦截器
Feign支持在发送请求前,对发送的模板进行操作。如果要自定义连接器的话,则需要实现RequestInterceptor接口,实现其apply方法。自定义拦截器的步骤:
6.1、自定义拦截器,实现RequestInterceptor接口。
6.2、创建客户端,把自定义的拦截器传入reuqestInterceptor方法中,拦截器可以有多个。
7、接口日志
默认情况下, Feign是不记录接口日志的。为了方便了解接口的调用情况使用LogLevel方法来进行配置(配置日志输出位置以及级别)
public static void main(String[] args) {
// 获取服务接口
PersonClient personClient = Feign.builder()
.logLevel(Logger.Level.HEADERS)
.logger(new Logger.JavaLogger().appendToFile("logs/feign.log"))
.target(PersonClient.class, "http://127.0.0.1:8089/");
personClient.sayHello();
}
二、单独使用Feign
1、在pom.xml中引入Feign依赖
<dependency>
<groupId>io.github.openfeign</groupId>
<artifactId>feign-core</artifactId>
<version>9.5.0</version>
</dependency>
<dependency>
<groupId>io.github.openfeign</groupId>
<artifactId>feign-gson</artifactId>
<version>9.5.0</version>
</dependency>
2、编写服务接口,通过Get向服务提供方请求hello服务。
public interface HelloClient {
@RequestLine("GET /hello")
String sayHello();
}
3、 编写客户端运行类
public class HelloMain {
public static void main(String[] args) {
// 调用Hello接口
HelloClient hello = Feign.builder().target(HelloClient.class,
"http://127.0.0.1:8080/");
System.out.println(hello.getClass().getName());
System.out.println(hello.sayHello());
}
}
Feign利用jdk动态代理机制,生成动态代理,动态代理实例会封装请求信息,然后交给feign.Clint来发送请求。
三、Spring Cloud整合Feign
1、在pom.xml中引入Feign依赖
<dependency>
<groupId>org.springframework.cloud</groupId>
<artifactId>spring-cloud-starter-feign</artifactId>
</dependency>
2、在启动类中加入@EnableFeignClients注解,打开Feign开关
@SpringBootApplication
@EnableEurekaClient
@EnableFeignClients
public class InvokerApplication {
public static void main(String[] args) {
SpringApplication.run(InvokerApplication.class, args);
}
}
3、编写客户端接口,接口类前加@FeignClient(“调用的服务名称”)
@FeignClient("spring-feign-provider") //声明调用的服务名称
public interface PersonClient {
@RequestMapping(method = RequestMethod.GET, value = "/hello")
String hello();
@RequestMapping(method = RequestMethod.GET, value = "/person/{personId}")
Person getPerson(@PathVariable("personId") Integer personId);
}