SpringCloud中的Feign详解

 更新时间:2023年09月11日 11:42:49   作者:silmeweed  
这篇文章主要介绍了SpringCloud中的Feign详解,Feign是一个声明式的Web Service客户端,以Java接口注解的方式调用Http请求,同时Feign整合了Ribbon和Hystrix,实现负载均衡与容断功能,需要的朋友可以参考下

一、简介:

Feign是一个声明式的Web Service客户端,以Java接口注解的方式调用Http请求。同时Feign整合了Ribbon和Hystrix,实现负载均衡与容断功能。

1. Feign具有如下特性:

  • 可插拔的注解支持,包括Feign注解和JAX-RS注解;
  • 支持可插拔的HTTP编码器和解码器;
  • 支持Hystrix和它的Fallback;
  • 支持Ribbon的负载均衡;
  • 支持HTTP请求和响应的压缩
  • feign不支持GET请求直接传递POJO对象的.

2.@FeignClient注解说明

@FeignClient:是Spring识别OpenFeign客户端的注释,OpenFign客户端必须是接口。

@Target(ElementType.TYPE)
@Retention(RetentionPolicy.RUNTIME)
@Documented
public @interface FeignClient {
    //1.Ribbon负载均衡器的Feign客户端的名称
    @AliasFor("name")
    String value() default "";
    @AliasFor("value")
    String name() default "";
    //不使用ribbon时,请求url
    String url() default "";
    //配置响应状态码为404时是否应该抛出FeignExceptions
    boolean decode404() default false;
    //用于记录,拦截器等额外配置.
    Class<?>[] configuration() default {};
    //如果启用了Hystrix,则可以实现回退方法
    Class<?> fallback() default void.class;
    Class<?> fallbackFactory() default void.class;
    //自动给所有方法的requestMapping前加上前缀
    String path() default "";
    boolean primary() default true;
}

@FeignClient(value = "common-wx", url = "www.baidu.com/common-wx")

  • value/name:是将用于创建Ribbon负载均衡器的Feign客户端的名称.
  • url: 当您不使用Ribbon时,您还可以使用url属性将客户端指向目标应用程序。
  • fallback:如果启用了Hystrix,则可以实现回退方法.(底层依赖hystrix,启动类要加上@EnableHystrix)
  • configuration:用于记录,拦截器等额外配置.
  • path: 自动给所有方法的requestMapping前加上前缀,类似与controller类上的requestMapping
  • decode404:配置响应状态码为404时是否应该抛出FeignExceptions。(默认false)

3. HTTP客户端

OpenFeign的默认HTTP客户端HttpUrlConnection用于执行其HTTP请求。您可以配置其他客户端(ApacheHttpClient,OkHttpClient)

(1)使用OKhttp发送request

Feign底层默认是使用jdk中的HttpURLConnection发送HTTP请求,feign也提供了OKhttp来发送请求,具体配置如下:

//作用在所有Feign Client上的配置.
feign:
  client:
    config:
      default:
        connectTimeout: 5000
        readTimeout: 5000
        loggerLevel: basic
  okhttp:
    enabled: true
  hystrix:
    enabled: true

4.构建器(启用feign客户端)

构建器是让我们创建一个客户端bean并返回一个Feign构建器。生成方式有二种:

(1) 基于面向接口的动态代理方式生成实现类。使用Feign.builder()操作类实现。 

(2) 使用注解@EnableFeignClients启用feign客户端.(需要结合使用注解@FeignClient 定义一起使用)

注解@EnableFeignClients:扫描和注册feign客户端bean定义。 注解@EnableFeignClients用于告诉框架扫描所有通过注解@FeignClient定义的feign客户端。

//1.生成Bean 
@Bean
AuthClient authClient() {
    return Feign.builder()
            .client(new ApacheHttpClient())//重新使用HttpClient
            .target(AuthClient.class, baseServerUrl);
}
//2.注解方式生成Bean(需要使用注解@FeignClient 定义结合)
@EnableFeignClients(
    defaultConfiguration = DefaultFeignConfiguration.class,
    basePackages= {"com.missuteam.onepiece.oauth.api.impl"}
)
@Retention(RetentionPolicy.RUNTIME)
@Target(ElementType.TYPE)
@Documented
@Import(FeignClientsRegistrar.class)
public @interface EnableFeignClients {
   //扫描的包路径
    String[] value() default {};
    String[] basePackages() default {};
    Class<?>[] basePackageClasses() default {};
    //配置
    Class<?>[] defaultConfiguration() default {};
    //配置HttpClient 
    Class<?>[] clients() default {};
}
//自定义配置
@Configuration
public class DefaultFeignConfiguration {
    @Bean
    public Retryer feignRetryer() {
        return new Retryer.Default(1000,3000,3);
    }
    @Bean
    public Logger.Level feignLoggerLevel(){
        return Logger.Level.BASIC;
    }
}
//可配置的属性
public static class FeignClientConfiguration {
    private Logger.Level loggerLevel;
    private Integer connectTimeout;
    private Integer readTimeout;
    private Class<Retryer> retryer;
    private Class<ErrorDecoder> errorDecoder;
    private List<Class<RequestInterceptor>> requestInterceptors;
    private Boolean decode404;
    private Class<Decoder> decoder;
    private Class<Encoder> encoder;
    private Class<Contract> contract;
}

5. Contract协议规则(接口定义时的注释规则)

(1)默认Contract 实现:

Feign 默认有一套自己的协议规范,规定了一些注解,可以映射成对应的Http请求。

注解接口Target使用说明
@RequestLine方法上定义HttpMethod 和 UriTemplate. UriTemplate 中使用{} 包裹的表达式
@Param方法参数定义模板变量,模板变量的值可以使用名称的方式使用模板注入解析
@Headers类上或者方法上定义头部模板变量,使用@Param 注解提供参数值的注入。如果该注解添加在接口类上,则所有的请求都会携带对应的Header信息;如果在方法上,则只会添加到对应的方法请求上
@QueryMap方法上定义一个键值对或者 pojo,参数值将会被转换成URL上的 query 字符串上
@HeaderMap方法上定义一个HeaderMap, 与 UrlTemplate 和HeaderTemplate 类型,可以使用@Param 注解提供参数值

(2)基于Spring MVC的协议规范SpringMvcContract:

当前Spring Cloud 微服务解决方案中,为了降低学习成本,采用了Spring MVC的部分注解来完成 请求协议解析,也就是说 ,写客户端请求接口和像写服务端代码一样。目前的Spring MVC的注解并不是可以完全使用的,有一些注解并不支持,如 @GetMapping , @PutMapping  等,仅支持使用 @RequestMapping  等。

6.Feign开启GZIP压缩

Spring Cloud Feign支持对请求和响应进行GZIP压缩,以提高通信效率。开启GZIP压缩之后,Feign之间的调用数据通过二进制协议进行传输,返回值需要修改为ResponseEntity<byte[]>才可以正常显示。

//作用在所有Feign Client上的配置
feign:
  compression:
    request: #请求
      enabled: true #开启
      mime-types: text/xml,application/xml,application/json #开启支持压缩的MIME TYPE
      min-request-size: 2048 #配置压缩数据大小的下限
    response: #响应
      enabled: true #开启响应GZIP压缩

7. 配置:

##################FeignClientProperties###############
#全局默认配置名称:defalut
feign.client.config.defalut.error-decoder=com.example.feign.MyErrorDecoder
feign.client.config.defalut.connectTimeout=5000
#修改全局默认配置名称为:my-config
feign.client.default-config=my-config
feign.client.config.my-config.error-decoder=com.example.feign.MyErrorDecoder
feign.client.config.my-config.connectTimeout=5000
#局部配置,@FeignClient#name=user
feign.client.config.user.error-decoder=com.example.feign.MyErrorDecoder
feign.client.config.user.connectTimeout=5000
##################FeignHttpClientProperties##################
feign.httpclient.enabled=true
feign.httpclient.connectionTimeout=5000
##################FeignClientEncodingProperties##################
# 配置请求GZIP压缩
feign.compression.request.enabled=true
# 配置响应GZIP压缩 FeignContentGzipEncodingAutoConfiguration
feign.compression.response.enabled=true
# 配置压缩支持的MIME TYPE
feign.compression.request.mime-types=text/xml,application/xml,application/json
# 配置压缩数据大小的下限
feign.compression.request.min-request-size=2048

二、原理分析

在服务调用的场景中,我们经常调用基于Http协议的服务,而我们经常使用到的框架可能有HttpURLConnection、Apache HttpComponnets、OkHttp3 、Netty等等。(如下图)

 在Feign 底层,通过基于面向接口的动态代理方式生成实现类,将请求调用委托到动态代理实现类,基本原理如下所示

到此这篇关于SpringCloud中的Feign详解的文章就介绍到这了,更多相关Feign详解内容请搜索脚本之家以前的文章或继续浏览下面的相关文章希望大家以后多多支持脚本之家!

相关文章

  • java stream实现分组BigDecimal求和以及自定义分组求和

    java stream实现分组BigDecimal求和以及自定义分组求和

    这篇文章主要给大家介绍了关于java stream实现分组BigDecimal求和以及自定义分组求和的相关资料,Stream是Java8的一大亮点,是对容器对象功能的增强,它专注于对容器对象进行各种非常便利、高效的聚合操作或者大批量数据操作,需要的朋友可以参考下
    2023-12-12
  • JAVA中的 map,list,set

    JAVA中的 map,list,set

    这篇文章主要介绍了JAVA中的 map、list、set这三个集合,下面文章围绕JAVA中的三大集合 map、list、set详情讲解,需要的朋友可以参考一下
    2021-11-11
  • java常用API介绍之包装类

    java常用API介绍之包装类

    这篇文章主要介绍了java常用API介绍之包装类,API,即Application Programming Interface,中文名称是“应用程序接口",这些接口就是"jdk所提供"给我们使用的类,需要的朋友可以参考下
    2023-04-04
  • Java线程池中的各个参数如何合理设置

    Java线程池中的各个参数如何合理设置

    这篇文章主要介绍了Java线程池中的各个参数如何合理设置操作,具有很好的参考价值,希望对大家有所帮助。如有错误或未考虑完全的地方,望不吝赐教
    2021-06-06
  • Spring集成JPA配置懒加载报错解决方案

    Spring集成JPA配置懒加载报错解决方案

    这篇文章主要介绍了Spring集成JPA配置懒加载报错解决方案,文中通过示例代码介绍的非常详细,对大家的学习或者工作具有一定的参考学习价值,需要的朋友可以参考下
    2019-10-10
  • Java中的String、StringBuilder、StringBuffer三者的区别详解

    Java中的String、StringBuilder、StringBuffer三者的区别详解

    这篇文章主要介绍了Java中的String、StringBuilder、StringBuffer三者的区别详解,就是String,StringBuilder以及StringBuffer这三个类之间有什么区别呢,自己从网上搜索了一些资料,有所了解了之后在这里整理一下,便于大家观看,需要的朋友可以参考下
    2023-12-12
  • IDEA中Maven依赖包无法下载或导入的解决方案(系统缺失文件导致)

    IDEA中Maven依赖包无法下载或导入的解决方案(系统缺失文件导致)

    在配置Maven环境时,可能会遇到各种报错问题,首先确保Maven路径配置正确,例如使用apache-maven-3.5.0版本,则需要在系统环境变量的Path中添加其bin目录路径,并上移优先级,接下来,在Maven的conf目录下修改settings.xml文件,将镜像源改为阿里云
    2024-09-09
  • Java中StringBuilder常用构造方法解析

    Java中StringBuilder常用构造方法解析

    这篇文章主要介绍了Java中StringBuilder常用构造方法解析,StringBuilder是一个可标的字符串类,我们可以吧它看成是一个容器这里的可变指的是StringBuilder对象中的内容是可变的,需要的朋友可以参考下
    2024-01-01
  • SpringBoot整合Elasticsearch游标查询的示例代码(scroll)

    SpringBoot整合Elasticsearch游标查询的示例代码(scroll)

    这篇文章主要介绍了SpringBoot整合Elasticsearch游标查询(scroll),本文给大家介绍的非常详细,对大家的学习或工作具有一定的参考借鉴价值,需要的朋友可以参考下
    2020-10-10
  • 详解Hibernate缓存与性能优化

    详解Hibernate缓存与性能优化

    在hibernate中,提到性能优化,很自然地我们就想到了缓存。缓存是什么,都有哪些呢?下面这篇文章就主要给大家介绍了关于Hibernate缓存与性能优化的相关资料,需要的朋友可以参考下。
    2017-02-02

最新评论