Feign 是一个声明式的 web 服务客户端. 这使得 Web 服务客户端的写入更加方便 要使用 Feign 创建一个界面并对其进行注释. 它具有可插拔注释支持, 包括 Feign 注释和 JAX-RS 注释. Feign 还支持可插拔编码器和解码器. Spring Cloud 添加了对 Spring MVC 注释的支持, 并在 Spring Web 中使用默认使用的 HttpMessageConverters.Spring Cloud 集成 Ribbon 和 Eureka 以在使用 Feign 时提供负载均衡的 http 客户端
本文将介绍 Feign 的原理和一些相关知识点以及如何在项目中使用
一, Feign 的原理
1, 启动时, 程序会进行包扫描, 扫描所有包下所有 @FeignClient 注解的类, 并将这些类注入到 spring 的 IoC 容器中. 当定义的 Feign 中的接口被调用时, 通过 JDK 的动态代理来生成 RequestTemplate.
2,RequestTemplate 中包含请求的所有信息, 如请求参数, 请求 URL 等
3,RequestTemplate 生成 Request, 然后将 Request 交给 client 处理, 这个 client 默认是 JDK 的 HTTPUrlConnection, 也可以是 OKhttp,Apache 的 HTTPClient 等
4, 最后 client 封装成 LoadBaLanceClient, 结合 ribbon 负载均衡地发起调用
二, 项目中使用
1, 搭建 Eureka 注册中心
本文不介绍如何搭建 Eureka 服务, 不了解 Eureka 的可以前往查看这篇文章学习: SpringCloud 组件之 Eureka
2, 搭建目标服务
a, 导入依赖
- <dependency>
- <groupId>org.springframework.boot</groupId>
- <artifactId>spring-boot-starter-Web</artifactId>
- </dependency>
- <dependency>
- <groupId>org.springframework.cloud</groupId>
- <artifactId>spring-cloud-starter-netflix-eureka-client</artifactId>
- </dependency>
b, 启动类标注 Eureka 客户端注解
- /**
- * @author Gjing
- */
- @SpringBootApplication
- @EnableEurekaClient
- public class DemoApplication {
- public static void main(String[] args) {
- SpringApplication.run(DemoApplication.class, args);
- }
- }
c,YAML 文件配置
- server:
- port: 8090
- spring:
- application:
- name: demo
- eureka:
- client:
- service-url:
- defaultZone: http://localhost:8761/eureka/
d, 编写接口, 提供给 Feign 调用
- /**
- * @author Gjing
- **/
- @RestController
- public class TestController {
- @GetMapping("/test")
- public Map<String,Object>test() {
- Map<String,Object> map = new HashMap<>(16);
- map.put("code", "ok");
- return map;
- }
- @GetMapping("/test2")
- public String test2(@RequestParam(name = "param1") String param1) {
- return param1;
- }
- @PostMapping("/test3")
- public Integer test3(Integer id) {
- return id;
- }
- }
3, 搭建调用服务
a, 导入依赖
- <dependency>
- <groupId>org.springframework.boot</groupId>
- <artifactId>spring-boot-starter-Web</artifactId>
- </dependency>
- <dependency>
- <groupId>org.springframework.cloud</groupId>
- <artifactId>spring-cloud-starter-netflix-eureka-client</artifactId>
- </dependency>
- <dependency>
- <groupId>org.springframework.cloud</groupId>
- <artifactId>spring-cloud-starter-openfeign</artifactId>
- </dependency>
b, 启动类增加注解
- /**
- * @author Gjing
- */
- @SpringBootApplication
- @EnableFeignUtil
- @EnableEurekaClient
- public class FeignApplication {
- public static void main(String[] args) {
- SpringApplication.run(FeignApplication.class, args);
- }
- }
c,YAML 配置
- server:
- port: 8083
- spring:
- application:
- name: feign-demo
- eureka:
- client:
- service-url:
- defaultZone: http://localhost:8761/eureka/
d, 创建 service, 用于调用服务
- /**
- * @author Gjing
- **/
- @FeignClient(name = "demo")
- public interface FeignTestService {
- @RequestMapping(value = "/test", method = RequestMethod.GET)
- Map<String,Object>test();
- @RequestMapping(value = "test4", method = RequestMethod.GET)
- String test2(@RequestParam("param1") String param1);
- @RequestMapping(value = "/test3", method = RequestMethod.POST)
- Integer test3(@RequestParam("id") Integer id);
- }
e, 编写 Controller 进行测试访问
- /**
- * @author Gjing
- **/
- @RestController
- public class FeignTestController {
- @Resource
- private FeignTestService feignTestService;
- @GetMapping("/test")
- public String test() {
- return feignTestService.test().toString();
- }
- @GetMapping("/test2")
- public ResponseEntity test2() {
- String test2 = feignTestService.test2("你好");
- return ResponseEntity.ok(test2);
- }
- @GetMapping("/test3")
- public ResponseEntity test3() {
- Integer test3 = feignTestService.test3(1);
- return ResponseEntity.ok(test3);
- }
- }
4,Feign 如何进行回退处理
Feign 本身集成了 Hystrix, 因此, 我们直接在启动类加上 @EnableCircuitBreaker 即可, 对 Hystrix 不了解的可以前往这篇文章: SpringCloud 组件之 Hystrix
a,pom 文件增加依赖, 否则会 Hystrix 出错
- <dependency>
- <groupId>org.springframework.cloud</groupId>
- <artifactId>spring-cloud-starter-netflix-hystrix</artifactId>
- </dependency>
b, 启动类增加注解
@EnableCircuitBreaker
c,YAML 文件开启 Hystrix 保护
- feign:
- hystrix:
- enabled: true
d, 创建回退类并实现之前的 Feign 接口类
- /**
- * @author Gjing
- **/
- @Component
- public class FeignTestFallbackImpl implements FeignTestService {
- @Override
- public Map<String, Object> test() {
- // TODO: 2019/7/3 这里就实现回退后的处理咯
- Map<String,Object> map = new HashMap<>(16);
- map.put("code", "回退了");
- return map;
- }
- @Override
- public String test2(String param1) {
- return null;
- }
- @Override
- public Integer test3(Integer id) {
- return null;
- }
- }
e, 修改 feign 接口类, 设置回退类
- /**
- * @author Gjing
- **/
- @FeignClient(name = "demo",fallback = FeignTestFallbackImpl.class)
- public interface FeignTestService {
- @RequestMapping(value = "/test", method = RequestMethod.GET)
- Map<String,Object> test();
- @RequestMapping(value = "test4", method = RequestMethod.GET)
- String test2(@RequestParam("param1") String param1);
- @RequestMapping(value = "/test3", method = RequestMethod.POST)
- Integer test3(@RequestParam("id") Integer id);
- }
f, 调用测试
如果出现超时或者异常, 将进行回退处理
本文到此就结束了, 如果发现有误欢迎指正哦, Feign 默认是使用 HttpUrlConnection 进行 http 请求的, 还支持 okHttp 和 httpClient 的哈, 这些用法大家自行研究, 本文不作介绍了, 如果有兴趣了解另一种使用 Feign, 可以参考我这篇文章: SpringCloud-Feign,Demo 源代码地址: SpringCloud-Demo
来源: https://yq.aliyun.com/articles/707308