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详解内容请搜索脚本之家以前的文章或继续浏览下面的相关文章希望大家以后多多支持脚本之家!

相关文章

  • kafka生产者和消费者的javaAPI的示例代码

    kafka生产者和消费者的javaAPI的示例代码

    这篇文章主要介绍了kafka生产者和消费者的javaAPI的示例代码,小编觉得挺不错的,现在分享给大家,也给大家做个参考。一起跟随小编过来看看吧
    2018-06-06
  • 零基础写Java知乎爬虫之获取知乎编辑推荐内容

    零基础写Java知乎爬虫之获取知乎编辑推荐内容

    上篇文章我们拿百度首页做了个小测试,今天我们来个复杂的,直接抓取知乎编辑推荐的内容,小伙伴们可算松了口气,终于进入正题了,哈哈。
    2014-11-11
  • java命令调用虚拟机方法总结

    java命令调用虚拟机方法总结

    在本篇文章里我们给大家整理了关于java中的java命令如何调用虚拟机的方法和具体步骤,需要的朋友们跟着操作下。
    2019-05-05
  • spring通过构造函数注入实现方法分析

    spring通过构造函数注入实现方法分析

    这篇文章主要介绍了spring通过构造函数注入实现方法,结合实例形式分析了spring通过构造函数注入的原理、实现步骤及相关操作注意事项,需要的朋友可以参考下
    2019-10-10
  • 简单了解JAVA NIO

    简单了解JAVA NIO

    这篇文章主要介绍了JAVA NIO的的相关资料,文中讲解非常细致,帮助大家更好的理解和学习,感兴趣的朋友可以了解下
    2020-07-07
  • Java实用小技能之快速创建List常用几种方式

    Java实用小技能之快速创建List常用几种方式

    java集合可以说无论是面试、刷题还是工作中都是非常常用的,下面这篇文章主要给大家介绍了关于Java实用小技能之快速创建List常用的几种方式,文中通过实例代码介绍的非常详细,需要的朋友可以参考下
    2022-12-12
  • 详解Java Slipped Conditions

    详解Java Slipped Conditions

    这篇文章主要介绍了Java Slipped Conditions的相关资料,帮助大家更好的理解和使用Java,感兴趣的朋友可以了解下
    2021-01-01
  • SpringBoot使用SensitiveWord实现敏感词过滤

    SpringBoot使用SensitiveWord实现敏感词过滤

    这篇文章主要为大家详细介绍了SpringBoot如何使用SensitiveWord实现敏感词过滤功能,文中示例代码讲解详细,感兴趣的小伙伴可以了解一下
    2023-01-01
  • Spring MVC参数自动绑定List的解决方法

    Spring MVC参数自动绑定List的解决方法

    这篇文章主要为大家详细介绍了Spring MVC参数自动绑定List的解决方法,具有一定的参考价值,感兴趣的小伙伴们可以参考一下
    2017-12-12
  • Java异步编程之Callbacks与Futures模型详解

    Java异步编程之Callbacks与Futures模型详解

    这篇文章主要为大家详细介绍了Java异步编程中Callbacks与Futures模型的使用,文中的示例代码讲解详细,感兴趣的小伙伴可以跟随小编一起学习一下
    2023-03-03

最新评论