FeignClient介绍
简介
1、什么是FeignClient
Feign:
Feign 的英文表意为“假装,伪装,变形”, 是一个http请求调用的轻量级框架,灵感来自于Retrofit。
Feign 可以以Java接口注解的方式调用Http请求,而不用像Java中通过封装HTTP请求报文的方式直接调用。Feign通过处理注解,将请求模板化,当实际调用的时候,传入参数,根据参数再应用到请求上,进而转化成真正的请求,这种请求相对而言比较直观
Feign 是Spring Cloud组件中一个轻量级RESTful的HTTP服务客户端,Feign内置了Ribbon,用来做客户端负载均衡,去调用服务注册中心的服务。
区别与dubbo基于tcp协议,feign是基于http的
OpenFeign:
OpenFeign是Spring Cloud在Feign的基础上支持了SpringMVC的注解,如@RequestMapping等等。OpenFeign的@FeignClient可以解析SpringMVC的@RequestMapping注解下的接口,并通过动态代理的方式产生实现类
一般而言feignClient通常指的是openfeign:
由于springcloud F 及F版本以上 springboot 2.0 以上基本上使用openfeign,openfeign 如果从框架结构上看就是2019年feign停更后出现版本,也可以说大多数新项目都用openfeign ,2018年以前的项目在使用feign。
因此本文内容主要说的就是openFeign
2、feignClient使用:
依赖引入:
<dependency>
<groupId>org.springframework.cloud</groupId>
<artifactId>spring-cloud-starter-openfeign</artifactId>
<version>2.1.5.RELEASE</version>
</dependency>
使用场景
主配置类使用@EnableFeignClients注解开启
package com.cvte.maxhub.mhqa;
@SpringBootApplication
@EnableFeignClients
public class Application {
public static void main(String[] args) {
SpringApplication app = new SpringApplication(Application.class);
app.setBannerMode(Banner.Mode.OFF);
app.run(args);
}
}
1、在基于spring-cloud的微服务中作为rpc使用
在接口中使用@FeignClient(value = "微服务名")来调用对应服务的接口
@FeignClient自带负载均衡(基于ribbon)
package com.cvte.maxhub.mhqa.link.service.remote;
@FeignClient(value = "ferry-executor")
public interface RemoteFerryExecutorService {
@GetMapping("executor/task")
Result build(@RequestParam String instanceId, @RequestParam int resourceOrder);
}
以上接口是用于调用ferry-executor服务的executor/task接口,如下,编写好controller后,将接口直接拷贝过去就能用,非常方便
package com.cvte.maxhub.ferrybroker.controller;
@RestController
@RequestMapping("executor")
@RequiredArgsConstructor
@Slf4j
public class TaskInstanceExecController {
private final InstanceExecutor instanceExecutor;
@GetMapping("task")
public Result<BuildInfoVO> build(@RequestParam String instanceId,
@RequestParam int resourceOrder) throws EnvException {
return Result.success("创建任务成功", instanceExecutor.process(instanceId, resourceOrder));
}
}
2、作为普通httpclient使用
在接口中使用@FeignClient(value = "微服务名", url="hostname")来调用对应服务的接口
@FeignClient用做普通的httpclient时候可以通过url指定host来调用接口
以上接口是用于调用http://localhost:9090的executor/task接口,
package com.cvte.maxhub.mhqa.link.service.remote;
@FeignClient(value = "ferry-executor", url = "http://localhost:9090")
public interface RemoteFerryExecutorService {
@GetMapping("executor/task")
Result build(@RequestParam String instanceId, @RequestParam int resourceOrder);
}
当url需要灵活设置,可以采用以下在函数中添加URI的方式实现。调用build函数的时候动态传入uri可以使用调用不同host的接口
package com.cvte.maxhub.mhqa.link.service.remote;
@FeignClient(value = "ferry-executor", url = "http://localhost:9090")
public interface RemoteFerryExecutorService {
@GetMapping("executor/task")
Result build(URI uri, @RequestParam String instanceId, @RequestParam int resourceOrder);
}
被调用的接口
package com.cvte.maxhub.ferrybroker.controller;
@RestController
@RequestMapping("executor")
@RequiredArgsConstructor
@Slf4j
public class TaskInstanceExecController {
private final InstanceExecutor instanceExecutor;
@GetMapping("task")
public Result<BuildInfoVO> build(@RequestParam String instanceId,
@RequestParam int resourceOrder) throws EnvException {
return Result.success("创建任务成功", instanceExecutor.process(instanceId, resourceOrder));
}
}
3、优缺点:
优点:
1、使用简单、便捷
2、自带负载均衡
3、灵活
4、高度封装,不需要像OkHttp、HttpClient自己处理stream,比RestTemplate使用简单
5、代码维护简单,测试方便
缺点:
1、高度封装,不易于理解其底层原理
4、原理
HttpURLConnection、Apache HttpComponnets、OkHttp3 、Netty等:
这些框架在基于自身的专注点提供了自身特性。而从角色划分上来看,他们的职能是一致的提供Http调用服务。具体流程如下
这些框架需要频繁的封装HTTP请求报文的方式直接调用,并处理返回结果,相当不便捷,测试麻烦。
Feign:
A 在Feign 底层,通过基于面向接口的动态代理方式生成实现类,将请求调用委托到动态代理实现类,基本原理如下所示:
B 根据传入的Bean对象和注解信息,从中提取出相应的值,来构造Http Request 对象:
C Feign 最终会将请求转换成Http 消息发送出去,传入的请求对象最终会解析成消息体,如下所示:
涉及负载均衡ribbon部分后续再补充。。。