ICode9

精准搜索请尝试: 精确搜索
首页 > 其他分享> 文章详细

springCloud Fegin

2021-07-25 21:31:13  阅读:178  来源: 互联网

标签:Feign Spring Fegin springCloud springframework import org 注解


Feign简介


我们之前学习的时候对微服务的调用采用了RestTemplate+Ribbon的方式 Feign是 Netflflix 公司开源的轻量级 Rest 客户端 ( https://github.com/OpenFeign/feign ) ,使用 Feign 可以非常方
便、简单的实现 Http 客户端, 使用 Feign 只需要定义一个接口,然后在接口上添加注解即可 。
Feign是Netflix开发的声明式、模板化的HTTP客户端, Feign可以帮助我们更快捷、优雅地调用HTTP API。
在Spring Cloud中,使用Feign非常简单——创建一个接口,并在接口上添加一些注解,代码就完成了。Feign支持多种注解,例如Feign自带的注解或者JAX-RS注解等。
Spring Cloud对Feign进行了增强,使Feign支持了Spring MVC注解,并整合了Ribbon和Eureka,从而让Feign的使用更加方便。
Spring Cloud Feign是基于Netflix feign实现,整合了Spring Cloud Ribbon和Spring Cloud Hystrix(后面会学习),除了提供这两者的强大功能外,还提供了一种声明式的Web服务客户端定义的方式。
Spring Cloud Feign帮助我们定义和实现依赖服务接口的定义。在Spring Cloud feign的实现下,只需要创建一个接口并用注解方式配置它,即可完成服务提供方的接口绑定,简化了在使用Spring Cloud Ribbon时自行封装服务调用客户端的开发量。
Spring Cloud Feign具备可插拔的注解支持,支持Feign注解、JAX-RS注解和Spring MVC的注解。

 

Feign的简单使用

 

1、在consumer模块的pom文件添加一个依赖

<!--feign 依赖-->
<dependency>
<groupId>org.springframework.cloud</groupId>
<artifactId>spring-cloud-starter-openfeign</artifactId>
</dependency>

2、新建 ProductClientService 接口,使用 @FeignClient(" 服务名称 ") 注解标识,来指定调用哪个服务。requestmapping里面的是要访问的服务提供者的访问路径和HTTP动词。

package com.haogenmin.consumer.service;

import com.haogenmin.model.Product;
import org.springframework.cloud.openfeign.FeignClient;
import org.springframework.web.bind.annotation.PathVariable;
import org.springframework.web.bind.annotation.RequestMapping;
import org.springframework.web.bind.annotation.RequestMethod;

import java.util.List;

/**
* @author :HaoGenmin
* @Title :ProductClientService
* @date :Created in 2020/6/29 14:14
* @description:
*/
@FeignClient(value = "microservice-product")
public interface ProductClientService {
@RequestMapping(value = "/provider/products", method = RequestMethod.POST)
public boolean add(Product product);

@RequestMapping(value = "/provider/products/{id}", method = RequestMethod.GET)
public Product get(Long id);

@RequestMapping(value = "/provider/products",method = RequestMethod.GET)
public List<Product> list();

}

3、修改controller,这时候之前配置的RestTemplate就没用了。

package com.haogenmin.consumer.controller;


import com.haogenmin.consumer.service.ProductClientService;
import com.haogenmin.model.Product;
import org.springframework.beans.factory.annotation.Autowired;
import org.springframework.web.bind.annotation.PathVariable;
import org.springframework.web.bind.annotation.RequestMapping;
import org.springframework.web.bind.annotation.RequestMethod;
import org.springframework.web.bind.annotation.RestController;
import org.springframework.web.client.RestTemplate;

import java.util.List;


@RestController
@RequestMapping("/consumer")
public class ProductController_Consumer {

@Autowired
private ProductClientService productClientService;

@RequestMapping(value = "/products", method = RequestMethod.POST)
public boolean add(Product product) {
return productClientService.add(product);
}

@RequestMapping(value = "/products/{id}", method = RequestMethod.GET)
public Product get(@PathVariable("id") Long id) {
return productClientService.get(id);
}

@RequestMapping(value = "/products",method = RequestMethod.GET)
public List<Product> list() {
return productClientService.list();
}



}


4、最后主启动类上面扫描一下我们的Feign客户端这个包。

package com.haogenmin.consumer;

import org.springframework.boot.SpringApplication;
import org.springframework.boot.autoconfigure.SpringBootApplication;
import org.springframework.cloud.netflix.eureka.EnableEurekaClient;
import org.springframework.cloud.openfeign.EnableFeignClients;

/**
* @author :HaoGenmin
* @Title :ConsumerApplication
* @date :Created in 2020/6/23 19:31
* @description:
*/
@EnableFeignClients(basePackages= {"com.haogenmin.consumer.service"})
@EnableEurekaClient
@SpringBootApplication
public class ConsumerApplication {
public static void main(String[] args) {
SpringApplication.run(ConsumerApplication.class,args);
}
}

展示:

 

以上的过程如下:

启动时,程序会进行包扫描,扫描所有包下所有@FeignClient注解的类,并将这些类注入到spring的IOC容器中。当定义的Feign中的接口被调用时,通过JDK的动态代理来生成RequestTemplate。
RequestTemplate中包含请求的所有信息,如请求参数,请求URL等。
RequestTemplate生成Request,然后将Request交给client处理,这个client默认是JDK的HTTPUrlConnection,也可以是OKhttp、Apache的HTTPClient等。
最后client封装成LoadBaLanceClient,结合ribbon负载均衡地发起调用。

Feign原理


Feign封装了Http调用流程,更适合面向接口化的变成习惯。

在服务调用的场景中,我们经常调用基于Http协议的服务,而我们经常使用到的框架可能有HttpURLConnection、Apache HttpComponnets、OkHttp3 、Netty等等,这些框架在基于自身的专注点提供了自身特性。而从角色划分上来看,他们的职能是一致的提供Http调用服务。具体流程如下:

 

 

 

 

Feign设计

 

 

 

要理解以上内容,需要理解动态代理的知识。

1、我们在自己写的接口上面加了注解以及注解里面的参数信息。Feign根据这些信息,生成了一个代理类,这个代理类可以把接口方法的参数,转成request,然后用ribbon找到服务器,用http客户端把请求发出去,再解析请求。等等等等。

2、代理类咋做的呢?我们知道动态代理真正执行的是InvocationHandler里面的invoke方法。实际上,Feign实现了专门用于FeignClient的InvocationHandler,但是,它是构建了一个接口方法到方法处理器的映射表(Method==>MethodHandler),当我们执行接口的method方法的时候,我们通过这个映射表找到对应的MethodHandler,MethodHandler是真正的执行者。

3、MethodHandler就厉害了,它根据参数信息,注解信息,把请求参数等相关信息创建了一个requestTemplate出来。然后执行请求并解析数据。这一切都是MethodHandler做的,当然,它用到了encoder和decoder以及httpClient。

4、Feign定义了拦截器接口,在请求发送之前可以拦截一下,对其进行自定义修改请求信息。

5、httpclient有很多种,默认的性能比较低,生产环境按需修改,而我们使用的一般是一个httpclient的包装类,为啥?因为我们配置的是应用名啊,我们得需要先找到对应的服务器才能发请求。所以这个httpclient是这个包装Client类的一个属性引用,在访问请求的时候,这个包装类先用ribbon根据负载策略找到合适的服务器IP端口。然后,用httpclient进行最终的请求。

如果大家觉得我说的太简单,看不懂。请看这一篇。我这里主要是针对源码进行分析。

原理参考:

https://www.cnblogs.com/crazymakercircle/p/11965726.html

 

标签:Feign,Spring,Fegin,springCloud,springframework,import,org,注解
来源: https://www.cnblogs.com/langcangsheng/p/15059071.html

本站声明: 1. iCode9 技术分享网(下文简称本站)提供的所有内容,仅供技术学习、探讨和分享;
2. 关于本站的所有留言、评论、转载及引用,纯属内容发起人的个人观点,与本站观点和立场无关;
3. 关于本站的所有言论和文字,纯属内容发起人的个人观点,与本站观点和立场无关;
4. 本站文章均是网友提供,不完全保证技术分享内容的完整性、准确性、时效性、风险性和版权归属;如您发现该文章侵犯了您的权益,可联系我们第一时间进行删除;
5. 本站为非盈利性的个人网站,所有内容不会用来进行牟利,也不会利用任何形式的广告来间接获益,纯粹是为了广大技术爱好者提供技术内容和技术思想的分享性交流网站。

专注分享技术,共同学习,共同进步。侵权联系[81616952@qq.com]

Copyright (C)ICode9.com, All Rights Reserved.

ICode9版权所有