Spring Cloud学习笔记【五】Feign简单使用和原理了解
1 、什么是Feign?
feigin是一种模板化,声明式的http客户端,feign可以通过注解绑定到接口上来简化Http请求访问。当然我们也可以在创建Feign对象时定制自定义解码器(xml或者json等格式解析)和错误处理。
2、Open Feign vs Spring Cloud Feign
OpenFeign 是最原始,最早的feign,与Spring 无关。就是一个Java的组件,封装了对http请求和响应的处理。它的具体demo可以参考 Readme.txt。
3、SpringCloud对feign的支持
在Spring Cloud 1.XX 系列版本中,feign 没有被单独拿出来,而是放在spring-cloud-netflix 下面。依赖的pom是:
<dependency>
<groupId>org.springframework.cloud</groupId>
<artifactId>spring-cloud-starter-feign</artifactId>
</dependency>
而到了Spring Cloud 2.XX 系列版本后,feign 成为了Spring Cloud 下的一级项目,项目地址是:https://spring.io/projects/spring-cloud-openfeign
<dependency>
<groupId>org.springframework.cloud</groupId>
<artifactId>spring-cloud-starter-openfeign</artifactId>
</dependency>
a.启动类上增加注解@EnableFeignClients。
@SpringBootApplication
@EnableEurekaClient
@EnableFeignClients
public class DemoApplication {
public static void main(String[] args) {
SpringApplication.run(DemoApplication.class, args);
}
}
b.调用Feign的接口,可以指定服务,接口参数,接口地址,请求方法等 。
@FeignClient(name = "CLIENT-SERVICE")//服务名称
public interface ClientService {
//请求方式 和 请求地址
@GetMapping("/order/info")
String getOrderInfo();
}
c.服务提供者接口编写
@RestController
@RequestMapping("/order")
public class OrderController {
private Log LOGGER = LogFactory.getLog(OrderController.class);
@GetMapping("/info")
public String test(HttpServletRequest request) {
LOGGER.info("address:" + request.getRemoteAddr());
return "server:9005 order:info address:" + request.getRemoteAddr();
}
}
d.将接口注入到调用处使用
@RestController
@RequestMapping("/test")
public class TestClientController {
@Autowired
private ClientService clientService;
@RequestMapping("/orderInfo")
public String test() {
return clientService.getOrderInfo();
}
}
e.eureka注册中心
f.服务端的打印日志
g.调用返回的结果
4、原理了解
我们经常调用基于Http协议的服务,而我们经常使用到的框架可能有HttpURLConnection、Apache HttpComponnets、OkHttp3 、Netty等等,这些框架在基于自身的专注点提供了自身特性。而从角色划分上来看,他们的职能是一致的提供Http调用服务。具体流程如下:
feign设计流程
Feign的源码实现的过程如下:
- 首先通过@EnableFeignCleints注解开启FeignCleint
- 根据Feign的规则实现接口,并加@FeignCleint注解
- 程序启动后,会进行包扫描,扫描所有的@ FeignCleint的注解的类,并将这些信息注入到ioc容器中。
- 当接口的方法被调用,通过jdk的代理,来生成具体的RequesTemplate
- RequesTemplate在生成Request
- Request交给Client去处理,其中Client可以是HttpUrlConnection、HttpClient也可以是Okhttp
- 最后Client被封装到LoadBalanceClient类,这个类结合类Ribbon做到了负载均衡。