Feign详解(原理作用及使用实例)

Feign详解(原理作用及使用实例)-mikechen

Feign定义

Feign是Spring Cloud Netiflix组件中的一个轻量级Restful的HTTP服务客户端,通过 接口 + 注解的方式发起 HTTP 请求调用。

Feign面向接口编程,而不是像 Java 中通过封装 HTTP 请求报文的方式直接调用,集成了Ribbon(负载均衡组件)和Hystrix(服务治理组件)。

Feign被应用在Spring Cloud 的解决方案中,是学习基于Spring Cloud 微服务架构不可或缺的重要组件。

 

Feign作用

Feign 主要是帮助我们方便进行Rest API服务间的调用,Feign最大的作用就是减少 HTTP 远程调用的复杂性。

Feign实现了像调用本地方法一样调用远程方法,无感知远程HTTP 请求,类似于Dubbo Consumer直接调用Provider的接口方法。

服务消费方拿到服务提供方的接⼝,然后像调⽤本地接⼝⽅法⼀样去调⽤,实际发出的是远程的请求。

Feign使得开发人员无需关注与远程的交互细节,将更多的注意力集中在具体的业务开发,被⼴泛应⽤在 Spring Cloud 的解决⽅案中。

 

Feign使用

在Spring Cloud中使用 Feign 非常简单,创建一个接口并在接口上添加一些注解,代码就完成了。

如下所示:

1.引入 feign 的依赖

<!-- 支持使用feign客户端 --> <dependency> <groupId>org.springframework.cloud</groupId> <artifactId>spring-cloud-starter-openfeign</artifactId> </dependency>

 

2.开启Feign

通过@EnableFeignClients注解,开启Spring Cloud Feign的支持功能。

如下所示:

@MapperScan("com.mikechen.orderservice.mapper")
@SpringBootApplication
@EnableFeignClients    //开启Feign的功能
public class OrderServiceApplication {
    public static void main(String[] args) {
        SpringApplication.run(OrderServiceApplication.class, args);
    }
}

 

3.创建业务接口

添加@FeignClient接口,此接口是在Feign中调用微服务的核心接口,声明需要调用的服务。

如下所示:

@FeignClient("userservice")
public interface UserClient {
    @GetMapping("/user/{id}")
    User findById(@PathVariable("id") Long id);
}

详细的参数解释如下:

  • 定义各参数绑定时:@PathVariable、@RequestParam、@RequestHeader等可以指定参数属 性;
  • @FeignClient:注解通过name指定需要调用的微服务的名称,上面指定目标服务名称:userservice;
  • @GetMappding 指定发起的请求方式:GET;
  • @GetMappding 参数指定请求路径:/user/{id};
  • 成员方法的返回值指定了 http 请求返回值的类型:User;

 

4.Feign调用接口

然后就可以在代码中通过调用该接口类的方法来发起 http 请求了。

如下所示:

@Service
public class OrderService {
    @Autowired
    OrderMapper orderMapper;
    @Autowired
    private UserClient userClient;
    public Order queryOrderById(Long orderId) {
        // 1.查询订单
        Order order = orderMapper.findById(orderId);
        // 2.利用feign发起http请求
        User user = userClient.findById(orderId);
        // 3.封装user到Order
        order.setUser(user);
        // 4.返回
        return order;
    }
}

以上就使用了 Feign 客户端代替了 RestTemplate 来发起 http 请求。

 

Feign原理

通过上面的使用示例,我们知道了在启动类上标记 @EnableFeignClients 注解来开启feign的功能。

@MapperScan("com.mikechen.orderservice.mapper")
@SpringBootApplication
@EnableFeignClients    //开启Feign的功能
public class OrderServiceApplication {
    public static void main(String[] args) {
        SpringApplication.run(OrderServiceApplication.class, args);
    }
}

服务启动后会扫描 @FeignClient 注解标记的接口,然后根据扫描的注解信息为每个接口类生成feign客户端请求。

同时解析接口方法中的Spring MVC的相关注解,通过专门的注解解析器识别这些注解信息,以便后面可以正确的组装请求参数,使用 Ribbon 和 Eureka 获取到请求服务的真实地址等信息。

最后使用 http 相关组件进行执行调用。

其Feign大致工作流程图如下:

Feign详解(原理作用及使用实例)-mikechen

总的来说Feign 的源码实现过程如下:

1.首先通过@EnableFeignClients注解开启FeignClient 的功能,只有这个注解存在,才会在程序启动时开启对@FeignClient注解的包扫描;

2.根据Feign的规则实现接口,并在接口上面加上@FeignClient注解;

3.程序启动后会进行包扫描,扫描所有的@ FeignClient 的注解的类,并将这些信息注入IOC容器中;

4.当接口的方法被调用时,通过JDK的代理来生成具体的RequestTemplate模板对象;

5.根据RequestTemplate再生成Http请求的Request对象;

6.Request 对象交给Client去处理,其中Client的网络请求框架可以是HtpURLConnection、HttpClient等;

7.最后Client被封装到LoadBalanceClient类,这个类结合类Ribbon做到了负载均衡。

陈睿mikechen

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

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

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

评论交流
    说说你的看法