Feign最全详解(工作原理及用法使用)

Feign最全详解(工作原理及用法使用)

Feign是非常重要的微服务组件,也是SpringCloud的核心组件,下面我就全面来详解Feign@mikechen

Feign

Feign 是一个声明式、模板化的 HTTP 客户端,Feign 可以与 Spring Cloud 很好地集成。

Feign 提供了一种在微服务架构中,一种简单、优雅的方式来调用 RESTful 服务。

Feign 只需要定义接口,无需手动编写 HTTP 请求的代码,大大简化了客户端代码的编写。

 

Feign优缺点

优点:

  1. 简化了客户端代码: Feign 只需要定义接口,并使用注解描述远程服务的细节,而无需手动编写 HTTP 请求的代码,大大简化了客户端代码的编写。
  2. 与 Spring Cloud 集成良好: Feign 可以很方便地与 Spring Cloud 等微服务框架集成,提供了一种在微服务架构中进行服务调用的便捷方式。
  3. 自带负载均衡和容错支持: Feign 整合了 Ribbon 和 Hystrix,可以实现负载均衡和容错,提高了服务的可用性和稳定性。

 

缺点:

  1. 依赖关系: 使用 Feign 需要依赖于 Spring Cloud 或者其他类似的微服务框架,如果不使用这些框架,Feign 将无法正常工作。
  2. 性能损耗: 由于 Feign 是基于动态代理和注解实现的,相比于直接使用 HttpClient 等底层 HTTP 客户端,可能存在一定的性能损耗。

 

Feign原理

Feign 的原理:是通过动态代理、和注解来简化 HTTP 客户端的编写。

1、注解

在使用 Feign 时,我们只需定义一个接口,并在接口上添加 @FeignClient 注解来指定要调用的服务名称。

如下所示:

  1. import org.springframework.cloud.openfeign.FeignClient;
  2. import org.springframework.web.bind.annotation.GetMapping;
  3. import org.springframework.web.bind.annotation.PathVariable;
  4.  
  5. @FeignClient(name = "userService", url = "http://user-service-url")
  6. public interface UserFeignClient {
  7. @GetMapping("/users/{userId}")
  8. User getUserById(@PathVariable("userId") Long userId);
  9. }

Feign 在程序运行时,会通过 Java 的动态代理技术,生成一个实现了该接口的代理对象。

 

2、动态代理

例如,假设我们有一个接口 UserService,并使用 Feign 进行代理:

  1. import org.springframework.cloud.openfeign.FeignClient;
  2. import org.springframework.web.bind.annotation.GetMapping;
  3. import org.springframework.web.bind.annotation.PathVariable;
  4.  
  5. @FeignClient(name = "userService", url = "http://user-service-url")
  6. public interface UserService {
  7. @GetMapping("/users/{userId}")
  8. User getUserById(@PathVariable("userId") Long userId);
  9. }

在运行时,Feign 将会生成一个实现了 UserService 接口的代理对象。

当调用 UserService 接口的方法时,实际上是调用 Feign 生成的代理对象的方法。

Feign大致工作流程,如下图所示:

Feign最全详解(工作原理及用法使用)

 

Feign使用

1、定义接口

首先,我们需要定义一个 Feign 接口,来声明我们要调用的远程服务:

  1. import org.springframework.cloud.openfeign.FeignClient;
  2. import org.springframework.web.bind.annotation.GetMapping;
  3.  
  4. @FeignClient(name = "helloService", url = "http://localhost:8080") // 指定服务名称和 URL
  5. public interface HelloFeignClient {
  6.  
  7. @GetMapping("/hello") // 指定请求的路径
  8. String getHelloMessage(); // 定义方法,用于调用远程服务
  9. }

 

2、feign使用

接下来,我们在另一个微服务中,使用这个 Feign 接口来调用远程服务:

  1. import org.springframework.beans.factory.annotation.Autowired;
  2. import org.springframework.web.bind.annotation.GetMapping;
  3. import org.springframework.web.bind.annotation.RestController;
  4.  
  5. @RestController
  6. public class HelloController {
  7.  
  8. @Autowired
  9. private HelloFeignClient helloFeignClient; // 注入 Feign 接口
  10.  
  11. @GetMapping("/message")
  12. public String getMessage() {
  13. // 调用 Feign 接口中定义的方法,实际上是发送 HTTP 请求到远程服务
  14. String message = helloFeignClient.getHelloMessage();
  15. return "Received message from remote service: " + message;
  16. }
  17. }

在这个示例中,HelloController 类中的 getMessage() 方法调用了 HelloFeignClient 接口中定义的 getHelloMessage() 方法。

陈睿mikechen

10年+大厂架构经验,资深技术专家,就职于阿里巴巴、淘宝、百度等一线互联网大厂。

关注作者「mikechen」公众号,获取更多技术干货!

后台回复架构,即可获取《阿里架构师进阶专题全部合集》,后台回复面试即可获取《史上最全阿里Java面试题总结

0 条回复 A文章作者 M管理员
欢迎您,新朋友,感谢参与互动!
    暂无讨论,说说你的看法吧